crass 0.0.1 → 0.0.2

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,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: