csspool 0.2.6 → 2.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/.autotest +16 -0
- data/{CHANGELOG.txt → CHANGELOG.rdoc} +10 -0
- data/Manifest.txt +60 -72
- data/README.rdoc +78 -0
- data/Rakefile +9 -52
- data/lib/csspool/collection.rb +50 -0
- data/lib/csspool/css/charset.rb +7 -0
- data/lib/csspool/css/declaration.rb +8 -0
- data/lib/csspool/css/document.rb +34 -0
- data/lib/csspool/css/document_handler.rb +51 -0
- data/lib/csspool/css/import_rule.rb +15 -0
- data/lib/csspool/css/media.rb +7 -0
- data/lib/csspool/css/rule_set.rb +12 -0
- data/lib/csspool/css.rb +7 -0
- data/lib/csspool/lib_croco/cr_additional_sel.rb +46 -0
- data/lib/csspool/lib_croco/cr_attr_sel.rb +16 -0
- data/lib/csspool/lib_croco/cr_doc_handler.rb +24 -0
- data/lib/csspool/lib_croco/cr_num.rb +13 -0
- data/lib/csspool/lib_croco/cr_parser.rb +11 -0
- data/lib/csspool/lib_croco/cr_parsing_location.rb +17 -0
- data/lib/csspool/lib_croco/cr_pseudo.rb +14 -0
- data/lib/csspool/lib_croco/cr_rgb.rb +18 -0
- data/lib/csspool/lib_croco/cr_selector.rb +34 -0
- data/lib/csspool/lib_croco/cr_simple_sel.rb +54 -0
- data/lib/csspool/lib_croco/cr_term.rb +97 -0
- data/lib/csspool/lib_croco/glist.rb +21 -0
- data/lib/csspool/lib_croco.rb +78 -0
- data/lib/csspool/node.rb +5 -0
- data/lib/csspool/sac/document.rb +35 -0
- data/lib/csspool/sac/parser.rb +122 -0
- data/lib/csspool/sac.rb +2 -0
- data/lib/csspool/selector.rb +32 -0
- data/lib/csspool/selectors/additional.rb +6 -0
- data/lib/csspool/selectors/attribute.rb +21 -0
- data/lib/csspool/selectors/class.rb +11 -0
- data/lib/csspool/selectors/id.rb +11 -0
- data/lib/csspool/selectors/pseudo_class.rb +13 -0
- data/lib/csspool/selectors/simple.rb +22 -0
- data/lib/csspool/selectors/type.rb +6 -0
- data/lib/csspool/selectors/universal.rb +6 -0
- data/lib/csspool/selectors.rb +8 -0
- data/lib/csspool/terms/function.rb +17 -0
- data/lib/csspool/terms/hash.rb +6 -0
- data/lib/csspool/terms/ident.rb +15 -0
- data/lib/csspool/terms/number.rb +14 -0
- data/lib/csspool/terms/rgb.rb +23 -0
- data/lib/csspool/terms/string.rb +6 -0
- data/lib/csspool/terms/uri.rb +6 -0
- data/lib/csspool/terms.rb +7 -0
- data/lib/csspool/visitable.rb +18 -0
- data/lib/csspool/visitors/comparable.rb +78 -0
- data/lib/csspool/visitors/to_css.rb +201 -0
- data/lib/csspool/visitors/visitor.rb +17 -0
- data/lib/csspool/visitors.rb +3 -0
- data/lib/csspool.rb +18 -1
- data/test/css/test_document.rb +13 -0
- data/test/css/test_import_rule.rb +42 -0
- data/test/helper.rb +62 -6
- data/test/sac/test_parser.rb +115 -0
- data/test/sac/test_properties.rb +43 -0
- data/test/sac/test_terms.rb +134 -0
- data/test/test_collection.rb +81 -0
- data/test/test_parser.rb +75 -241
- data/test/test_selector.rb +45 -34
- data/test/visitors/test_comparable.rb +72 -0
- data/test/visitors/test_to_css.rb +141 -0
- metadata +98 -85
- data/README.txt +0 -79
- data/lib/css/sac/conditions/attribute_condition.rb +0 -56
- data/lib/css/sac/conditions/begin_hyphen_condition.rb +0 -22
- data/lib/css/sac/conditions/class_condition.rb +0 -22
- data/lib/css/sac/conditions/combinator_condition.rb +0 -40
- data/lib/css/sac/conditions/condition.rb +0 -35
- data/lib/css/sac/conditions/id_condition.rb +0 -27
- data/lib/css/sac/conditions/one_of_condition.rb +0 -22
- data/lib/css/sac/conditions/pseudo_class_condition.rb +0 -24
- data/lib/css/sac/conditions.rb +0 -5
- data/lib/css/sac/document_handler.rb +0 -67
- data/lib/css/sac/error_handler.rb +0 -14
- data/lib/css/sac/generated_parser.rb +0 -999
- data/lib/css/sac/generated_property_parser.rb +0 -9214
- data/lib/css/sac/lexeme.rb +0 -29
- data/lib/css/sac/lexical_unit.rb +0 -203
- data/lib/css/sac/parse_exception.rb +0 -6
- data/lib/css/sac/parser.rb +0 -115
- data/lib/css/sac/property_parser.rb +0 -47
- data/lib/css/sac/selectors/child_selector.rb +0 -40
- data/lib/css/sac/selectors/conditional_selector.rb +0 -49
- data/lib/css/sac/selectors/descendant_selector.rb +0 -40
- data/lib/css/sac/selectors/element_selector.rb +0 -39
- data/lib/css/sac/selectors/selector.rb +0 -31
- data/lib/css/sac/selectors/sibling_selector.rb +0 -39
- data/lib/css/sac/selectors/simple_selector.rb +0 -25
- data/lib/css/sac/selectors.rb +0 -5
- data/lib/css/sac/token.rb +0 -27
- data/lib/css/sac/tokenizer.rb +0 -187
- data/lib/css/sac/visitable.rb +0 -106
- data/lib/css/sac.rb +0 -14
- data/lib/css/stylesheet/rule.rb +0 -20
- data/lib/css/stylesheet/stylesheet.rb +0 -96
- data/lib/css/stylesheet.rb +0 -3
- data/lib/parser.y +0 -308
- data/lib/property_parser.y +0 -2346
- data/lib/property_parser.y.erb +0 -1321
- data/test/condition_test_case.rb +0 -6
- data/test/selector_test_case.rb +0 -20
- data/test/test_all.rb +0 -4
- data/test/test_attribute_condition.rb +0 -39
- data/test/test_begin_hyphen_condition.rb +0 -15
- data/test/test_child_selector.rb +0 -60
- data/test/test_class_condition.rb +0 -15
- data/test/test_combinator_condition.rb +0 -38
- data/test/test_condition.rb +0 -31
- data/test/test_conditional_selector.rb +0 -44
- data/test/test_descendant_selector.rb +0 -64
- data/test/test_element_selector.rb +0 -31
- data/test/test_error_recovery.rb +0 -28
- data/test/test_id_condition.rb +0 -16
- data/test/test_lexeme.rb +0 -39
- data/test/test_lexical_color.rb +0 -49
- data/test/test_lexical_function.rb +0 -31
- data/test/test_lexical_ident.rb +0 -30
- data/test/test_lexical_number.rb +0 -68
- data/test/test_lexical_string.rb +0 -23
- data/test/test_lexical_unit.rb +0 -106
- data/test/test_lexical_uri.rb +0 -28
- data/test/test_one_of_condition.rb +0 -15
- data/test/test_parse_error.rb +0 -199
- data/test/test_property_parser.rb +0 -593
- data/test/test_selector_as_string.rb +0 -94
- data/test/test_selector_parser.rb +0 -178
- data/test/test_sibling_selector.rb +0 -42
- data/test/test_simple_selector.rb +0 -9
- data/test/test_specificity.rb +0 -76
- data/test/test_stylesheet.rb +0 -95
- data/test/test_token.rb +0 -24
- data/test/test_tokenizer.rb +0 -127
- data/test/test_xpath.rb +0 -105
|
@@ -1,178 +0,0 @@
|
|
|
1
|
-
require File.dirname(__FILE__) + "/helper"
|
|
2
|
-
|
|
3
|
-
class SelectorParserTest < Test::Unit::TestCase
|
|
4
|
-
def setup
|
|
5
|
-
@sac = CSS::SAC::Parser.new()
|
|
6
|
-
class << @sac.document_handler
|
|
7
|
-
attr_reader :selectors
|
|
8
|
-
def start_selector(selectors)
|
|
9
|
-
@selectors = selectors
|
|
10
|
-
end
|
|
11
|
-
end
|
|
12
|
-
end
|
|
13
|
-
|
|
14
|
-
def test_multiple_selectors
|
|
15
|
-
@sac.parse('h1, h2 { }')
|
|
16
|
-
selectors = @sac.document_handler.selectors
|
|
17
|
-
assert_equal(2, selectors.length)
|
|
18
|
-
end
|
|
19
|
-
|
|
20
|
-
def test_eql?
|
|
21
|
-
@sac.parse('h1, h1 { }')
|
|
22
|
-
selectors = @sac.document_handler.selectors
|
|
23
|
-
assert_equal(2, selectors.length)
|
|
24
|
-
assert_equal selectors[0], selectors[1]
|
|
25
|
-
assert selectors[0].eql?(selectors[1])
|
|
26
|
-
end
|
|
27
|
-
|
|
28
|
-
def test_adjacent
|
|
29
|
-
@sac.parse('h1 + h2 { }')
|
|
30
|
-
selectors = @sac.document_handler.selectors
|
|
31
|
-
assert_equal(1, selectors.length)
|
|
32
|
-
|
|
33
|
-
sel = selectors.first
|
|
34
|
-
assert_equal(:SAC_DIRECT_ADJACENT_SELECTOR, sel.selector_type)
|
|
35
|
-
|
|
36
|
-
sibling = sel.sibling_selector
|
|
37
|
-
assert sibling
|
|
38
|
-
assert_equal('h2', sibling.local_name)
|
|
39
|
-
|
|
40
|
-
first = sel.selector
|
|
41
|
-
assert first
|
|
42
|
-
assert_equal('h1', first.local_name)
|
|
43
|
-
end
|
|
44
|
-
|
|
45
|
-
def test_descendant_non_direct
|
|
46
|
-
@sac.parse('h1 h2 { }')
|
|
47
|
-
selectors = @sac.document_handler.selectors
|
|
48
|
-
assert_equal(1, selectors.length)
|
|
49
|
-
|
|
50
|
-
sel = selectors.first
|
|
51
|
-
assert_equal(:SAC_DESCENDANT_SELECTOR, sel.selector_type)
|
|
52
|
-
|
|
53
|
-
ancestor = sel.ancestor_selector
|
|
54
|
-
assert ancestor
|
|
55
|
-
assert_equal('h1', ancestor.local_name)
|
|
56
|
-
|
|
57
|
-
me = sel.selector
|
|
58
|
-
assert me
|
|
59
|
-
assert_equal('h2', me.local_name)
|
|
60
|
-
end
|
|
61
|
-
|
|
62
|
-
def test_descendant_direct
|
|
63
|
-
@sac.parse('h1 > h2 { }')
|
|
64
|
-
selectors = @sac.document_handler.selectors
|
|
65
|
-
assert_equal(1, selectors.length)
|
|
66
|
-
|
|
67
|
-
sel = selectors.first
|
|
68
|
-
assert_equal(:SAC_CHILD_SELECTOR, sel.selector_type)
|
|
69
|
-
|
|
70
|
-
ancestor = sel.ancestor_selector
|
|
71
|
-
assert ancestor
|
|
72
|
-
assert_equal('h1', ancestor.local_name)
|
|
73
|
-
|
|
74
|
-
me = sel.selector
|
|
75
|
-
assert me
|
|
76
|
-
assert_equal('h2', me.local_name)
|
|
77
|
-
end
|
|
78
|
-
|
|
79
|
-
@@single_selector_tests = {
|
|
80
|
-
:id => {
|
|
81
|
-
:css => '#foo { }',
|
|
82
|
-
:value => 'foo',
|
|
83
|
-
:type => :SAC_ID_CONDITION,
|
|
84
|
-
},
|
|
85
|
-
:class => {
|
|
86
|
-
:css => '.foo { }',
|
|
87
|
-
:value => 'foo',
|
|
88
|
-
:type => :SAC_CLASS_CONDITION,
|
|
89
|
-
},
|
|
90
|
-
:attribute => {
|
|
91
|
-
:css => '[foo=bar] { }',
|
|
92
|
-
:value => 'bar',
|
|
93
|
-
:type => :SAC_ATTRIBUTE_CONDITION,
|
|
94
|
-
},
|
|
95
|
-
:pseudo => {
|
|
96
|
-
:css => ':clicked { }',
|
|
97
|
-
:value => 'clicked',
|
|
98
|
-
:type => :SAC_PSEUDO_CLASS_CONDITION,
|
|
99
|
-
}
|
|
100
|
-
}
|
|
101
|
-
|
|
102
|
-
@@multiple_selector_tests = {
|
|
103
|
-
:ids => {
|
|
104
|
-
:css => '#foo#bar#baz { }',
|
|
105
|
-
:values => %w{ foo bar baz },
|
|
106
|
-
:types => [:SAC_ID_CONDITION] * 3,
|
|
107
|
-
},
|
|
108
|
-
:classes => {
|
|
109
|
-
:css => '.foo.bar.baz { }',
|
|
110
|
-
:values => %w{ foo bar baz },
|
|
111
|
-
:types => [:SAC_CLASS_CONDITION] * 3,
|
|
112
|
-
},
|
|
113
|
-
:attributes => {
|
|
114
|
-
:css => '[foo=bar][bar=baz] { }',
|
|
115
|
-
:values => %w{ bar baz },
|
|
116
|
-
:types => [:SAC_ATTRIBUTE_CONDITION] * 2,
|
|
117
|
-
},
|
|
118
|
-
:pseudo => {
|
|
119
|
-
:css => ':clicked:hover { }',
|
|
120
|
-
:values => %w{ clicked hover },
|
|
121
|
-
:types => [:SAC_PSEUDO_CLASS_CONDITION] * 2,
|
|
122
|
-
}
|
|
123
|
-
}
|
|
124
|
-
|
|
125
|
-
@@single_selector_tests.each do |name,tests|
|
|
126
|
-
define_method :"test_single_#{name}" do
|
|
127
|
-
@sac.parse(tests[:css])
|
|
128
|
-
selectors = @sac.document_handler.selectors
|
|
129
|
-
assert_equal(1, selectors.length)
|
|
130
|
-
|
|
131
|
-
selector = selectors.first
|
|
132
|
-
assert_nil selector.simple_selector
|
|
133
|
-
assert selector.condition
|
|
134
|
-
assert_equal(:SAC_CONDITIONAL_SELECTOR, selector.selector_type)
|
|
135
|
-
|
|
136
|
-
condition = selector.condition
|
|
137
|
-
assert_equal(tests[:type], condition.condition_type)
|
|
138
|
-
assert_equal(tests[:value], condition.value)
|
|
139
|
-
end
|
|
140
|
-
end
|
|
141
|
-
|
|
142
|
-
@@multiple_selector_tests.each do |name,tests|
|
|
143
|
-
define_method :"test_multiple_#{name}" do
|
|
144
|
-
@sac.parse(tests[:css])
|
|
145
|
-
selectors = @sac.document_handler.selectors
|
|
146
|
-
assert_equal(1, selectors.length)
|
|
147
|
-
|
|
148
|
-
selector = selectors.first
|
|
149
|
-
assert_nil selector.simple_selector
|
|
150
|
-
assert selector.condition
|
|
151
|
-
assert_equal(:SAC_CONDITIONAL_SELECTOR, selector.selector_type)
|
|
152
|
-
|
|
153
|
-
combined = reduce_combinator_condition(selector.condition)
|
|
154
|
-
assert_equal(tests[:values].length, combined.length)
|
|
155
|
-
assert_equal(tests[:values], combined.map { |x| x.value })
|
|
156
|
-
assert_equal(tests[:types], combined.map { |x| x.condition_type })
|
|
157
|
-
end
|
|
158
|
-
end
|
|
159
|
-
|
|
160
|
-
def reduce_combinator_condition(condition)
|
|
161
|
-
conditions = []
|
|
162
|
-
assert_equal(:SAC_AND_CONDITION, condition.condition_type)
|
|
163
|
-
first = condition.first_condition
|
|
164
|
-
second = condition.second_condition
|
|
165
|
-
|
|
166
|
-
assert first
|
|
167
|
-
assert second
|
|
168
|
-
assert_not_equal(:SAC_AND_CONDITION, first.condition_type)
|
|
169
|
-
conditions << first
|
|
170
|
-
|
|
171
|
-
if second.condition_type == :SAC_AND_CONDITION
|
|
172
|
-
conditions += reduce_combinator_condition(second)
|
|
173
|
-
else
|
|
174
|
-
conditions << second
|
|
175
|
-
end
|
|
176
|
-
conditions
|
|
177
|
-
end
|
|
178
|
-
end
|
|
@@ -1,42 +0,0 @@
|
|
|
1
|
-
require File.dirname(__FILE__) + "/helper"
|
|
2
|
-
|
|
3
|
-
class SiblingSelectorTest < SelectorTestCase
|
|
4
|
-
def test_hash
|
|
5
|
-
first = SiblingSelector.new(1,1)
|
|
6
|
-
second = SiblingSelector.new(1,1)
|
|
7
|
-
assert_equal first.hash, second.hash
|
|
8
|
-
|
|
9
|
-
third = SiblingSelector.new(1,2)
|
|
10
|
-
assert_not_equal first.hash, third.hash
|
|
11
|
-
end
|
|
12
|
-
|
|
13
|
-
def test_equals2
|
|
14
|
-
first = SiblingSelector.new(1,1)
|
|
15
|
-
second = SiblingSelector.new(1,1)
|
|
16
|
-
assert_equal first, second
|
|
17
|
-
|
|
18
|
-
third = SiblingSelector.new(1,2)
|
|
19
|
-
assert_not_equal first, third
|
|
20
|
-
|
|
21
|
-
fourth = SiblingSelector.new(2,1)
|
|
22
|
-
assert_not_equal first, fourth
|
|
23
|
-
end
|
|
24
|
-
|
|
25
|
-
def test_equals_tilde
|
|
26
|
-
selector = ElementSelector.new('div')
|
|
27
|
-
sibling = ElementSelector.new('p')
|
|
28
|
-
sel = SiblingSelector.new(selector, sibling)
|
|
29
|
-
|
|
30
|
-
sibling = Node.new('p', nil, nil, nil)
|
|
31
|
-
node = Node.new('div', nil, nil, sibling)
|
|
32
|
-
assert sel =~ node
|
|
33
|
-
|
|
34
|
-
sibling1 = Node.new('div', nil, nil, nil)
|
|
35
|
-
node1 = Node.new('p', nil, nil, sibling)
|
|
36
|
-
assert(! (sel =~ node1))
|
|
37
|
-
|
|
38
|
-
assert(! (sel =~ NoParentNode.new('div')))
|
|
39
|
-
assert(! (sel =~ Node.new('div', nil, nil)))
|
|
40
|
-
end
|
|
41
|
-
end
|
|
42
|
-
|
data/test/test_specificity.rb
DELETED
|
@@ -1,76 +0,0 @@
|
|
|
1
|
-
require File.dirname(__FILE__) + "/helper"
|
|
2
|
-
|
|
3
|
-
# http://www.w3.org/TR/REC-CSS2/cascade.html#specificity
|
|
4
|
-
# * {} /* a=0 b=0 c=0 -> specificity = 0 */
|
|
5
|
-
# LI {} /* a=0 b=0 c=1 -> specificity = 1 */
|
|
6
|
-
# UL LI {} /* a=0 b=0 c=2 -> specificity = 2 */
|
|
7
|
-
# UL OL+LI {} /* a=0 b=0 c=3 -> specificity = 3 */
|
|
8
|
-
# H1 + *[REL=up]{} /* a=0 b=1 c=1 -> specificity = 11 */
|
|
9
|
-
# UL OL LI.red {} /* a=0 b=1 c=3 -> specificity = 13 */
|
|
10
|
-
# LI.red.level {} /* a=0 b=2 c=1 -> specificity = 21 */
|
|
11
|
-
# #x34y {} /* a=1 b=0 c=0 -> specificity = 100 */
|
|
12
|
-
class SpecificityTest < Test::Unit::TestCase
|
|
13
|
-
def setup
|
|
14
|
-
@sac = CSS::SAC::Parser.new()
|
|
15
|
-
class << @sac.document_handler
|
|
16
|
-
attr_accessor :selectors
|
|
17
|
-
alias :start_selector :selectors=
|
|
18
|
-
end
|
|
19
|
-
end
|
|
20
|
-
|
|
21
|
-
def test_star
|
|
22
|
-
@sac.parse('* {}')
|
|
23
|
-
selector = @sac.document_handler.selectors.first
|
|
24
|
-
assert_not_nil selector
|
|
25
|
-
assert_equal [0, 0, 0, 0], selector.specificity
|
|
26
|
-
end
|
|
27
|
-
|
|
28
|
-
def test_li
|
|
29
|
-
@sac.parse('li {}')
|
|
30
|
-
selector = @sac.document_handler.selectors.first
|
|
31
|
-
assert_not_nil selector
|
|
32
|
-
assert_equal [0, 0, 0, 1], selector.specificity
|
|
33
|
-
end
|
|
34
|
-
|
|
35
|
-
def test_ul_li
|
|
36
|
-
@sac.parse('ul li {}')
|
|
37
|
-
selector = @sac.document_handler.selectors.first
|
|
38
|
-
assert_not_nil selector
|
|
39
|
-
assert_equal [0, 0, 0, 2], selector.specificity
|
|
40
|
-
end
|
|
41
|
-
|
|
42
|
-
def test_ul_ol_plus_li
|
|
43
|
-
@sac.parse('ul ol+li {}')
|
|
44
|
-
selector = @sac.document_handler.selectors.first
|
|
45
|
-
assert_not_nil selector
|
|
46
|
-
assert_equal [0, 0, 0, 3], selector.specificity
|
|
47
|
-
end
|
|
48
|
-
|
|
49
|
-
def test_h1_attributes
|
|
50
|
-
@sac.parse('h1 + *[REL=up] {}')
|
|
51
|
-
selector = @sac.document_handler.selectors.first
|
|
52
|
-
assert_not_nil selector
|
|
53
|
-
assert_equal [0, 0, 1, 1], selector.specificity
|
|
54
|
-
end
|
|
55
|
-
|
|
56
|
-
def test_one_class_selector
|
|
57
|
-
@sac.parse('ul ol li.red {}')
|
|
58
|
-
selector = @sac.document_handler.selectors.first
|
|
59
|
-
assert_not_nil selector
|
|
60
|
-
assert_equal [0, 0, 1, 3], selector.specificity
|
|
61
|
-
end
|
|
62
|
-
|
|
63
|
-
def test_two_class_selectors
|
|
64
|
-
@sac.parse('li.red.level {}')
|
|
65
|
-
selector = @sac.document_handler.selectors.first
|
|
66
|
-
assert_not_nil selector
|
|
67
|
-
assert_equal [0, 0, 2, 1], selector.specificity
|
|
68
|
-
end
|
|
69
|
-
|
|
70
|
-
def test_id_selector
|
|
71
|
-
@sac.parse('#x34y {}')
|
|
72
|
-
selector = @sac.document_handler.selectors.first
|
|
73
|
-
assert_not_nil selector
|
|
74
|
-
assert_equal [0, 1, 0, 0], selector.specificity
|
|
75
|
-
end
|
|
76
|
-
end
|
data/test/test_stylesheet.rb
DELETED
|
@@ -1,95 +0,0 @@
|
|
|
1
|
-
require File.dirname(__FILE__) + "/helper"
|
|
2
|
-
|
|
3
|
-
class StyleSheetTest < SelectorTestCase
|
|
4
|
-
def setup
|
|
5
|
-
@sac = CSS::SAC::Parser.new
|
|
6
|
-
end
|
|
7
|
-
|
|
8
|
-
def test_rules_matching
|
|
9
|
-
doc = @sac.parse("div > p { letter-spacing: 1px; }")
|
|
10
|
-
node = parent_child_tree('div', 'p')
|
|
11
|
-
expected = doc.rules.first
|
|
12
|
-
|
|
13
|
-
found = doc.rules_matching(node)
|
|
14
|
-
assert_equal 1, found.length
|
|
15
|
-
assert_equal expected.selector, found.first.selector
|
|
16
|
-
|
|
17
|
-
found2 = (doc =~ node)
|
|
18
|
-
assert_equal 1, found2.length
|
|
19
|
-
assert_equal expected.selector, found2.first.selector
|
|
20
|
-
end
|
|
21
|
-
|
|
22
|
-
def test_find_rule
|
|
23
|
-
doc = @sac.parse("h1 { letter-spacing: 1px; }")
|
|
24
|
-
expected = doc.rules.first
|
|
25
|
-
assert_equal expected, doc.find_rule('h1')
|
|
26
|
-
assert_equal expected, doc['h1']
|
|
27
|
-
assert_equal expected, doc[expected]
|
|
28
|
-
end
|
|
29
|
-
|
|
30
|
-
def test_create_rule
|
|
31
|
-
doc = @sac.parse("h1 { letter-spacing: 1px; }")
|
|
32
|
-
rule = doc.create_rule('h1')
|
|
33
|
-
assert_equal doc.rules.first.selector, rule.selector
|
|
34
|
-
end
|
|
35
|
-
|
|
36
|
-
def test_reduce!
|
|
37
|
-
doc = @sac.parse(<<END
|
|
38
|
-
h1 {
|
|
39
|
-
background-color: red;
|
|
40
|
-
border-color: green;
|
|
41
|
-
}
|
|
42
|
-
h1 { letter-spacing: 1px; }
|
|
43
|
-
END
|
|
44
|
-
)
|
|
45
|
-
assert_equal(1, doc.rules.length)
|
|
46
|
-
end
|
|
47
|
-
|
|
48
|
-
def test_rules_by_property
|
|
49
|
-
doc = @sac.parse(<<END
|
|
50
|
-
h1 {
|
|
51
|
-
background-color: red;
|
|
52
|
-
padding: 100px;
|
|
53
|
-
border-color: green;
|
|
54
|
-
}
|
|
55
|
-
div {
|
|
56
|
-
border-color: green;
|
|
57
|
-
background-color: red;
|
|
58
|
-
padding: 100px;
|
|
59
|
-
}
|
|
60
|
-
END
|
|
61
|
-
)
|
|
62
|
-
assert_equal(2, doc.rules.length)
|
|
63
|
-
assert_equal(doc.rules[0].properties, doc.rules[1].properties)
|
|
64
|
-
assert_equal(1, doc.rules_by_property.keys.length)
|
|
65
|
-
assert_equal(2, doc.rules_by_property.values.first.length)
|
|
66
|
-
end
|
|
67
|
-
|
|
68
|
-
def test_to_css
|
|
69
|
-
doc = @sac.parse(<<END
|
|
70
|
-
h1 {
|
|
71
|
-
background-color: red;
|
|
72
|
-
padding: 100px;
|
|
73
|
-
border-color: green;
|
|
74
|
-
}
|
|
75
|
-
div {
|
|
76
|
-
border-color: green;
|
|
77
|
-
background-color: red;
|
|
78
|
-
padding: 100px;
|
|
79
|
-
}
|
|
80
|
-
.marquee { background: url(images/sfx1_bg.gif) bottom repeat-x;}
|
|
81
|
-
SELECT {font-family: Arial, Verdana, Geneva, sans-serif; font-size: small; }
|
|
82
|
-
END
|
|
83
|
-
)
|
|
84
|
-
css = doc.to_css
|
|
85
|
-
assert_match('div, h1 {', css)
|
|
86
|
-
|
|
87
|
-
[ 'border-color:green;',
|
|
88
|
-
'background-color:red;',
|
|
89
|
-
'url(images/sfx1_bg.gif',
|
|
90
|
-
'Arial, Verdana, Geneva, sans-serif;',
|
|
91
|
-
'padding:100px;'].each do |attribute|
|
|
92
|
-
assert_match(attribute, css)
|
|
93
|
-
end
|
|
94
|
-
end
|
|
95
|
-
end
|
data/test/test_token.rb
DELETED
|
@@ -1,24 +0,0 @@
|
|
|
1
|
-
require File.dirname(__FILE__) + "/helper"
|
|
2
|
-
|
|
3
|
-
class TokenTest < Test::Unit::TestCase
|
|
4
|
-
include CSS
|
|
5
|
-
|
|
6
|
-
def test_tokens_have_a_name_value_and_position
|
|
7
|
-
token = SAC::Token.new(:foo, "bar", 14)
|
|
8
|
-
assert_equal(:foo, token.name)
|
|
9
|
-
assert_equal("bar", token.value)
|
|
10
|
-
assert_equal(14, token.position)
|
|
11
|
-
end
|
|
12
|
-
|
|
13
|
-
def test_to_racc_token_returns_a_name_value_array
|
|
14
|
-
assert_equal([:foo, "bar"], SAC::Token.new(:foo, "bar", 99).to_racc_token)
|
|
15
|
-
end
|
|
16
|
-
|
|
17
|
-
def test_delimiter_token_is_always_delim
|
|
18
|
-
assert_equal(:delim, SAC::DelimiterToken.new(";", 99).name)
|
|
19
|
-
end
|
|
20
|
-
|
|
21
|
-
def test_delimiter_token_just_returns_values_for_racc
|
|
22
|
-
assert_equal(%w(; ;), SAC::DelimiterToken.new(";", 99).to_racc_token)
|
|
23
|
-
end
|
|
24
|
-
end
|
data/test/test_tokenizer.rb
DELETED
|
@@ -1,127 +0,0 @@
|
|
|
1
|
-
require File.dirname(__FILE__) + "/helper"
|
|
2
|
-
|
|
3
|
-
class TokenizerTest < Test::Unit::TestCase
|
|
4
|
-
include CSS::SAC
|
|
5
|
-
|
|
6
|
-
def setup
|
|
7
|
-
@tokenizer = Tokenizer.new
|
|
8
|
-
end
|
|
9
|
-
|
|
10
|
-
def test_tokenize
|
|
11
|
-
assert_equal([], @tokenizer.tokenize(""))
|
|
12
|
-
end
|
|
13
|
-
|
|
14
|
-
def test_parse_simple
|
|
15
|
-
text = '
|
|
16
|
-
@import "subs.css";
|
|
17
|
-
* { margin: 0px; }
|
|
18
|
-
body {
|
|
19
|
-
margin: 0px;
|
|
20
|
-
padding: 0px;
|
|
21
|
-
}'
|
|
22
|
-
|
|
23
|
-
assert_tokens(text,
|
|
24
|
-
[:IMPORT_SYM, "@import"],
|
|
25
|
-
[:STRING, "\"subs.css\""],
|
|
26
|
-
[:delim, ";"],
|
|
27
|
-
[:delim, "*"],
|
|
28
|
-
[:LBRACE, " {"],
|
|
29
|
-
[:IDENT, "margin"],
|
|
30
|
-
[:delim, ":"],
|
|
31
|
-
[:LENGTH, "0px"],
|
|
32
|
-
[:delim, ";"],
|
|
33
|
-
[:delim, "}"],
|
|
34
|
-
[:IDENT, "body"],
|
|
35
|
-
[:LBRACE, " {"],
|
|
36
|
-
[:IDENT, "margin"],
|
|
37
|
-
[:delim, ":"],
|
|
38
|
-
[:LENGTH, "0px"],
|
|
39
|
-
[:delim, ";"],
|
|
40
|
-
[:IDENT, "padding"],
|
|
41
|
-
[:delim, ":"],
|
|
42
|
-
[:LENGTH, "0px"],
|
|
43
|
-
[:delim, ";"],
|
|
44
|
-
[:delim, "}"])
|
|
45
|
-
end
|
|
46
|
-
|
|
47
|
-
def test_at_import
|
|
48
|
-
tokens = @tokenizer.tokenize('@import "subs.css" print;')
|
|
49
|
-
assert_equal(6, tokens.length)
|
|
50
|
-
end
|
|
51
|
-
|
|
52
|
-
def test_at_media
|
|
53
|
-
assert_tokens('@media print { h1 { color: black; } }',
|
|
54
|
-
[:MEDIA_SYM, "@media"],
|
|
55
|
-
[:IDENT, "print"],
|
|
56
|
-
[:LBRACE, " {"],
|
|
57
|
-
[:IDENT, "h1"],
|
|
58
|
-
[:LBRACE, " {"],
|
|
59
|
-
[:IDENT, "color"],
|
|
60
|
-
[:delim, ":"],
|
|
61
|
-
[:IDENT, "black"],
|
|
62
|
-
[:delim, ";"],
|
|
63
|
-
[:delim, "}"],
|
|
64
|
-
[:delim, "}"])
|
|
65
|
-
end
|
|
66
|
-
|
|
67
|
-
def test_at_page
|
|
68
|
-
tokens = @tokenizer.tokenize('@page print { color: black; }')
|
|
69
|
-
assert_equal(12, tokens.length)
|
|
70
|
-
|
|
71
|
-
tokens = @tokenizer.tokenize('@page :left { color: black; }')
|
|
72
|
-
assert_equal(13, tokens.length)
|
|
73
|
-
|
|
74
|
-
tokens = @tokenizer.tokenize('@page print :left { color: black; }')
|
|
75
|
-
assert_equal(15, tokens.length)
|
|
76
|
-
end
|
|
77
|
-
|
|
78
|
-
def test_two_strings
|
|
79
|
-
tokens = @tokenizer.tokenize('"one" "two"')
|
|
80
|
-
assert_equal(3, tokens.length)
|
|
81
|
-
end
|
|
82
|
-
|
|
83
|
-
def test_at_font_face
|
|
84
|
-
tokens = @tokenizer.tokenize('@font-face { color: black; }')
|
|
85
|
-
assert_equal(11, tokens.length)
|
|
86
|
-
end
|
|
87
|
-
|
|
88
|
-
def test_ignorable_at
|
|
89
|
-
tokens = @tokenizer.tokenize('@aaron { color: black; }')
|
|
90
|
-
assert_equal(11, tokens.length)
|
|
91
|
-
end
|
|
92
|
-
|
|
93
|
-
def test_function_token
|
|
94
|
-
assert_tokens("foo(aaron)", :FUNCTION, :IDENT, :delim)
|
|
95
|
-
end
|
|
96
|
-
|
|
97
|
-
def test_an_example_of_assert_tokens
|
|
98
|
-
assert_tokens("body { color: pink; }",
|
|
99
|
-
:IDENT, :LBRACE, :IDENT, :delim, [:IDENT, "pink"], :delim, :delim)
|
|
100
|
-
end
|
|
101
|
-
|
|
102
|
-
def test_comment_with_an_asterisk_in_it
|
|
103
|
-
assert_tokens("/* * */", :COMMENT)
|
|
104
|
-
end
|
|
105
|
-
|
|
106
|
-
def assert_tokens(text, *expected)
|
|
107
|
-
tokens = @tokenizer.tokenize(text).reject { |t| t.name == :S }
|
|
108
|
-
|
|
109
|
-
assert_equal(expected.size, tokens.size)
|
|
110
|
-
|
|
111
|
-
count = 1
|
|
112
|
-
|
|
113
|
-
tokens.zip(expected).each do |sets|
|
|
114
|
-
token, expected_name, expected_value = sets.flatten
|
|
115
|
-
assert_equal(expected_name, token.name, "token #{count} name")
|
|
116
|
-
assert_equal(expected_value, token.value, "token #{count} value") if expected_value
|
|
117
|
-
count += 1
|
|
118
|
-
end
|
|
119
|
-
end
|
|
120
|
-
|
|
121
|
-
def test_comments_pattern_is_lazy
|
|
122
|
-
text = "/* * HAI * */ a {display:block} /* * BAI * */ em {font-style:normal}"
|
|
123
|
-
assert_tokens text,
|
|
124
|
-
:COMMENT, :IDENT, :LBRACE, :IDENT, :delim, [:IDENT, "block"], :delim,
|
|
125
|
-
:COMMENT, :IDENT, :LBRACE, :IDENT, :delim, [:IDENT, "normal"], :delim
|
|
126
|
-
end
|
|
127
|
-
end
|
data/test/test_xpath.rb
DELETED
|
@@ -1,105 +0,0 @@
|
|
|
1
|
-
require File.dirname(__FILE__) + "/helper"
|
|
2
|
-
|
|
3
|
-
# Thanks, Joe!
|
|
4
|
-
# http://www.joehewitt.com/blog/files/getElementsBySelector.js
|
|
5
|
-
|
|
6
|
-
class XPathTest < Test::Unit::TestCase
|
|
7
|
-
def setup
|
|
8
|
-
@parser = CSS::SAC::Parser.new()
|
|
9
|
-
class << @parser.document_handler
|
|
10
|
-
attr_accessor :selectors
|
|
11
|
-
def start_selector(selectors)
|
|
12
|
-
@selectors = selectors
|
|
13
|
-
end
|
|
14
|
-
end
|
|
15
|
-
end
|
|
16
|
-
|
|
17
|
-
# TODO: looks like attribute value quoting
|
|
18
|
-
# might be broken on the css side?
|
|
19
|
-
# this: input[type="text"] should be valid CSS
|
|
20
|
-
# and probably not return the quotes in the node
|
|
21
|
-
|
|
22
|
-
def test_any
|
|
23
|
-
assert_xpath("//*", "*")
|
|
24
|
-
end
|
|
25
|
-
|
|
26
|
-
def test_element
|
|
27
|
-
assert_xpath("//h1", "h1")
|
|
28
|
-
end
|
|
29
|
-
|
|
30
|
-
def test_id
|
|
31
|
-
assert_xpath("//*[@id='foo']", "#foo")
|
|
32
|
-
end
|
|
33
|
-
|
|
34
|
-
def test_class
|
|
35
|
-
assert_xpath("//*[contains(@class, 'foo')]", ".foo")
|
|
36
|
-
end
|
|
37
|
-
|
|
38
|
-
def test_attribute_with_no_value
|
|
39
|
-
assert_xpath("//*[@checked]", "[checked]")
|
|
40
|
-
end
|
|
41
|
-
|
|
42
|
-
def test_attribute_with_value
|
|
43
|
-
assert_xpath("//*[@type='text']", "[type=text]")
|
|
44
|
-
end
|
|
45
|
-
|
|
46
|
-
def test_hyphen_separated_attribute
|
|
47
|
-
# the contains behavior is probably fine here
|
|
48
|
-
assert_xpath("//*[contains(@type, 'text')]", "[type~=text]")
|
|
49
|
-
end
|
|
50
|
-
|
|
51
|
-
def test_space_separated_attribute
|
|
52
|
-
# the contains behavior is probably fine here
|
|
53
|
-
assert_xpath("//*[contains(@type, 'text')]", "[type|=text]")
|
|
54
|
-
end
|
|
55
|
-
|
|
56
|
-
def test_element_with_id
|
|
57
|
-
assert_xpath("//h1[@id='monkey']", "h1#monkey")
|
|
58
|
-
end
|
|
59
|
-
|
|
60
|
-
def test_element_with_class
|
|
61
|
-
assert_xpath("//h1[contains(@class, 'foo')]", "h1.foo")
|
|
62
|
-
end
|
|
63
|
-
|
|
64
|
-
def test_element_with_id_and_class
|
|
65
|
-
assert_xpath("//h1[@id='monkey'][contains(@class, 'foo')]", "h1#monkey.foo")
|
|
66
|
-
end
|
|
67
|
-
|
|
68
|
-
def test_element_with_multiple_classes
|
|
69
|
-
assert_xpath("//h1[contains(@class, 'foo')][contains(@class, 'bar')]", "h1.foo.bar")
|
|
70
|
-
end
|
|
71
|
-
|
|
72
|
-
def test_descendant
|
|
73
|
-
assert_xpath("//div//p", "div p")
|
|
74
|
-
assert_xpath("//div//*[contains(@class, 'angry')]", "div .angry")
|
|
75
|
-
end
|
|
76
|
-
|
|
77
|
-
def test_direct_descendant
|
|
78
|
-
assert_xpath("//div/p", "div > p")
|
|
79
|
-
end
|
|
80
|
-
|
|
81
|
-
def test_sibling
|
|
82
|
-
assert_xpath("//div/following-sibling::p", "div + p")
|
|
83
|
-
end
|
|
84
|
-
|
|
85
|
-
def test_safely_ignores_pseudoclasses
|
|
86
|
-
assert_xpath("//a", "a:hover")
|
|
87
|
-
end
|
|
88
|
-
|
|
89
|
-
private
|
|
90
|
-
|
|
91
|
-
def assert_xpath(xpath, css)
|
|
92
|
-
assert_equal(xpath, selector_for(css).to_xpath)
|
|
93
|
-
end
|
|
94
|
-
|
|
95
|
-
def selector_for(string)
|
|
96
|
-
selectors = selectors_for(string)
|
|
97
|
-
assert_equal(1, selectors.length)
|
|
98
|
-
selectors.first
|
|
99
|
-
end
|
|
100
|
-
|
|
101
|
-
def selectors_for(string)
|
|
102
|
-
@parser.parse("#{string} {}")
|
|
103
|
-
@parser.document_handler.selectors
|
|
104
|
-
end
|
|
105
|
-
end
|