css_parser_master 1.2.4

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.
@@ -0,0 +1,69 @@
1
+ # coding: iso-8859-1
2
+ require 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
@@ -0,0 +1,6 @@
1
+ require 'rubygems'
2
+ require 'test/unit'
3
+ require 'net/http'
4
+ require 'open-uri'
5
+ require 'WEBrick'
6
+ require File.dirname(__FILE__) + '/../lib/css_parser'
@@ -0,0 +1,88 @@
1
+ require 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
+ end
@@ -0,0 +1,90 @@
1
+ require 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|
41
+ actual << {:selector => sel.selector, :declarations => sel.declarations_to_s, :specificity => sel.specificity}
42
+ end
43
+
44
+ assert_equal(expected, actual)
45
+ end
46
+
47
+
48
+ def test_each_declaration
49
+ expected = Set.new([
50
+ {:property => 'margin', :value => '1px -0.25em', :is_important => false},
51
+ {:property => 'background', :value => 'white none no-repeat', :is_important => true},
52
+ {:property => 'color', :value => '#fff', :is_important => false}
53
+ ])
54
+
55
+ actual = Set.new
56
+ rs = RuleSet.new(nil, 'color: #fff; Background: white none no-repeat !important; margin: 1px -0.25em;')
57
+ rs.each_declaration do |decl|
58
+ prop = decl.property
59
+ val = decl.value
60
+ imp = decl.important
61
+ actual << {:property => prop, :value => val, :is_important => imp}
62
+ end
63
+
64
+ assert_equal(expected, actual)
65
+ end
66
+
67
+ def test_each_declaration_respects_order
68
+ css_fragment = "margin: 0; padding: 20px; margin-bottom: 28px;"
69
+ rs = RuleSet.new(nil, css_fragment)
70
+ expected = %w(margin padding margin-bottom)
71
+ actual = []
72
+ # rs.each_declaration { |prop, val, imp| actual << prop }
73
+ rs.each_declaration { |decl| actual << decl.property }
74
+ assert_equal(expected, actual)
75
+ end
76
+
77
+ def test_declarations_to_s
78
+ declarations = 'color: #fff;font-weight: bold;'
79
+ rs = RuleSet.new('#content p, a', declarations)
80
+ puts "declarations: #{rs.declarations_to_s}"
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|
87
+ assert_equal 1000, sel.specificity
88
+ end
89
+ end
90
+ end
@@ -0,0 +1,90 @@
1
+ require 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
+ # ==== Dimensions shorthand
12
+ def test_combining_dimensions_into_shorthand
13
+ properties = {'margin-right' => 'auto', 'margin-bottom' => '0px', 'margin-left' => 'auto', 'margin-top' => '0px',
14
+ 'padding-right' => '1.25em', 'padding-bottom' => '11%', 'padding-left' => '3pc', 'padding-top' => '11.25ex'}
15
+
16
+ combined = create_shorthand(properties)
17
+
18
+ assert_equal('0px auto;', combined['margin'])
19
+ assert_equal('11.25ex 1.25em 11% 3pc;', combined['padding'])
20
+
21
+ # after creating shorthand, all long-hand properties should be deleted
22
+ assert_properties_are_deleted(combined, properties)
23
+
24
+ # should not combine if any properties are missing
25
+ properties.delete('margin-right')
26
+ properties.delete('padding-right')
27
+
28
+ combined = create_shorthand(properties)
29
+
30
+ assert_equal '', combined['margin']
31
+ assert_equal '', combined['padding']
32
+ end
33
+
34
+ # ==== Font shorthand
35
+ def test_combining_font_into_shorthand
36
+ # should combine if all font properties are present
37
+ properties = {"font-weight" => "300", "font-size" => "12pt",
38
+ "font-family" => "sans-serif", "line-height" => "18px",
39
+ "font-style" => "oblique", "font-variant" => "small-caps"}
40
+
41
+ combined = create_shorthand(properties)
42
+ assert_equal('oblique small-caps 300 12pt/18px sans-serif;', combined['font'])
43
+
44
+ # after creating shorthand, all long-hand properties should be deleted
45
+ assert_properties_are_deleted(combined, properties)
46
+
47
+ # should not combine if any properties are missing
48
+ properties.delete('font-weight')
49
+ combined = create_shorthand(properties)
50
+ assert_equal '', combined['font']
51
+ end
52
+
53
+ # ==== Background shorthand
54
+ def test_combining_background_into_shorthand
55
+ properties = {'background-image' => 'url(\'chess.png\')', 'background-color' => 'gray',
56
+ 'background-position' => 'center -10.2%', 'background-attachment' => 'fixed',
57
+ 'background-repeat' => 'no-repeat'}
58
+
59
+ combined = create_shorthand(properties)
60
+
61
+ assert_equal('gray url(\'chess.png\') no-repeat center -10.2% fixed;', combined['background'])
62
+
63
+ # after creating shorthand, all long-hand properties should be deleted
64
+ assert_properties_are_deleted(combined, properties)
65
+ end
66
+
67
+ def test_property_values_in_url
68
+ 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;")
69
+ rs.expand_shorthand!
70
+ assert_equal('top right;', rs['background-position'])
71
+ rs.create_shorthand!
72
+ assert_equal('url(http://example.com/1528/www/top-logo.jpg) no-repeat top right;', rs['background'])
73
+ end
74
+
75
+ protected
76
+ def assert_properties_are_deleted(ruleset, properties)
77
+ properties.each do |property, value|
78
+ assert_equal '', ruleset[property]
79
+ end
80
+ end
81
+
82
+ def create_shorthand(properties)
83
+ ruleset = RuleSet.new(nil, nil)
84
+ properties.each do |property, value|
85
+ ruleset[property] = value
86
+ end
87
+ ruleset.create_shorthand!
88
+ ruleset
89
+ end
90
+ end
@@ -0,0 +1,179 @@
1
+ require File.dirname(__FILE__) + '/test_helper'
2
+
3
+ class RuleSetExpandingShorthandTests < Test::Unit::TestCase
4
+ include CssParser
5
+
6
+ def setup
7
+ @cp = CssParser::Parser.new
8
+ end
9
+
10
+ # ==== Dimensions shorthand
11
+ def test_getting_dimensions_from_shorthand
12
+ # test various shorthand forms
13
+ ['margin: 0px auto', 'margin: 0px auto 0px', 'margin: 0px auto 0px'].each do |shorthand|
14
+ declarations = expand_declarations(shorthand)
15
+ assert_equal({"margin-right" => "auto", "margin-bottom" => "0px", "margin-left" => "auto", "margin-top" => "0px"}, declarations)
16
+ end
17
+
18
+ # test various units
19
+ ['em', 'ex', 'in', 'px', 'pt', 'pc', '%'].each do |unit|
20
+ shorthand = "margin: 0% -0.123#{unit} 9px -.9pc"
21
+ declarations = expand_declarations(shorthand)
22
+ assert_equal({"margin-right" => "-0.123#{unit}", "margin-bottom" => "9px", "margin-left" => "-.9pc", "margin-top" => "0%"}, declarations)
23
+ end
24
+ end
25
+
26
+
27
+ # ==== Font shorthand
28
+ def test_getting_font_size_from_shorthand
29
+ ['em', 'ex', 'in', 'px', 'pt', 'pc', '%'].each do |unit|
30
+ shorthand = "font: 300 italic 11.25#{unit}/14px verdana, helvetica, sans-serif;"
31
+ declarations = expand_declarations(shorthand)
32
+ assert_equal("11.25#{unit}", declarations['font-size'])
33
+ end
34
+
35
+ ['smaller', 'small', 'medium', 'large', 'x-large', 'auto'].each do |unit|
36
+ shorthand = "font: 300 italic #{unit}/14px verdana, helvetica, sans-serif;"
37
+ declarations = expand_declarations(shorthand)
38
+ assert_equal(unit, declarations['font-size'])
39
+ end
40
+ end
41
+
42
+ def test_getting_font_families_from_shorthand
43
+ shorthand = "font: 300 italic 12px/14px \"Helvetica-Neue-Light 45\", 'verdana', helvetica, sans-serif;"
44
+ declarations = expand_declarations(shorthand)
45
+ assert_equal("\"Helvetica-Neue-Light 45\", 'verdana', helvetica, sans-serif", declarations['font-family'])
46
+ end
47
+
48
+ def test_getting_font_weight_from_shorthand
49
+ ['300', 'bold', 'bolder', 'lighter', 'normal'].each do |unit|
50
+ shorthand = "font: #{unit} italic 12px sans-serif;"
51
+ declarations = expand_declarations(shorthand)
52
+ assert_equal(unit, declarations['font-weight'])
53
+ end
54
+
55
+ # ensure normal is the default state
56
+ ['font: normal italic 12px sans-serif;', 'font: italic 12px sans-serif;',
57
+ 'font: small-caps normal 12px sans-serif;', 'font: 12px/16px sans-serif;'].each do |shorthand|
58
+ declarations = expand_declarations(shorthand)
59
+ assert_equal('normal', declarations['font-weight'], shorthand)
60
+ end
61
+ end
62
+
63
+ def test_getting_font_variant_from_shorthand
64
+ shorthand = "font: small-caps italic 12px sans-serif;"
65
+ declarations = expand_declarations(shorthand)
66
+ assert_equal('small-caps', declarations['font-variant'])
67
+
68
+ # ensure normal is the default state
69
+ ['font: normal italic 12px sans-serif;', 'font: italic 12px sans-serif;',
70
+ 'font: normal 12px sans-serif;', 'font: 12px/16px sans-serif;'].each do |shorthand|
71
+ declarations = expand_declarations(shorthand)
72
+ assert_equal('normal', declarations['font-variant'], shorthand)
73
+ end
74
+ end
75
+
76
+ def test_getting_font_style_from_shorthand
77
+ ['italic', 'oblique'].each do |unit|
78
+ shorthand = "font: normal #{unit} bold 12px sans-serif;"
79
+ declarations = expand_declarations(shorthand)
80
+ assert_equal(unit, declarations['font-style'])
81
+ end
82
+
83
+ # ensure normal is the default state
84
+ ['font: normal bold 12px sans-serif;', 'font: small-caps 12px sans-serif;',
85
+ 'font: normal 12px sans-serif;', 'font: 12px/16px sans-serif;'].each do |shorthand|
86
+ declarations = expand_declarations(shorthand)
87
+ assert_equal('normal', declarations['font-style'], shorthand)
88
+ end
89
+ end
90
+
91
+ def test_getting_line_height_from_shorthand
92
+ ['em', 'ex', 'in', 'px', 'pt', 'pc', '%'].each do |unit|
93
+ shorthand = "font: 300 italic 12px/0.25#{unit} verdana, helvetica, sans-serif;"
94
+ declarations = expand_declarations(shorthand)
95
+ assert_equal("0.25#{unit}", declarations['line-height'])
96
+ end
97
+
98
+ # ensure normal is the default state
99
+ ['font: normal bold 12px sans-serif;', 'font: small-caps 12px sans-serif;',
100
+ 'font: normal 12px sans-serif;', 'font: 12px sans-serif;'].each do |shorthand|
101
+ declarations = expand_declarations(shorthand)
102
+ assert_equal('normal', declarations['line-height'], shorthand)
103
+ end
104
+ end
105
+
106
+
107
+ # ==== Background shorthand
108
+ def test_getting_background_properties_from_shorthand
109
+ expected = {"background-image" => "url('chess.png')", "background-color" => "gray", "background-repeat" => "repeat",
110
+ "background-attachment" => "fixed", "background-position" => "50%"}
111
+
112
+ shorthand = "background: url('chess.png') gray 50% repeat fixed;"
113
+ declarations = expand_declarations(shorthand)
114
+ assert_equal expected, declarations
115
+ end
116
+
117
+ def test_getting_background_position_from_shorthand
118
+ ['em', 'ex', 'in', 'px', 'pt', 'pc', '%'].each do |unit|
119
+ shorthand = "background: url('chess.png') gray 30% -0.15#{unit} repeat fixed;"
120
+ declarations = expand_declarations(shorthand)
121
+ assert_equal("30% -0.15#{unit}", declarations['background-position'])
122
+ end
123
+
124
+ ['left', 'center', 'right', 'top', 'bottom', 'inherit'].each do |position|
125
+ shorthand = "background: url('chess.png') #000fff #{position} no-repeat fixed;"
126
+ declarations = expand_declarations(shorthand)
127
+ assert_equal(position, declarations['background-position'])
128
+ end
129
+ end
130
+
131
+ def test_getting_background_colour_from_shorthand
132
+ ['blue', 'lime', 'rgb(10,10,10)', 'rgb ( -10%, 99, 300)', '#ffa0a0', '#03c', 'trAnsparEnt', 'inherit'].each do |colour|
133
+ shorthand = "background:#{colour} url('chess.png') center repeat fixed ;"
134
+ declarations = expand_declarations(shorthand)
135
+ assert_equal(colour, declarations['background-color'])
136
+ end
137
+ end
138
+
139
+ def test_getting_background_attachment_from_shorthand
140
+ ['scroll', 'fixed', 'inherit'].each do |attachment|
141
+ shorthand = "background:#0f0f0f url('chess.png') center repeat #{attachment};"
142
+ declarations = expand_declarations(shorthand)
143
+ assert_equal(attachment, declarations['background-attachment'])
144
+ end
145
+ end
146
+
147
+ def test_getting_background_repeat_from_shorthand
148
+ ['repeat-x', 'repeat-y', 'no-repeat', 'inherit'].each do |repeat|
149
+ shorthand = "background:#0f0f0f none #{repeat};"
150
+ declarations = expand_declarations(shorthand)
151
+ assert_equal(repeat, declarations['background-repeat'])
152
+ end
153
+ end
154
+
155
+ def test_getting_background_image_from_shorthand
156
+ ['url("chess.png")', 'url("https://example.org:80/~files/chess.png?123=abc&test#5")',
157
+ 'url(https://example.org:80/~files/chess.png?123=abc&test#5)',
158
+ "url('https://example.org:80/~files/chess.png?123=abc&test#5')", 'none', 'inherit'].each do |image|
159
+
160
+ shorthand = "background: #0f0f0f #{image} ;"
161
+ declarations = expand_declarations(shorthand)
162
+ assert_equal(image, declarations['background-image'])
163
+ end
164
+ end
165
+
166
+
167
+ protected
168
+ def expand_declarations(declarations)
169
+ ruleset = RuleSet.new(nil, declarations)
170
+ ruleset.expand_shorthand!
171
+
172
+ collected = {}
173
+ # ruleset.each_declaration do |prop, val, imp|
174
+ ruleset.each_declaration do |decl|
175
+ collected[decl.property.to_s] = decl.value.to_s
176
+ end
177
+ collected
178
+ end
179
+ end