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