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