5c8a38083bda8c31c141976951745d338281dbb0
[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 # el[attr]
35 is( HTML::Zoom->from_html('<div frew="yo"></div>'.$stub)
36    ->select('div[frew]')
37       ->replace_content('grg')
38    ->to_html,
39    '<div frew="yo">grg</div>'.$stub,
40    'E[attr] works' );
41
42 # *[attr]
43 is( HTML::Zoom->from_html('<div frew="yo"></div><span frew="ay"></span>'.$stub)
44    ->select('*[frew]')
45       ->replace_content('grg')
46    ->to_html,
47    '<div frew="yo">grg</div><span frew="ay">grg</span>'.$stub,
48    '*[attr] works' );
49
50 # el[attr="foo"]
51 is( HTML::Zoom->from_html('<div frew="yo"></div>'.$stub)
52    ->select('div[frew="yo"]')
53       ->replace_content('grg')
54    ->to_html,
55    '<div frew="yo">grg</div>'.$stub,
56    'E[attr="val"] works' );
57
58 # el[attr=foo]
59 is( HTML::Zoom->from_html('<div frew="yo"></div>'.$stub)
60     ->select('div[frew=yo]')
61     ->replace_content('grg')
62     ->to_html,
63     '<div frew="yo">grg</div>'.$stub,
64     'E[attr=val] works' );
65
66 # el[attr!="foo"]
67 is( HTML::Zoom->from_html('<div f="f"></div><div class="quux"></div>'.$stub)
68     ->select('div[class!="waargh"]')
69        ->replace_content('grg')
70     ->to_html,
71     '<div f="f">grg</div><div class="quux">grg</div>'.$stub,
72     'E[attr!="val"] works' );
73
74 # el[attr*="foo"]
75 is( HTML::Zoom->from_html('<div f="frew goog"></div>'.$stub)
76    ->select('div[f*="oo"]')
77       ->replace_content('grg')
78    ->to_html,
79    '<div f="frew goog">grg</div>'.$stub,
80    'E[attr*="val"] works' );
81
82 # el[attr^="foo"]
83 is( HTML::Zoom->from_html('<div f="foobar"></div>'.$stub)
84    ->select('div[f^="foo"]')
85       ->replace_content('grg')
86    ->to_html,
87    '<div f="foobar">grg</div>'.$stub,
88    'E[attr^="val"] works' );
89
90 # el[attr$="foo"]
91 is( HTML::Zoom->from_html('<div f="foobar"></div>'.$stub)
92    ->select('div[f$="bar"]')
93       ->replace_content('grg')
94    ->to_html,
95    '<div f="foobar">grg</div>'.$stub,
96    'E[attr$="val"] works' );
97
98 # el[attr*="foo"]
99 is( HTML::Zoom->from_html('<div f="foo bar"></div>'.$stub)
100    ->select('div[f*="bar"]')
101       ->replace_content('grg')
102    ->to_html,
103    '<div f="foo bar">grg</div>'.$stub,
104    'E[attr*="val"] works' );
105
106 # el[attr~="foo"]
107 is( HTML::Zoom->from_html('<div frew="foo bar baz"></div>'.$stub)
108    ->select('div[frew~="bar"]')
109       ->replace_content('grg')
110    ->to_html,
111    '<div frew="foo bar baz">grg</div>'.$stub,
112    'E[attr~="val"] works' );
113
114 # el[attr|="foo"]
115 is( HTML::Zoom->from_html('<div lang="pl"></div><div lang="english"></div>'.
116                           '<div lang="en"></div><div lang="en-US"></div>'.$stub)
117    ->select('div[lang|="en"]')
118       ->replace_content('grg')
119    ->to_html,
120    '<div lang="pl"></div><div lang="english"></div>'.
121    '<div lang="en">grg</div><div lang="en-US">grg</div>'.$stub,
122    'E[attr|="val"] works' );
123
124 # [attr=bar]
125 ok( check_select( '[prop=moo]'), '[attr=bar]' );
126
127 # el[attr=bar],[prop=foo]
128 is( check_select('span[class=career],[prop=moo]'), 2,
129     'Multiple selectors: el[attr=bar],[attr=foo]');
130
131
132 # selector parse error test:
133 eval{
134     HTML::Zoom->from_html('<span att="bar"></span>')
135       ->select('[att=bar')
136       ->replace_content('cats')
137           ->to_html;
138 };
139 like( $@, qr/Error parsing dispatch specification/,
140       'Malformed attribute selector ([att=bar) results in a helpful error' );
141
142
143 TODO: {
144 local $TODO = "descendant selectors doesn't work yet";
145 # sel1 sel2
146 is( eval { HTML::Zoom->from_html('<table><tr></tr><tr></tr></table>')
147    ->select('table tr')
148       ->replace_content('<td></td>')
149    ->to_html },
150    '<table><tr><td></td></tr><tr><td></td></tr></table>',
151    'sel1 sel2 works' );
152 diag($@) if $@;
153
154 # sel1 sel2 sel3
155 is( eval { HTML::Zoom->from_html('<table><tr><td></td></tr><tr><td></td></tr></table>')
156    ->select('table tr td')
157       ->replace_content('frew')
158    ->to_html },
159    '<table><tr><td>frew</td></tr><tr><td>frew</td></tr></table>',
160    'sel1 sel2 sel3 works' );
161 diag($@) if $@;
162 }
163
164 done_testing;
165
166
167 sub check_select {
168     # less crude?:
169     my $output = HTML::Zoom
170     ->from_html($tmpl)
171     ->select(shift)->replace("the monkey")->to_html;
172     my $count = 0;
173     while ( $output =~ /the monkey/g ){
174         $count++;
175     }
176     return $count;
177 }