csspool 0.2.6 → 2.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (138) hide show
  1. data/.autotest +16 -0
  2. data/{CHANGELOG.txt → CHANGELOG.rdoc} +10 -0
  3. data/Manifest.txt +60 -72
  4. data/README.rdoc +78 -0
  5. data/Rakefile +9 -52
  6. data/lib/csspool/collection.rb +50 -0
  7. data/lib/csspool/css/charset.rb +7 -0
  8. data/lib/csspool/css/declaration.rb +8 -0
  9. data/lib/csspool/css/document.rb +34 -0
  10. data/lib/csspool/css/document_handler.rb +51 -0
  11. data/lib/csspool/css/import_rule.rb +15 -0
  12. data/lib/csspool/css/media.rb +7 -0
  13. data/lib/csspool/css/rule_set.rb +12 -0
  14. data/lib/csspool/css.rb +7 -0
  15. data/lib/csspool/lib_croco/cr_additional_sel.rb +46 -0
  16. data/lib/csspool/lib_croco/cr_attr_sel.rb +16 -0
  17. data/lib/csspool/lib_croco/cr_doc_handler.rb +24 -0
  18. data/lib/csspool/lib_croco/cr_num.rb +13 -0
  19. data/lib/csspool/lib_croco/cr_parser.rb +11 -0
  20. data/lib/csspool/lib_croco/cr_parsing_location.rb +17 -0
  21. data/lib/csspool/lib_croco/cr_pseudo.rb +14 -0
  22. data/lib/csspool/lib_croco/cr_rgb.rb +18 -0
  23. data/lib/csspool/lib_croco/cr_selector.rb +34 -0
  24. data/lib/csspool/lib_croco/cr_simple_sel.rb +54 -0
  25. data/lib/csspool/lib_croco/cr_term.rb +97 -0
  26. data/lib/csspool/lib_croco/glist.rb +21 -0
  27. data/lib/csspool/lib_croco.rb +78 -0
  28. data/lib/csspool/node.rb +5 -0
  29. data/lib/csspool/sac/document.rb +35 -0
  30. data/lib/csspool/sac/parser.rb +122 -0
  31. data/lib/csspool/sac.rb +2 -0
  32. data/lib/csspool/selector.rb +32 -0
  33. data/lib/csspool/selectors/additional.rb +6 -0
  34. data/lib/csspool/selectors/attribute.rb +21 -0
  35. data/lib/csspool/selectors/class.rb +11 -0
  36. data/lib/csspool/selectors/id.rb +11 -0
  37. data/lib/csspool/selectors/pseudo_class.rb +13 -0
  38. data/lib/csspool/selectors/simple.rb +22 -0
  39. data/lib/csspool/selectors/type.rb +6 -0
  40. data/lib/csspool/selectors/universal.rb +6 -0
  41. data/lib/csspool/selectors.rb +8 -0
  42. data/lib/csspool/terms/function.rb +17 -0
  43. data/lib/csspool/terms/hash.rb +6 -0
  44. data/lib/csspool/terms/ident.rb +15 -0
  45. data/lib/csspool/terms/number.rb +14 -0
  46. data/lib/csspool/terms/rgb.rb +23 -0
  47. data/lib/csspool/terms/string.rb +6 -0
  48. data/lib/csspool/terms/uri.rb +6 -0
  49. data/lib/csspool/terms.rb +7 -0
  50. data/lib/csspool/visitable.rb +18 -0
  51. data/lib/csspool/visitors/comparable.rb +78 -0
  52. data/lib/csspool/visitors/to_css.rb +201 -0
  53. data/lib/csspool/visitors/visitor.rb +17 -0
  54. data/lib/csspool/visitors.rb +3 -0
  55. data/lib/csspool.rb +18 -1
  56. data/test/css/test_document.rb +13 -0
  57. data/test/css/test_import_rule.rb +42 -0
  58. data/test/helper.rb +62 -6
  59. data/test/sac/test_parser.rb +115 -0
  60. data/test/sac/test_properties.rb +43 -0
  61. data/test/sac/test_terms.rb +134 -0
  62. data/test/test_collection.rb +81 -0
  63. data/test/test_parser.rb +75 -241
  64. data/test/test_selector.rb +45 -34
  65. data/test/visitors/test_comparable.rb +72 -0
  66. data/test/visitors/test_to_css.rb +141 -0
  67. metadata +98 -85
  68. data/README.txt +0 -79
  69. data/lib/css/sac/conditions/attribute_condition.rb +0 -56
  70. data/lib/css/sac/conditions/begin_hyphen_condition.rb +0 -22
  71. data/lib/css/sac/conditions/class_condition.rb +0 -22
  72. data/lib/css/sac/conditions/combinator_condition.rb +0 -40
  73. data/lib/css/sac/conditions/condition.rb +0 -35
  74. data/lib/css/sac/conditions/id_condition.rb +0 -27
  75. data/lib/css/sac/conditions/one_of_condition.rb +0 -22
  76. data/lib/css/sac/conditions/pseudo_class_condition.rb +0 -24
  77. data/lib/css/sac/conditions.rb +0 -5
  78. data/lib/css/sac/document_handler.rb +0 -67
  79. data/lib/css/sac/error_handler.rb +0 -14
  80. data/lib/css/sac/generated_parser.rb +0 -999
  81. data/lib/css/sac/generated_property_parser.rb +0 -9214
  82. data/lib/css/sac/lexeme.rb +0 -29
  83. data/lib/css/sac/lexical_unit.rb +0 -203
  84. data/lib/css/sac/parse_exception.rb +0 -6
  85. data/lib/css/sac/parser.rb +0 -115
  86. data/lib/css/sac/property_parser.rb +0 -47
  87. data/lib/css/sac/selectors/child_selector.rb +0 -40
  88. data/lib/css/sac/selectors/conditional_selector.rb +0 -49
  89. data/lib/css/sac/selectors/descendant_selector.rb +0 -40
  90. data/lib/css/sac/selectors/element_selector.rb +0 -39
  91. data/lib/css/sac/selectors/selector.rb +0 -31
  92. data/lib/css/sac/selectors/sibling_selector.rb +0 -39
  93. data/lib/css/sac/selectors/simple_selector.rb +0 -25
  94. data/lib/css/sac/selectors.rb +0 -5
  95. data/lib/css/sac/token.rb +0 -27
  96. data/lib/css/sac/tokenizer.rb +0 -187
  97. data/lib/css/sac/visitable.rb +0 -106
  98. data/lib/css/sac.rb +0 -14
  99. data/lib/css/stylesheet/rule.rb +0 -20
  100. data/lib/css/stylesheet/stylesheet.rb +0 -96
  101. data/lib/css/stylesheet.rb +0 -3
  102. data/lib/parser.y +0 -308
  103. data/lib/property_parser.y +0 -2346
  104. data/lib/property_parser.y.erb +0 -1321
  105. data/test/condition_test_case.rb +0 -6
  106. data/test/selector_test_case.rb +0 -20
  107. data/test/test_all.rb +0 -4
  108. data/test/test_attribute_condition.rb +0 -39
  109. data/test/test_begin_hyphen_condition.rb +0 -15
  110. data/test/test_child_selector.rb +0 -60
  111. data/test/test_class_condition.rb +0 -15
  112. data/test/test_combinator_condition.rb +0 -38
  113. data/test/test_condition.rb +0 -31
  114. data/test/test_conditional_selector.rb +0 -44
  115. data/test/test_descendant_selector.rb +0 -64
  116. data/test/test_element_selector.rb +0 -31
  117. data/test/test_error_recovery.rb +0 -28
  118. data/test/test_id_condition.rb +0 -16
  119. data/test/test_lexeme.rb +0 -39
  120. data/test/test_lexical_color.rb +0 -49
  121. data/test/test_lexical_function.rb +0 -31
  122. data/test/test_lexical_ident.rb +0 -30
  123. data/test/test_lexical_number.rb +0 -68
  124. data/test/test_lexical_string.rb +0 -23
  125. data/test/test_lexical_unit.rb +0 -106
  126. data/test/test_lexical_uri.rb +0 -28
  127. data/test/test_one_of_condition.rb +0 -15
  128. data/test/test_parse_error.rb +0 -199
  129. data/test/test_property_parser.rb +0 -593
  130. data/test/test_selector_as_string.rb +0 -94
  131. data/test/test_selector_parser.rb +0 -178
  132. data/test/test_sibling_selector.rb +0 -42
  133. data/test/test_simple_selector.rb +0 -9
  134. data/test/test_specificity.rb +0 -76
  135. data/test/test_stylesheet.rb +0 -95
  136. data/test/test_token.rb +0 -24
  137. data/test/test_tokenizer.rb +0 -127
  138. data/test/test_xpath.rb +0 -105
@@ -0,0 +1,23 @@
1
+ module CSSPool
2
+ module Terms
3
+ class Rgb < CSSPool::Node
4
+ attr_accessor :red
5
+ attr_accessor :green
6
+ attr_accessor :blue
7
+ attr_accessor :percentage
8
+ attr_accessor :parse_location
9
+ attr_accessor :operator
10
+ alias :percentage? :percentage
11
+
12
+ def initialize red, green, blue, percentage, operator, parse_location
13
+ super()
14
+ @red = red
15
+ @green = green
16
+ @blue = blue
17
+ @percentage = percentage
18
+ @operator = operator
19
+ @parse_location = parse_location
20
+ end
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,6 @@
1
+ module CSSPool
2
+ module Terms
3
+ class String < Ident
4
+ end
5
+ end
6
+ end
@@ -0,0 +1,6 @@
1
+ module CSSPool
2
+ module Terms
3
+ class URI < Ident
4
+ end
5
+ end
6
+ end
@@ -0,0 +1,7 @@
1
+ require 'csspool/terms/ident'
2
+ require 'csspool/terms/string'
3
+ require 'csspool/terms/number'
4
+ require 'csspool/terms/function'
5
+ require 'csspool/terms/uri'
6
+ require 'csspool/terms/rgb'
7
+ require 'csspool/terms/hash'
@@ -0,0 +1,18 @@
1
+ module CSSPool
2
+ module Visitable
3
+ def accept target
4
+ target.accept self
5
+ end
6
+
7
+ def to_css
8
+ accept Visitors::ToCSS.new
9
+ end
10
+ alias :to_s :to_css
11
+
12
+ def == other
13
+ return false unless self.class == other.class
14
+
15
+ accept Visitors::Comparable.new other
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,78 @@
1
+ module CSSPool
2
+ module Visitors
3
+ class Comparable < Visitor
4
+ def initialize other
5
+ super()
6
+ @other = other
7
+ end
8
+
9
+ visitor_for CSS::Document do |target|
10
+ [
11
+ :parent,
12
+ :charsets,
13
+ :parent_import_rule,
14
+ :import_rules,
15
+ :rule_sets,
16
+ ].all? { |m| target.send(m) == @other.send(m) }
17
+ end
18
+
19
+ visitor_for CSS::RuleSet do |target|
20
+ [:selectors, :declarations, :media].all? { |m|
21
+ target.send(m) == @other.send(m)
22
+ }
23
+ end
24
+
25
+ visitor_for Selector do |target|
26
+ target.simple_selectors == @other.simple_selectors
27
+ end
28
+
29
+ visitor_for CSS::ImportRule do |target|
30
+ [:uri, :namespace, :media].all? { |m|
31
+ target.send(m) == @other.send(m)
32
+ }
33
+ end
34
+
35
+ visitor_for CSS::Media do |target|
36
+ target.name == @other.name
37
+ end
38
+
39
+ visitor_for Selectors::Type do |target|
40
+ [:name, :combinator, :additional_selectors].all? { |m|
41
+ target.send(m) == @other.send(m)
42
+ }
43
+ end
44
+
45
+ visitor_for CSS::Declaration do |target|
46
+ [:property, :expressions, :important].all? { |m|
47
+ target.send(m) == @other.send(m)
48
+ }
49
+ end
50
+
51
+ visitor_for Terms::Function do |target|
52
+ [:name, :params, :operator].all? { |m|
53
+ target.send(m) == @other.send(m)
54
+ }
55
+ end
56
+
57
+ visitor_for Terms::Number do |target|
58
+ [:type, :unary_operator, :value, :operator].all? { |m|
59
+ target.send(m) == @other.send(m)
60
+ }
61
+ end
62
+
63
+ visitor_for Terms::URI,Terms::String,Terms::Ident,Terms::Hash do |target|
64
+ [:value, :operator].all? { |m| target.send(m) == @other.send(m) }
65
+ end
66
+
67
+ visitor_for Terms::Rgb do |target|
68
+ [
69
+ :red,
70
+ :green,
71
+ :blue,
72
+ :percentage,
73
+ :operator
74
+ ].all? { |m| target.send(m) == @other.send(m) }
75
+ end
76
+ end
77
+ end
78
+ end
@@ -0,0 +1,201 @@
1
+ module CSSPool
2
+ module Visitors
3
+ class ToCSS < Visitor
4
+ def initialize
5
+ @indent_level = 0
6
+ @indent_space = ' '
7
+ end
8
+
9
+ visitor_for CSS::Document do |target|
10
+ media_hash = {}
11
+
12
+ # Default media list is []
13
+ current_media_type = []
14
+
15
+ tokens = []
16
+
17
+ target.charsets.each do |char_set|
18
+ tokens << char_set.accept(self)
19
+ end
20
+
21
+ target.import_rules.each do |ir|
22
+ tokens << ir.accept(self)
23
+ end
24
+
25
+ target.rule_sets.each { |rs|
26
+ if rs.media != current_media_type
27
+ tokens << "#{indent}@media #{rs.media.map { |x| x.name }.join(", ")} {"
28
+ @indent_level += 1
29
+ end
30
+
31
+ tokens << rs.accept(self)
32
+
33
+ if rs.media != current_media_type
34
+ current_media_type = rs.media
35
+ @indent_level -= 1
36
+ tokens << "#{indent}}"
37
+ end
38
+ }
39
+ tokens.join("\n")
40
+ end
41
+
42
+ visitor_for CSS::Charset do |target|
43
+ "@charset \"#{target.name}\";"
44
+ end
45
+
46
+ visitor_for CSS::ImportRule do |target|
47
+ media = ''
48
+ media = " " + target.media.map { |x|
49
+ x.name
50
+ }.join(', ') if target.media.length > 0
51
+
52
+ "#{indent}@import url(\"#{target.uri}\")#{media};"
53
+ end
54
+
55
+ visitor_for CSS::RuleSet do |target|
56
+ "#{indent}" +
57
+ target.selectors.map { |sel| sel.accept self }.join(", ") + " {\n" +
58
+ target.declarations.map { |decl| decl.accept self }.join("\n") +
59
+ "\n#{indent}}"
60
+ end
61
+
62
+ visitor_for CSS::Declaration do |target|
63
+ important = target.important? ? ' !important' : ''
64
+
65
+ indent {
66
+ "#{indent}#{target.property}: " + target.expressions.map { |exp|
67
+
68
+ op = '/' == exp.operator ? ' /' : exp.operator
69
+
70
+ [
71
+ op,
72
+ exp.accept(self),
73
+ ].join ' '
74
+ }.join.strip + "#{important};"
75
+ }
76
+ end
77
+
78
+ visitor_for Terms::Ident do |target|
79
+ target.value
80
+ end
81
+
82
+ visitor_for Terms::Hash do |target|
83
+ "##{target.value}"
84
+ end
85
+
86
+ visitor_for Selectors::Simple, Selectors::Universal do |target|
87
+ ([target.name] + target.additional_selectors.map { |x|
88
+ x.accept self
89
+ }).join
90
+ end
91
+
92
+ visitor_for Terms::URI do |target|
93
+ "url(#{target.value})"
94
+ end
95
+
96
+ visitor_for Terms::Function do |target|
97
+ "#{target.name}(" +
98
+ target.params.map { |x|
99
+ [
100
+ x.operator,
101
+ x.accept(self)
102
+ ].compact.join(' ')
103
+ }.join + ')'
104
+ end
105
+
106
+ visitor_for Terms::Rgb do |target|
107
+ params = [
108
+ target.red,
109
+ target.green,
110
+ target.blue
111
+ ].map { |c| target.percentage? ? "#{c}%" : c }.join(',')
112
+
113
+ %{rgb(#{params})}
114
+ end
115
+
116
+ visitor_for Terms::String do |target|
117
+ "\"#{target.value}\""
118
+ end
119
+
120
+ visitor_for Selector do |target|
121
+ target.simple_selectors.map { |ss| ss.accept self }.join
122
+ end
123
+
124
+ visitor_for Selectors::Type do |target|
125
+ combo = {
126
+ 0 => nil,
127
+ 1 => ' ',
128
+ 2 => ' + ',
129
+ 3 => ' > '
130
+ }[target.combinator]
131
+
132
+ [combo, target.name].compact.join +
133
+ target.additional_selectors.map { |as| as.accept self }.join
134
+ end
135
+
136
+ visitor_for Terms::Number do |target|
137
+ units = {
138
+ 2 => 'em',
139
+ 3 => 'ex',
140
+ 4 => 'px',
141
+ 5 => 'in',
142
+ 6 => 'cm',
143
+ 7 => 'mm',
144
+ 8 => 'pt',
145
+ 9 => 'pc',
146
+ 10 => 'deg',
147
+ 11 => 'rad',
148
+ 12 => 'grad',
149
+ 13 => 'ms',
150
+ 14 => 's',
151
+ 15 => 'Hz',
152
+ 16 => 'kHz',
153
+ 17 => '%',
154
+ }[target.type]
155
+ [
156
+ target.unary_operator == :minus ? '-' : nil,
157
+ target.value,
158
+ units
159
+ ].compact.join
160
+ end
161
+
162
+ visitor_for Selectors::Id do |target|
163
+ "##{target.name}"
164
+ end
165
+
166
+ visitor_for Selectors::Class do |target|
167
+ ".#{target.name}"
168
+ end
169
+
170
+ visitor_for Selectors::PseudoClass do |target|
171
+ ":#{target.name}"
172
+ end
173
+
174
+ visitor_for Selectors::Attribute do |target|
175
+ case target.match_way
176
+ when Selectors::Attribute::SET
177
+ "[#{target.name}]"
178
+ when Selectors::Attribute::EQUALS
179
+ "[#{target.name}=\"#{target.value}\"]"
180
+ when Selectors::Attribute::INCLUDES
181
+ "[#{target.name} ~= \"#{target.value}\"]"
182
+ when Selectors::Attribute::DASHMATCH
183
+ "[#{target.name} |= \"#{target.value}\"]"
184
+ else
185
+ raise "no matching matchway"
186
+ end
187
+ end
188
+
189
+ private
190
+ def indent
191
+ if block_given?
192
+ @indent_level += 1
193
+ result = yield
194
+ @indent_level -= 1
195
+ return result
196
+ end
197
+ "#{@indent_space * @indent_level}"
198
+ end
199
+ end
200
+ end
201
+ end
@@ -0,0 +1,17 @@
1
+ module CSSPool
2
+ module Visitors
3
+ class Visitor
4
+ def self.visitor_for *klasses, &block
5
+ klasses.each do |klass|
6
+ method_name = klass.name.split('::').join('_')
7
+ define_method(:"visit_#{method_name}", block)
8
+ end
9
+ end
10
+
11
+ def accept target
12
+ method_name = target.class.name.split('::').join('_')
13
+ send(:"visit_#{method_name}", target)
14
+ end
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,3 @@
1
+ require 'csspool/visitors/visitor'
2
+ require 'csspool/visitors/to_css'
3
+ require 'csspool/visitors/comparable'
data/lib/csspool.rb CHANGED
@@ -1 +1,18 @@
1
- require 'css/sac'
1
+ require 'csspool/visitable'
2
+ require 'csspool/node'
3
+ require 'csspool/selectors'
4
+ require 'csspool/terms'
5
+ require 'csspool/selector'
6
+ require 'csspool/sac'
7
+ require 'csspool/lib_croco'
8
+ require 'csspool/css'
9
+ require 'csspool/visitors'
10
+ require 'csspool/collection'
11
+
12
+ module CSSPool
13
+ VERSION = "2.0.0"
14
+
15
+ def self.CSS doc
16
+ CSSPool::CSS::Document.parse doc
17
+ end
18
+ end
@@ -0,0 +1,13 @@
1
+ require 'helper'
2
+
3
+ module CSSPool
4
+ module CSS
5
+ class TestDocument < CSSPool::TestCase
6
+ def test_search
7
+ doc = CSSPool.CSS('div > p { background: red; }')
8
+ assert_equal 1, doc['div > p'].length
9
+ assert_equal 1, doc['div > p'].first.declarations.length
10
+ end
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,42 @@
1
+ require 'helper'
2
+
3
+ module CSSPool
4
+ module CSS
5
+ class TestImportRule < CSSPool::TestCase
6
+ def test_import
7
+ doc = CSSPool.CSS <<-eocss
8
+ @import "foo.css";
9
+ eocss
10
+
11
+ assert_equal 1, doc.import_rules.length
12
+
13
+ doc.import_rules.each do |ir|
14
+ new_doc = ir.load do |url|
15
+ assert_equal "foo.css", url
16
+ "div { background: red; }"
17
+ end
18
+ assert new_doc
19
+ assert_equal 1, new_doc.rule_sets.length
20
+ assert_equal ir, new_doc.parent_import_rule
21
+ assert_equal doc, new_doc.parent
22
+ end
23
+ end
24
+
25
+ def test_import_with_media
26
+ doc = CSSPool.CSS <<-eocss
27
+ @import "foo.css" screen, print;
28
+ eocss
29
+
30
+ assert_equal 1, doc.import_rules.length
31
+ doc.import_rules.each do |ir|
32
+ new_doc = ir.load do |url|
33
+ "div { background: red; }"
34
+ end
35
+ new_doc.rule_sets.each do |rs|
36
+ assert_equal ir.media, rs.media
37
+ end
38
+ end
39
+ end
40
+ end
41
+ end
42
+ end
data/test/helper.rb CHANGED
@@ -1,9 +1,65 @@
1
1
  require "test/unit"
2
+ require "csspool"
2
3
 
3
- require "rubygems"
4
- require "flexmock"
5
- require "flexmock/test_unit"
4
+ module CSSPool
5
+ class TestCase < Test::Unit::TestCase
6
+ unless RUBY_VERSION >= '1.9'
7
+ undef :default_test
8
+ end
6
9
 
7
- require "css/sac"
8
- require "test/selector_test_case"
9
- require "test/condition_test_case"
10
+ ASSET_DIR = File.join(File.dirname(__FILE__), 'files')
11
+
12
+ class MyDoc < CSSPool::SAC::Document
13
+ attr_accessor :start_documents, :end_documents
14
+ attr_accessor :charsets, :import_styles, :comments, :start_selectors
15
+ attr_accessor :end_selectors, :properties
16
+
17
+ def initialize
18
+ @start_documents = []
19
+ @end_documents = []
20
+ @charsets = []
21
+ @import_styles = []
22
+ @comments = []
23
+ @start_selectors = []
24
+ @end_selectors = []
25
+ @properties = []
26
+ end
27
+
28
+ def property name, expression, important
29
+ @properties << [name, expression]
30
+ end
31
+
32
+ def start_document
33
+ @start_documents << true
34
+ end
35
+
36
+ def end_document
37
+ @end_documents << true
38
+ end
39
+
40
+ def charset name, location
41
+ @charsets << [name, location]
42
+ end
43
+
44
+ def import_style media_list, uri, default_ns, location
45
+ @import_styles << [media_list, uri, default_ns, location]
46
+ end
47
+
48
+ def namespace_declaration prefix, uri, location
49
+ @import_styles << [prefix, uri, location]
50
+ end
51
+
52
+ def comment string
53
+ @comments << string
54
+ end
55
+
56
+ def start_selector selectors
57
+ @start_selectors << selectors
58
+ end
59
+
60
+ def end_selector selectors
61
+ @end_selectors << selectors
62
+ end
63
+ end
64
+ end
65
+ end
@@ -0,0 +1,115 @@
1
+ require 'helper'
2
+
3
+ module CSSPool
4
+ module SAC
5
+ class TestParser < CSSPool::TestCase
6
+ def setup
7
+ super
8
+ @doc = MyDoc.new
9
+ @css = <<-eocss
10
+ @charset "UTF-8";
11
+ @import url("foo.css") screen;
12
+ /* This is a comment */
13
+ div a.foo, #bar, * { background: red; }
14
+ div#a, a.foo, a:hover, a[href][int="10"]{ background: red; }
15
+ eocss
16
+ @parser = CSSPool::SAC::Parser.new(@doc)
17
+ @parser.parse(@css)
18
+ end
19
+
20
+ def test_start_and_end_called_with_the_same
21
+ assert_equal @doc.start_selectors, @doc.end_selectors
22
+ end
23
+
24
+ def test_parse_no_doc
25
+ parser = CSSPool::SAC::Parser.new
26
+ parser.parse(@css)
27
+ end
28
+
29
+ def test_start_document
30
+ assert_equal [true], @doc.start_documents
31
+ end
32
+
33
+ def test_end_document
34
+ assert_equal [true], @doc.end_documents
35
+ end
36
+
37
+ def test_charset
38
+ assert_equal(
39
+ [["UTF-8", { :line => 1, :byte_offset => 10, :column => 11}]],
40
+ @doc.charsets)
41
+ end
42
+
43
+ def test_import_style
44
+ styles = @doc.import_styles.first
45
+ assert_equal ["screen"], styles.first
46
+ assert_equal "foo.css", styles[1]
47
+ assert_nil styles[2]
48
+ end
49
+
50
+ def test_start_selector
51
+ selectors_for_rule = @doc.start_selectors.first
52
+ assert selectors_for_rule
53
+ assert_equal 3, selectors_for_rule.length
54
+ end
55
+
56
+ def test_simple_selector
57
+ selectors_for_rule = @doc.start_selectors.first
58
+ selector = selectors_for_rule.first # => div a.foo
59
+ assert_equal 2, selector.simple_selectors.length
60
+ selector.simple_selectors.each do |ss|
61
+ assert ss.parse_location
62
+ end
63
+ end
64
+
65
+ def test_additional_selector_list
66
+ selectors_for_rule = @doc.start_selectors.first
67
+ selector = selectors_for_rule.first # => div a.foo
68
+ simple_selector = selector.simple_selectors[1] # => a.foo
69
+ assert additional_selectors = simple_selector.additional_selectors
70
+ assert_equal 1, additional_selectors.length
71
+ end
72
+
73
+ def test_additional_selector_class_name
74
+ selectors_for_rule = @doc.start_selectors.first
75
+ selector = selectors_for_rule.first # => div a.foo
76
+ simple_selector = selector.simple_selectors[1] # => a.foo
77
+ assert additional_selectors = simple_selector.additional_selectors
78
+ foo_class = additional_selectors.first
79
+ assert_equal 'foo', foo_class.name
80
+ end
81
+
82
+ # div#a, a.foo, a:hover, a[href='watever'] { background: red; }
83
+ def test_id_additional_selector
84
+ selectors_for_rule = @doc.start_selectors[1]
85
+ selector = selectors_for_rule.first # => div#a
86
+ simple_selector = selector.simple_selectors.first # => div#a
87
+ assert_equal 'a', simple_selector.additional_selectors.first.name
88
+ end
89
+
90
+ # div#a, a.foo, a:hover, a[href][int="10"]{ background: red; }
91
+ def test_pseudo_additional_selector
92
+ selectors_for_rule = @doc.start_selectors[1]
93
+ selector = selectors_for_rule[2] # => 'a:hover'
94
+ simple_selector = selector.simple_selectors.first # => a:hover
95
+ assert_equal 'hover', simple_selector.additional_selectors.first.name
96
+ assert_nil simple_selector.additional_selectors.first.extra
97
+ end
98
+
99
+ # div#a, a.foo, a:hover, a[href][int="10"]{ background: red; }
100
+ def test_attribute_selector
101
+ selectors_for_rule = @doc.start_selectors[1]
102
+ selector = selectors_for_rule[3] # => a[href][int="10"]
103
+ simple_selector = selector.simple_selectors.first
104
+
105
+ assert_equal 'href', simple_selector.additional_selectors.first.name
106
+ assert_nil simple_selector.additional_selectors.first.value
107
+ assert_equal 1, simple_selector.additional_selectors.first.match_way
108
+
109
+ assert_equal 'int', simple_selector.additional_selectors[1].name
110
+ assert_equal '10', simple_selector.additional_selectors[1].value
111
+ assert_equal 2, simple_selector.additional_selectors[1].match_way
112
+ end
113
+ end
114
+ end
115
+ end
@@ -0,0 +1,43 @@
1
+ require 'helper'
2
+
3
+ module CSSPool
4
+ module SAC
5
+ class TestProperties < CSSPool::TestCase
6
+ def setup
7
+ super
8
+ @doc = MyDoc.new
9
+ @css = <<-eocss
10
+ @charset "UTF-8";
11
+ @import url("foo.css") screen;
12
+ /* This is a comment */
13
+ div a.foo, #bar, * { background: red; }
14
+ div#a, a.foo, a:hover, a[href][int="10"]{ background: red; }
15
+ eocss
16
+ @parser = CSSPool::SAC::Parser.new(@doc)
17
+ @parser.parse(@css)
18
+ end
19
+
20
+ def test_properties
21
+ assert_equal ['background'], @doc.properties.map { |x| x.first }.uniq
22
+ @doc.properties.each do |property|
23
+ assert_equal 1, property[1].length
24
+ end
25
+ assert_equal ['red'], @doc.properties.map { |x| x[1].first.value }.uniq
26
+ end
27
+
28
+ def test_ident_with_comma
29
+ doc = MyDoc.new
30
+ parser = CSSPool::SAC::Parser.new(doc)
31
+ parser.parse <<-eocss
32
+ h1 { font-family: Verdana, sans-serif, monospace; }
33
+ eocss
34
+ assert_equal 1, doc.properties.length
35
+ values = doc.properties.first[1]
36
+ assert_equal 3, values.length
37
+ assert_equal [nil, ',', ','],
38
+ values.map { |value| value.operator }
39
+ values.each { |value| assert value.parse_location }
40
+ end
41
+ end
42
+ end
43
+ end