Failing test for mixed-case attr name matching
[catagits/HTML-Zoom.git] / t / selectors.t
1 use strictures 1;
2 use Test::More;
3
4 use HTML::Zoom;
5
6 my $tmpl = <<END;
7 <body>
8   <div class="main">
9     <span prop='moo' class="hilight name">Bob</span>
10     <span class="career">Builder</span>
11     <hr />
12   </div>
13 </body>
14 END
15
16 my $stub = '<div class="waargh"></div>';
17
18 # el#id
19 is( HTML::Zoom->from_html('<div id="yo"></div>'.$stub)
20    ->select('div#yo')
21       ->replace_content('grg')
22    ->to_html,
23    '<div id="yo">grg</div>'.$stub,
24    'E#id works' );
25
26 # el.class1
27 is( HTML::Zoom->from_html('<div class="yo"></div>'.$stub)
28    ->select('div.yo')
29       ->replace_content('grg')
30    ->to_html,
31    '<div class="yo">grg</div>'.$stub,
32    'E.class works' );
33
34
35 # el.class\.1
36 is( HTML::Zoom->from_html('<div class="yo.yo"></div>'.$stub)
37    ->select('div.yo\.yo')
38       ->replace_content('grg')
39    ->to_html,
40    '<div class="yo.yo">grg</div>'.$stub,
41    'E.class\.0 works' );
42
43 # el[attr]
44 is( HTML::Zoom->from_html('<div frew="yo"></div>'.$stub)
45    ->select('div[frew]')
46       ->replace_content('grg')
47    ->to_html,
48    '<div frew="yo">grg</div>'.$stub,
49    'E[attr] works' );
50
51 # *[attr]
52 is( HTML::Zoom->from_html('<div frew="yo"></div><span frew="ay"></span>'.$stub)
53    ->select('*[frew]')
54       ->replace_content('grg')
55    ->to_html,
56    '<div frew="yo">grg</div><span frew="ay">grg</span>'.$stub,
57    '*[attr] works' );
58
59 # el[attr="foo"]
60 is( HTML::Zoom->from_html('<div frew="yo"></div>'.$stub)
61    ->select('div[frew="yo"]')
62       ->replace_content('grg')
63    ->to_html,
64    '<div frew="yo">grg</div>'.$stub,
65    'E[attr="val"] works' );
66
67 # el[attr=foo]
68 is( HTML::Zoom->from_html('<div frew="yo"></div>'.$stub)
69     ->select('div[frew=yo]')
70     ->replace_content('grg')
71     ->to_html,
72     '<div frew="yo">grg</div>'.$stub,
73     'E[attr=val] works' );
74
75 {
76     local $TODO = 'mixed-case attribute names are broken';
77     # el[Attr=foo]
78     is( HTML::Zoom->from_html('<div FreW="yo"></div>'.$stub)
79         ->select('div[FreW=yo]')
80         ->replace_content('grg')
81         ->to_html,
82         '<div FreW="yo">grg</div>'.$stub,
83         'E[attr=val] works with mixed-case attribute names' );
84 }
85
86 # el[attr=foo\.bar]
87 is( HTML::Zoom->from_html('<div frew="yo.yo"></div>'.$stub)
88     ->select('div[frew=yo\.yo]')
89     ->replace_content('grg')
90     ->to_html,
91     '<div frew="yo.yo">grg</div>'.$stub,
92     'E[attr=foo\.bar] works' );
93
94 # el[attr!="foo"]
95 is( HTML::Zoom->from_html('<div f="f"></div><div class="quux"></div>'.$stub)
96     ->select('div[class!="waargh"]')
97        ->replace_content('grg')
98     ->to_html,
99     '<div f="f">grg</div><div class="quux">grg</div>'.$stub,
100     'E[attr!="val"] works' );
101
102 # el[attr*="foo"]
103 is( HTML::Zoom->from_html('<div f="frew goog"></div>'.$stub)
104    ->select('div[f*="oo"]')
105       ->replace_content('grg')
106    ->to_html,
107    '<div f="frew goog">grg</div>'.$stub,
108    'E[attr*="val"] works' );
109
110 # el[attr^="foo"]
111 is( HTML::Zoom->from_html('<div f="foobar"></div>'.$stub)
112    ->select('div[f^="foo"]')
113       ->replace_content('grg')
114    ->to_html,
115    '<div f="foobar">grg</div>'.$stub,
116    'E[attr^="val"] works' );
117
118 # el[attr$="foo"]
119 is( HTML::Zoom->from_html('<div f="foobar"></div>'.$stub)
120    ->select('div[f$="bar"]')
121       ->replace_content('grg')
122    ->to_html,
123    '<div f="foobar">grg</div>'.$stub,
124    'E[attr$="val"] works' );
125
126 # el[attr*="foo"]
127 is( HTML::Zoom->from_html('<div f="foo bar"></div>'.$stub)
128    ->select('div[f*="bar"]')
129       ->replace_content('grg')
130    ->to_html,
131    '<div f="foo bar">grg</div>'.$stub,
132    'E[attr*="val"] works' );
133
134 # el[attr~="foo"]
135 is( HTML::Zoom->from_html('<div frew="foo bar baz"></div>'.$stub)
136    ->select('div[frew~="bar"]')
137       ->replace_content('grg')
138    ->to_html,
139    '<div frew="foo bar baz">grg</div>'.$stub,
140    'E[attr~="val"] works' );
141
142 # el[attr|="foo"]
143 is( HTML::Zoom->from_html('<div lang="pl"></div><div lang="english"></div>'.
144                           '<div lang="en"></div><div lang="en-US"></div>'.$stub)
145    ->select('div[lang|="en"]')
146       ->replace_content('grg')
147    ->to_html,
148    '<div lang="pl"></div><div lang="english"></div>'.
149    '<div lang="en">grg</div><div lang="en-US">grg</div>'.$stub,
150    'E[attr|="val"] works' );
151
152 # [attr=bar]
153 ok( check_select( '[prop=moo]'), '[attr=bar]' );
154
155 # el[attr=bar],[prop=foo]
156 is( check_select('span[class=career],[prop=moo]'), 2,
157     'Multiple selectors: el[attr=bar],[attr=foo]');
158
159
160 # selector parse error test:
161 eval{
162     HTML::Zoom->from_html('<span att="bar"></span>')
163       ->select('[att=bar')
164       ->replace_content('cats')
165           ->to_html;
166 };
167 like( $@, qr/Error parsing dispatch specification/,
168       'Malformed attribute selector ([att=bar) results in a helpful error' );
169
170
171 TODO: {
172 local $TODO = "descendant selectors doesn't work yet";
173 # sel1 sel2
174 is( eval { HTML::Zoom->from_html('<table><tr></tr><tr></tr></table>')
175    ->select('table tr')
176       ->replace_content('<td></td>')
177    ->to_html },
178    '<table><tr><td></td></tr><tr><td></td></tr></table>',
179    'sel1 sel2 works' );
180 diag($@) if $@;
181
182 # sel1 sel2 sel3
183 is( eval { HTML::Zoom->from_html('<table><tr><td></td></tr><tr><td></td></tr></table>')
184    ->select('table tr td')
185       ->replace_content('frew')
186    ->to_html },
187    '<table><tr><td>frew</td></tr><tr><td>frew</td></tr></table>',
188    'sel1 sel2 sel3 works' );
189 diag($@) if $@;
190 }
191
192 done_testing;
193
194
195 sub check_select {
196     # less crude?:
197     my $output = HTML::Zoom
198     ->from_html($tmpl)
199     ->select(shift)->replace("the monkey")->to_html;
200     my $count = 0;
201     while ( $output =~ /the monkey/g ){
202         $count++;
203     }
204     return $count;
205 }