marcosinger-css_parser 1.3.0
Sign up to get free protection for your applications and to get access to all the features.
- data/lib/css_parser.rb +162 -0
- data/lib/css_parser/parser.rb +454 -0
- data/lib/css_parser/regexps.rb +75 -0
- data/lib/css_parser/rule_set.rb +451 -0
- data/test/fixtures/import-circular-reference.css +4 -0
- data/test/fixtures/import-with-media-types.css +3 -0
- data/test/fixtures/import1.css +3 -0
- data/test/fixtures/simple.css +6 -0
- data/test/fixtures/subdir/import2.css +3 -0
- data/test/test_css_parser_basic.rb +72 -0
- data/test/test_css_parser_loading.rb +139 -0
- data/test/test_css_parser_media_types.rb +106 -0
- data/test/test_css_parser_misc.rb +164 -0
- data/test/test_css_parser_regexps.rb +69 -0
- data/test/test_helper.rb +6 -0
- data/test/test_merging.rb +103 -0
- data/test/test_rule_set.rb +90 -0
- data/test/test_rule_set_creating_shorthand.rb +119 -0
- data/test/test_rule_set_expanding_shorthand.rb +198 -0
- metadata +101 -0
@@ -0,0 +1,72 @@
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + '/test_helper')
|
2
|
+
|
3
|
+
# Test cases for reading and generating CSS shorthand properties
|
4
|
+
class CssParserBasicTests < Test::Unit::TestCase
|
5
|
+
include CssParser
|
6
|
+
|
7
|
+
def setup
|
8
|
+
@cp = CssParser::Parser.new
|
9
|
+
@css = <<-EOT
|
10
|
+
html, body, p { margin: 0px; }
|
11
|
+
p { padding: 0px; }
|
12
|
+
#content { font: 12px/normal sans-serif; }
|
13
|
+
.content { color: red; }
|
14
|
+
EOT
|
15
|
+
end
|
16
|
+
|
17
|
+
def test_finding_by_selector
|
18
|
+
@cp.add_block!(@css)
|
19
|
+
assert_equal 'margin: 0px;', @cp.find_by_selector('body').join(' ')
|
20
|
+
assert_equal 'margin: 0px; padding: 0px;', @cp.find_by_selector('p').join(' ')
|
21
|
+
assert_equal 'font: 12px/normal sans-serif;', @cp.find_by_selector('#content').join(' ')
|
22
|
+
assert_equal 'color: red;', @cp.find_by_selector('.content').join(' ')
|
23
|
+
|
24
|
+
assert_equal 'margin: 0px;', @cp.find_by_selector(/body/).join(' ')
|
25
|
+
assert_equal 'margin: 0px; padding: 0px;', @cp.find_by_selector(/p/).join(' ')
|
26
|
+
assert_equal 'font: 12px/normal sans-serif;', @cp.find_by_selector(/#content/).join(' ')
|
27
|
+
assert_equal 'color: red;', @cp.find_by_selector(/\.content/).join(' ')
|
28
|
+
|
29
|
+
hash = {"#content" => {"font" => "12px/normal sans-serif;"}, ".content" => {"color" => "red;"}}
|
30
|
+
assert_equal hash, @cp.find_by_selector(/content/)
|
31
|
+
end
|
32
|
+
|
33
|
+
def test_adding_block
|
34
|
+
@cp.add_block!(@css)
|
35
|
+
assert_equal 'margin: 0px;', @cp.find_by_selector('body').join
|
36
|
+
end
|
37
|
+
|
38
|
+
def test_adding_block_without_closing_brace
|
39
|
+
@cp.add_block!('p { color: red;')
|
40
|
+
assert_equal 'color: red;', @cp.find_by_selector('p').join
|
41
|
+
end
|
42
|
+
|
43
|
+
def test_adding_a_rule
|
44
|
+
@cp.add_rule!('div', 'color: blue;')
|
45
|
+
assert_equal 'color: blue;', @cp.find_by_selector('div').join(' ')
|
46
|
+
end
|
47
|
+
|
48
|
+
def test_adding_a_rule_set
|
49
|
+
rs = CssParser::RuleSet.new('div', 'color: blue;')
|
50
|
+
@cp.add_rule_set!(rs)
|
51
|
+
assert_equal 'color: blue;', @cp.find_by_selector('div').join(' ')
|
52
|
+
end
|
53
|
+
|
54
|
+
def test_toggling_uri_conversion
|
55
|
+
# with conversion
|
56
|
+
cp_with_conversion = Parser.new(:absolute_paths => true)
|
57
|
+
cp_with_conversion.add_block!("body { background: url('../style/yellow.png?abc=123') };",
|
58
|
+
:base_uri => 'http://example.org/style/basic.css')
|
59
|
+
|
60
|
+
assert_equal "background: url('http://example.org/style/yellow.png?abc=123');",
|
61
|
+
cp_with_conversion['body'].join(' ')
|
62
|
+
|
63
|
+
# without conversion
|
64
|
+
cp_without_conversion = Parser.new(:absolute_paths => false)
|
65
|
+
cp_without_conversion.add_block!("body { background: url('../style/yellow.png?abc=123') };",
|
66
|
+
:base_uri => 'http://example.org/style/basic.css')
|
67
|
+
|
68
|
+
assert_equal "background: url('../style/yellow.png?abc=123');",
|
69
|
+
cp_without_conversion['body'].join(' ')
|
70
|
+
end
|
71
|
+
|
72
|
+
end
|
@@ -0,0 +1,139 @@
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + '/test_helper')
|
2
|
+
|
3
|
+
# Test cases for the CssParser's loading functions.
|
4
|
+
class CssParserLoadingTests < Test::Unit::TestCase
|
5
|
+
include CssParser
|
6
|
+
include WEBrick
|
7
|
+
|
8
|
+
def setup
|
9
|
+
# from http://nullref.se/blog/2006/5/17/testing-with-webrick
|
10
|
+
@cp = Parser.new
|
11
|
+
|
12
|
+
@uri_base = 'http://localhost:12000'
|
13
|
+
|
14
|
+
@www_root = File.dirname(__FILE__) + '/fixtures/'
|
15
|
+
|
16
|
+
@server_thread = Thread.new do
|
17
|
+
s = WEBrick::HTTPServer.new(:Port => 12000, :DocumentRoot => @www_root, :Logger => Log.new(nil, BasicLog::FATAL), :AccessLog => [])
|
18
|
+
@port = s.config[:Port]
|
19
|
+
begin
|
20
|
+
s.start
|
21
|
+
ensure
|
22
|
+
s.shutdown
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
sleep 1 # ensure the server has time to load
|
27
|
+
end
|
28
|
+
|
29
|
+
def teardown
|
30
|
+
@server_thread.kill
|
31
|
+
@server_thread.join(5)
|
32
|
+
@server_thread = nil
|
33
|
+
end
|
34
|
+
|
35
|
+
def test_loading_a_local_file
|
36
|
+
file_name = File.dirname(__FILE__) + '/fixtures/simple.css'
|
37
|
+
@cp.load_file!(file_name)
|
38
|
+
assert_equal 'margin: 0px;', @cp.find_by_selector('p').join(' ')
|
39
|
+
end
|
40
|
+
|
41
|
+
def test_loading_a_local_file_with_scheme
|
42
|
+
file_name = 'file://' + File.expand_path(File.dirname(__FILE__)) + '/fixtures/simple.css'
|
43
|
+
@cp.load_uri!(file_name)
|
44
|
+
assert_equal 'margin: 0px;', @cp.find_by_selector('p').join(' ')
|
45
|
+
end
|
46
|
+
|
47
|
+
def test_loading_a_remote_file
|
48
|
+
@cp.load_uri!("#{@uri_base}/simple.css")
|
49
|
+
assert_equal 'margin: 0px;', @cp.find_by_selector('p').join(' ')
|
50
|
+
end
|
51
|
+
|
52
|
+
# http://github.com/alexdunae/css_parser/issues#issue/4
|
53
|
+
def test_loading_a_remote_file_over_ssl
|
54
|
+
# TODO: test SSL locally
|
55
|
+
@cp.load_uri!("https://www.expresspardons.com/inc/screen.css")
|
56
|
+
assert_match /margin\: 0\;/, @cp.find_by_selector('body').join(' ')
|
57
|
+
end
|
58
|
+
|
59
|
+
|
60
|
+
def test_following_at_import_rules_local
|
61
|
+
base_dir = File.dirname(__FILE__) + '/fixtures'
|
62
|
+
@cp.load_file!('import1.css', base_dir)
|
63
|
+
|
64
|
+
# from '/import1.css'
|
65
|
+
assert_equal 'color: lime;', @cp.find_by_selector('div').join(' ')
|
66
|
+
|
67
|
+
# from '/subdir/import2.css'
|
68
|
+
assert_equal 'text-decoration: none;', @cp.find_by_selector('a').join(' ')
|
69
|
+
|
70
|
+
# from '/subdir/../simple.css'
|
71
|
+
assert_equal 'margin: 0px;', @cp.find_by_selector('p').join(' ')
|
72
|
+
end
|
73
|
+
|
74
|
+
def test_following_at_import_rules_remote
|
75
|
+
@cp.load_uri!("#{@uri_base}/import1.css")
|
76
|
+
|
77
|
+
# from '/import1.css'
|
78
|
+
assert_equal 'color: lime;', @cp.find_by_selector('div').join(' ')
|
79
|
+
|
80
|
+
# from '/subdir/import2.css'
|
81
|
+
assert_equal 'text-decoration: none;', @cp.find_by_selector('a').join(' ')
|
82
|
+
|
83
|
+
# from '/subdir/../simple.css'
|
84
|
+
assert_equal 'margin: 0px;', @cp.find_by_selector('p').join(' ')
|
85
|
+
end
|
86
|
+
|
87
|
+
def test_following_at_import_rules_from_add_block
|
88
|
+
css_block = '@import "../simple.css";'
|
89
|
+
|
90
|
+
@cp.add_block!(css_block, :base_uri => "#{@uri_base}/subdir/")
|
91
|
+
|
92
|
+
# from 'simple.css'
|
93
|
+
assert_equal 'margin: 0px;', @cp.find_by_selector('p').join(' ')
|
94
|
+
end
|
95
|
+
|
96
|
+
def test_importing_with_media_types
|
97
|
+
@cp.load_uri!("#{@uri_base}/import-with-media-types.css")
|
98
|
+
|
99
|
+
# from simple.css with :screen media type
|
100
|
+
assert_equal 'margin: 0px;', @cp.find_by_selector('p', :screen).join(' ')
|
101
|
+
assert_equal '', @cp.find_by_selector('p', :tty).join(' ')
|
102
|
+
end
|
103
|
+
|
104
|
+
def test_throwing_circular_reference_exception
|
105
|
+
assert_raise CircularReferenceError do
|
106
|
+
@cp.load_uri!("#{@uri_base}/import-circular-reference.css")
|
107
|
+
end
|
108
|
+
|
109
|
+
cp_without_exceptions = Parser.new(:io_exceptions => false)
|
110
|
+
|
111
|
+
assert_nothing_raised CircularReferenceError do
|
112
|
+
cp_without_exceptions.load_uri!("#{@uri_base}/import-circular-reference.css")
|
113
|
+
end
|
114
|
+
|
115
|
+
end
|
116
|
+
|
117
|
+
def test_toggling_circular_reference_exception
|
118
|
+
cp_without_exceptions = Parser.new(:io_exceptions => false)
|
119
|
+
|
120
|
+
assert_nothing_raised CircularReferenceError do
|
121
|
+
cp_without_exceptions.load_uri!("#{@uri_base}/import-circular-reference.css")
|
122
|
+
end
|
123
|
+
end
|
124
|
+
|
125
|
+
def test_toggling_not_found_exceptions
|
126
|
+
cp_with_exceptions = Parser.new(:io_exceptions => true)
|
127
|
+
|
128
|
+
assert_raise RemoteFileError do
|
129
|
+
cp_with_exceptions.load_uri!("#{@uri_base}/no-exist.xyz")
|
130
|
+
end
|
131
|
+
|
132
|
+
cp_without_exceptions = Parser.new(:io_exceptions => false)
|
133
|
+
|
134
|
+
assert_nothing_raised RemoteFileError do
|
135
|
+
cp_without_exceptions.load_uri!("#{@uri_base}/no-exist.xyz")
|
136
|
+
end
|
137
|
+
end
|
138
|
+
|
139
|
+
end
|
@@ -0,0 +1,106 @@
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + '/test_helper')
|
2
|
+
|
3
|
+
# Test cases for the handling of media types
|
4
|
+
class CssParserMediaTypesTests < Test::Unit::TestCase
|
5
|
+
include CssParser
|
6
|
+
|
7
|
+
def setup
|
8
|
+
@cp = Parser.new
|
9
|
+
end
|
10
|
+
|
11
|
+
def test_finding_by_media_type
|
12
|
+
# from http://www.w3.org/TR/CSS21/media.html#at-media-rule
|
13
|
+
css = <<-EOT
|
14
|
+
@media print {
|
15
|
+
body { font-size: 10pt }
|
16
|
+
}
|
17
|
+
@media screen {
|
18
|
+
body { font-size: 13px }
|
19
|
+
}
|
20
|
+
@media screen, print {
|
21
|
+
body { line-height: 1.2 }
|
22
|
+
}
|
23
|
+
EOT
|
24
|
+
|
25
|
+
@cp.add_block!(css)
|
26
|
+
|
27
|
+
assert_equal 'font-size: 10pt; line-height: 1.2;', @cp.find_by_selector('body', :print).join(' ')
|
28
|
+
assert_equal 'font-size: 13px; line-height: 1.2;', @cp.find_by_selector('body', :screen).join(' ')
|
29
|
+
end
|
30
|
+
|
31
|
+
def test_finding_by_multiple_media_types
|
32
|
+
css = <<-EOT
|
33
|
+
@media print {
|
34
|
+
body { font-size: 10pt }
|
35
|
+
}
|
36
|
+
@media handheld {
|
37
|
+
body { font-size: 13px }
|
38
|
+
}
|
39
|
+
@media screen, print {
|
40
|
+
body { line-height: 1.2 }
|
41
|
+
}
|
42
|
+
EOT
|
43
|
+
@cp.add_block!(css)
|
44
|
+
|
45
|
+
assert_equal 'font-size: 13px; line-height: 1.2;', @cp.find_by_selector('body', [:screen,:handheld]).join(' ')
|
46
|
+
end
|
47
|
+
|
48
|
+
def test_adding_block_with_media_types
|
49
|
+
css = <<-EOT
|
50
|
+
body { font-size: 10pt }
|
51
|
+
EOT
|
52
|
+
|
53
|
+
@cp.add_block!(css, :media_types => [:screen])
|
54
|
+
|
55
|
+
assert_equal 'font-size: 10pt;', @cp.find_by_selector('body', :screen).join(' ')
|
56
|
+
assert @cp.find_by_selector('body', :handheld).empty?
|
57
|
+
end
|
58
|
+
|
59
|
+
def test_adding_block_and_limiting_media_types1
|
60
|
+
css = <<-EOT
|
61
|
+
@import "import1.css", print
|
62
|
+
EOT
|
63
|
+
|
64
|
+
base_dir = File.dirname(__FILE__) + '/fixtures/'
|
65
|
+
|
66
|
+
@cp.add_block!(css, :only_media_types => :screen, :base_dir => base_dir)
|
67
|
+
assert @cp.find_by_selector('div').empty?
|
68
|
+
|
69
|
+
end
|
70
|
+
|
71
|
+
def test_adding_block_and_limiting_media_types2
|
72
|
+
css = <<-EOT
|
73
|
+
@import "import1.css", print
|
74
|
+
EOT
|
75
|
+
|
76
|
+
base_dir = File.dirname(__FILE__) + '/fixtures/'
|
77
|
+
|
78
|
+
@cp.add_block!(css, :only_media_types => :print, :base_dir => base_dir)
|
79
|
+
assert_match 'color: lime', @cp.find_by_selector('div').join(' ')
|
80
|
+
end
|
81
|
+
|
82
|
+
def test_adding_block_and_limiting_media_types
|
83
|
+
css = <<-EOT
|
84
|
+
@import "import1.css"
|
85
|
+
EOT
|
86
|
+
|
87
|
+
base_dir = File.dirname(__FILE__) + '/fixtures/'
|
88
|
+
|
89
|
+
@cp.add_block!(css, :only_media_types => :print, :base_dir => base_dir)
|
90
|
+
assert_match 'color: lime', @cp.find_by_selector('div').join(' ')
|
91
|
+
end
|
92
|
+
|
93
|
+
|
94
|
+
def test_adding_rule_set_with_media_type
|
95
|
+
@cp.add_rule!('body', 'color: black;', [:handheld,:tty])
|
96
|
+
@cp.add_rule!('body', 'color: blue;', :screen)
|
97
|
+
assert_equal 'color: black;', @cp.find_by_selector('body', :handheld).join(' ')
|
98
|
+
end
|
99
|
+
|
100
|
+
def test_selecting_with_all_media_types
|
101
|
+
@cp.add_rule!('body', 'color: black;', [:handheld,:tty])
|
102
|
+
assert_equal 'color: black;', @cp.find_by_selector('body', :all).join(' ')
|
103
|
+
end
|
104
|
+
|
105
|
+
|
106
|
+
end
|
@@ -0,0 +1,164 @@
|
|
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
|