crass 0.0.1 → 0.0.2

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,16 @@
1
+ # encoding: utf-8
2
+ require_relative 'support/common'
3
+
4
+ describe 'Crass.parse' do
5
+ it 'should call Crass::Parser.parse_stylesheet with input and options' do
6
+ assert_equal(
7
+ CP.parse_stylesheet(" /**/ .foo {} #bar {}"),
8
+ Crass.parse(" /**/ .foo {} #bar {}")
9
+ )
10
+
11
+ assert_equal(
12
+ CP.parse_stylesheet(" /**/ .foo {} #bar {}", :preserve_comments => true),
13
+ Crass.parse(" /**/ .foo {} #bar {}", :preserve_comments => true)
14
+ )
15
+ end
16
+ end
@@ -0,0 +1,380 @@
1
+ # encoding: utf-8
2
+
3
+ # Includes tests based on Simon Sapin's CSS parsing tests:
4
+ # https://github.com/SimonSapin/css-parsing-tests/
5
+
6
+ require_relative 'support/common'
7
+
8
+ describe 'Crass::Parser' do
9
+ describe '#parse_stylesheet' do
10
+ it 'should parse an empty stylesheet' do
11
+ assert_equal [], CP.parse_stylesheet('')
12
+ assert_equal [], CP.parse_stylesheet('foo')
13
+ assert_equal [], CP.parse_stylesheet('foo 4')
14
+ end
15
+
16
+ describe 'should parse an at-rule' do
17
+ describe 'without a block' do
18
+ it 'without a prelude' do
19
+ tree = CP.parse_stylesheet('@foo')
20
+ rule = tree[0]
21
+
22
+ assert_equal 1, tree.size
23
+ assert_equal :at_rule, rule[:node]
24
+ assert_equal "foo", rule[:name]
25
+ assert_equal [], rule[:prelude]
26
+ assert_tokens "@foo", rule[:tokens]
27
+ end
28
+
29
+ it 'with a prelude followed by a comment' do
30
+ tree = CP.parse_stylesheet("@foo bar; \t/* comment */")
31
+ rule = tree[0]
32
+
33
+ assert_equal 2, tree.size
34
+ assert_equal :at_rule, rule[:node]
35
+ assert_equal "foo", rule[:name]
36
+ assert_tokens " bar", rule[:prelude], 4
37
+ assert_tokens "@foo bar;", rule[:tokens]
38
+ assert_tokens " \t", tree[1], 9
39
+ end
40
+
41
+ it 'with a prelude followed by a comment, when :preserve_comments == true' do
42
+ options = {:preserve_comments => true}
43
+ tree = CP.parse_stylesheet("@foo bar; \t/* comment */", options)
44
+ rule = tree[0]
45
+
46
+ assert_equal 3, tree.size
47
+ assert_equal :at_rule, rule[:node]
48
+ assert_equal "foo", rule[:name]
49
+ assert_tokens " bar", rule[:prelude], 4, options
50
+ assert_tokens "@foo bar;", rule[:tokens], 0, options
51
+ assert_tokens " \t", tree[1], 9, options
52
+ assert_tokens "/* comment */", tree[2], 11, options
53
+ end
54
+
55
+ it 'with a prelude containing a simple block' do
56
+ tree = CP.parse_stylesheet("@foo [ bar")
57
+ rule = tree[0]
58
+
59
+ assert_equal 1, tree.size
60
+ assert_equal :at_rule, rule[:node]
61
+ assert_equal "foo", rule[:name]
62
+ assert_tokens "@foo [ bar", rule[:tokens]
63
+
64
+ prelude = rule[:prelude]
65
+ assert_equal 2, prelude.size
66
+ assert_tokens " ", prelude[0], 4
67
+
68
+ block = prelude[1]
69
+ assert_equal :simple_block, block[:node]
70
+ assert_equal "[", block[:start]
71
+ assert_equal "]", block[:end]
72
+ assert_tokens "[ bar", block[:tokens], 5
73
+ assert_tokens " bar", block[:value], 6
74
+ end
75
+ end
76
+
77
+ describe 'with a block' do
78
+ it 'unclosed' do
79
+ tree = CP.parse_stylesheet("@foo { bar")
80
+ rule = tree[0]
81
+
82
+ assert_equal 1, tree.size
83
+ assert_equal :at_rule, rule[:node]
84
+ assert_equal "foo", rule[:name]
85
+ assert_tokens " ", rule[:prelude], 4
86
+ assert_tokens "@foo { bar", rule[:tokens]
87
+
88
+ block = rule[:block]
89
+ assert_equal :simple_block, block[:node]
90
+ assert_equal "{", block[:start]
91
+ assert_equal "}", block[:end]
92
+ assert_tokens "{ bar", block[:tokens], 5
93
+ assert_tokens " bar", block[:value], 6
94
+ end
95
+
96
+ it 'unclosed, preceded by a comment' do
97
+ tree = CP.parse_stylesheet(" /**/ @foo bar{[(4")
98
+ rule = tree[2]
99
+
100
+ assert_equal 3, tree.size
101
+ assert_tokens " /**/ ", tree[0..1]
102
+ assert_equal :at_rule, rule[:node]
103
+ assert_equal "foo", rule[:name]
104
+ assert_tokens " bar", rule[:prelude], 10
105
+ assert_tokens "@foo bar{[(4", rule[:tokens], 6
106
+
107
+ block = rule[:block]
108
+ assert_equal :simple_block, block[:node]
109
+ assert_equal "{", block[:start]
110
+ assert_equal "}", block[:end]
111
+ assert_tokens "{[(4", block[:tokens], 14
112
+ assert_equal 1, block[:value].size
113
+
114
+ block = block[:value].first
115
+ assert_equal :simple_block, block[:node]
116
+ assert_equal "[", block[:start]
117
+ assert_equal "]", block[:end]
118
+ assert_tokens "[(4", block[:tokens], 15
119
+ assert_equal 1, block[:value].size
120
+
121
+ block = block[:value].first
122
+ assert_equal :simple_block, block[:node]
123
+ assert_equal "(", block[:start]
124
+ assert_equal ")", block[:end]
125
+ assert_tokens "(4", block[:tokens], 16
126
+ assert_tokens "4", block[:value], 17
127
+ end
128
+
129
+ it 'unclosed, preceded by a comment, when :preserve_comments == true' do
130
+ options = {:preserve_comments => true}
131
+ tree = CP.parse_stylesheet(" /**/ @foo bar{[(4", options)
132
+ rule = tree[3]
133
+
134
+ assert_equal 4, tree.size
135
+ assert_tokens " /**/ ", tree[0..2], 0, options
136
+
137
+ assert_equal :at_rule, rule[:node]
138
+ assert_equal "foo", rule[:name]
139
+ assert_tokens " bar", rule[:prelude], 10, options
140
+ assert_tokens "@foo bar{[(4", rule[:tokens], 6, options
141
+
142
+ block = rule[:block]
143
+ assert_equal :simple_block, block[:node]
144
+ assert_equal "{", block[:start]
145
+ assert_equal "}", block[:end]
146
+ assert_tokens "{[(4", block[:tokens], 14, options
147
+ assert_equal 1, block[:value].size
148
+
149
+ block = block[:value].first
150
+ assert_equal :simple_block, block[:node]
151
+ assert_equal "[", block[:start]
152
+ assert_equal "]", block[:end]
153
+ assert_tokens "[(4", block[:tokens], 15, options
154
+ assert_equal 1, block[:value].size
155
+
156
+ block = block[:value].first
157
+ assert_equal :simple_block, block[:node]
158
+ assert_equal "(", block[:start]
159
+ assert_equal ")", block[:end]
160
+ assert_tokens "(4", block[:tokens], 16, options
161
+ assert_tokens "4", block[:value], 17, options
162
+ end
163
+
164
+ end
165
+ end
166
+
167
+ describe 'should parse a style rule' do
168
+ it 'with preceding comment, selector, block, comment' do
169
+ tree = CP.parse_stylesheet(" /**/ div > p { color: #aaa; } /**/ ")
170
+
171
+ assert_equal 5, tree.size
172
+ assert_tokens " /**/ ", tree[0..1]
173
+ assert_tokens " /**/ ", tree[3..4], 31
174
+
175
+ rule = tree[2]
176
+ assert_equal :style_rule, rule[:node]
177
+
178
+ selector = rule[:selector]
179
+ assert_equal :selector, selector[:node]
180
+ assert_equal "div > p", selector[:value]
181
+ assert_tokens "div > p ", selector[:tokens], 6
182
+
183
+ children = rule[:children]
184
+ assert_equal 3, children.size
185
+ assert_tokens " ", children[0], 15
186
+ assert_tokens " ", children[2], 28
187
+
188
+ property = children[1]
189
+ assert_equal :property, property[:node]
190
+ assert_equal "color", property[:name]
191
+ assert_equal "#aaa", property[:value]
192
+ assert_tokens "color: #aaa;", property[:tokens], 16
193
+ end
194
+
195
+ it 'with preceding comment, selector, block, comment, when :preserve_comments == true' do
196
+ options = {:preserve_comments => true}
197
+ tree = CP.parse_stylesheet(" /**/ div > p { color: #aaa; } /**/ ", options)
198
+
199
+ assert_equal 7, tree.size
200
+ assert_tokens " /**/ ", tree[0..2], 0, options
201
+ assert_tokens " /**/ ", tree[4..6], 31, options
202
+
203
+ rule = tree[3]
204
+ assert_equal :style_rule, rule[:node]
205
+
206
+ selector = rule[:selector]
207
+ assert_equal :selector, selector[:node]
208
+ assert_equal "div > p", selector[:value]
209
+ assert_tokens "div > p ", selector[:tokens], 6, options
210
+
211
+ children = rule[:children]
212
+ assert_equal 3, children.size
213
+ assert_tokens " ", children[0], 15, options
214
+ assert_tokens " ", children[2], 28, options
215
+
216
+ property = children[1]
217
+ assert_equal :property, property[:node]
218
+ assert_equal "color", property[:name]
219
+ assert_equal "#aaa", property[:value]
220
+ assert_tokens "color: #aaa;", property[:tokens], 16, options
221
+ end
222
+
223
+ it 'unclosed, with preceding comment, no selector' do
224
+ tree = CP.parse_stylesheet(" /**/ { color: #aaa ")
225
+
226
+ assert_equal 3, tree.size
227
+ assert_tokens " /**/ ", tree[0..1]
228
+
229
+ rule = tree[2]
230
+ assert_equal :style_rule, rule[:node]
231
+
232
+ selector = rule[:selector]
233
+ assert_equal :selector, selector[:node]
234
+ assert_equal "", selector[:value]
235
+ assert_equal [], selector[:tokens]
236
+
237
+ children = rule[:children]
238
+ assert_equal 2, children.size
239
+ assert_tokens " ", children[0], 7
240
+
241
+ property = children[1]
242
+ assert_equal :property, property[:node]
243
+ assert_equal "color", property[:name]
244
+ assert_equal "#aaa", property[:value]
245
+ assert_tokens "color: #aaa ", property[:tokens], 8
246
+ end
247
+
248
+ it 'unclosed, with preceding comment, no selector, when :preserve_comments == true' do
249
+ options = {:preserve_comments => true}
250
+ tree = CP.parse_stylesheet(" /**/ { color: #aaa ", options)
251
+
252
+ assert_equal 4, tree.size
253
+ assert_tokens " /**/ ", tree[0..2], 0, options
254
+
255
+ rule = tree[3]
256
+ assert_equal :style_rule, rule[:node]
257
+
258
+ selector = rule[:selector]
259
+ assert_equal :selector, selector[:node]
260
+ assert_equal "", selector[:value]
261
+ assert_equal [], selector[:tokens]
262
+
263
+ children = rule[:children]
264
+ assert_equal 2, children.size
265
+ assert_tokens " ", children[0], 7, options
266
+
267
+ property = children[1]
268
+ assert_equal :property, property[:node]
269
+ assert_equal "color", property[:name]
270
+ assert_equal "#aaa", property[:value]
271
+ assert_tokens "color: #aaa ", property[:tokens], 8, options
272
+ end
273
+
274
+ it 'with CDO/CDC before rule' do
275
+ tree = CP.parse_stylesheet(" <!-- --> {")
276
+
277
+ assert_equal 4, tree.size
278
+
279
+ tree[0..2].each do |node|
280
+ assert_equal :whitespace, node[:node]
281
+ end
282
+
283
+ rule = tree[3]
284
+ assert_equal :style_rule, rule[:node]
285
+ assert_equal [], rule[:children]
286
+
287
+ selector = rule[:selector]
288
+ assert_equal :selector, selector[:node]
289
+ assert_equal "", selector[:value]
290
+ assert_equal [], selector[:tokens]
291
+ end
292
+
293
+ it 'followed by CDC' do
294
+ tree = CP.parse_stylesheet("div {} -->")
295
+
296
+ assert_equal 2, tree.size
297
+
298
+ rule = tree[0]
299
+ assert_equal :style_rule, rule[:node]
300
+ assert_equal [], rule[:children]
301
+
302
+ selector = rule[:selector]
303
+ assert_equal :selector, selector[:node]
304
+ assert_equal "div", selector[:value]
305
+ assert_tokens "div ", selector[:tokens]
306
+
307
+ assert_tokens " ", tree[1], 6
308
+ end
309
+ end
310
+
311
+ it 'should parse multiple style rules' do
312
+ tree = CP.parse_stylesheet("div { color: #aaa; } p{}")
313
+
314
+ assert_equal 3, tree.size
315
+
316
+ rule = tree[0]
317
+ assert_equal :style_rule, rule[:node]
318
+
319
+ selector = rule[:selector]
320
+ assert_equal :selector, selector[:node]
321
+ assert_equal "div", selector[:value]
322
+ assert_tokens "div ", selector[:tokens]
323
+
324
+ children = rule[:children]
325
+ assert_equal 3, children.size
326
+ assert_tokens " ", children[0], 5
327
+ assert_tokens " ", children[2], 18
328
+
329
+ prop = children[1]
330
+ assert_equal :property, prop[:node]
331
+ assert_equal "color", prop[:name]
332
+ assert_equal "#aaa", prop[:value]
333
+ assert_tokens "color: #aaa;", prop[:tokens], 6
334
+
335
+ assert_tokens " ", tree[1], 20
336
+
337
+ rule = tree[2]
338
+ assert_equal :style_rule, rule[:node]
339
+
340
+ selector = rule[:selector]
341
+ assert_equal :selector, selector[:node]
342
+ assert_equal "p", selector[:value]
343
+ assert_tokens "p", selector[:tokens], 21
344
+ end
345
+
346
+ it 'should ignore a block-less selector following a selector-less style rule' do
347
+ tree = CP.parse_stylesheet("{}a")
348
+ assert_equal 1, tree.size
349
+
350
+ rule = tree[0]
351
+ assert_equal :style_rule, rule[:node]
352
+ assert_equal [], rule[:children]
353
+
354
+ selector = rule[:selector]
355
+ assert_equal :selector, selector[:node]
356
+ assert_equal "", selector[:value]
357
+ assert_equal [], selector[:tokens]
358
+ end
359
+
360
+ it 'should handle an at-rule following a selector-less style rule' do
361
+ tree = CP.parse_stylesheet("{}@a")
362
+ assert_equal 2, tree.size
363
+
364
+ rule = tree[0]
365
+ assert_equal :style_rule, rule[:node]
366
+ assert_equal [], rule[:children]
367
+
368
+ selector = rule[:selector]
369
+ assert_equal :selector, selector[:node]
370
+ assert_equal "", selector[:value]
371
+ assert_equal [], selector[:tokens]
372
+
373
+ rule = tree[1]
374
+ assert_equal :at_rule, rule[:node]
375
+ assert_equal "a", rule[:name]
376
+ assert_equal [], rule[:prelude]
377
+ assert_tokens "@a", rule[:tokens], 2
378
+ end
379
+ end
380
+ end
@@ -0,0 +1,18 @@
1
+ # encoding: utf-8
2
+ require_relative 'support/common'
3
+
4
+ describe 'Serialization' do
5
+ Dir[File.join(File.dirname(__FILE__), 'support/serialization/*.css')].each do |filepath|
6
+ it "should parse and serialize #{filepath}" do
7
+ input = File.read(filepath)
8
+
9
+ tree = Crass.parse(input,
10
+ :preserve_comments => true,
11
+ :preserve_hacks => true)
12
+
13
+ output = CP.stringify(tree)
14
+
15
+ assert_equal input, output
16
+ end
17
+ end
18
+ end
metadata CHANGED
@@ -1,20 +1,18 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: crass
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.1
5
- prerelease:
4
+ version: 0.0.2
6
5
  platform: ruby
7
6
  authors:
8
7
  - Ryan Grove
9
8
  autorequire:
10
9
  bindir: bin
11
10
  cert_chain: []
12
- date: 2013-09-28 00:00:00.000000000 Z
11
+ date: 2013-09-30 00:00:00.000000000 Z
13
12
  dependencies:
14
13
  - !ruby/object:Gem::Dependency
15
14
  name: minitest
16
15
  requirement: !ruby/object:Gem::Requirement
17
- none: false
18
16
  requirements:
19
17
  - - ~>
20
18
  - !ruby/object:Gem::Version
@@ -22,7 +20,6 @@ dependencies:
22
20
  type: :development
23
21
  prerelease: false
24
22
  version_requirements: !ruby/object:Gem::Requirement
25
- none: false
26
23
  requirements:
27
24
  - - ~>
28
25
  - !ruby/object:Gem::Version
@@ -30,7 +27,6 @@ dependencies:
30
27
  - !ruby/object:Gem::Dependency
31
28
  name: rake
32
29
  requirement: !ruby/object:Gem::Requirement
33
- none: false
34
30
  requirements:
35
31
  - - ~>
36
32
  - !ruby/object:Gem::Version
@@ -38,49 +34,70 @@ dependencies:
38
34
  type: :development
39
35
  prerelease: false
40
36
  version_requirements: !ruby/object:Gem::Requirement
41
- none: false
42
37
  requirements:
43
38
  - - ~>
44
39
  - !ruby/object:Gem::Version
45
40
  version: 10.1.0
46
- description:
47
- email: ryan@wonko.com
41
+ description: Crass is a pure Ruby CSS parser based on the CSS Syntax Module Level
42
+ 3 draft.
43
+ email:
44
+ - ryan@wonko.com
48
45
  executables: []
49
46
  extensions: []
50
47
  extra_rdoc_files: []
51
48
  files:
49
+ - .gitignore
50
+ - .travis.yml
51
+ - .yardopts
52
+ - Gemfile
52
53
  - HISTORY.md
53
54
  - LICENSE
54
55
  - README.md
56
+ - Rakefile
57
+ - crass.gemspec
58
+ - lib/crass.rb
55
59
  - lib/crass/parser.rb
56
60
  - lib/crass/scanner.rb
57
61
  - lib/crass/token-scanner.rb
58
62
  - lib/crass/tokenizer.rb
59
63
  - lib/crass/version.rb
60
- - lib/crass.rb
64
+ - test/support/common.rb
65
+ - test/support/serialization/bootstrap-theme.css
66
+ - test/support/serialization/bootstrap.css
67
+ - test/support/serialization/pure.css
68
+ - test/test_crass.rb
69
+ - test/test_parse_stylesheet.rb
70
+ - test/test_serialization.rb
61
71
  homepage: https://github.com/rgrove/crass/
62
- licenses: []
72
+ licenses:
73
+ - MIT
74
+ metadata: {}
63
75
  post_install_message:
64
76
  rdoc_options: []
65
77
  require_paths:
66
78
  - lib
67
79
  required_ruby_version: !ruby/object:Gem::Requirement
68
- none: false
69
80
  requirements:
70
81
  - - ! '>='
71
82
  - !ruby/object:Gem::Version
72
83
  version: 1.9.2
73
84
  required_rubygems_version: !ruby/object:Gem::Requirement
74
- none: false
75
85
  requirements:
76
86
  - - ! '>='
77
87
  - !ruby/object:Gem::Version
78
88
  version: '0'
79
89
  requirements: []
80
90
  rubyforge_project:
81
- rubygems_version: 1.8.23
91
+ rubygems_version: 2.1.3
82
92
  signing_key:
83
- specification_version: 3
93
+ specification_version: 4
84
94
  summary: CSS parser based on the CSS Syntax Module Level 3 draft.
85
- test_files: []
95
+ test_files:
96
+ - test/support/common.rb
97
+ - test/support/serialization/bootstrap-theme.css
98
+ - test/support/serialization/bootstrap.css
99
+ - test/support/serialization/pure.css
100
+ - test/test_crass.rb
101
+ - test/test_parse_stylesheet.rb
102
+ - test/test_serialization.rb
86
103
  has_rdoc: