css_parser 1.2.2 → 3.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.
- checksums.yaml +7 -0
- data/MIT-LICENSE +21 -0
- data/lib/css_parser/parser.rb +532 -185
- data/lib/css_parser/regexps.rb +220 -42
- data/lib/css_parser/rule_set.rb +491 -266
- data/lib/css_parser/version.rb +5 -0
- data/lib/css_parser.rb +56 -60
- metadata +40 -52
- data/test/fixtures/import-circular-reference.css +0 -4
- data/test/fixtures/import-with-media-types.css +0 -3
- data/test/fixtures/import1.css +0 -3
- data/test/fixtures/simple.css +0 -6
- data/test/fixtures/subdir/import2.css +0 -3
- data/test/test_css_parser_basic.rb +0 -64
- data/test/test_css_parser_loading.rb +0 -146
- data/test/test_css_parser_media_types.rb +0 -106
- data/test/test_css_parser_misc.rb +0 -164
- data/test/test_css_parser_regexps.rb +0 -69
- data/test/test_helper.rb +0 -6
- data/test/test_merging.rb +0 -110
- data/test/test_rule_set.rb +0 -90
- data/test/test_rule_set_creating_shorthand.rb +0 -143
- data/test/test_rule_set_expanding_shorthand.rb +0 -223
|
@@ -1,164 +0,0 @@
|
|
|
1
|
-
require File.expand_path(File.dirname(__FILE__) + '/test_helper')
|
|
2
|
-
|
|
3
|
-
# Test cases for the CssParser.
|
|
4
|
-
class CssParserTests < Test::Unit::TestCase
|
|
5
|
-
include CssParser
|
|
6
|
-
|
|
7
|
-
def setup
|
|
8
|
-
@cp = Parser.new
|
|
9
|
-
end
|
|
10
|
-
|
|
11
|
-
def test_at_page_rule
|
|
12
|
-
# from http://www.w3.org/TR/CSS21/page.html#page-selectors
|
|
13
|
-
css = <<-EOT
|
|
14
|
-
@page { margin: 2cm }
|
|
15
|
-
|
|
16
|
-
@page :first {
|
|
17
|
-
margin-top: 10cm
|
|
18
|
-
}
|
|
19
|
-
EOT
|
|
20
|
-
|
|
21
|
-
@cp.add_block!(css)
|
|
22
|
-
|
|
23
|
-
assert_equal 'margin: 2cm;', @cp.find_by_selector('@page').join(' ')
|
|
24
|
-
assert_equal 'margin-top: 10cm;', @cp.find_by_selector('@page :first').join(' ')
|
|
25
|
-
end
|
|
26
|
-
|
|
27
|
-
def test_should_ignore_comments
|
|
28
|
-
# see http://www.w3.org/Style/CSS/Test/CSS2.1/current/html4/t040109-c17-comments-00-b.htm
|
|
29
|
-
css =<<-EOT
|
|
30
|
-
/* This is a CSS comment. */
|
|
31
|
-
.one {color: green;} /* Another comment */
|
|
32
|
-
/* The following should not be used:
|
|
33
|
-
.one {color: red;} */
|
|
34
|
-
.two {color: green; /* color: yellow; */}
|
|
35
|
-
/**
|
|
36
|
-
.three {color: red;} */
|
|
37
|
-
.three {color: green;}
|
|
38
|
-
/**/
|
|
39
|
-
.four {color: green;}
|
|
40
|
-
/*********/
|
|
41
|
-
.five {color: green;}
|
|
42
|
-
/* a comment **/
|
|
43
|
-
.six {color: green;}
|
|
44
|
-
EOT
|
|
45
|
-
|
|
46
|
-
@cp.add_block!(css)
|
|
47
|
-
@cp.each_selector do |sel, decs, spec|
|
|
48
|
-
assert_equal 'color: green;', decs
|
|
49
|
-
end
|
|
50
|
-
end
|
|
51
|
-
|
|
52
|
-
def test_parsing_blocks
|
|
53
|
-
# dervived from http://www.w3.org/TR/CSS21/syndata.html#rule-sets
|
|
54
|
-
css = <<-EOT
|
|
55
|
-
div[name='test'] {
|
|
56
|
-
|
|
57
|
-
color:
|
|
58
|
-
|
|
59
|
-
red;
|
|
60
|
-
|
|
61
|
-
}div:hover{coloR:red;
|
|
62
|
-
}div:first-letter{color:red;/*color:blue;}"commented out"*/}
|
|
63
|
-
|
|
64
|
-
p[example="public class foo\
|
|
65
|
-
{\
|
|
66
|
-
private string x;\
|
|
67
|
-
\
|
|
68
|
-
foo(int x) {\
|
|
69
|
-
this.x = 'test';\
|
|
70
|
-
this.x = \"test\";\
|
|
71
|
-
}\
|
|
72
|
-
\
|
|
73
|
-
}"] { color: red }
|
|
74
|
-
|
|
75
|
-
p { color:red}
|
|
76
|
-
EOT
|
|
77
|
-
|
|
78
|
-
@cp.add_block!(css)
|
|
79
|
-
|
|
80
|
-
@cp.each_selector do |sel, decs, spec|
|
|
81
|
-
assert_equal 'color: red;', decs
|
|
82
|
-
end
|
|
83
|
-
end
|
|
84
|
-
|
|
85
|
-
def test_ignoring_malformed_declarations
|
|
86
|
-
# dervived from http://www.w3.org/TR/CSS21/syndata.html#parsing-errors
|
|
87
|
-
css = <<-EOT
|
|
88
|
-
p { color:green }
|
|
89
|
-
p { color:green; color } /* malformed declaration missing ':', value */
|
|
90
|
-
p { color:red; color; color:green } /* same with expected recovery */
|
|
91
|
-
p { color:green; color: } /* malformed declaration missing value */
|
|
92
|
-
p { color:red; color:; color:green } /* same with expected recovery */
|
|
93
|
-
p { color:green; color{;color:maroon} } /* unexpected tokens { } */
|
|
94
|
-
p { color:red; color{;color:maroon}; color:green } /* same with recovery */
|
|
95
|
-
EOT
|
|
96
|
-
|
|
97
|
-
@cp.add_block!(css)
|
|
98
|
-
|
|
99
|
-
@cp.each_selector do |sel, decs, spec|
|
|
100
|
-
assert_equal 'color: green;', decs
|
|
101
|
-
end
|
|
102
|
-
end
|
|
103
|
-
|
|
104
|
-
def test_calculating_specificity
|
|
105
|
-
# from http://www.w3.org/TR/CSS21/cascade.html#specificity
|
|
106
|
-
assert_equal 0, CssParser.calculate_specificity('*')
|
|
107
|
-
assert_equal 1, CssParser.calculate_specificity('li')
|
|
108
|
-
assert_equal 2, CssParser.calculate_specificity('li:first-line')
|
|
109
|
-
assert_equal 2, CssParser.calculate_specificity('ul li')
|
|
110
|
-
assert_equal 3, CssParser.calculate_specificity('ul ol+li')
|
|
111
|
-
assert_equal 11, CssParser.calculate_specificity('h1 + *[rel=up]')
|
|
112
|
-
assert_equal 13, CssParser.calculate_specificity('ul ol li.red')
|
|
113
|
-
assert_equal 21, CssParser.calculate_specificity('li.red.level')
|
|
114
|
-
assert_equal 100, CssParser.calculate_specificity('#x34y')
|
|
115
|
-
|
|
116
|
-
# from http://www.hixie.ch/tests/adhoc/css/cascade/specificity/003.html
|
|
117
|
-
assert_equal CssParser.calculate_specificity('div *'), CssParser.calculate_specificity('p')
|
|
118
|
-
assert CssParser.calculate_specificity('body div *') > CssParser.calculate_specificity('div *')
|
|
119
|
-
|
|
120
|
-
# other tests
|
|
121
|
-
assert_equal 11, CssParser.calculate_specificity('h1[id|=123]')
|
|
122
|
-
end
|
|
123
|
-
|
|
124
|
-
def test_converting_uris
|
|
125
|
-
base_uri = 'http://www.example.org/style/basic.css'
|
|
126
|
-
["body { background: url(yellow) };", "body { background: url('yellow') };",
|
|
127
|
-
"body { background: url('/style/yellow') };",
|
|
128
|
-
"body { background: url(\"../style/yellow\") };",
|
|
129
|
-
"body { background: url(\"lib/../../style/yellow\") };"].each do |css|
|
|
130
|
-
converted_css = CssParser.convert_uris(css, base_uri)
|
|
131
|
-
assert_equal "body { background: url('http://www.example.org/style/yellow') };", converted_css
|
|
132
|
-
end
|
|
133
|
-
|
|
134
|
-
converted_css = CssParser.convert_uris("body { background: url(../style/yellow-dot_symbol$.png?abc=123&def=456&ghi=789#1011) };", base_uri)
|
|
135
|
-
assert_equal "body { background: url('http://www.example.org/style/yellow-dot_symbol$.png?abc=123&def=456&ghi=789#1011') };", converted_css
|
|
136
|
-
|
|
137
|
-
# taken from error log: 2007-10-23 04:37:41#2399
|
|
138
|
-
converted_css = CssParser.convert_uris('.specs {font-family:Helvetica;font-weight:bold;font-style:italic;color:#008CA8;font-size:1.4em;list-style-image:url("images/bullet.gif");}', 'http://www.example.org/directory/file.html')
|
|
139
|
-
assert_equal ".specs {font-family:Helvetica;font-weight:bold;font-style:italic;color:#008CA8;font-size:1.4em;list-style-image:url('http://www.example.org/directory/images/bullet.gif');}", converted_css
|
|
140
|
-
end
|
|
141
|
-
|
|
142
|
-
def test_ruleset_with_braces
|
|
143
|
-
=begin
|
|
144
|
-
parser = Parser.new
|
|
145
|
-
parser.add_block!("div { background-color: black !important; }")
|
|
146
|
-
parser.add_block!("div { background-color: red; }")
|
|
147
|
-
|
|
148
|
-
rulesets = []
|
|
149
|
-
|
|
150
|
-
parser['div'].each do |declaration|
|
|
151
|
-
rulesets << RuleSet.new('div', declaration)
|
|
152
|
-
end
|
|
153
|
-
|
|
154
|
-
merged = CssParser.merge(rulesets)
|
|
155
|
-
|
|
156
|
-
result: # merged.to_s => "{ background-color: black !important; }"
|
|
157
|
-
=end
|
|
158
|
-
|
|
159
|
-
new_rule = RuleSet.new('div', "{ background-color: black !important; }")
|
|
160
|
-
|
|
161
|
-
assert_equal 'div { background-color: black !important; }', new_rule.to_s
|
|
162
|
-
end
|
|
163
|
-
|
|
164
|
-
end
|
|
@@ -1,69 +0,0 @@
|
|
|
1
|
-
# coding: iso-8859-1
|
|
2
|
-
require File.expand_path(File.dirname(__FILE__) + '/test_helper')
|
|
3
|
-
|
|
4
|
-
# Test cases for CSS regular expressions
|
|
5
|
-
#
|
|
6
|
-
# see http://www.w3.org/TR/CSS21/syndata.html and
|
|
7
|
-
# http://www.w3.org/TR/CSS21/grammar.html
|
|
8
|
-
class CssParserRegexpTests < Test::Unit::TestCase
|
|
9
|
-
def test_strings
|
|
10
|
-
# complete matches
|
|
11
|
-
['"abcd"', '" A sd s�drcv \'dsf\' asd rfg asd"', '"A\ d??ef 123!"',
|
|
12
|
-
"\"this is\\\n a test\"", '"back\67round"', '"r\000065 ed"',
|
|
13
|
-
"'abcd'", "' A sd sedrcv \"dsf\" asd rf�&23$%#%$g asd'", "'A\\\n def 123!'",
|
|
14
|
-
"'this is\\\n a test'", "'back\\67round'", "'r\\000065 ed'"
|
|
15
|
-
].each do |str|
|
|
16
|
-
assert_equal str, str.match(CssParser::RE_STRING).to_s
|
|
17
|
-
end
|
|
18
|
-
|
|
19
|
-
test_string = "p { background: red url(\"url\\.'p'ng\"); }"
|
|
20
|
-
assert_equal "\"url\\.'p'ng\"", test_string.match(CssParser::RE_STRING).to_s
|
|
21
|
-
|
|
22
|
-
end
|
|
23
|
-
|
|
24
|
-
def test_unicode
|
|
25
|
-
['back\67round', 'r\000065 ed', '\00006C'].each do |str|
|
|
26
|
-
assert_match(Regexp.new(CssParser::RE_UNICODE), str)
|
|
27
|
-
end
|
|
28
|
-
end
|
|
29
|
-
|
|
30
|
-
def test_colour
|
|
31
|
-
['color: #fff', 'color:#f0a09c;', 'color: #04A', 'color: #04a9CE',
|
|
32
|
-
'color: rgb(100, -10%, 300);', 'color: rgb(10,10,10)', 'color:rgb(12.7253%, -12%,0)',
|
|
33
|
-
'color: black', 'color:Red;', 'color: AqUa;', 'color: blue ', 'color: transparent'
|
|
34
|
-
].each do |colour|
|
|
35
|
-
assert_match(CssParser::RE_COLOUR, colour)
|
|
36
|
-
end
|
|
37
|
-
|
|
38
|
-
['color: #fa', 'color:#f009c;', 'color: #04G', 'color: #04a9Cq',
|
|
39
|
-
'color: rgb 100, -10%, 300;', 'color: rgb 10,10,10', 'color:rgb(12px, -12%,0)',
|
|
40
|
-
'color:fuscia;', 'color: thick'
|
|
41
|
-
].each do |colour|
|
|
42
|
-
assert_no_match(CssParser::RE_COLOUR, colour)
|
|
43
|
-
end
|
|
44
|
-
end
|
|
45
|
-
|
|
46
|
-
def test_uris
|
|
47
|
-
crazy_uri = 'http://www.example.com:80/~/redb%20all.png?test=test&test;test+test#test!'
|
|
48
|
-
|
|
49
|
-
assert_equal "url('#{crazy_uri}')",
|
|
50
|
-
"li { list-style: url('#{crazy_uri}') disc }".match(CssParser::RE_URI).to_s
|
|
51
|
-
|
|
52
|
-
assert_equal "url(#{crazy_uri})",
|
|
53
|
-
"li { list-style: url(#{crazy_uri}) disc }".match(CssParser::RE_URI).to_s
|
|
54
|
-
|
|
55
|
-
assert_equal "url(\"#{crazy_uri}\")",
|
|
56
|
-
"li { list-style: url(\"#{crazy_uri}\") disc }".match(CssParser::RE_URI).to_s
|
|
57
|
-
end
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
protected
|
|
61
|
-
def load_test_file(filename)
|
|
62
|
-
fh = File.new("fixtures/#{filename}", 'r')
|
|
63
|
-
test_file = fh.read
|
|
64
|
-
fh.close
|
|
65
|
-
|
|
66
|
-
return test_file
|
|
67
|
-
end
|
|
68
|
-
|
|
69
|
-
end
|
data/test/test_helper.rb
DELETED
data/test/test_merging.rb
DELETED
|
@@ -1,110 +0,0 @@
|
|
|
1
|
-
require File.expand_path(File.dirname(__FILE__) + '/test_helper')
|
|
2
|
-
|
|
3
|
-
class MergingTests < Test::Unit::TestCase
|
|
4
|
-
include CssParser
|
|
5
|
-
|
|
6
|
-
def setup
|
|
7
|
-
@cp = CssParser::Parser.new
|
|
8
|
-
end
|
|
9
|
-
|
|
10
|
-
def test_simple_merge
|
|
11
|
-
rs1 = RuleSet.new(nil, 'color: black;')
|
|
12
|
-
rs2 = RuleSet.new(nil, 'margin: 0px;')
|
|
13
|
-
merged = CssParser.merge(rs1, rs2)
|
|
14
|
-
assert_equal '0px;', merged['margin']
|
|
15
|
-
assert_equal 'black;', merged['color']
|
|
16
|
-
end
|
|
17
|
-
|
|
18
|
-
def test_merging_array
|
|
19
|
-
rs1 = RuleSet.new(nil, 'color: black;')
|
|
20
|
-
rs2 = RuleSet.new(nil, 'margin: 0px;')
|
|
21
|
-
merged = CssParser.merge([rs1, rs2])
|
|
22
|
-
assert_equal '0px;', merged['margin']
|
|
23
|
-
assert_equal 'black;', merged['color']
|
|
24
|
-
end
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
def test_merging_multiple
|
|
28
|
-
rs1 = RuleSet.new(nil, 'color: black;')
|
|
29
|
-
rs2 = RuleSet.new(nil, 'margin: 0px;')
|
|
30
|
-
rs3 = RuleSet.new(nil, 'margin: 5px;')
|
|
31
|
-
merged = CssParser.merge(rs1, rs2, rs3)
|
|
32
|
-
assert_equal '5px;', merged['margin']
|
|
33
|
-
end
|
|
34
|
-
|
|
35
|
-
def test_multiple_selectors_should_have_zero_specificity
|
|
36
|
-
rs1 = RuleSet.new('p, a[rel="external"]', 'color: black;')
|
|
37
|
-
rs2 = RuleSet.new('a', 'color: blue;')
|
|
38
|
-
merged = CssParser.merge(rs1, rs2)
|
|
39
|
-
assert_equal 'blue;', merged['color']
|
|
40
|
-
end
|
|
41
|
-
|
|
42
|
-
def test_setting_specificity
|
|
43
|
-
rs1 = RuleSet.new(nil, 'color: red;', 20)
|
|
44
|
-
rs2 = RuleSet.new(nil, 'color: blue;', 10)
|
|
45
|
-
merged = CssParser.merge(rs1, rs2)
|
|
46
|
-
assert_equal 'red;', merged['color']
|
|
47
|
-
end
|
|
48
|
-
|
|
49
|
-
def test_properties_should_be_case_insensitive
|
|
50
|
-
rs1 = RuleSet.new(nil, ' CoLor : red ;', 20)
|
|
51
|
-
rs2 = RuleSet.new(nil, 'color: blue;', 10)
|
|
52
|
-
merged = CssParser.merge(rs1, rs2)
|
|
53
|
-
assert_equal 'red;', merged['color']
|
|
54
|
-
end
|
|
55
|
-
|
|
56
|
-
def test_merging_backgrounds
|
|
57
|
-
rs1 = RuleSet.new(nil, 'background-color: black;')
|
|
58
|
-
rs2 = RuleSet.new(nil, 'background-image: none;')
|
|
59
|
-
merged = CssParser.merge(rs1, rs2)
|
|
60
|
-
assert_equal 'black none;', merged['background']
|
|
61
|
-
end
|
|
62
|
-
|
|
63
|
-
def test_merging_dimensions
|
|
64
|
-
rs1 = RuleSet.new(nil, 'margin: 3em;')
|
|
65
|
-
rs2 = RuleSet.new(nil, 'margin-left: 1em;')
|
|
66
|
-
merged = CssParser.merge(rs1, rs2)
|
|
67
|
-
assert_equal '3em 3em 3em 1em;', merged['margin']
|
|
68
|
-
end
|
|
69
|
-
|
|
70
|
-
def test_merging_fonts
|
|
71
|
-
rs1 = RuleSet.new(nil, 'font: 11px Arial;')
|
|
72
|
-
rs2 = RuleSet.new(nil, 'font-weight: bold;')
|
|
73
|
-
merged = CssParser.merge(rs1, rs2)
|
|
74
|
-
assert_equal 'bold 11px Arial;', merged['font']
|
|
75
|
-
end
|
|
76
|
-
|
|
77
|
-
def test_raising_error_on_bad_type
|
|
78
|
-
assert_raise ArgumentError do
|
|
79
|
-
CssParser.merge([1,2,3])
|
|
80
|
-
end
|
|
81
|
-
end
|
|
82
|
-
|
|
83
|
-
def test_returning_early_with_only_one_params
|
|
84
|
-
rs = RuleSet.new(nil, 'font-weight: bold;')
|
|
85
|
-
merged = CssParser.merge(rs)
|
|
86
|
-
assert_equal rs.object_id, merged.object_id
|
|
87
|
-
end
|
|
88
|
-
|
|
89
|
-
def test_merging_important
|
|
90
|
-
rs1 = RuleSet.new(nil, 'color: black !important;')
|
|
91
|
-
rs2 = RuleSet.new(nil, 'color: red;')
|
|
92
|
-
merged = CssParser.merge(rs1, rs2)
|
|
93
|
-
assert_equal 'black !important;', merged['color']
|
|
94
|
-
end
|
|
95
|
-
|
|
96
|
-
def test_merging_multiple_important
|
|
97
|
-
rs1 = RuleSet.new(nil, 'color: black !important;', 1000)
|
|
98
|
-
rs2 = RuleSet.new(nil, 'color: red !important;', 1)
|
|
99
|
-
merged = CssParser.merge(rs1, rs2)
|
|
100
|
-
assert_equal 'black !important;', merged['color']
|
|
101
|
-
end
|
|
102
|
-
|
|
103
|
-
def test_merging_shorthand_important
|
|
104
|
-
rs1 = RuleSet.new(nil, 'background: black none !important;')
|
|
105
|
-
rs2 = RuleSet.new(nil, 'background-color: red;')
|
|
106
|
-
merged = CssParser.merge(rs1, rs2)
|
|
107
|
-
assert_equal 'black !important;', merged['background-color']
|
|
108
|
-
end
|
|
109
|
-
|
|
110
|
-
end
|
data/test/test_rule_set.rb
DELETED
|
@@ -1,90 +0,0 @@
|
|
|
1
|
-
require File.expand_path(File.dirname(__FILE__) + '/test_helper')
|
|
2
|
-
require "set"
|
|
3
|
-
|
|
4
|
-
# Test cases for parsing CSS blocks
|
|
5
|
-
class RuleSetTests < Test::Unit::TestCase
|
|
6
|
-
include CssParser
|
|
7
|
-
|
|
8
|
-
def setup
|
|
9
|
-
@cp = Parser.new
|
|
10
|
-
end
|
|
11
|
-
|
|
12
|
-
def test_setting_property_values
|
|
13
|
-
rs = RuleSet.new(nil, nil)
|
|
14
|
-
|
|
15
|
-
rs['background-color'] = 'red'
|
|
16
|
-
assert_equal('red;', rs['background-color'])
|
|
17
|
-
|
|
18
|
-
rs['background-color'] = 'blue !important;'
|
|
19
|
-
assert_equal('blue !important;', rs['background-color'])
|
|
20
|
-
end
|
|
21
|
-
|
|
22
|
-
def test_getting_property_values
|
|
23
|
-
rs = RuleSet.new('#content p, a', 'color: #fff;')
|
|
24
|
-
assert_equal('#fff;', rs['color'])
|
|
25
|
-
end
|
|
26
|
-
|
|
27
|
-
def test_getting_property_value_ignoring_case
|
|
28
|
-
rs = RuleSet.new('#content p, a', 'color: #fff;')
|
|
29
|
-
assert_equal('#fff;', rs[' ColoR '])
|
|
30
|
-
end
|
|
31
|
-
|
|
32
|
-
def test_each_selector
|
|
33
|
-
expected = [
|
|
34
|
-
{:selector => "#content p", :declarations => "color: #fff;", :specificity => 101},
|
|
35
|
-
{:selector => "a", :declarations => "color: #fff;", :specificity => 1}
|
|
36
|
-
]
|
|
37
|
-
|
|
38
|
-
actual = []
|
|
39
|
-
rs = RuleSet.new('#content p, a', 'color: #fff;')
|
|
40
|
-
rs.each_selector do |sel, decs, spec|
|
|
41
|
-
actual << {:selector => sel, :declarations => decs, :specificity => spec}
|
|
42
|
-
end
|
|
43
|
-
|
|
44
|
-
assert_equal(expected, actual)
|
|
45
|
-
end
|
|
46
|
-
|
|
47
|
-
def test_each_declaration
|
|
48
|
-
expected = Set.new([
|
|
49
|
-
{:property => 'margin', :value => '1px -0.25em', :is_important => false},
|
|
50
|
-
{:property => 'background', :value => 'white none no-repeat', :is_important => true},
|
|
51
|
-
{:property => 'color', :value => '#fff', :is_important => false}
|
|
52
|
-
])
|
|
53
|
-
|
|
54
|
-
actual = Set.new
|
|
55
|
-
rs = RuleSet.new(nil, 'color: #fff; Background: white none no-repeat !important; margin: 1px -0.25em;')
|
|
56
|
-
rs.each_declaration do |prop, val, imp|
|
|
57
|
-
actual << {:property => prop, :value => val, :is_important => imp}
|
|
58
|
-
end
|
|
59
|
-
|
|
60
|
-
assert_equal(expected, actual)
|
|
61
|
-
end
|
|
62
|
-
|
|
63
|
-
def test_each_declaration_respects_order
|
|
64
|
-
css_fragment = "margin: 0; padding: 20px; margin-bottom: 28px;"
|
|
65
|
-
rs = RuleSet.new(nil, css_fragment)
|
|
66
|
-
expected = %w(margin padding margin-bottom)
|
|
67
|
-
actual = []
|
|
68
|
-
rs.each_declaration { |prop, val, imp| actual << prop }
|
|
69
|
-
assert_equal(expected, actual)
|
|
70
|
-
end
|
|
71
|
-
|
|
72
|
-
def test_declarations_to_s
|
|
73
|
-
declarations = 'color: #fff; font-weight: bold;'
|
|
74
|
-
rs = RuleSet.new('#content p, a', declarations)
|
|
75
|
-
assert_equal(declarations.split(' ').sort, rs.declarations_to_s.split(' ').sort)
|
|
76
|
-
end
|
|
77
|
-
|
|
78
|
-
def test_important_declarations_to_s
|
|
79
|
-
declarations = 'color: #fff; font-weight: bold !important;'
|
|
80
|
-
rs = RuleSet.new('#content p, a', declarations)
|
|
81
|
-
assert_equal(declarations.split(' ').sort, rs.declarations_to_s.split(' ').sort)
|
|
82
|
-
end
|
|
83
|
-
|
|
84
|
-
def test_overriding_specificity
|
|
85
|
-
rs = RuleSet.new('#content p, a', 'color: white', 1000)
|
|
86
|
-
rs.each_selector do |sel, decs, spec|
|
|
87
|
-
assert_equal 1000, spec
|
|
88
|
-
end
|
|
89
|
-
end
|
|
90
|
-
end
|
|
@@ -1,143 +0,0 @@
|
|
|
1
|
-
require File.expand_path(File.dirname(__FILE__) + '/test_helper')
|
|
2
|
-
|
|
3
|
-
# Test cases for reading and generating CSS shorthand properties
|
|
4
|
-
class RuleSetCreatingShorthandTests < Test::Unit::TestCase
|
|
5
|
-
include CssParser
|
|
6
|
-
|
|
7
|
-
def setup
|
|
8
|
-
@cp = CssParser::Parser.new
|
|
9
|
-
end
|
|
10
|
-
|
|
11
|
-
# ==== Border shorthand
|
|
12
|
-
def test_combining_borders_into_shorthand
|
|
13
|
-
properties = {'border-top-width' => 'auto', 'border-right-width' => 'thin', 'border-bottom-width' => 'auto', 'border-left-width' => '0px'}
|
|
14
|
-
|
|
15
|
-
combined = create_shorthand(properties)
|
|
16
|
-
|
|
17
|
-
assert_equal('', combined['border'])
|
|
18
|
-
assert_equal('auto thin auto 0px;', combined['border-width'])
|
|
19
|
-
|
|
20
|
-
# after creating shorthand, all long-hand properties should be deleted
|
|
21
|
-
assert_properties_are_deleted(combined, properties)
|
|
22
|
-
|
|
23
|
-
# should not combine if any properties are missing
|
|
24
|
-
properties.delete('border-top-width')
|
|
25
|
-
|
|
26
|
-
combined = create_shorthand(properties)
|
|
27
|
-
|
|
28
|
-
assert_equal '', combined['border-width']
|
|
29
|
-
|
|
30
|
-
properties = {'border-width' => '22%', 'border-color' => 'rgba(255, 0, 0)'}
|
|
31
|
-
combined = create_shorthand(properties)
|
|
32
|
-
assert_equal '22% rgba(255, 0, 0);', combined['border']
|
|
33
|
-
assert_equal '', combined['border-width']
|
|
34
|
-
|
|
35
|
-
properties = {'border-top-style' => 'none', 'border-right-style' => 'none', 'border-bottom-style' => 'none', 'border-left-style' => 'none'}
|
|
36
|
-
combined = create_shorthand(properties)
|
|
37
|
-
assert_equal 'none;', combined['border']
|
|
38
|
-
end
|
|
39
|
-
|
|
40
|
-
# ==== Dimensions shorthand
|
|
41
|
-
def test_combining_dimensions_into_shorthand
|
|
42
|
-
properties = {'margin-right' => 'auto', 'margin-bottom' => '0px', 'margin-left' => 'auto', 'margin-top' => '0px',
|
|
43
|
-
'padding-right' => '1.25em', 'padding-bottom' => '11%', 'padding-left' => '3pc', 'padding-top' => '11.25ex'}
|
|
44
|
-
|
|
45
|
-
combined = create_shorthand(properties)
|
|
46
|
-
|
|
47
|
-
assert_equal('0px auto;', combined['margin'])
|
|
48
|
-
assert_equal('11.25ex 1.25em 11% 3pc;', combined['padding'])
|
|
49
|
-
|
|
50
|
-
# after creating shorthand, all long-hand properties should be deleted
|
|
51
|
-
assert_properties_are_deleted(combined, properties)
|
|
52
|
-
|
|
53
|
-
# should not combine if any properties are missing
|
|
54
|
-
properties.delete('margin-right')
|
|
55
|
-
properties.delete('padding-right')
|
|
56
|
-
|
|
57
|
-
combined = create_shorthand(properties)
|
|
58
|
-
|
|
59
|
-
assert_equal '', combined['margin']
|
|
60
|
-
assert_equal '', combined['padding']
|
|
61
|
-
end
|
|
62
|
-
|
|
63
|
-
# ==== Dimensions shorthand, auto property
|
|
64
|
-
def test_combining_dimensions_into_shorthand_with_auto
|
|
65
|
-
rs = RuleSet.new('#page', "margin: 0; margin-left: auto; margin-right: auto;")
|
|
66
|
-
rs.expand_shorthand!
|
|
67
|
-
assert_equal('auto;', rs['margin-left'])
|
|
68
|
-
rs.create_shorthand!
|
|
69
|
-
assert_equal('0 auto;', rs['margin'])
|
|
70
|
-
end
|
|
71
|
-
|
|
72
|
-
# ==== Font shorthand
|
|
73
|
-
def test_combining_font_into_shorthand
|
|
74
|
-
# should combine if all font properties are present
|
|
75
|
-
properties = {"font-weight" => "300", "font-size" => "12pt",
|
|
76
|
-
"font-family" => "sans-serif", "line-height" => "18px",
|
|
77
|
-
"font-style" => "oblique", "font-variant" => "small-caps"}
|
|
78
|
-
|
|
79
|
-
combined = create_shorthand(properties)
|
|
80
|
-
assert_equal('oblique small-caps 300 12pt/18px sans-serif;', combined['font'])
|
|
81
|
-
|
|
82
|
-
# after creating shorthand, all long-hand properties should be deleted
|
|
83
|
-
assert_properties_are_deleted(combined, properties)
|
|
84
|
-
|
|
85
|
-
# should not combine if any properties are missing
|
|
86
|
-
properties.delete('font-weight')
|
|
87
|
-
combined = create_shorthand(properties)
|
|
88
|
-
assert_equal '', combined['font']
|
|
89
|
-
end
|
|
90
|
-
|
|
91
|
-
# ==== Background shorthand
|
|
92
|
-
def test_combining_background_into_shorthand
|
|
93
|
-
properties = {'background-image' => 'url(\'chess.png\')', 'background-color' => 'gray',
|
|
94
|
-
'background-position' => 'center -10.2%', 'background-attachment' => 'fixed',
|
|
95
|
-
'background-repeat' => 'no-repeat'}
|
|
96
|
-
|
|
97
|
-
combined = create_shorthand(properties)
|
|
98
|
-
|
|
99
|
-
assert_equal('gray url(\'chess.png\') no-repeat center -10.2% fixed;', combined['background'])
|
|
100
|
-
|
|
101
|
-
# after creating shorthand, all long-hand properties should be deleted
|
|
102
|
-
assert_properties_are_deleted(combined, properties)
|
|
103
|
-
end
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
# ==== List-style shorthand
|
|
107
|
-
def test_combining_list_style_into_shorthand
|
|
108
|
-
properties = {'list-style-image' => 'url(\'chess.png\')', 'list-style-type' => 'katakana',
|
|
109
|
-
'list-style-position' => 'inside'}
|
|
110
|
-
|
|
111
|
-
combined = create_shorthand(properties)
|
|
112
|
-
|
|
113
|
-
assert_equal('katakana inside url(\'chess.png\');', combined['list-style'])
|
|
114
|
-
|
|
115
|
-
# after creating shorthand, all long-hand properties should be deleted
|
|
116
|
-
assert_properties_are_deleted(combined, properties)
|
|
117
|
-
end
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
def test_property_values_in_url
|
|
121
|
-
rs = RuleSet.new('#header', "background:url(http://example.com/1528/www/top-logo.jpg) no-repeat top right; padding: 79px 0 10px 0; text-align:left;")
|
|
122
|
-
rs.expand_shorthand!
|
|
123
|
-
assert_equal('top right;', rs['background-position'])
|
|
124
|
-
rs.create_shorthand!
|
|
125
|
-
assert_equal('url(http://example.com/1528/www/top-logo.jpg) no-repeat top right;', rs['background'])
|
|
126
|
-
end
|
|
127
|
-
|
|
128
|
-
protected
|
|
129
|
-
def assert_properties_are_deleted(ruleset, properties)
|
|
130
|
-
properties.each do |property, value|
|
|
131
|
-
assert_equal '', ruleset[property]
|
|
132
|
-
end
|
|
133
|
-
end
|
|
134
|
-
|
|
135
|
-
def create_shorthand(properties)
|
|
136
|
-
ruleset = RuleSet.new(nil, nil)
|
|
137
|
-
properties.each do |property, value|
|
|
138
|
-
ruleset[property] = value
|
|
139
|
-
end
|
|
140
|
-
ruleset.create_shorthand!
|
|
141
|
-
ruleset
|
|
142
|
-
end
|
|
143
|
-
end
|