1#!/usr/bin/perl -Tw
2
3use strict; use warnings; no warnings qw 'utf8 parenthesis regexp once qw';
4our $tests;
5BEGIN { ++$INC{'tests.pm'} }
6sub tests'VERSION { $tests += pop };
7use Test::More;
8plan tests => $tests;
9
10# --------------- Object API ---------------- #
11
12use tests 1; # use
13use_ok 'CSS::DOM::PropertyParser';
14
15use tests 1; # constructor
16isa_ok my $parser = CSS::DOM::PropertyParser->new,
17	'CSS::DOM::PropertyParser';
18
19use tests 4; # clone
20my $clone = (my $css21 = $CSS::DOM::PropertyParser::CSS21)->clone;
21isn't $clone, $css21, 'clone at the first level';
22isn't $clone->get_property('background-position'),
23      $css21->get_property('background-position'),
24 'clone clones individual property specs';
25isn't
26 $clone->get_property('border-color')->{properties}
27  {'border-top-color'},
28 $css21->get_property('border-color')->{properties}
29  {'border-top-color'},
30 'clone clones deeply';
31is_deeply
32 $clone->get_property('border-color')->{properties}
33  {'border-top-color'},
34 $css21->get_property('border-color')->{properties}
35  {'border-top-color'},
36 'the values within the clone are still identical';
37
38use tests 3; # add/get/delete_property
39$parser->add_property("foo", my $prop = {});
40is $parser->get_property("foo"), $prop, 'add/get_property';
41is $parser->delete_property("foo"), $prop, 'delete_property retval';
42is $parser->get_property("foo"), undef, 'effect of delete_property';
43
44use tests 1; # property_names
45$parser->add_property($_,{}) for reverse "a".."f";
46is_deeply [$parser->property_names], ["a".."f"], 'property_names';
47
48# ------------------------- CSS::DOM::Style ------------------------ #
49
50require CSS::DOM::Style;
51
52use tests 2; # invalid properties in parsing
53my $s = CSS::DOM::Style::parse(
54 'azimuth: 0; azimuth: blue', property_parser => $css21
55);
56is $s->azimuth, '0',
57 'invalid property values are ignored in parsing (CSS::DOM::Style::parse)';
58
59$s->cssText('');
60$s->cssText('azimuth: 0; azimuth: blue'),
61is $s->azimuth, 0, 'style->cssText ignores invalid values';
62
63# ------------------------- CSS 2.1 tests ------------------------ #
64
65use tests 28; # azimuth
66for(qw/ left-side far-left left center-left center center-right right
67        far-right right-insidE behInd leftwards rightwards 0 0deg 80deg
68        60rad 38grad -0 +0 -80deg +80deg inherit /,
69    'left behind', 'behind center') {
70 $s->azimuth($_);
71 like $s->azimuth, qr/^\Q$_\E\z/i, "azimuth value: \L$_"
72}
73$s->azimuth('left');
74for(qw/ 38 38cm upwards /, "center leftwards") {
75 $s->azimuth($_);
76 is $s->azimuth, 'left', "invalid azimuth value: $_";
77}
78
79use tests 3; # background-attachment
80for(qw/ scroll fixed /) {
81 $s->backgroundAttachment($_);
82 is $s->backgroundAttachment, $_, "background-attachment value: \L$_"
83}
84$s->backgroundAttachment('38');
85is $s->backgroundAttachment, 'fixed', "invalid bg-attachment value: 38";
86
87use tests 197; # background-color
88for(qw/ #abc #abcdef rgb(1,2,3) rgb(1%,2%,3%) rgba(1,2,3,4)
89        rgba(1%,2%,3%,4) transparent Aliceblue antiquewhitE aqua
90        aquamarine azure beige bisque black blanchedalmond blue blueviolet
91        brown burlywood cadetblue chartreuse chocolate coral cornflowerblue
92        cornsilk crimson cyan darkblue darkcyan darkgoldenrod darkgray
93        darkgreen darkgrey darkkhaki darkmagenta darkolivegreen darkorange
94        darkorchid darkred darksalmon darkseagreen darkslateblue
95        darkslategray darkslategrey darkturquoise darkviolet deeppink
96        deepskyblue dimgray dimgrey dodgerblue firebrick floralwhite
97        forestgreen fuchsia gainsboro ghostwhite gold goldenrod gray green
98        greenyellow grey honeydew hotpink indianred indigo ivory khaki
99        lavender lavenderblush lawngreen lemonchiffon lightblue lightcoral
100        lightcyan lightgoldenrodyellow lightgray lightgreen lightgrey
101        lightpink lightsalmon lightseagreen lightskyblue lightslategray
102        lightslategrey lightsteelblue lightyellow lime limegreen linen
103        magenta maroon mediumaquamarine mediumblue mediumorchid
104        mediumpurple mediumseagreen mediumslateblue mediumspringgreen
105        mediumturquoise mediumvioletred midnightblue mintcream mistyrose
106        moccasin navajowhite navy oldlace olive olivedrab orange orangered
107        orchid palegoldenrod palegreen paleturquoise palevioletred
108        papayawhip peachpuff peru pink plum powderblue purple red rosybrown
109        royalblue saddlebrown salmon sandybrown seagreen seashell sienna
110        silver skyblue slateblue slategray slategrey snow springgreen
111        steelblue tan teal thistle tomato turquoise violet wheat white
112        whitesmoke yellow yellowgreen activeborder activecaption
113        appworkspace background buttonface buttonhighlight buttonshadow
114        buttontext captiontext graytext highlight highlighttext
115        inactiveborder inactivecaption incativecaptiontext infobackground
116        infotext menu menutext scrollbar threeddarkshadow threedface
117        threedhighlight threedlightshadow threedshadow window windowframe
118        windowtext rgb(-5%,-6%,-7%) rgb(+5%,+6%,+7%) rgb(-5,-6,-7)
119        rgb(+5,+6,+7) rgba(-5%,-6%,-0%,-1) rgba(+5%,+6%,+7%,+5)
120        rgba(-5,-6,-0,-1) rgba(+5,+6,+7,+5)/) {
121 $s->backgroundColor($_);
122 my $__ = $s->backgroundColor;
123 for($__) {
124  s/ //g if /,/;
125 }
126 is $__, $_, "background-color value: \L$_"
127}
128$s->backgroundColor('white');
129for(qw/ #1234 #defghi rgb(1%,2,3) rgb(1,2,3,4) rgba(1%,2,3,4)
130        rgba(1,2%,3%,4) SaladDressing /) {
131 $s->backgroundColor($_);
132 my $__ = $s->backgroundColor;
133 for($__) {
134  s/ //g if /,/;
135 }
136 is $__, 'white', "invalid bg-color value: $_";
137}
138
139use tests 3; # background-image
140for(qw/ none url(foo) /) {
141 $s->backgroundImage($_);
142 is $s->backgroundImage, $_, "background-image value: \L$_"
143}
144$s->backgroundImage('38');
145is $s->backgroundImage, 'url(foo)', "invalid bg-image value: 38";
146
147use tests 57; # background-position
148for('5%','-5%','+5%', '5% 5%', '5% 5px', '5% top', '5% bottom','5% center',
149    '5% bottom', '5em', '5ex', '5px', '5in', '5cm', '5mm', '5pt', '5pc', 0,
150    '-5px','-0','+0','+5px','5px 5%', '5px 5px', '5px top', '5px center',
151    '5px bottom','left','left 5%','left 5px','left top','left center',
152    'left bottom','center','center 5%','center 5px','center top',
153    'center center','center bottom','right','right 5%','right 5px',
154    'right top','right center','right bottom','top','top left',
155    'top center','top right','center left','center right','bottom',
156    'bottom left', 'bottom center', 'bottom right') {
157 $s->backgroundPosition($_);
158 is $s->backgroundPosition, $_, "background-position value: \L$_"
159}
160$s->backgroundPosition('left');
161for("top bottom", "5% 5") {
162 $s->backgroundPosition($_);
163 is $s->backgroundPosition, 'left', "invalid bg-position value: $_";
164}
165
166use tests 6; # background-repeat
167for(qw 'repeat repeat-x repeat-y no-repeat') {
168 $s->backgroundRepeat($_);
169 is $s-> backgroundRepeat, $_, "background-repeat value: \L$_"
170}
171$s-> backgroundRepeat('no-repeat');
172for(qw "top 5") {
173 $s-> backgroundRepeat($_);
174 is $s-> backgroundRepeat, 'no-repeat', "invalid bg-repeat value: $_";
175}
176
177use tests 23; # background
178{
179 my $props = sub {
180  return join ",", map $s->getPropertyValue("background-$_"),
181   qw(color image repeat attachment position)
182 };
183 $s->background('white');
184 is $s->background, 'white', 'background: colour';
185 is &$props, 'white,none,repeat,scroll,0% 0%',
186  'other sub-properties after setting background to colour';
187 is # bug fixed in 0.09, that only occurred in 5.10.0 [RT #54809]
188   $s->getPropertyCSSValue('background-color')->cssValueType,
189   1, # CSS_PRIMITIVE_VALUE
190  'value types of named subprops of shorthand props after sh. assignment';
191 $s->background('url(foo)');
192 is $s->background, 'url(foo)', 'background: url';
193 is &$props, 'transparent,url(foo),repeat,scroll,0% 0%',
194  'other sub-properties after setting background to url';
195 $s->background('no-repeat');
196 is $s->background, 'no-repeat', 'background: repeat';
197 is &$props, 'transparent,none,no-repeat,scroll,0% 0%',
198  'other sub-properties after setting background to repeat';
199 $s->background('fixed');
200 is $s->background, 'fixed', 'background: attachment';
201 is &$props, 'transparent,none,repeat,fixed,0% 0%',
202  'other sub-properties after setting background to attachment';
203 $s->background('top');
204 is $s->background, 'top', 'background: position (single keyword)';
205 is &$props, 'transparent,none,repeat,scroll,top',
206  'other sub-properties after setting background to position (single)';
207 $s->background('top left');
208 is $s->background, 'top left', 'background: position (two words)';
209 is &$props, 'transparent,none,repeat,scroll,top left',
210  'other sub-properties after setting background to position';
211 $s->background('red url("foo") no-repeat center center fixed');
212 is $s->background, 'red url("foo") no-repeat fixed center center',
213  'background with five values';
214 is &$props, 'red,url("foo"),no-repeat,fixed,center center',
215  'bg subprops after setting all at once';
216 $s->background('bottom scroll repeat-y none #00f');
217 is $s->background, '#00f repeat-y bottom',
218  'background with five values in reverse order';
219 is &$props, '#00f,none,repeat-y,scroll,bottom',
220  'bg subprops after setting backwards';
221 $s->background('');
222 is $s->background, '', 'setting background to nothing ...';
223 is &$props, ',,,,', ' ... resets all its sub-properties';
224 $s->background('blue');
225 $s->backgroundAttachment("");
226 is $s->background, '',
227  'background is blank if not all sub-properties are specified';
228 $s->background('transparent none repeat scroll 0% 0%');
229 is $s->background, 'none',
230  'background is none when all sub-properties are set to initial values';
231}
232$s->background('red');
233$s->background("top red left");
234is $s->background, 'red', "invalid background value: top red left";
235$s->background("0");
236is $s->background, "0", 'setting background to 0';
237
238use tests 3; # border-collapse
239for(qw 'collapse separate') {
240 $s->borderCollapse($_);
241 is $s->borderCollapse, $_, "border-collapse value: \L$_"
242}
243$s->borderCollapse('collapse');
244$s->borderCollapse('no-repeat');
245is $s->borderCollapse, 'collapse', "invalid border-claps val: no-repeat";
246
247use tests 15; # border-color
248{
249 my $props = sub {
250  return join ",", map $s->getPropertyValue("border-$_-color"),
251   qw(top right bottom left)
252 };
253
254 $s->borderColor('red');
255 is $s->borderColor, 'red', 'setting border-color to one value';
256 is &$props, 'red,red,red,red',
257  'result of setting border-color to one value';
258 $s->borderColor('red green');
259 is $s->borderColor, 'red green', 'setting border-color to two values';
260 is &$props, 'red,green,red,green',
261  'result of setting border-color to two values';
262 $s->borderColor('red green blue');
263 is $s->borderColor, 'red green blue',
264  'setting border-color to three values';
265 is &$props, 'red,green,blue,green',
266  'result of setting border-color to three values';
267 $s->borderColor('red green blue #f0f');
268 is $s->borderColor, 'red green blue #f0f',
269  'setting border-color to fourvalues';
270 is &$props, 'red,green,blue,#f0f',
271  'result of setting border-color to four values';
272 $s->borderColor('red red blue #f0f');
273 is $s->borderColor, 'red red blue #f0f',
274  'setting border-color to four values, the 1st 2 the same';
275 is &$props, 'red,red,blue,#f0f',
276  'result of setting border-color to four values, the 1st 2 the same';
277 $s->borderColor('rgb(255, 0, 0) rgb(0, 255, 0) rgb(0, 0, 255) rgb(0, 0, 0)');
278 is $s->borderColor, 'rgb(255, 0, 0) rgb(0, 255, 0) rgb(0, 0, 255) rgb(0, 0, 0)', # bug in 0.08 (fixed in 0.09)
279  'setting border-color to four rgb() values';  # that only affected
280                                                     # cygwin perl
281
282 $s->borderColor('');
283 is $s->borderColor, '', 'setting border-color to nothing ...';
284 is &$props, ',,,', ' ... resets all its sub-properties';
285 $s->borderColor('blue');
286 $s->borderTopColor("");
287 is $s->borderColor, '',
288  'borderColor is blank if not all sub-properties are specified';
289}
290$s->borderColor('red');
291$s->borderColor("poiple");
292is $s->borderColor, 'red', "invalid border-color value";
293
294use tests 4; # border-spacing
295for(0, '0cm', '5cm 4em') {
296 $s->borderSpacing($_);
297 is $s->borderSpacing, $_, "border-spacing value: \L$_"
298}
299$s->borderSpacing('0');
300$s->borderSpacing('1');
301is $s->borderSpacing, '0', "invalid border-spacing val";
302
303use tests 29; # border-style
304{
305 my $props = sub {
306  return join ",", map $s->getPropertyValue("border-$_-style"),
307   qw(top right bottom left)
308 };
309
310 $s->borderStyle('none');
311 is $s->borderStyle, 'none', 'setting border-style to one value';
312 is &$props, 'none,none,none,none',
313  'result of setting border-style to one value';
314 $s->borderStyle('hidden none');
315 is $s->borderStyle, 'hidden none', 'setting border-style to two values';
316 is &$props, 'hidden,none,hidden,none',
317  'result of setting border-style to two values';
318 $s->borderStyle('dotted hidden none');
319 is $s->borderStyle, 'dotted hidden none',
320  'setting border-style to three values';
321 is &$props, 'dotted,hidden,none,hidden',
322  'result of setting border-style to three values';
323
324 $s->borderStyle('dashed dotted hidden none');
325 is $s->borderStyle, 'dashed dotted hidden none',
326  'setting border-style to four values: dashed dotted hidden none';
327 is &$props, 'dashed,dotted,hidden,none',
328  'result of setting border-style to dashed dotted hidden none';
329 $s->borderStyle('solid dashed dotted hidden');
330 is $s->borderStyle, 'solid dashed dotted hidden',
331  'setting border-style to four values: solid dashed dotted hidden';
332 is &$props, 'solid,dashed,dotted,hidden',
333  'result of setting border-style to solid dashed dotted hidden';
334 $s->borderStyle('double solid dashed dotted');
335 is $s->borderStyle, 'double solid dashed dotted',
336  'setting border-style to four values: double solid dashed dotted';
337 is &$props, 'double,solid,dashed,dotted',
338  'result of setting border-style to double solid dashed dotted';
339 $s->borderStyle('groove double solid dashed');
340 is $s->borderStyle, 'groove double solid dashed',
341  'setting border-style to four values: groove double solid dashed';
342 is &$props, 'groove,double,solid,dashed',
343  'result of setting border-style to groove double solid dashed';
344 $s->borderStyle('ridge groove double solid');
345 is $s->borderStyle, 'ridge groove double solid',
346  'setting border-style to four values: ridge groove double solid';
347 is &$props, 'ridge,groove,double,solid',
348  'result of setting border-style to ridge groove double solid';
349 $s->borderStyle('inset ridge groove double');
350 is $s->borderStyle, 'inset ridge groove double',
351  'setting border-style to four values: inset ridge groove double';
352 is &$props, 'inset,ridge,groove,double',
353  'result of setting border-style to inset ridge groove double';
354 $s->borderStyle('outset inset ridge groove');
355 is $s->borderStyle, 'outset inset ridge groove',
356  'setting border-style to four values: outset inset ridge groove';
357 is &$props, 'outset,inset,ridge,groove',
358  'result of setting border-style to outset inset ridge groove';
359 $s->borderStyle('none outset inset ridge');
360 is $s->borderStyle, 'none outset inset ridge',
361  'setting border-style to four values: none outset inset ridge';
362 is &$props, 'none,outset,inset,ridge',
363  'result of setting border-style to none outset inset ridge';
364 $s->borderStyle('none none outset inset');
365 is $s->borderStyle, 'none none outset inset',
366  'setting border-style to four values: none none outset inset';
367 is &$props, 'none,none,outset,inset',
368  'result of setting border-style to none none outset inset';
369 $s->borderStyle('none none none outset');
370 is $s->borderStyle, 'none none none outset',
371  'setting border-style to four values: none none none outset';
372 is &$props, 'none,none,none,outset',
373  'result of setting border-style to none none none outset';
374
375 $s->borderStyle('');
376 is $s->borderStyle, '', 'setting border-style to nothing ...';
377 is &$props, ',,,', ' ... resets all its sub-properties';
378 $s->borderStyle('inset');
379 $s->borderTopStyle("");
380 is $s->borderStyle, '',
381  'border-style is blank if not all sub-properties are specified';
382}
383
384use tests 40; # border-top/left/right/bottom
385for my $side(qw/ top right left bottom /) {
386 my $meth = "border\u$side";
387 my $prop = "border-$side";
388 my $props = sub {
389  return join ",", map $s->getPropertyValue("$prop-$_"),
390   qw(width style color)
391 };
392 $s->$meth('white');
393 is $s->$meth, 'white', "$prop: colour";
394 is &$props, 'medium,none,white',
395  "other sub-properties after setting $prop to colour";
396 $s->$meth('inset');
397 is $s->$meth, '', "$prop: style";
398 is &$props, 'medium,inset,',
399  "other sub-properties after setting $prop to style";
400 $s->$meth('thick');
401 is $s->$meth, '', "$prop: weight";
402 is &$props, 'thick,none,',
403  "other sub-properties after setting $prop to a style value";
404 $s->$meth('solid 1px red');
405 is $s->$meth, '1px solid red',
406  "$prop with three values";
407 is &$props, '1px,solid,red',
408  "$prop subprops after setting all at once";
409
410 $s->$meth('');
411 is $s->$meth, '', "setting $prop to nothing ...";
412 is &$props, ',,', " ... resets all its sub-properties";
413}
414
415use tests 8; # border-*-color
416for(qw/ top right bottom left /) {
417 my $meth = "border\u${_}Color";
418 $s->$meth('green');
419 is $s->$meth, 'green', "border-$_-color";
420 $s->$meth('bloo');
421 is $s->$meth, 'green', "border-$_-color with invalid value";
422}
423
424use tests 40; # border-*-style
425for(qw/ top right bottom left/) {
426 my $meth = "border\u${_}Style";
427 my $prop = "border-$_-style";
428 for(qw/none hidden dotted dashed solid double groove ridge inset outset/){
429  $s->$meth($_);
430  is $s->$meth, $_, "setting $prop to $_";
431 }
432}
433
434use tests 16; # border-*-width
435for(qw/ top right bottom left/) {
436 my $meth = "border\u${_}Width";
437 my $prop = "border-$_-width";
438 for(qw/5em thin thick medium/){
439  $s->$meth($_);
440  is $s->$meth, $_, "setting $prop to $_";
441 }
442}
443
444use tests 19; # border-width
445{
446 my $props = sub {
447  return join ",", map $s->getPropertyValue("border-$_-width"),
448   qw(top right bottom left)
449 };
450
451 $s->borderWidth('4em');
452 is $s->borderWidth, '4em', 'setting border-width to one value';
453 is &$props, '4em,4em,4em,4em',
454  'result of setting border-width to one value';
455 $s->borderWidth('thin 5em');
456 is $s->borderWidth, 'thin 5em', 'setting border-width to two values';
457 is &$props, 'thin,5em,thin,5em',
458  'result of setting border-width to two values';
459 $s->borderWidth('thick thin 5em');
460 is $s->borderWidth, 'thick thin 5em',
461  'setting border-width to three values';
462 is &$props, 'thick,thin,5em,thin',
463  'result of setting border-width to three values';
464
465 $s->borderWidth('medium thick thin 5em');
466 is $s->borderWidth, 'medium thick thin 5em',
467  'setting border-width to four values: medium thick thin 5em';
468 is &$props, 'medium,thick,thin,5em',
469  'result of setting border-width to medium thick thin 5em';
470 $s->borderWidth('0 medium thick thin');
471 is $s->borderWidth, '0 medium thick thin',
472  'setting border-width to four values: 0 medium thick thin';
473 is &$props, '0,medium,thick,thin',
474  'result of setting border-width to 0 medium thick thin';
475 $s->borderWidth('1px 0 medium thick');
476 is $s->borderWidth, '1px 0 medium thick',
477  'setting border-width to four values: 1px 0 medium thick';
478 is &$props, '1px,0,medium,thick',
479  'result of setting border-width to 1px 0 medium thick';
480 $s->borderWidth('2in 1px 0 medium');
481 is $s->borderWidth, '2in 1px 0 medium',
482  'setting border-width to four values: 2in 1px 0 medium';
483 is &$props, '2in,1px,0,medium',
484  'result of setting border-width to 2in 1px 0 medium';
485 $s->borderWidth('0 0 0 5px');
486 is $s->borderWidth, '0 0 0 5px',
487  'setting border-width to four values: 0 0 0 5px';
488 is &$props, '0,0,0,5px',
489  'result of setting border-width to 0 0 0 5px';
490
491 $s->borderWidth('');
492 is $s->borderWidth, '', 'setting border-width to nothing ...';
493 is &$props, ',,,', ' ... resets all its sub-properties';
494 $s->borderWidth('medium');
495 $s->borderTopWidth("");
496 is $s->borderWidth, '',
497  'border-width is blank if not all sub-properties are specified';
498}
499
500use tests 23; # border
501{
502 my $props = sub {
503  return join ",", map $s->getPropertyValue("border-$_"),
504   map +("top-$_", "left-$_", "right-$_", "bottom-$_"),
505   qw(width style color)
506 };
507 $s->border('white');
508 is $s->border, 'white', "border: colour";
509 is &$props, 'medium,'x4 .'none,none,none,none,white,white,white,white',
510  "other sub-properties after setting border to a colour";
511
512 for(qw( none hidden dotted dashed solid double groove ridge inset outset))
513 {
514  $s->border("$_");
515  is &$props, 'medium,'x4 ."$_,"x4 .',,,',
516   "setting border to $_";
517 }
518
519 for(qw( thin thick medium 5px))
520 {
521  $s->border("$_");
522  is &$props, "$_,"x4 ."none,"x4 .',,,',
523   "setting border to $_";
524 }
525
526 $s->border('solid 1px red');
527 is $s->border, '1px solid red',
528  "border with three values";
529 is &$props, '1px,'x4 .'solid,'x4 .'red,red,red,red',
530  "border subprops after setting all at once";
531
532 $s->borderTopColor('green');
533 is $s->border, '', 'border is blank when not all colour values are equal';
534 $s->border('solid 1px red');
535 $s->borderRightStyle('inset');
536 is $s->border, '', 'border is blank when not all style values are equal';
537 $s->border('solid 1px red');
538 $s->borderBottomWidth('2px');
539 is $s->border, '', 'border is blank when not all width values are equal';
540
541 $s->border('');
542 is $s->border, '', "setting border to nothing ...";
543 is &$props, ',,,,,,,,,,,', " ... resets all its sub-properties";
544}
545
546use tests 3; # bottom
547for(qw( 5em 5% auto )) {
548 $s->bottom($_);
549 is $s->bottom, $_, "bottom value: \L$_"
550}
551
552use tests 2; # caption-side
553for(qw( top bottom )) {
554 $s->captionSide($_);
555 is $s->captionSide, $_, "caption-side value: \L$_"
556}
557
558use tests 4; # clear
559for(qw( none left right both )) {
560 $s->clear($_);
561 is $s->clear, $_, "clear value: \L$_"
562}
563
564use tests 3; # clip
565for('rect(0 auto 5px -7em)', 'rect(0, auto, 5px, -7em)', 'auto') {
566 $s->clip($_);
567 is $s->clip, $_, "clip value: \L$_"
568}
569
570use tests 2; # color
571for('black', 'rgb(0, 0, 0)') {
572 $s->color($_);
573 is $s->color, $_, "color value: \L$_"
574}
575
576use tests 19; # content
577for(qw/ normal none open-quote close-quote no-open-quote no-close-quote
578        "foo" 'bar' url(foo) counter(foo)/,
579    'counter(foo, disc)',
580    'counters(foo, "bar")',
581    'counters(foo, "bar", circle)',
582    'attr(bexieiehehtett)',
583    'normal none',
584    'none open-quote close-quote',
585    'open-quote close-quote no-open-quote no-close-quote',
586    'close-quote no-open-quote no-close-quote "strine" url(url)',
587    "no-open-quote no-close-quote 'oetd' url(eeudon\\)) counter(udux)"
588      ." attr(x)",
589) {
590 $s->content($_);
591 is $s->content, $_, "content value: \L$_"
592}
593
594use tests 10; # counter-increment and -reset
595for my $prop('increment','reset') {
596 my $meth = "counter\u$prop";
597 for('tahi',
598    'rua toru',
599    'wha 4 rima 5',
600    'ono whitu 7',
601    'waru 8 iwa 9',
602 ) {
603  $s->$meth($_);
604  is $s->$meth, $_, "counter-$prop value: \L$_"
605 }
606}
607
608use tests 4; # cue-after and -before
609for my $prop('after','before') {
610 my $meth = "cue\u$prop";
611 for(qw/ none url(foo) /) {
612  $s->$meth($_);
613  is $s->$meth, $_, "cue-$prop value: \L$_"
614 }
615}
616
617use tests 9; # cue
618{
619 my $props = sub {
620  return join ",", map $s->getPropertyValue("cue-$_"),
621   qw(before after)
622 };
623
624 $s->cue('url(po)');
625 is $s->cue, 'url(po)', 'setting cue to one value';
626 is &$props, 'url(po),url(po)',
627  'result of setting cue to one value';
628 $s->cue('none url(sto)');
629 is $s->cue, 'none url(sto)', 'setting cue to two values';
630 is &$props, 'none,url(sto)',
631  'result of setting cue to two values';
632 $s->cue('none none');
633 is $s->cue, 'none', 'setting cue to none none';
634 is &$props, 'none,none',
635  'result of setting cue to none none';
636
637 $s->cue('');
638 is $s->cue, '', 'setting cue to nothing ...';
639 is &$props, ',', ' ... resets all its sub-properties';
640 $s->cue('none');
641 $s->cueAfter("");
642 is $s->cue, '',
643  'cue is blank if not all sub-properties are specified';
644}
645
646use tests 17; # cursor
647for('url(lous), auto',
648    'url(os), crosshair',
649    'url(exe), default',
650    'url(eelthe), pointer',
651    'url(oit), move',
652    'url(ou), e-resize',
653    'url(ampe), ne-resize',
654    'url(lon), nw-resize',
655    'url(ose), n-resize',
656    'url(rgat), se-resize',
657    'url(aike), sw-resize',
658    'url(ryx), s-resize',
659    'url(ate), w-resize',
660    'url(tonte), text',
661    'url(san), wait',
662    'url(ast), help',
663    'url(264), url(ech), progress',
664) {
665 $s->cursor($_);
666 is $s->cursor, $_, "cursor value: \L$_"
667}
668
669use tests 2; # direction
670for(qw/ ltr rtl /) {
671 $s->direction($_);
672 is $s->direction, $_, "direction value: \L$_"
673}
674
675use tests 16; # display
676for(qw/ inline block list-item run-in inline-block table inline-table
677        table-row-group table-header-group table-footer-group table-row
678        table-column-group table-column table-cell table-caption none /) {
679 $s->display($_);
680 is $s->display, $_, "display value: \L$_"
681}
682
683use tests 6; # elevation
684for(qw/ 70deg below level above higher lower /) {
685 $s->elevation($_);
686 is $s->elevation, $_, "elevation value: \L$_"
687}
688
689use tests 2; # empty-cells
690for(qw/ show hide /) {
691 $s->emptyCells($_);
692 is $s->emptyCells, $_, "empty-cells value: \L$_"
693}
694
695use tests 3; # float
696for(qw/ left right none /) {
697 $s->float($_);
698 is $s->float, $_, "float value: \L$_"
699}
700
701use tests 10; # font-family
702for(qw/ serif sans-serif cursive fantasy monospace "Times" Times /,
703    'Lucida Grande',
704    'serif, sans-serif, Lucida Grande',
705    'Lucida Grande, Times, fantasy',
706) {
707 $s->fontFamily($_);
708 is $s->fontFamily, $_, "font-family value: \L$_"
709}
710
711use tests 11; # font-size
712for(qw/ xx-small x-small small medium large x-large xx-large larger smaller
713        5px 5% /) {
714 $s->fontSize($_);
715 is $s->fontSize, $_, "font-size value: \L$_"
716}
717
718use tests 2; # font-variant
719for(qw/ normal small-caps /) {
720 $s->fontVariant($_);
721 is $s->fontVariant, $_, "font-variant value: \L$_"
722}
723
724use tests 13; # font-weight
725for(qw/ normal bold bolder lighter 100 200 300 400 500 600 700 800 900 /) {
726 $s->fontWeight($_);
727 is $s->fontWeight, $_, "font-weight value: \L$_"
728}
729
730use tests 25; # font
731{
732 my $props = sub {
733  return join ",", map $s->getPropertyValue($_),
734   qw(
735    font-style font-variant font-weight font-size line-height font-family
736   )
737 };
738 $s->font('13px my font');
739 is $s->font, '13px my font', "font: size typeface";
740 is &$props, 'normal,normal,normal,13px,normal,my font',
741  "other sub-properties after setting font to size/typeface";
742 $s->font('italic medium medium');
743 is $s->font, 'italic medium medium', "font: style size typeface";
744 is &$props, 'italic,normal,normal,medium,normal,medium',
745  "other sub-properties after setting font to style/size/typeface";
746 $s->font('small-caps medium "quoted  font"');
747 is $s->font, 'small-caps medium "quoted  font"',
748  "font: variant size typeface";
749 is &$props, 'normal,small-caps,normal,medium,normal,"quoted  font"',
750  "other sub-properties after setting font to variant/size/typeface";
751 $s->font('100 medium foo');
752 is $s->font, '100 medium foo',
753  "font: weight size typeface";
754 is &$props, 'normal,normal,100,medium,normal,foo',
755  "other sub-properties after setting font to weight/size/typeface";
756 $s->font('medium/13px foo');
757 is $s->font, 'medium/13px foo',
758  "font: size/leading typeface";
759 is &$props, 'normal,normal,normal,medium,13px,foo',
760  "other sub-properties after setting font to size/leading/typeface";
761 $s->font('normal bold italic 0 foo');
762 is $s->font, 'italic bold 0 foo',
763  "font with first three sub-props out of order and normal variant";
764 is &$props, 'italic,normal,bold,0,normal,foo',
765  "result of setting font with normal variant & props out of order";
766 $s->font('small-caps normal 0 foo');
767 is $s->font, 'small-caps 0 foo',
768  "font with first 2/3 sub-props & explicit variant (normal applies to 2)";
769 is &$props, 'normal,small-caps,normal,0,normal,foo',
770  "result of setting font with small-caps normal";
771 $s->font('bold italic small-caps 0/5px Times, serif');
772 is $s->font, 'italic small-caps bold 0/5px Times, serif',
773  "font with all sub props and comma in typeface";
774 is &$props, 'italic,small-caps,bold,0,5px,Times, serif',
775  "result of setting font with all sub-props";
776
777 $s->font('caption');
778 is &$props,
779  'normal,normal,normal,13px,normal,Lucida Grande, sans-serif',
780  "sub-props after setting font to caption";
781 $s->font('');$s->font('icon');
782 is &$props,
783  'normal,normal,normal,13px,normal,Lucida Grande, sans-serif',
784  "sub-props after setting font to icon";
785 $s->font('');$s->font('menu');
786 is &$props,
787  'normal,normal,normal,13px,normal,Lucida Grande, sans-serif',
788  "sub-props after setting font to menu";
789 $s->font('');$s->font('message-box');
790 is &$props,
791  'normal,normal,normal,13px,normal,Lucida Grande, sans-serif',
792  "sub-props after setting font to message-box";
793 $s->font('');$s->font('small-caption');
794 is &$props,
795  'normal,normal,normal,11px,normal,Lucida Grande, sans-serif',
796  "sub-props after setting font to small-caption";
797 $s->font('');$s->font('status-bar');
798 is &$props,
799  'normal,normal,normal,10px,normal,Lucida Grande, sans-serif',
800  "sub-props after setting font to status-bar";
801
802 $s->lineHeight('');
803 is $s->font, '', 'font is blank when not all sub-props are specified';
804
805 $s->font('');
806 is $s->font, '', "setting font to nothing ...";
807 is &$props, ',,,,,', " ... resets all its sub-properties";
808}
809
810use tests 3; # height
811for(qw( 5em 5% auto )) {
812 $s->height($_);
813 is $s->height, $_, "height value: \L$_"
814}
815
816use tests 3; # left
817for(qw( 5em 5% auto )) {
818 $s->left($_);
819 is $s->left, $_, "left value: \L$_"
820}
821
822use tests 2; # letter-spacing
823for(qw( 5em normal )) {
824 $s->letterSpacing($_);
825 is $s->letterSpacing, $_, "letter-spacing value: \L$_"
826}
827
828use tests 4; # line-height
829for(qw( 5em 5% 5 normal )) {
830 $s->lineHeight($_);
831 is $s->lineHeight, $_, "line-height value: \L$_"
832}
833
834use tests 2; # list-style-image
835for(qw/ none url(foo) /) {
836  $s->listStyleImage($_);
837  is $s->listStyleImage, $_, "list-style-image value: \L$_"
838}
839
840use tests 2; # list-style-position
841for(qw/ inside outside /) {
842  $s->listStylePosition($_);
843  is $s->listStylePosition, $_, "list-style-position value: \L$_"
844}
845
846use tests 14; # list-style-type
847for(qw/ disc circle square decimal decimal-leading-zero
848        lower-roman upper-roman lower-greek lower-latin
849        upper-latin armenian georgian lower-alpha
850        upper-alpha /) {
851  $s->listStyleType($_);
852  is $s->listStyleType, $_, "list-style-type value: \L$_"
853}
854
855use tests 11; # list-style
856{
857 my $props = sub {
858  return join ",", map $s->getPropertyValue("list-style-$_"),
859   qw(type position image)
860 };
861 $s->listStyle('circle');
862 is $s->listStyle, 'circle', "list-style: type";
863 is &$props, 'circle,outside,none',
864  "other sub-properties after setting list-style to type";
865 $s->listStyle('inside');
866 is $s->listStyle, 'inside', "list-style: position";
867 is &$props, 'disc,inside,none',
868  "other sub-properties after setting list-style to position";
869 $s->listStyle('url(foo)');
870 is $s->listStyle, 'url(foo)', "list-style: image";
871 is &$props, 'disc,outside,url(foo)',
872  "other sub-properties after setting list-style to an image url";
873 $s->listStyle('inside url(oo) square');
874 is $s->listStyle, 'square inside url(oo)',
875  "list-style with three values";
876 is &$props, 'square,inside,url(oo)',
877  "list-style subprops after setting all at once";
878
879 $s->listStyleType('');
880 is $s->listStyle, '', 'list-style is blank if not all sub-props are set';
881
882 $s->listStyle('');
883 is $s->listStyle, '', "setting list-style to nothing ...";
884 is &$props, ',,', " ... resets all its sub-properties";
885}
886
887use tests 12; # margin-*
888for(qw/ top right bottom left/) {
889 my $meth = "margin\u${_}";
890 my $prop = "margin-$_";
891 for(qw/5em 5% auto/){
892  $s->$meth($_);
893  is $s->$meth, $_, "setting $prop to $_";
894 }
895}
896
897use tests 15; # margin
898{
899 my $props = sub {
900  return join ",", map $s->getPropertyValue("margin-$_"),
901   qw(top right bottom left)
902 };
903
904 $s->margin('4em');
905 is $s->margin, '4em', 'setting margin to one value';
906 is &$props, '4em,4em,4em,4em',
907  'result of setting margin to one value';
908 $s->margin('5% 5em');
909 is $s->margin, '5% 5em', 'setting margin to two values';
910 is &$props, '5%,5em,5%,5em',
911  'result of setting margin to two values';
912 $s->margin('auto 5% 5em');
913 is $s->margin, 'auto 5% 5em',
914  'setting margin to three values';
915 is &$props, 'auto,5%,5em,5%',
916  'result of setting margin to three values';
917
918 $s->margin('6em auto 5% 5em');
919 is $s->margin, '6em auto 5% 5em',
920  'setting margin to four values: 6em auto 5% 5em';
921 is &$props, '6em,auto,5%,5em',
922  'result of setting margin to 6em auto 5% 5em';
923 $s->margin('6% 6em auto 5%');
924 is $s->margin, '6% 6em auto 5%',
925  'setting margin to four values: 6% 6em auto 5%';
926 is &$props, '6%,6em,auto,5%',
927  'result of setting margin to 6% 6em auto 5%';
928 $s->margin('auto 6% 6em auto');
929 is $s->margin, 'auto 6% 6em auto',
930  'setting margin to four values: auto 6% 6em auto';
931 is &$props, 'auto,6%,6em,auto',
932  'result of setting margin to auto 6% 6em auto';
933
934 $s->margin('');
935 is $s->margin, '', 'setting margin to nothing ...';
936 is &$props, ',,,', ' ... resets all its sub-properties';
937 $s->margin('medium');
938 $s->marginTop("");
939 is $s->margin, '',
940  'margin is blank if not all sub-properties are specified';
941}
942
943use tests 12; # min/max-width/height
944for my $prop (qw/ max-height max-width min-height min-width /) {
945 (my $meth = $prop) =~ s/-(.)/\u$1/g;
946 for(qw/5em 5% none/){
947  $s->$meth($_);
948  is $s->$meth, $_, "setting $prop to $_";
949 }
950}
951
952use tests 1; # orphans
953$s->orphans(5);
954is $s->orphans, 5, "orphans";
955
956use tests 2; # outline-color
957for(qw/green invert/){
958  $s->outlineColor($_);
959  is $s->outlineColor, $_, "setting outline-color to $_";
960}
961
962use tests 10; # outline-style
963for(qw/ none hidden dotted dashed solid double groove ridge inset outset/){
964  $s->outlineStyle($_);
965  is $s->outlineStyle, $_, "setting outline-style to $_";
966}
967
968use tests 4; # outline-width
969for(qw/ 3px thin thick medium /){
970  $s->outlineWidth($_);
971  is $s->outlineWidth, $_, "setting outline-width to $_";
972}
973
974use tests 11; # outline
975{
976 my $props = sub {
977  return join ",", map $s->getPropertyValue("outline-$_"),
978   qw(color style width)
979 };
980 $s->outline('thick');
981 is $s->outline, 'thick', "outline: weight";
982 is &$props, 'invert,none,thick',
983  "other sub-properties after setting outline to weight";
984 $s->outline('inset');
985 is $s->outline, 'inset', "outline: style";
986 is &$props, 'invert,inset,medium',
987  "other sub-properties after setting outline to style";
988 $s->outline('white');
989 is $s->outline, 'white', "outline: colour";
990 is &$props, 'white,none,medium',
991  "other sub-properties after setting outline to a colour";
992 $s->outline('solid red 1px');
993 is $s->outline, 'red solid 1px',
994  "outline with three values";
995 is &$props, 'red,solid,1px',
996  "outline subprops after setting all at once";
997
998 $s->outlineWidth('');
999 is $s->outline,'', 'outline is blank if not all sub-props are set';
1000
1001 $s->outline('');
1002 is $s->outline, '', "setting outline to nothing ...";
1003 is &$props, ',,', " ... resets all its sub-properties";
1004}
1005
1006use tests 4; # overflow
1007for(qw/ visible hidden scroll auto /){
1008  $s->overflow($_);
1009  is $s->overflow, $_, "setting overflow to $_";
1010}
1011
1012use tests 8; # padding-*
1013for(qw/ top right bottom left/) {
1014 my $meth = "padding\u${_}";
1015 my $prop = "padding-$_";
1016 for(qw/5em 5%/){
1017  $s->$meth($_);
1018  is $s->$meth, $_, "setting $prop to $_";
1019 }
1020}
1021
1022use tests 13; # padding
1023{
1024 my $props = sub {
1025  return join ",", map $s->getPropertyValue("padding-$_"),
1026   qw(top right bottom left)
1027 };
1028
1029 $s->padding('4em');
1030 is $s->padding, '4em', 'setting padding to one value';
1031 is &$props, '4em,4em,4em,4em',
1032  'result of setting padding to one value';
1033 $s->padding('5% 5em');
1034 is $s->padding, '5% 5em', 'setting padding to two values';
1035 is &$props, '5%,5em,5%,5em',
1036  'result of setting padding to two values';
1037 $s->padding('6px 5% 5em');
1038 is $s->padding, '6px 5% 5em',
1039  'setting padding to three values';
1040 is &$props, '6px,5%,5em,5%',
1041  'result of setting padding to three values';
1042
1043 $s->padding('6% 6px 5% 5em');
1044 is $s->padding, '6% 6px 5% 5em',
1045  'setting padding to four values: 6% 6px 5% 5em';
1046 is &$props, '6%,6px,5%,5em',
1047  'result of setting padding to 6% 6px 5% 5em';
1048 $s->padding('6% 6px 5% 7%');
1049 is $s->padding, '6% 6px 5% 7%',
1050  'setting padding to four values: 6% 6px 5% 7%';
1051 is &$props, '6%,6px,5%,7%',
1052  'result of setting padding to 6% 6px 5% 7%';
1053
1054 $s->padding('');
1055 is $s->padding, '', 'setting padding to nothing ...';
1056 is &$props, ',,,', ' ... resets all its sub-properties';
1057 $s->padding('medium');
1058 $s->paddingTop("");
1059 is $s->padding, '',
1060  'padding is blank if not all sub-properties are specified';
1061}
1062
1063use tests 10; # page-break-before/after
1064for(qw/ before after/) {
1065 my $meth = "pageBreak\u${_}";
1066 my $prop = "page-break-$_";
1067 for(qw/auto always avoid left right/){
1068  $s->$meth($_);
1069  is $s->$meth, $_, "setting page-break-$prop to $_";
1070 }
1071}
1072
1073use tests 2; # page-break-inside
1074for(qw/ avoid auto /){
1075  $s->pageBreakInside($_);
1076  is $s->pageBreakInside, $_, "setting page-break-inside to $_";
1077}
1078
1079use tests 4; # pause-*
1080for(qw/ before after/) {
1081 my $meth = "pause\u${_}";
1082 my $prop = "pause-$_";
1083 for(qw/ 3s 3% /){
1084  $s->$meth($_);
1085  is $s->$meth, $_, "setting $prop to $_";
1086 }
1087}
1088
1089use tests 1; # pitch-range
1090$s->pitchRange(5);
1091is $s->pitchRange, 5, "pitch-range";
1092
1093use tests 10; # pitch
1094for(qw/ -0 +0 70hz 80khz +70hz x-low low medium high x-high /){
1095  $s->pitch($_);
1096  is $s->pitch, $_, "setting pitch to $_";
1097}
1098
1099use tests 7; # play-during
1100for(
1101 'url(foo)',
1102 'url(bar) mix',
1103 'url(baz) repeat',
1104 'url(log) mix repeat',
1105 'url(ose) repeat mix',
1106 'auto',
1107 'none',
1108){
1109  $s->playDuring($_);
1110  is $s->playDuring, $_, "setting play-during to $_";
1111}
1112
1113use tests 4; # position
1114for(qw/ static relative absolute fixed /){
1115  $s->position($_);
1116  is $s->position, $_, "setting position to $_";
1117}
1118
1119use tests 4; # quotes
1120for(
1121 "'foo' 'bar'",
1122 "'‘' '’' '“' '”'",
1123 '"‘" "’" "“" "“" "«" "»"',
1124 'none',
1125){
1126  $s->quotes($_);
1127  is $s->quotes, $_, "setting quotes to $_";
1128}
1129
1130use tests 1; # richness
1131$s->richness(5);
1132is $s->richness, 5, "richness";
1133
1134use tests 3; # right
1135for(qw( 5em 5% auto )) {
1136 $s->right($_);
1137 is $s->right, $_, "right value: \L$_"
1138}
1139
1140use tests 2; # speak-header
1141for(qw( once always )) {
1142 $s->speakHeader($_);
1143 is $s->speakHeader, $_, "speak-header value: \L$_"
1144}
1145
1146use tests 2; # speak-numeral
1147for(qw( digits continuous )) {
1148 $s->speakNumeral($_);
1149 is $s->speakNumeral, $_, "speak-numeral value: \L$_"
1150}
1151
1152use tests 2; # speak-punctuation
1153for(qw( code none )) {
1154 $s->speakPunctuation($_);
1155 is $s->speakPunctuation, $_, "speak-punctuation value: \L$_"
1156}
1157
1158use tests 3; # speak
1159for(qw( normal none spell-out )) {
1160 $s->speak($_);
1161 is $s->speak, $_, "speak value: \L$_"
1162}
1163
1164use tests 8; # speech-rate
1165for(qw( 3 x-slow slow medium fast x-fast faster slower )) {
1166 $s->speechRate($_);
1167 is $s->speechRate, $_, "speech-rate value: \L$_"
1168}
1169
1170use tests 1; # stress
1171$s->stress(5);
1172is $s->stress, 5, "stress";
1173
1174use tests 2; # table-layout
1175for(qw( auto fixed )) {
1176 $s->tableLayout($_);
1177 is $s->tableLayout, $_, "table-layout value: \L$_"
1178}
1179
1180use tests 5; # text-align
1181for(qw( left right center justify auto )) {
1182 $s->textAlign($_);
1183 is $s->textAlign, $_, "text-align value: \L$_"
1184}
1185
1186use tests 7; # text-decoration
1187for(
1188 "none",
1189 "underline",
1190 'overline',
1191 'line-through',
1192 'blink',
1193 'underline overline line-through blink',
1194 'overline blink underline line-through',
1195){
1196  $s->textDecoration($_);
1197  is $s->textDecoration, $_, "setting text-decoration to $_";
1198}
1199
1200use tests 2; # text-indent
1201for(qw/5em 5%/){
1202  $s->textIndent($_);
1203  is $s->textIndent, $_, "setting text-indent to $_";
1204}
1205
1206use tests 4; # text-transform
1207for(qw( capitalize uppercase lowercase none )) {
1208 $s->textTransform($_);
1209 is $s->textTransform, $_, "text-transform value: \L$_"
1210}
1211
1212use tests 3; # top
1213for(qw/5em 5% auto/){
1214  $s->top($_);
1215  is $s->top, $_, "setting top to $_";
1216}
1217
1218use tests 3; # unicode-bidi
1219for(qw/normal embed bidi-override/){
1220  $s->unicodeBidi($_);
1221  is $s->unicodeBidi, $_, "setting unicode-bidi to $_";
1222}
1223
1224use tests 10; # vertical-align
1225for(qw/ baseline sub super top text-top middle bottom text-bottom 5% 5em/){
1226  $s->verticalAlign($_);
1227  is $s->verticalAlign, $_, "setting vertical-align to $_";
1228}
1229
1230use tests 3; # visibility
1231for(qw/ visible hidden collapse /){
1232  $s->visibility($_);
1233  is $s->visibility, $_, "setting visibility to $_";
1234}
1235
1236use tests 8; # voice-family
1237for(qw/ male female child "Times" Times /,
1238    'Lucida Grande',
1239    'male, female, Lucida Grande',
1240    'Lucida Grande, Times, child',
1241) {
1242 $s->voiceFamily($_);
1243 is $s->voiceFamily, $_, "voice-family value: \L$_"
1244}
1245
1246use tests 10; # volume
1247for(qw/ soft medium 5% 5 silent x-soft soft medium loud x-loud /){
1248  $s->volume($_);
1249  is $s->volume, $_, "setting volume to $_";
1250}
1251
1252use tests 1; # widows
1253$s->widows(5);
1254is $s->widows, 5, "widows";
1255
1256use tests 3; # width
1257for(qw/5em 5% auto/){
1258  $s->width($_);
1259  is $s->width, $_, "setting width to $_";
1260}
1261
1262use tests 2; # word-spacing
1263for(qw/ normal 51em /){
1264  $s->wordSpacing($_);
1265  is $s->wordSpacing, $_, "setting word-spacing to $_";
1266}
1267
1268use tests 2; # z-index
1269for(qw/ auto 5 /){
1270  $s->zIndex($_);
1271  is $s->zIndex, $_, "setting z-index to $_";
1272}
1273
1274# ------------- CSS::DOM’s part of the interface ---------- #
1275
1276require CSS::DOM;
1277
1278use tests 3;
1279
1280my $sheet = CSS::DOM::parse(
1281 '* {azimuth: 0; azimuth: blue}', property_parser => $css21
1282);
1283is $sheet->cssRules->[0]->style->azimuth, '0',
1284 'CSS::DOM::parse ..., property_parser => ...';
1285is $sheet->property_parser, $css21, 'sheet->property_parser';
1286
1287$sheet = new CSS::DOM property_parser => $css21;
1288$sheet -> insertRule('* {azimuth: 0; azimuth: blue}',0);
1289is $sheet->cssRules->[0]->style->azimuth, '0',
1290 'new CSS::DOM property_parser => ...';
1291
1292# ------------- Miscellaneous Bug Fixes ------------- #
1293
1294use tests 4;
1295{
1296 # Note: These fixes rely on border-top-color not having a default value.
1297 # That may change, in which case we will have to create our own property
1298 # specs for the tests’ sake.
1299 $s->cssText('border-top-color: white; border-top: inset');
1300 is $s->borderTopColor, "",
1301  'assignment to shorthand properties initiated by the parser deletes a'
1302   .' subproperty whose default value is blank';
1303 is +()=$s->getPropertyCSSValue("border-top-color"), 0,
1304  ' and that assignment causes getPropertyCSSValue to return nothing';
1305 $s->borderTopColor('white'); $s->borderTop('inset');
1306 is $s->borderTopColor, "",
1307  'direct assignment to shorthand properties deletes a'
1308   .' subproperty whose default value is blank';
1309 is +()=$s->getPropertyCSSValue("border-top-color"), 0,
1310  ' and *that* assignment causes getPropertyCSSValue to return nothing';
1311}
1312
1313use tests 2; # parsing colours
1314{ # Tests for problems with colours in cygwin’s perl (broken in 0.08; fixed
1315  # in 0.09) and for bugs temporarily introduced while those problems were
1316  # being addressed.
1317 my $p = new CSS'DOM'PropertyParser;
1318 $p->add_property(
1319  'colours' => {
1320    format => '<colour>+',
1321   },
1322 );
1323 my $s = CSS'DOM'Style'parse(
1324  "colours: rgb(0,0,0) rgb(1,1,1)",
1325   property_parser => $p
1326 );
1327 use CSS'DOM'Constants 'CSS_CUSTOM';
1328 is $s->getPropertyCSSValue('colours')->cssValueType, CSS_CUSTOM,
1329   'quantified <colour>s';
1330 $p->add_property(
1331  "agent" => {
1332    format => '(<identifier> <colour>)',
1333    properties => { "agent-name" => [1] }
1334   }
1335 );
1336 $s->agent("honey #bee");
1337 is $s->agentName, "honey #bee",
1338  '#colour within paren group and not at the start of the group';
1339}
1340
1341use tests 1; # backtracking with list properties
1342{ # This bug,  fixed in 0.15,  was discovered as a result  of  perl  change
1343  # 3da9985538. See <http://rt.perl.org/rt3/Ticket/Display.html?id=114628>.
1344  # When I wrote  PropertyParser.pm,  I thought that  local @{$whatever}
1345  # would  localise  the  entire  contents  of  the  array,  just  as
1346  # local ${$whatever}[0]  localises one element.  But it  actually
1347  # replaces the array temporarily with a new one,  which cannot
1348  # work with references.
1349 my $p = new CSS'DOM'PropertyParser;
1350 $p->add_property(
1351  'foo' => {
1352    format => '[(foo)|(foo),]+', # [(foo),?]+ does not trigger the bug
1353    list   => 1,
1354   },
1355 );
1356 my $s = CSS'DOM'Style'parse(
1357  "foo: foo, foo",
1358   property_parser => $p
1359 );
1360 use CSS'DOM'Constants 'CSS_VALUE_LIST';
1361 is_deeply [map cssText $_, @{$s->getPropertyCSSValue('foo')}],[('foo')x2],
1362   'backtracking does not preserve existing captures';
1363}
1364