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