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