xref: /openbsd-src/gnu/usr.bin/perl/ext/XS-APItest/t/blockhooks.t (revision 5759b3d249badf144a6240f7eec4dcf9df003e6b)
1#!/usr/bin/perl
2
3use warnings;
4use strict;
5use Test::More tests => 17;
6
7use XS::APItest;
8
9BEGIN { push @INC, '.' } # t/BHK.pm is in ext/XS-APItest/ directory
10
11use t::BHK ();      # make sure it gets compiled early
12
13BEGIN { package XS::APItest; *main::bhkav = \@XS::APItest::bhkav }
14
15# 'use t::BHK' switches on recording hooks, and clears @bhkav.
16# 'no t::BHK' switches recording off again.
17# 'use t::BHK push => "foo"' pushes onto @bhkav
18
19use t::BHK;
20    1;
21no t::BHK;
22
23BEGIN { is_deeply \@bhkav, [], "no blocks" }
24
25use t::BHK;
26    {
27        1;
28    }
29no t::BHK;
30
31BEGIN { is_deeply \@bhkav,
32    [[start => 1], qw/pre_end post_end/],
33    "plain block";
34}
35
36use t::BHK;
37    if (1) { 1 }
38no t::BHK;
39
40BEGIN { is_deeply \@bhkav,
41    [
42        [start => 1],
43        [start => 0],
44        qw/pre_end post_end/,
45        qw/pre_end post_end/,
46    ],
47    "if block";
48}
49
50use t::BHK;
51    for (1) { 1 }
52no t::BHK;
53
54BEGIN { is_deeply \@bhkav,
55    [
56        [start => 1],
57        [start => 0],
58        qw/pre_end post_end/,
59        qw/pre_end post_end/,
60    ],
61    "for loop";
62}
63
64use t::BHK;
65    {
66        { 1; }
67    }
68no t::BHK;
69
70BEGIN { is_deeply \@bhkav,
71    [
72        [start => 1],
73        [start => 1],
74        qw/pre_end post_end/,
75        qw/pre_end post_end/,
76    ],
77    "nested blocks";
78}
79
80use t::BHK;
81    use t::BHK push => "before";
82    {
83        use t::BHK push => "inside";
84    }
85    use t::BHK push => "after";
86no t::BHK;
87
88BEGIN { is_deeply \@bhkav,
89    [
90        "before",
91        [start => 1],
92        "inside",
93        qw/pre_end post_end/,
94        "after"
95    ],
96    "hooks called in the correct places";
97}
98
99use t::BHK;
100    BEGIN { 1 }
101no t::BHK;
102
103BEGIN { is_deeply \@bhkav,
104    [
105        [start => 1],
106        qw/pre_end post_end/,
107    ],
108    "BEGIN block";
109}
110
111use t::BHK; t::BHK->import;
112    eval "1";
113no t::BHK; t::BHK->unimport;
114
115BEGIN { is_deeply \@bhkav, [], "string eval (compile)" }
116is_deeply \@bhkav,
117    [
118        [eval => "entereval"],
119        [start => 1],
120        qw/pre_end post_end/,
121    ],
122    "string eval (run)";
123
124delete @INC{qw{t/Null.pm t/Block.pm}};
125
126t::BHK->import;
127    do "t/Null.pm";
128t::BHK->unimport;
129
130is_deeply \@bhkav,
131    [
132        [eval => "dofile"],
133        [start => 1],
134        qw/pre_end post_end/,
135    ],
136    "do file (null)";
137
138t::BHK->import;
139    do "t/Block.pm";
140t::BHK->unimport;
141
142is_deeply \@bhkav,
143    [
144        [eval => "dofile"],
145        [start => 1],
146        [start => 1],
147        qw/pre_end post_end/,
148        qw/pre_end post_end/,
149    ],
150    "do file (single block)";
151
152delete @INC{qw{t/Null.pm t/Block.pm}};
153
154t::BHK->import;
155    require t::Null;
156t::BHK->unimport;
157
158is_deeply \@bhkav,
159    [
160        [eval => "require"],
161        [start => 1],
162        qw/pre_end post_end/,
163    ],
164    "require (null)";
165
166t::BHK->import;
167    require t::Block;
168t::BHK->unimport;
169
170is_deeply \@bhkav,
171    [
172        [eval => "require"],
173        [start => 1],
174        [start => 1],
175        qw/pre_end post_end/,
176        qw/pre_end post_end/,
177    ],
178    "require (single block)";
179
180BEGIN { delete $INC{"t/Block.pm"} }
181
182use t::BHK;
183    use t::Block;
184no t::BHK;
185
186BEGIN { is_deeply \@bhkav,
187    [
188        [eval => "require"],
189        [start => 1],
190        [start => 1],
191        qw/pre_end post_end/,
192        qw/pre_end post_end/,
193    ],
194    "use (single block)";
195}
196
197BEGIN { delete $INC{"t/Markers.pm"} }
198
199use t::BHK;
200    use t::BHK push => "compile/main/before";
201    use t::Markers;
202    use t::BHK push => "compile/main/after";
203no t::BHK;
204
205BEGIN { is_deeply \@bhkav,
206    [
207        "compile/main/before",
208        [eval => "require"],
209        [start => 1],
210            "compile/pm/before",
211            [start => 1],
212                "compile/pm/inside",
213            qw/pre_end post_end/,
214            "compile/pm/after",
215        qw/pre_end post_end/,
216        "run/pm",
217        "run/import",
218        "compile/main/after",
219    ],
220    "use with markers";
221}
222
223# OK, now some *really* evil stuff...
224
225BEGIN {
226    package EvalDestroy;
227
228    sub DESTROY { $_[0]->() }
229}
230
231use t::BHK;
232    {
233        BEGIN {
234            # grumbleSCOPECHECKgrumble
235            push @XS::APItest::COMPILE_SCOPE_CONTAINER,
236                bless sub {
237                    push @bhkav, "DESTROY";
238                }, "EvalDestroy";
239        }
240        1;
241    }
242no t::BHK;
243
244BEGIN { is_deeply \@bhkav,
245    [
246        [start => 1],                   # block
247            [start => 1],               # BEGIN
248                [start => 1],           # sub
249                qw/pre_end post_end/,
250            qw/pre_end post_end/,
251        "pre_end",
252            "DESTROY",
253        "post_end",
254    ],
255    "compile-time DESTROY comes between pre_ and post_end";
256}
257
258use t::BHK;
259    {
260        BEGIN {
261            push @XS::APItest::COMPILE_SCOPE_CONTAINER,
262                bless sub {
263                    eval "{1}";
264                }, "EvalDestroy";
265        }
266        1;
267    }
268no t::BHK;
269
270BEGIN { is_deeply \@bhkav,
271    [
272        [start => 1],                   # block
273            [start => 1],               # BEGIN
274                [start => 1],           # sub
275                qw/pre_end post_end/,
276            qw/pre_end post_end/,
277        "pre_end",
278            [eval => "entereval"],
279            [start => 1],               # eval
280                [start => 1],           # block inside eval
281                qw/pre_end post_end/,
282            qw/pre_end post_end/,
283        "post_end",
284    ],
285    "evil eval-in-DESTROY tricks";
286}
287