sass 3.3.0 → 3.4.25

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.
Files changed (208) hide show
  1. checksums.yaml +4 -4
  2. data/.yardopts +3 -1
  3. data/CODE_OF_CONDUCT.md +10 -0
  4. data/CONTRIBUTING.md +148 -0
  5. data/MIT-LICENSE +1 -1
  6. data/README.md +76 -62
  7. data/Rakefile +104 -24
  8. data/VERSION +1 -1
  9. data/VERSION_DATE +1 -1
  10. data/VERSION_NAME +1 -1
  11. data/bin/sass +1 -1
  12. data/bin/scss +1 -1
  13. data/extra/sass-spec-ref.sh +32 -0
  14. data/extra/update_watch.rb +1 -1
  15. data/lib/sass/cache_stores/filesystem.rb +9 -5
  16. data/lib/sass/cache_stores/memory.rb +4 -5
  17. data/lib/sass/callbacks.rb +2 -2
  18. data/lib/sass/css.rb +12 -13
  19. data/lib/sass/deprecation.rb +55 -0
  20. data/lib/sass/engine.rb +106 -70
  21. data/lib/sass/environment.rb +39 -19
  22. data/lib/sass/error.rb +17 -20
  23. data/lib/sass/exec/base.rb +199 -0
  24. data/lib/sass/exec/sass_convert.rb +283 -0
  25. data/lib/sass/exec/sass_scss.rb +440 -0
  26. data/lib/sass/exec.rb +5 -771
  27. data/lib/sass/features.rb +9 -2
  28. data/lib/sass/importers/base.rb +8 -3
  29. data/lib/sass/importers/filesystem.rb +30 -38
  30. data/lib/sass/logger/base.rb +8 -2
  31. data/lib/sass/logger/delayed.rb +50 -0
  32. data/lib/sass/logger.rb +8 -3
  33. data/lib/sass/media.rb +1 -4
  34. data/lib/sass/plugin/compiler.rb +224 -90
  35. data/lib/sass/plugin/configuration.rb +38 -22
  36. data/lib/sass/plugin/merb.rb +2 -2
  37. data/lib/sass/plugin/rack.rb +3 -3
  38. data/lib/sass/plugin/rails.rb +1 -1
  39. data/lib/sass/plugin/staleness_checker.rb +4 -4
  40. data/lib/sass/plugin.rb +6 -5
  41. data/lib/sass/script/css_lexer.rb +1 -1
  42. data/lib/sass/script/css_parser.rb +2 -3
  43. data/lib/sass/script/css_variable_warning.rb +52 -0
  44. data/lib/sass/script/functions.rb +739 -318
  45. data/lib/sass/script/lexer.rb +134 -54
  46. data/lib/sass/script/parser.rb +252 -56
  47. data/lib/sass/script/tree/funcall.rb +13 -6
  48. data/lib/sass/script/tree/interpolation.rb +127 -4
  49. data/lib/sass/script/tree/list_literal.rb +31 -4
  50. data/lib/sass/script/tree/literal.rb +4 -0
  51. data/lib/sass/script/tree/node.rb +21 -3
  52. data/lib/sass/script/tree/operation.rb +54 -1
  53. data/lib/sass/script/tree/selector.rb +26 -0
  54. data/lib/sass/script/tree/string_interpolation.rb +59 -38
  55. data/lib/sass/script/tree/variable.rb +1 -1
  56. data/lib/sass/script/tree.rb +1 -0
  57. data/lib/sass/script/value/base.rb +17 -14
  58. data/lib/sass/script/value/bool.rb +0 -5
  59. data/lib/sass/script/value/color.rb +78 -42
  60. data/lib/sass/script/value/helpers.rb +119 -2
  61. data/lib/sass/script/value/list.rb +0 -15
  62. data/lib/sass/script/value/map.rb +1 -1
  63. data/lib/sass/script/value/null.rb +0 -5
  64. data/lib/sass/script/value/number.rb +112 -31
  65. data/lib/sass/script/value/string.rb +102 -13
  66. data/lib/sass/script/value.rb +0 -1
  67. data/lib/sass/script.rb +3 -3
  68. data/lib/sass/scss/css_parser.rb +24 -4
  69. data/lib/sass/scss/parser.rb +290 -383
  70. data/lib/sass/scss/rx.rb +17 -9
  71. data/lib/sass/scss/static_parser.rb +306 -4
  72. data/lib/sass/scss.rb +0 -2
  73. data/lib/sass/selector/abstract_sequence.rb +35 -18
  74. data/lib/sass/selector/comma_sequence.rb +114 -19
  75. data/lib/sass/selector/pseudo.rb +266 -0
  76. data/lib/sass/selector/sequence.rb +146 -40
  77. data/lib/sass/selector/simple.rb +22 -33
  78. data/lib/sass/selector/simple_sequence.rb +122 -39
  79. data/lib/sass/selector.rb +57 -197
  80. data/lib/sass/shared.rb +2 -2
  81. data/lib/sass/source/map.rb +31 -14
  82. data/lib/sass/source/position.rb +4 -4
  83. data/lib/sass/stack.rb +2 -8
  84. data/lib/sass/supports.rb +10 -13
  85. data/lib/sass/tree/at_root_node.rb +1 -0
  86. data/lib/sass/tree/charset_node.rb +1 -1
  87. data/lib/sass/tree/comment_node.rb +1 -1
  88. data/lib/sass/tree/css_import_node.rb +9 -1
  89. data/lib/sass/tree/directive_node.rb +8 -2
  90. data/lib/sass/tree/error_node.rb +18 -0
  91. data/lib/sass/tree/extend_node.rb +1 -1
  92. data/lib/sass/tree/function_node.rb +9 -0
  93. data/lib/sass/tree/import_node.rb +6 -5
  94. data/lib/sass/tree/keyframe_rule_node.rb +15 -0
  95. data/lib/sass/tree/node.rb +5 -3
  96. data/lib/sass/tree/prop_node.rb +6 -7
  97. data/lib/sass/tree/rule_node.rb +26 -11
  98. data/lib/sass/tree/visitors/check_nesting.rb +56 -32
  99. data/lib/sass/tree/visitors/convert.rb +59 -44
  100. data/lib/sass/tree/visitors/cssize.rb +34 -30
  101. data/lib/sass/tree/visitors/deep_copy.rb +6 -1
  102. data/lib/sass/tree/visitors/extend.rb +15 -13
  103. data/lib/sass/tree/visitors/perform.rb +87 -50
  104. data/lib/sass/tree/visitors/set_options.rb +15 -1
  105. data/lib/sass/tree/visitors/to_css.rb +72 -43
  106. data/lib/sass/util/multibyte_string_scanner.rb +0 -2
  107. data/lib/sass/util/normalized_map.rb +0 -1
  108. data/lib/sass/util/subset_map.rb +2 -3
  109. data/lib/sass/util.rb +334 -154
  110. data/lib/sass/version.rb +7 -7
  111. data/lib/sass.rb +10 -8
  112. data/test/sass/cache_test.rb +62 -20
  113. data/test/sass/callbacks_test.rb +1 -1
  114. data/test/sass/compiler_test.rb +24 -11
  115. data/test/sass/conversion_test.rb +241 -50
  116. data/test/sass/css2sass_test.rb +73 -5
  117. data/test/sass/css_variable_test.rb +132 -0
  118. data/test/sass/encoding_test.rb +219 -0
  119. data/test/sass/engine_test.rb +343 -260
  120. data/test/sass/exec_test.rb +12 -2
  121. data/test/sass/extend_test.rb +333 -44
  122. data/test/sass/functions_test.rb +353 -260
  123. data/test/sass/importer_test.rb +40 -21
  124. data/test/sass/logger_test.rb +1 -1
  125. data/test/sass/more_results/more_import.css +1 -1
  126. data/test/sass/more_templates/more1.sass +10 -10
  127. data/test/sass/more_templates/more_import.sass +2 -2
  128. data/test/sass/plugin_test.rb +24 -21
  129. data/test/sass/results/compact.css +1 -1
  130. data/test/sass/results/complex.css +4 -4
  131. data/test/sass/results/expanded.css +1 -1
  132. data/test/sass/results/import.css +1 -1
  133. data/test/sass/results/import_charset_ibm866.css +2 -2
  134. data/test/sass/results/mixins.css +17 -17
  135. data/test/sass/results/nested.css +1 -1
  136. data/test/sass/results/parent_ref.css +2 -2
  137. data/test/sass/results/script.css +5 -5
  138. data/test/sass/results/scss_import.css +1 -1
  139. data/test/sass/script_conversion_test.rb +71 -39
  140. data/test/sass/script_test.rb +714 -123
  141. data/test/sass/scss/css_test.rb +213 -30
  142. data/test/sass/scss/rx_test.rb +8 -4
  143. data/test/sass/scss/scss_test.rb +766 -22
  144. data/test/sass/source_map_test.rb +263 -95
  145. data/test/sass/superselector_test.rb +210 -0
  146. data/test/sass/templates/_partial.sass +1 -1
  147. data/test/sass/templates/basic.sass +10 -10
  148. data/test/sass/templates/bork1.sass +1 -1
  149. data/test/sass/templates/bork5.sass +1 -1
  150. data/test/sass/templates/compact.sass +10 -10
  151. data/test/sass/templates/complex.sass +187 -187
  152. data/test/sass/templates/compressed.sass +10 -10
  153. data/test/sass/templates/expanded.sass +10 -10
  154. data/test/sass/templates/import.sass +2 -2
  155. data/test/sass/templates/importee.sass +3 -3
  156. data/test/sass/templates/mixins.sass +22 -22
  157. data/test/sass/templates/multiline.sass +4 -4
  158. data/test/sass/templates/nested.sass +13 -13
  159. data/test/sass/templates/parent_ref.sass +12 -12
  160. data/test/sass/templates/script.sass +70 -70
  161. data/test/sass/templates/scss_import.scss +2 -1
  162. data/test/sass/templates/subdir/nested_subdir/_nested_partial.sass +1 -1
  163. data/test/sass/templates/subdir/nested_subdir/nested_subdir.sass +2 -2
  164. data/test/sass/templates/subdir/subdir.sass +3 -3
  165. data/test/sass/templates/units.sass +10 -10
  166. data/test/sass/test_helper.rb +1 -1
  167. data/test/sass/util/multibyte_string_scanner_test.rb +11 -3
  168. data/test/sass/util/normalized_map_test.rb +1 -1
  169. data/test/sass/util/subset_map_test.rb +2 -2
  170. data/test/sass/util_test.rb +46 -45
  171. data/test/sass/value_helpers_test.rb +5 -7
  172. data/test/sass-spec.yml +3 -0
  173. data/test/test_helper.rb +7 -6
  174. data/vendor/listen/CHANGELOG.md +1 -228
  175. data/vendor/listen/Gemfile +5 -15
  176. data/vendor/listen/README.md +111 -77
  177. data/vendor/listen/Rakefile +0 -42
  178. data/vendor/listen/lib/listen/adapter.rb +195 -82
  179. data/vendor/listen/lib/listen/adapters/bsd.rb +27 -64
  180. data/vendor/listen/lib/listen/adapters/darwin.rb +21 -58
  181. data/vendor/listen/lib/listen/adapters/linux.rb +23 -55
  182. data/vendor/listen/lib/listen/adapters/polling.rb +25 -34
  183. data/vendor/listen/lib/listen/adapters/windows.rb +50 -46
  184. data/vendor/listen/lib/listen/directory_record.rb +96 -61
  185. data/vendor/listen/lib/listen/listener.rb +135 -37
  186. data/vendor/listen/lib/listen/turnstile.rb +9 -5
  187. data/vendor/listen/lib/listen/version.rb +1 -1
  188. data/vendor/listen/lib/listen.rb +33 -19
  189. data/vendor/listen/listen.gemspec +6 -0
  190. data/vendor/listen/spec/listen/adapter_spec.rb +43 -77
  191. data/vendor/listen/spec/listen/adapters/polling_spec.rb +8 -8
  192. data/vendor/listen/spec/listen/directory_record_spec.rb +81 -56
  193. data/vendor/listen/spec/listen/listener_spec.rb +128 -39
  194. data/vendor/listen/spec/listen_spec.rb +15 -21
  195. data/vendor/listen/spec/spec_helper.rb +4 -0
  196. data/vendor/listen/spec/support/adapter_helper.rb +52 -15
  197. data/vendor/listen/spec/support/directory_record_helper.rb +7 -5
  198. data/vendor/listen/spec/support/listeners_helper.rb +30 -7
  199. metadata +310 -300
  200. data/CONTRIBUTING +0 -3
  201. data/ext/mkrf_conf.rb +0 -27
  202. data/lib/sass/script/value/deprecated_false.rb +0 -55
  203. data/lib/sass/scss/script_lexer.rb +0 -15
  204. data/lib/sass/scss/script_parser.rb +0 -25
  205. data/vendor/listen/lib/listen/dependency_manager.rb +0 -126
  206. data/vendor/listen/lib/listen/multi_listener.rb +0 -143
  207. data/vendor/listen/spec/listen/dependency_manager_spec.rb +0 -107
  208. data/vendor/listen/spec/listen/multi_listener_spec.rb +0 -174
@@ -1,9 +1,9 @@
1
1
  #!/usr/bin/env ruby
2
- require 'test/unit'
2
+ require 'minitest/autorun'
3
3
  require File.dirname(__FILE__) + '/../test_helper'
4
4
  require 'sass/css'
5
5
 
6
- class CSS2SassTest < Test::Unit::TestCase
6
+ class CSS2SassTest < MiniTest::Test
7
7
  def test_basic
8
8
  css = <<CSS
9
9
  h1 {
@@ -14,7 +14,7 @@ CSS
14
14
  h1
15
15
  color: red
16
16
  SASS
17
- assert_equal(<<SASS, css2sass(css, :old => true))
17
+ silence_warnings {assert_equal(<<SASS, css2sass(css, :old => true))}
18
18
  h1
19
19
  :color red
20
20
  SASS
@@ -24,10 +24,13 @@ SASS
24
24
  assert_equal(<<SASS, css2sass(<<CSS))
25
25
  li
26
26
  display: none
27
+
27
28
  a
28
29
  text-decoration: none
30
+
29
31
  span
30
32
  color: yellow
33
+
31
34
  &:hover
32
35
  text-decoration: underline
33
36
  SASS
@@ -62,7 +65,7 @@ div .debug
62
65
  SASS
63
66
  div .warning {
64
67
  color: #d21a19; }
65
- span .debug {
68
+ span .debug {
66
69
  cursor: crosshair;}
67
70
  div .debug {
68
71
  cursor: default; }
@@ -117,6 +120,7 @@ span.turkey
117
120
 
118
121
  #overhere
119
122
  bored: sorta
123
+
120
124
  /* it's for a good
121
125
  * cause
122
126
  better_than: thread_pools
@@ -168,12 +172,16 @@ CSS
168
172
  assert_equal(<<SASS, css2sass(<<CSS))
169
173
  hello
170
174
  parent: true
175
+
171
176
  there
172
177
  parent: false
178
+
173
179
  who
174
180
  hoo: false
181
+
175
182
  why
176
183
  y: true
184
+
177
185
  when
178
186
  wen: nao
179
187
 
@@ -229,6 +237,7 @@ CSS
229
237
  assert_equal(<<SASS, css2sass(<<CSS))
230
238
  \\:focus
231
239
  a: b
240
+
232
241
  \\:foo
233
242
  bar: baz
234
243
  SASS
@@ -238,19 +247,22 @@ CSS
238
247
  end
239
248
 
240
249
  def test_subject
241
- assert_equal(<<SASS, css2sass(<<CSS))
250
+ silence_warnings {assert_equal(<<SASS, css2sass(<<CSS))}
242
251
  .foo
243
252
  .bar!
244
253
  .baz
245
254
  a: b
255
+
246
256
  .bip
247
257
  c: d
258
+
248
259
  .bar .bonk
249
260
  e: f
250
261
 
251
262
  .flip!
252
263
  &.bar
253
264
  a: b
265
+
254
266
  &.baz
255
267
  c: d
256
268
  SASS
@@ -263,8 +275,61 @@ SASS
263
275
  CSS
264
276
  end
265
277
 
278
+ def test_keyframes
279
+ assert_equal(<<SASS, css2sass(<<CSS))
280
+ @keyframes dash
281
+ from
282
+ stroke-dasharray: 1,200
283
+ stroke-dashoffset: 0
284
+
285
+ 50%
286
+ stroke-dasharray: 89,200
287
+ stroke-dashoffset: -35
288
+
289
+ to
290
+ stroke-dasharray: 89,200
291
+ stroke-dashoffset: -124
292
+ SASS
293
+ @keyframes dash {
294
+ from {
295
+ stroke-dasharray: 1,200;
296
+ stroke-dashoffset: 0;
297
+ }
298
+ 50% {
299
+ stroke-dasharray: 89,200;
300
+ stroke-dashoffset: -35;
301
+ }
302
+ to {
303
+ stroke-dasharray: 89,200;
304
+ stroke-dashoffset: -124;
305
+ }
306
+ }
307
+ CSS
308
+ end
309
+
266
310
  # Regressions
267
311
 
312
+ def test_nesting_with_matching_property
313
+ assert_equal(<<SASS, css2sass(<<CSS))
314
+ ul
315
+ width: 10px
316
+
317
+ div
318
+ width: 20px
319
+
320
+ article
321
+ width: 10px
322
+
323
+ p
324
+ width: 20px
325
+ SASS
326
+ ul {width: 10px}
327
+ ul div {width: 20px}
328
+ article {width: 10px}
329
+ article p {width: 20px}
330
+ CSS
331
+ end
332
+
268
333
  def test_empty_rule
269
334
  assert_equal(<<SASS, css2sass(<<CSS))
270
335
  a
@@ -277,6 +342,7 @@ CSS
277
342
  assert_equal(<<SASS, css2sass(<<CSS))
278
343
  a
279
344
  color: red
345
+
280
346
  > b
281
347
  SASS
282
348
  a {color: red}
@@ -327,6 +393,7 @@ CSS
327
393
  .foo >
328
394
  .bar
329
395
  a: b
396
+
330
397
  .baz
331
398
  c: d
332
399
  SASS
@@ -338,6 +405,7 @@ CSS
338
405
  .foo
339
406
  &::bar
340
407
  a: b
408
+
341
409
  &::baz
342
410
  c: d
343
411
  SASS
@@ -0,0 +1,132 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require File.dirname(__FILE__) + '/../test_helper'
4
+ require 'sass/engine'
5
+
6
+ class CssVariableTest < MiniTest::Test
7
+ def test_variable_warning_for_operators
8
+ resolve_with_variable_warning("1 == 2")
9
+ resolve_with_variable_warning("1 != 2")
10
+ resolve_with_variable_warning("1 < 2")
11
+ resolve_with_variable_warning("1 <= 2")
12
+ resolve_with_variable_warning("1 > 2")
13
+ resolve_with_variable_warning("1 >= 2")
14
+ resolve_with_variable_warning("1 + 1")
15
+ resolve_with_variable_warning("1 - 1")
16
+ resolve_with_variable_warning("1 * 1")
17
+ resolve_with_variable_warning("1 % 1")
18
+ end
19
+
20
+ def test_variable_warning_for_variable
21
+ render_with_variable_warning(<<SCSS, "$var", 3)
22
+ .foo {
23
+ $var: value;
24
+ --var: $var;
25
+ }
26
+ SCSS
27
+ end
28
+
29
+ def test_variable_warning_for_core_function
30
+ resolve_with_variable_warning("alpha(#abc)")
31
+ end
32
+
33
+ def test_variable_warning_for_sass_function
34
+ render_with_variable_warning(<<SCSS, "my-fn()", 2)
35
+ @function my-fn() {@return null}
36
+ .foo {--var: my-fn()}
37
+ SCSS
38
+ end
39
+
40
+ def test_variable_warning_for_parens
41
+ resolve_with_variable_warning("(foo)", "foo")
42
+ resolve_with_variable_warning("(foo,)")
43
+ end
44
+
45
+ def test_variable_warning_for_selector
46
+ resolve_with_variable_warning("&")
47
+ end
48
+
49
+ def test_variable_warning_for_nested_properties
50
+ assert_warning(<<WARNING) {render(<<SCSS)}
51
+ DEPRECATION WARNING on line 2 of #{filename_for_test :scss}:
52
+ Sass 3.6 will change the way CSS variables are parsed. Instead of being parsed as
53
+ normal properties, they will not allow any Sass-specific behavior other than \#{}.
54
+ WARNING
55
+ .foo {
56
+ --var: {
57
+ a: b;
58
+ }
59
+ }
60
+ SCSS
61
+ end
62
+
63
+ def test_no_warning
64
+ assert_no_variable_warning("foo")
65
+ assert_no_variable_warning("true")
66
+ assert_no_variable_warning("1, 2")
67
+ assert_no_variable_warning("1 2")
68
+ assert_no_variable_warning("1 / 2")
69
+ assert_no_variable_warning("foo / bar")
70
+ assert_no_variable_warning("asdf(foo)")
71
+ assert_no_variable_warning("calc(1 + 1)")
72
+ assert_no_variable_warning("asdf(foo=2)")
73
+ end
74
+
75
+ def test_no_warning_within_interpolation
76
+ assert_no_variable_warning('#{1 + 1}')
77
+ assert_no_variable_warning('#{alpha(#abc)}')
78
+ end
79
+
80
+ private
81
+
82
+ def assert_no_variable_warning(str)
83
+ assert_no_warning {render("a {--var: #{str}}")}
84
+ assert_no_warning {render("a\n --var: #{str}", :syntax => :sass)}
85
+ end
86
+
87
+ def resolve_with_variable_warning(str, expression = nil)
88
+ render_with_variable_warning("a {--var: #{str}}", expression || str, 1)
89
+ render_with_variable_warning(
90
+ "a\n --var: #{str}", expression || str, 2, :syntax => :sass)
91
+ end
92
+
93
+ def render_with_variable_warning(sass, expression, line, opts = {})
94
+ opts[:syntax] ||= :scss
95
+ assert_warning(<<WARNING) {render(sass, opts)}
96
+ DEPRECATION WARNING on line #{line} of #{filename_for_test(opts[:syntax])}:
97
+ Sass 3.6 will change the way CSS variables are parsed. Instead of being parsed as
98
+ normal properties, they will not allow any Sass-specific behavior other than \#{}.
99
+ For forwards-compatibility, use \#{}:
100
+
101
+ --variable: \#{#{expression}};
102
+ WARNING
103
+ end
104
+
105
+ def render(sass, options = {})
106
+ options[:syntax] ||= :scss
107
+ options[:cache] = false
108
+ munge_filename options
109
+ Sass::Engine.new(sass, options).render
110
+ end
111
+
112
+ def resolve(str, opts = {}, environment = env)
113
+ munge_filename opts
114
+ val = eval(str, opts, environment)
115
+ assert_kind_of Sass::Script::Value::Base, val
116
+ val.options = opts
117
+ val.is_a?(Sass::Script::Value::String) ? val.value : val.to_s
118
+ end
119
+
120
+ def eval(str, opts = {}, environment = env)
121
+ munge_filename opts
122
+ Sass::Script.parse(str, opts.delete(:line) || 1,
123
+ opts.delete(:offset) || 0, opts).
124
+ perform(Sass::Environment.new(environment, opts))
125
+ end
126
+
127
+ def env(hash = {})
128
+ env = Sass::Environment.new
129
+ hash.each {|k, v| env.set_var(k, v)}
130
+ env
131
+ end
132
+ end
@@ -0,0 +1,219 @@
1
+ #!/usr/bin/env ruby
2
+ # -*- coding: utf-8 -*-
3
+ require File.dirname(__FILE__) + '/../test_helper'
4
+ require File.dirname(__FILE__) + '/test_helper'
5
+ require 'sass/util/test'
6
+
7
+ class EncodingTest < MiniTest::Test
8
+ include Sass::Util::Test
9
+
10
+ def test_encoding_error
11
+ return skip "Can't be run on Ruby 1.8." if Sass::Util.ruby1_8?
12
+
13
+ render("foo\nbar\nb\xFEaz".force_encoding("utf-8"))
14
+ assert(false, "Expected exception")
15
+ rescue Sass::SyntaxError => e
16
+ assert_equal(3, e.sass_line)
17
+ assert_equal('Invalid UTF-8 character "\xFE"', e.message)
18
+ end
19
+
20
+ def test_ascii_incompatible_encoding_error
21
+ return skip "Can't be run on Ruby 1.8." if Sass::Util.ruby1_8?
22
+
23
+ template = "foo\nbar\nb_z".encode("utf-16le")
24
+ template[9] = "\xFE".force_encoding("utf-16le")
25
+ render(template)
26
+ assert(false, "Expected exception")
27
+ rescue Sass::SyntaxError => e
28
+ assert_equal(3, e.sass_line)
29
+ assert_equal('Invalid UTF-16LE character "\xFE"', e.message)
30
+ end
31
+
32
+ def test_prefers_charset_to_ruby_encoding
33
+ return skip "Can't be run on Ruby 1.8." if Sass::Util.ruby1_8?
34
+
35
+ assert_renders_encoded(<<CSS, <<SASS.encode("IBM866").force_encoding("UTF-8"))
36
+ @charset "UTF-8";
37
+ fЖЖ {
38
+ a: b; }
39
+ CSS
40
+ @charset "ibm866"
41
+ fЖЖ
42
+ a: b
43
+ SASS
44
+ end
45
+
46
+ def test_uses_ruby_encoding_without_charset
47
+ return skip "Can't be run on Ruby 1.8." if Sass::Util.ruby1_8?
48
+
49
+ assert_renders_encoded(<<CSS, <<SASS.encode("IBM866"))
50
+ @charset "UTF-8";
51
+ тАЬ {
52
+ a: b; }
53
+ CSS
54
+ тАЬ
55
+ a: b
56
+ SASS
57
+ end
58
+
59
+ def test_multibyte_charset_without_bom_declared_as_binary
60
+ return skip "Can't be run on Ruby 1.8." if Sass::Util.ruby1_8?
61
+
62
+ engine = Sass::Engine.new(<<SASS.encode("UTF-16LE").force_encoding("BINARY"))
63
+ @charset "utf-16le"
64
+ fóó
65
+ a: b
66
+ SASS
67
+ # Since multibyte encodings' @charset declarations aren't
68
+ # ASCII-compatible, we have to interpret the files as UTF-8 which will
69
+ # inevitably fail.
70
+ assert_raise_message(Sass::SyntaxError, "Invalid UTF-8 character \"\\xF3\"") {engine.render}
71
+ end
72
+
73
+ def test_multibyte_charset_without_bom_declared_as_utf_8
74
+ return skip "Can't be run on Ruby 1.8." if Sass::Util.ruby1_8?
75
+
76
+ engine = Sass::Engine.new(<<SASS.encode("UTF-16LE").force_encoding("UTF-8"))
77
+ @charset "utf-16le"
78
+ fóó
79
+ a: b
80
+ SASS
81
+ # Since multibyte encodings' @charset declarations aren't
82
+ # ASCII-compatible, we have to interpret the files as UTF-8 which will
83
+ # inevitably fail.
84
+ assert_raise_message(Sass::SyntaxError, "Invalid UTF-8 character \"\\xF3\"") {engine.render}
85
+ end
86
+
87
+ def test_utf_16le_with_bom
88
+ return skip "Can't be run on Ruby 1.8." if Sass::Util.ruby1_8?
89
+
90
+ assert_renders_encoded(<<CSS, <<SASS.encode("UTF-16LE").force_encoding("BINARY"))
91
+ @charset "UTF-8";
92
+ fóó {
93
+ a: b; }
94
+ CSS
95
+ \uFEFFfóó
96
+ a: b
97
+ SASS
98
+ end
99
+
100
+ def test_utf_16be_with_bom
101
+ return skip "Can't be run on Ruby 1.8." if Sass::Util.ruby1_8?
102
+
103
+ assert_renders_encoded(<<CSS, <<SASS.encode("UTF-16BE").force_encoding("BINARY"))
104
+ @charset "UTF-8";
105
+ fóó {
106
+ a: b; }
107
+ CSS
108
+ \uFEFFfóó
109
+ a: b
110
+ SASS
111
+ end
112
+
113
+ def test_utf_8_with_bom
114
+ return skip "Can't be run on Ruby 1.8." if Sass::Util.ruby1_8?
115
+
116
+ assert_renders_encoded(<<CSS, <<SASS.force_encoding("BINARY"))
117
+ @charset "UTF-8";
118
+ fóó {
119
+ a: b; }
120
+ CSS
121
+ \uFEFFfóó
122
+ a: b
123
+ SASS
124
+ end
125
+
126
+ def test_charset_with_multibyte_encoding
127
+ return skip "Can't be run on Ruby 1.8." if Sass::Util.ruby1_8?
128
+
129
+ engine = Sass::Engine.new(<<SASS)
130
+ @charset "utf-32be"
131
+ fóó
132
+ a: b
133
+ SASS
134
+ # The charset declaration is just false here, so we should get an
135
+ # encoding error.
136
+ assert_raise_message(Sass::SyntaxError, "Invalid UTF-32BE character \"\\xC3\"") {engine.render}
137
+ end
138
+
139
+ def test_charset_with_special_case_encoding
140
+ return skip "Can't be run on Ruby 1.8." if Sass::Util.ruby1_8?
141
+
142
+ # For some reason, a file with an ASCII-compatible UTF-16 charset
143
+ # declaration is specced to be parsed as UTF-8.
144
+ assert_renders_encoded(<<CSS, <<SASS.force_encoding("BINARY"))
145
+ @charset "UTF-8";
146
+ fóó {
147
+ a: b; }
148
+ CSS
149
+ @charset "utf-16"
150
+ fóó
151
+ a: b
152
+ SASS
153
+ end
154
+
155
+ def test_compressed_output_uses_bom
156
+ return skip "Can't be run on Ruby 1.8." if Sass::Util.ruby1_8?
157
+
158
+ assert_equal("\uFEFFfóó{a:b}\n", render(<<SASS, :style => :compressed))
159
+ fóó
160
+ a: b
161
+ SASS
162
+ end
163
+
164
+ def test_newline_normalization
165
+ assert_equal("/* foo\nbar\nbaz\nbang\nqux */\n",
166
+ render("/* foo\nbar\r\nbaz\fbang\rqux */", :syntax => :scss))
167
+ end
168
+
169
+ def test_null_normalization
170
+ return skip "Can't be run on Ruby 1.8." if Sass::Util.ruby1_8?
171
+
172
+ assert_equal(<<CSS, render("/* foo\x00bar\x00baz */", :syntax => :scss))
173
+ #{"@charset \"UTF-8\";\n" unless Sass::Util.ruby1_8?
174
+ }/* foo�bar�baz */
175
+ CSS
176
+ end
177
+
178
+ # Regression
179
+
180
+ def test_multibyte_prop_name
181
+ return skip "Can't be run on Ruby 1.8." if Sass::Util.ruby1_8?
182
+
183
+ assert_equal(<<CSS, render(<<SASS))
184
+ @charset "UTF-8";
185
+ #bar {
186
+ cölor: blue; }
187
+ CSS
188
+ #bar
189
+ cölor: blue
190
+ SASS
191
+ end
192
+
193
+ def test_multibyte_and_interpolation
194
+ return skip "Can't be run on Ruby 1.8." if Sass::Util.ruby1_8?
195
+
196
+ assert_equal(<<CSS, render(<<SCSS, :syntax => :scss))
197
+ #bar {
198
+ background: a 0%; }
199
+ CSS
200
+ #bar {
201
+ // 
202
+ background: \#{a} 0%;
203
+ }
204
+ SCSS
205
+ end
206
+
207
+ private
208
+
209
+ def assert_renders_encoded(css, sass)
210
+ result = render(sass)
211
+ assert_equal css.encoding, result.encoding
212
+ assert_equal css, result
213
+ end
214
+
215
+ def render(sass, options = {})
216
+ munge_filename options
217
+ Sass::Engine.new(sass, options).render
218
+ end
219
+ end