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.
- data/.gitignore +4 -0
- data/CHANGELOG +34 -0
- data/LICENSE +21 -0
- data/README +0 -0
- data/README.rdoc +77 -0
- data/Rakefile.rb +18 -0
- data/VERSION +1 -0
- data/lib/css_parser_master.rb +156 -0
- data/lib/css_parser_master/declaration.rb +31 -0
- data/lib/css_parser_master/declaration_api.rb +91 -0
- data/lib/css_parser_master/declarations.rb +23 -0
- data/lib/css_parser_master/parser.rb +388 -0
- data/lib/css_parser_master/regexps.rb +46 -0
- data/lib/css_parser_master/rule_set.rb +337 -0
- data/lib/css_parser_master/selector.rb +33 -0
- data/lib/css_parser_master/selectors.rb +27 -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 +84 -0
- data/test/test_css_parser_loading.rb +110 -0
- data/test/test_css_parser_media_types.rb +71 -0
- data/test/test_css_parser_misc.rb +151 -0
- data/test/test_css_parser_regexps.rb +69 -0
- data/test/test_helper.rb +6 -0
- data/test/test_merging.rb +88 -0
- data/test/test_rule_set.rb +90 -0
- data/test/test_rule_set_creating_shorthand.rb +90 -0
- data/test/test_rule_set_expanding_shorthand.rb +179 -0
- data/test/test_ruleset_expand.rb +40 -0
- data/test/test_selector.rb +26 -0
- data/test/test_selector_parsing.rb +27 -0
- metadata +112 -0
@@ -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
|
data/test/test_helper.rb
ADDED
@@ -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
|