Three new tests in t/action.t, two of them failing
[catagits/HTML-Zoom.git] / t / actions.t
CommitLineData
456a815d 1use strict;
2use warnings FATAL => 'all';
3use Test::More;
4
5use HTML::Zoom::Parser::BuiltIn;
6use HTML::Zoom::Producer::BuiltIn;
7use HTML::Zoom::SelectorParser;
8use HTML::Zoom::FilterBuilder;
9use HTML::Zoom::FilterStream;
10
11my $tmpl = <<END;
12<body>
13 <div class="main">
14 <span class="hilight name">Bob</span>
15 <span class="career">Builder</span>
16 <hr />
17 </div>
18</body>
19END
20
d80786d0 21sub src_stream { HTML::Zoom::Parser::BuiltIn->new->html_to_stream($tmpl); }
456a815d 22
d80786d0 23sub html_sink { HTML::Zoom::Producer::BuiltIn->new->html_from_stream($_[0]) }
456a815d 24
25my $fb = HTML::Zoom::FilterBuilder->new;
26
27my $sp = HTML::Zoom::SelectorParser->new;
28
29sub filter {
30 my ($stream, $sel, $cb) = @_;
31 return HTML::Zoom::FilterStream->new({
32 stream => $stream,
33 match => $sp->parse_selector($sel),
34 filter => do { local $_ = $fb; $cb->($fb) }
35 });
36}
37
38sub run_for (&;$) {
39 my $cb = shift;
40 (html_sink
41 (filter
42 src_stream,
43 (shift or '.main'),
44 $cb
45 )
46 )
47}
48
8f962884 49my ($expect, @ev);
50
51($expect = $tmpl) =~ s/class="main"/class="foo"/;
52
53is(
54 run_for { $_->set_attribute({ name => 'class', value => 'foo' }) },
55 $expect,
56 'set attribute on existing attribute'
57);
58
59($expect = $tmpl) =~ s/class="main"/class="main" foo="bar"/;
60
61is(
62 run_for { $_->set_attribute({ name => 'foo', value => 'bar' }) },
63 $expect,
64 'set attribute on non existing attribute'
65);
66
67($expect = $tmpl) =~ s/class="main"/class="main foo"/;
68
69is(
2daa653a 70 run_for { $_->add_to_attribute({ name => 'class', value => 'foo' }) },
8f962884 71 $expect,
72 'add attribute on existing attribute'
73);
74
75($expect = $tmpl) =~ s/class="main"/class="main" foo="bar"/;
76
77is(
2daa653a 78 run_for { $_->add_to_attribute({ name => 'foo', value => 'bar' }) },
8f962884 79 $expect,
80 'add attribute on non existing attribute'
81);
82
83($expect = $tmpl) =~ s/ class="main"//;
84
85is(
86 run_for { $_->remove_attribute({ name => 'class' }) },
87 $expect,
88 'remove attribute on existing attribute'
89);
90
91is(
92 run_for { $_->remove_attribute({ name => 'foo' }) },
93 $tmpl,
94 'remove attribute on non existing attribute'
95);
96
97($expect = $tmpl) =~ s/(?=<div)/O HAI/;
456a815d 98
99my $ohai = [ { type => 'TEXT', raw => 'O HAI' } ];
100
101is(
102 run_for { $_->add_before($ohai) },
103 $expect,
9aa040d7 104 'add_before event ok'
105);
106is(
107 eval { run_for { $_->add_before('O HAI') } },
108 $expect,
109 'add_before string ok'
456a815d 110);
111
112($expect = $tmpl) =~ s/(?<=<\/div>)/O HAI/;
113
114is(
115 run_for { $_->add_after($ohai) },
116 $expect,
9aa040d7 117 'add_after event ok'
118);
119is(
120 eval { run_for { $_->add_after('O HAI') } },
121 $expect,
122 'add_after string ok'
456a815d 123);
124
125($expect = $tmpl) =~ s/(?<=class="main">)/O HAI/;
126
127is(
865bb5d2 128 run_for { $_->prepend_content($ohai) },
456a815d 129 $expect,
865bb5d2 130 'prepend_content ok'
456a815d 131);
132
133($expect = $tmpl) =~ s/<hr \/>/<hr>O HAI<\/hr>/;
134
135is(
865bb5d2 136 (run_for { $_->prepend_content($ohai) } 'hr'),
456a815d 137 $expect,
865bb5d2 138 'prepend_content ok with in place close'
456a815d 139);
140
9aa040d7 141$expect = <<'HTML';
142<body>
456a815d 143 O HAI
144</body>
9aa040d7 145HTML
146is(
147 run_for { $_->replace($ohai) },
148 $expect,
149 'replace event ok'
150);
151is(
152 run_for { $_->replace('O HAI') },
153 $expect,
154 'replace string ok'
456a815d 155);
156
8f962884 157@ev = ();
c86c0ce2 158
159is(
160 run_for { $_->collect({ into => \@ev }) },
161 '<body>
162
163</body>
164',
165 'collect removes without passthrough'
166);
167
168is(
169 HTML::Zoom::Producer::BuiltIn->html_from_events(\@ev),
170 '<div class="main">
171 <span class="hilight name">Bob</span>
172 <span class="career">Builder</span>
173 <hr />
174 </div>',
175 'collect collected right events'
176);
41153e87 177
8f962884 178@ev = ();
41153e87 179
180is(
865bb5d2 181 run_for { $_->collect({ into => \@ev, content => 1 }) },
8f962884 182 '<body>
183 <div class="main"></div>
184</body>
185',
865bb5d2 186 'collect w/content removes correctly'
41153e87 187);
188
189is(
8f962884 190 HTML::Zoom::Producer::BuiltIn->html_from_events(\@ev),
191 '
192 <span class="hilight name">Bob</span>
193 <span class="career">Builder</span>
194 <hr />
195 ',
865bb5d2 196 'collect w/content collects correctly'
41153e87 197);
198
11cc25dd 199is(
865bb5d2 200 run_for { $_->replace($ohai, { content => 1 }) },
11cc25dd 201 '<body>
202 <div class="main">O HAI</div>
203</body>
204',
865bb5d2 205 'replace w/content'
11cc25dd 206);
207
a25b8d4d 208($expect = $tmpl) =~ s/(?=<\/div>)/O HAI/;
209
210is(
865bb5d2 211 run_for { $_->append_content($ohai) },
a25b8d4d 212 $expect,
865bb5d2 213 'append content ok'
a25b8d4d 214);
215
865bb5d2 216my $r_content = sub { my $r = shift; sub { $_->replace($r, { content => 1 }) } };
3cdbc13f 217
218is(
219 run_for {
220 $_->repeat(
221 [
222 sub {
223 filter
865bb5d2 224 filter($_ => '.name' => $r_content->('mst'))
225 => '.career' => $r_content->('Chainsaw Wielder')
3cdbc13f 226 },
227 sub {
228 filter
865bb5d2 229 filter($_ => '.name' => $r_content->('mdk'))
230 => '.career' => $r_content->('Adminion')
3cdbc13f 231 },
232 ]
233 )
234 },
235 q{<body>
236 <div class="main">
237 <span class="hilight name">mst</span>
238 <span class="career">Chainsaw Wielder</span>
239 <hr />
240 </div><div class="main">
241 <span class="hilight name">mdk</span>
242 <span class="career">Adminion</span>
243 <hr />
244 </div>
245</body>
246},
247 'repeat ok'
248);
249
865bb5d2 250is(
251 run_for {
252 $_->repeat_content(
253 [
254 sub {
255 filter
256 filter($_ => '.name' => $r_content->('mst'))
257 => '.career' => $r_content->('Chainsaw Wielder')
258 },
259 sub {
260 filter
261 filter($_ => '.name' => $r_content->('mdk'))
262 => '.career' => $r_content->('Adminion')
263 },
264 ]
265 )
266 },
267 q{<body>
268 <div class="main">
269 <span class="hilight name">mst</span>
270 <span class="career">Chainsaw Wielder</span>
271 <hr />
272
273 <span class="hilight name">mdk</span>
274 <span class="career">Adminion</span>
275 <hr />
276 </div>
277</body>
278},
279 'repeat_content ok'
280);
3cdbc13f 281
dae33531 282is(
283 run_for {
284 my @between;
285 $_->repeat_content(
286 [
287 sub {
b5a48c47 288 HTML::Zoom::ArrayStream->new({ array => [
dae33531 289 (filter
290 filter($_ => '.name' => $r_content->('mst'))
291 => '.career' => $r_content->('Chainsaw Wielder')),
b5a48c47 292 HTML::Zoom::ArrayStream->new({ array => \@between })
293 ] })->flatten
dae33531 294 },
295 sub {
296 filter
297 filter($_ => '.name' => $r_content->('mdk'))
298 => '.career' => $r_content->('Adminion')
299 },
300 ],
301 { filter => sub {
302 filter $_[0] => 'hr' => sub { $_->collect({ into => \@between }) }
303 }
304 }
305 )
306 },
307 q{<body>
308 <div class="main">
309 <span class="hilight name">mst</span>
310 <span class="career">Chainsaw Wielder</span>
311 <hr />
312 <span class="hilight name">mdk</span>
313 <span class="career">Adminion</span>
314
315 </div>
316</body>
317},
318 'repeat_content with filter ok'
319);
320
f8ed299b 321is(
322 run_for {
323 my @between;
324 $_->repeat_content(
325 [
326 sub {
327 filter
328 filter($_ => '.name' => $r_content->('mst'))
329 => '.career' => $r_content->('Chainsaw Wielder')
330 },
331 sub {
332 filter
333 filter($_ => '.name' => $r_content->('mdk'))
334 => '.career' => $r_content->('Adminion')
335 },
336 ],
337 { repeat_between => 'hr' }
338 )
339 },
340 q{<body>
341 <div class="main">
342 <span class="hilight name">mst</span>
343 <span class="career">Chainsaw Wielder</span>
344 <hr />
345 <span class="hilight name">mdk</span>
346 <span class="career">Adminion</span>
347
348 </div>
349</body>
350},
351 'repeat_content using repeat_between ok'
352);
353
456a815d 354done_testing;