Commit | Line | Data |
456a815d |
1 | use strict; |
2 | use warnings FATAL => 'all'; |
3 | use Test::More; |
4 | |
3cdbc13f |
5 | use Devel::Dwarn; |
6 | |
456a815d |
7 | use HTML::Zoom::Parser::BuiltIn; |
8 | use HTML::Zoom::Producer::BuiltIn; |
9 | use HTML::Zoom::SelectorParser; |
10 | use HTML::Zoom::FilterBuilder; |
11 | use HTML::Zoom::FilterStream; |
12 | |
13 | my $tmpl = <<END; |
14 | <body> |
15 | <div class="main"> |
16 | <span class="hilight name">Bob</span> |
17 | <span class="career">Builder</span> |
18 | <hr /> |
19 | </div> |
20 | </body> |
21 | END |
22 | |
23 | sub src_stream { HTML::Zoom::Parser::BuiltIn->html_to_stream($tmpl); } |
24 | |
25 | sub html_sink { HTML::Zoom::Producer::BuiltIn->html_from_stream($_[0]) } |
26 | |
27 | my $fb = HTML::Zoom::FilterBuilder->new; |
28 | |
29 | my $sp = HTML::Zoom::SelectorParser->new; |
30 | |
31 | sub filter { |
32 | my ($stream, $sel, $cb) = @_; |
33 | return HTML::Zoom::FilterStream->new({ |
34 | stream => $stream, |
35 | match => $sp->parse_selector($sel), |
36 | filter => do { local $_ = $fb; $cb->($fb) } |
37 | }); |
38 | } |
39 | |
40 | sub run_for (&;$) { |
41 | my $cb = shift; |
42 | (html_sink |
43 | (filter |
44 | src_stream, |
45 | (shift or '.main'), |
46 | $cb |
47 | ) |
48 | ) |
49 | } |
50 | |
8f962884 |
51 | my ($expect, @ev); |
52 | |
53 | ($expect = $tmpl) =~ s/class="main"/class="foo"/; |
54 | |
55 | is( |
56 | run_for { $_->set_attribute({ name => 'class', value => 'foo' }) }, |
57 | $expect, |
58 | 'set attribute on existing attribute' |
59 | ); |
60 | |
61 | ($expect = $tmpl) =~ s/class="main"/class="main" foo="bar"/; |
62 | |
63 | is( |
64 | run_for { $_->set_attribute({ name => 'foo', value => 'bar' }) }, |
65 | $expect, |
66 | 'set attribute on non existing attribute' |
67 | ); |
68 | |
69 | ($expect = $tmpl) =~ s/class="main"/class="main foo"/; |
70 | |
71 | is( |
72 | run_for { $_->add_attribute({ name => 'class', value => 'foo' }) }, |
73 | $expect, |
74 | 'add attribute on existing attribute' |
75 | ); |
76 | |
77 | ($expect = $tmpl) =~ s/class="main"/class="main" foo="bar"/; |
78 | |
79 | is( |
80 | run_for { $_->add_attribute({ name => 'foo', value => 'bar' }) }, |
81 | $expect, |
82 | 'add attribute on non existing attribute' |
83 | ); |
84 | |
85 | ($expect = $tmpl) =~ s/ class="main"//; |
86 | |
87 | is( |
88 | run_for { $_->remove_attribute({ name => 'class' }) }, |
89 | $expect, |
90 | 'remove attribute on existing attribute' |
91 | ); |
92 | |
93 | is( |
94 | run_for { $_->remove_attribute({ name => 'foo' }) }, |
95 | $tmpl, |
96 | 'remove attribute on non existing attribute' |
97 | ); |
98 | |
99 | ($expect = $tmpl) =~ s/(?=<div)/O HAI/; |
456a815d |
100 | |
101 | my $ohai = [ { type => 'TEXT', raw => 'O HAI' } ]; |
102 | |
103 | is( |
104 | run_for { $_->add_before($ohai) }, |
105 | $expect, |
106 | 'add_before ok' |
107 | ); |
108 | |
109 | ($expect = $tmpl) =~ s/(?<=<\/div>)/O HAI/; |
110 | |
111 | is( |
112 | run_for { $_->add_after($ohai) }, |
113 | $expect, |
114 | 'add_after ok' |
115 | ); |
116 | |
117 | ($expect = $tmpl) =~ s/(?<=class="main">)/O HAI/; |
118 | |
119 | is( |
120 | run_for { $_->prepend_inside($ohai) }, |
121 | $expect, |
122 | 'prepend_inside ok' |
123 | ); |
124 | |
125 | ($expect = $tmpl) =~ s/<hr \/>/<hr>O HAI<\/hr>/; |
126 | |
127 | is( |
128 | (run_for { $_->prepend_inside($ohai) } 'hr'), |
129 | $expect, |
130 | 'prepend_inside ok with in place close' |
131 | ); |
132 | |
133 | is( |
134 | run_for { $_->replace($ohai) }, |
135 | '<body> |
136 | O HAI |
137 | </body> |
138 | ', |
139 | 'replace ok' |
140 | ); |
141 | |
8f962884 |
142 | @ev = (); |
c86c0ce2 |
143 | |
144 | is( |
145 | run_for { $_->collect({ into => \@ev }) }, |
146 | '<body> |
147 | |
148 | </body> |
149 | ', |
150 | 'collect removes without passthrough' |
151 | ); |
152 | |
153 | is( |
154 | HTML::Zoom::Producer::BuiltIn->html_from_events(\@ev), |
155 | '<div class="main"> |
156 | <span class="hilight name">Bob</span> |
157 | <span class="career">Builder</span> |
158 | <hr /> |
159 | </div>', |
160 | 'collect collected right events' |
161 | ); |
41153e87 |
162 | |
8f962884 |
163 | @ev = (); |
41153e87 |
164 | |
165 | is( |
8f962884 |
166 | run_for { $_->collect({ into => \@ev, inside => 1 }) }, |
167 | '<body> |
168 | <div class="main"></div> |
169 | </body> |
170 | ', |
171 | 'collect w/inside removes correctly' |
41153e87 |
172 | ); |
173 | |
174 | is( |
8f962884 |
175 | HTML::Zoom::Producer::BuiltIn->html_from_events(\@ev), |
176 | ' |
177 | <span class="hilight name">Bob</span> |
178 | <span class="career">Builder</span> |
179 | <hr /> |
180 | ', |
181 | 'collect w/inside collects correctly' |
41153e87 |
182 | ); |
183 | |
11cc25dd |
184 | is( |
185 | run_for { $_->replace($ohai, { inside => 1 }) }, |
186 | '<body> |
187 | <div class="main">O HAI</div> |
188 | </body> |
189 | ', |
190 | 'replace w/inside' |
191 | ); |
192 | |
a25b8d4d |
193 | ($expect = $tmpl) =~ s/(?=<\/div>)/O HAI/; |
194 | |
195 | is( |
196 | run_for { $_->append_inside($ohai) }, |
197 | $expect, |
198 | 'append inside ok' |
199 | ); |
200 | |
3cdbc13f |
201 | if (1) { |
202 | |
203 | warn "\n\n----\n\n"; |
204 | |
205 | my $r_inside = sub { my $r = shift; sub { $_->replace($r, { inside => 1 }) } }; |
206 | |
207 | is( |
208 | run_for { |
209 | $_->repeat( |
210 | [ |
211 | sub { |
212 | filter |
213 | filter($_ => '.name' => $r_inside->('mst')) |
214 | => '.career' => $r_inside->('Chainsaw Wielder') |
215 | }, |
216 | sub { |
217 | filter |
218 | filter($_ => '.name' => $r_inside->('mdk')) |
219 | => '.career' => $r_inside->('Adminion') |
220 | }, |
221 | ] |
222 | ) |
223 | }, |
224 | q{<body> |
225 | <div class="main"> |
226 | <span class="hilight name">mst</span> |
227 | <span class="career">Chainsaw Wielder</span> |
228 | <hr /> |
229 | </div><div class="main"> |
230 | <span class="hilight name">mdk</span> |
231 | <span class="career">Adminion</span> |
232 | <hr /> |
233 | </div> |
234 | </body> |
235 | }, |
236 | 'repeat ok' |
237 | ); |
238 | |
239 | } |
240 | |
456a815d |
241 | done_testing; |