sass 3.3.0 → 3.4.0
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.
- checksums.yaml +4 -4
- data/MIT-LICENSE +1 -1
- data/README.md +58 -50
- data/Rakefile +1 -4
- data/VERSION +1 -1
- data/VERSION_DATE +1 -1
- data/VERSION_NAME +1 -1
- data/bin/sass +1 -1
- data/bin/scss +1 -1
- data/lib/sass/cache_stores/filesystem.rb +6 -2
- data/lib/sass/css.rb +1 -3
- data/lib/sass/engine.rb +37 -46
- data/lib/sass/environment.rb +13 -17
- data/lib/sass/error.rb +6 -9
- data/lib/sass/exec/base.rb +187 -0
- data/lib/sass/exec/sass_convert.rb +264 -0
- data/lib/sass/exec/sass_scss.rb +424 -0
- data/lib/sass/exec.rb +5 -771
- data/lib/sass/features.rb +7 -0
- data/lib/sass/importers/base.rb +7 -2
- data/lib/sass/importers/filesystem.rb +9 -25
- data/lib/sass/importers.rb +0 -1
- data/lib/sass/media.rb +1 -4
- data/lib/sass/plugin/compiler.rb +200 -83
- data/lib/sass/plugin/staleness_checker.rb +1 -1
- data/lib/sass/plugin.rb +3 -3
- data/lib/sass/script/css_lexer.rb +1 -1
- data/lib/sass/script/functions.rb +622 -268
- data/lib/sass/script/lexer.rb +99 -34
- data/lib/sass/script/parser.rb +24 -23
- data/lib/sass/script/tree/funcall.rb +1 -1
- data/lib/sass/script/tree/interpolation.rb +20 -2
- data/lib/sass/script/tree/selector.rb +26 -0
- data/lib/sass/script/tree/string_interpolation.rb +1 -1
- data/lib/sass/script/tree.rb +1 -0
- data/lib/sass/script/value/base.rb +7 -5
- data/lib/sass/script/value/bool.rb +0 -5
- data/lib/sass/script/value/color.rb +39 -21
- data/lib/sass/script/value/helpers.rb +107 -0
- data/lib/sass/script/value/list.rb +0 -15
- data/lib/sass/script/value/null.rb +0 -5
- data/lib/sass/script/value/number.rb +62 -14
- data/lib/sass/script/value/string.rb +59 -11
- data/lib/sass/script/value.rb +0 -1
- data/lib/sass/scss/css_parser.rb +8 -2
- data/lib/sass/scss/parser.rb +190 -328
- data/lib/sass/scss/rx.rb +15 -6
- data/lib/sass/scss/static_parser.rb +298 -1
- data/lib/sass/selector/abstract_sequence.rb +28 -13
- data/lib/sass/selector/comma_sequence.rb +92 -13
- data/lib/sass/selector/pseudo.rb +256 -0
- data/lib/sass/selector/sequence.rb +94 -24
- data/lib/sass/selector/simple.rb +14 -25
- data/lib/sass/selector/simple_sequence.rb +97 -33
- data/lib/sass/selector.rb +57 -194
- data/lib/sass/shared.rb +1 -1
- data/lib/sass/source/map.rb +26 -12
- data/lib/sass/stack.rb +0 -6
- data/lib/sass/supports.rb +2 -3
- data/lib/sass/tree/at_root_node.rb +1 -0
- data/lib/sass/tree/charset_node.rb +1 -1
- data/lib/sass/tree/directive_node.rb +8 -2
- data/lib/sass/tree/error_node.rb +18 -0
- data/lib/sass/tree/extend_node.rb +1 -1
- data/lib/sass/tree/function_node.rb +4 -0
- data/lib/sass/tree/keyframe_rule_node.rb +15 -0
- data/lib/sass/tree/prop_node.rb +1 -1
- data/lib/sass/tree/rule_node.rb +12 -7
- data/lib/sass/tree/visitors/check_nesting.rb +38 -10
- data/lib/sass/tree/visitors/convert.rb +16 -18
- data/lib/sass/tree/visitors/cssize.rb +29 -29
- data/lib/sass/tree/visitors/deep_copy.rb +5 -0
- data/lib/sass/tree/visitors/perform.rb +45 -33
- data/lib/sass/tree/visitors/set_options.rb +14 -0
- data/lib/sass/tree/visitors/to_css.rb +15 -14
- data/lib/sass/util/subset_map.rb +1 -1
- data/lib/sass/util.rb +222 -99
- data/lib/sass/version.rb +5 -5
- data/lib/sass.rb +0 -5
- data/test/sass/cache_test.rb +62 -20
- data/test/sass/callbacks_test.rb +1 -1
- data/test/sass/compiler_test.rb +19 -10
- data/test/sass/conversion_test.rb +58 -1
- data/test/sass/css2sass_test.rb +23 -4
- data/test/sass/encoding_test.rb +219 -0
- data/test/sass/engine_test.rb +136 -199
- data/test/sass/exec_test.rb +2 -2
- data/test/sass/extend_test.rb +236 -19
- data/test/sass/functions_test.rb +295 -253
- data/test/sass/importer_test.rb +31 -21
- data/test/sass/logger_test.rb +1 -1
- data/test/sass/more_results/more_import.css +1 -1
- data/test/sass/plugin_test.rb +14 -13
- data/test/sass/results/compact.css +1 -1
- data/test/sass/results/complex.css +4 -4
- data/test/sass/results/expanded.css +1 -1
- data/test/sass/results/import.css +1 -1
- data/test/sass/results/import_charset_ibm866.css +2 -2
- data/test/sass/results/mixins.css +17 -17
- data/test/sass/results/nested.css +1 -1
- data/test/sass/results/parent_ref.css +2 -2
- data/test/sass/results/script.css +3 -3
- data/test/sass/results/scss_import.css +1 -1
- data/test/sass/script_conversion_test.rb +10 -7
- data/test/sass/script_test.rb +288 -74
- data/test/sass/scss/css_test.rb +141 -24
- data/test/sass/scss/rx_test.rb +4 -4
- data/test/sass/scss/scss_test.rb +457 -18
- data/test/sass/source_map_test.rb +115 -25
- data/test/sass/superselector_test.rb +191 -0
- data/test/sass/templates/scss_import.scss +2 -1
- data/test/sass/test_helper.rb +1 -1
- data/test/sass/util/multibyte_string_scanner_test.rb +1 -1
- data/test/sass/util/normalized_map_test.rb +1 -1
- data/test/sass/util/subset_map_test.rb +2 -2
- data/test/sass/util_test.rb +31 -1
- data/test/sass/value_helpers_test.rb +5 -7
- data/test/test_helper.rb +2 -2
- data/vendor/listen/CHANGELOG.md +1 -228
- data/vendor/listen/Gemfile +5 -15
- data/vendor/listen/README.md +111 -77
- data/vendor/listen/Rakefile +0 -42
- data/vendor/listen/lib/listen/adapter.rb +195 -82
- data/vendor/listen/lib/listen/adapters/bsd.rb +27 -64
- data/vendor/listen/lib/listen/adapters/darwin.rb +21 -58
- data/vendor/listen/lib/listen/adapters/linux.rb +23 -55
- data/vendor/listen/lib/listen/adapters/polling.rb +25 -34
- data/vendor/listen/lib/listen/adapters/windows.rb +50 -46
- data/vendor/listen/lib/listen/directory_record.rb +96 -61
- data/vendor/listen/lib/listen/listener.rb +135 -37
- data/vendor/listen/lib/listen/turnstile.rb +9 -5
- data/vendor/listen/lib/listen/version.rb +1 -1
- data/vendor/listen/lib/listen.rb +33 -19
- data/vendor/listen/listen.gemspec +6 -0
- data/vendor/listen/spec/listen/adapter_spec.rb +43 -77
- data/vendor/listen/spec/listen/adapters/polling_spec.rb +8 -8
- data/vendor/listen/spec/listen/directory_record_spec.rb +81 -56
- data/vendor/listen/spec/listen/listener_spec.rb +128 -39
- data/vendor/listen/spec/listen_spec.rb +15 -21
- data/vendor/listen/spec/spec_helper.rb +4 -0
- data/vendor/listen/spec/support/adapter_helper.rb +52 -15
- data/vendor/listen/spec/support/directory_record_helper.rb +7 -5
- data/vendor/listen/spec/support/listeners_helper.rb +30 -7
- metadata +25 -22
- data/ext/mkrf_conf.rb +0 -27
- data/lib/sass/importers/deprecated_path.rb +0 -51
- data/lib/sass/script/value/deprecated_false.rb +0 -55
- data/vendor/listen/lib/listen/dependency_manager.rb +0 -126
- data/vendor/listen/lib/listen/multi_listener.rb +0 -143
- data/vendor/listen/spec/listen/dependency_manager_spec.rb +0 -107
- data/vendor/listen/spec/listen/multi_listener_spec.rb +0 -174
data/test/sass/cache_test.rb
CHANGED
@@ -3,7 +3,7 @@ require File.dirname(__FILE__) + '/../test_helper'
|
|
3
3
|
require File.dirname(__FILE__) + '/test_helper'
|
4
4
|
require 'sass/engine'
|
5
5
|
|
6
|
-
class CacheTest < Test
|
6
|
+
class CacheTest < MiniTest::Test
|
7
7
|
@@cache_dir = "tmp/file_cache"
|
8
8
|
|
9
9
|
def setup
|
@@ -18,42 +18,42 @@ class CacheTest < Test::Unit::TestCase
|
|
18
18
|
def test_file_cache_writes_a_file
|
19
19
|
file_store = Sass::CacheStores::Filesystem.new(@@cache_dir)
|
20
20
|
file_store.store("asdf/foo.scssc", "fakesha1", root_node)
|
21
|
-
assert File.
|
21
|
+
assert File.exist?("#{@@cache_dir}/asdf/foo.scssc")
|
22
22
|
end
|
23
23
|
|
24
24
|
def test_file_cache_reads_a_file
|
25
25
|
file_store = Sass::CacheStores::Filesystem.new(@@cache_dir)
|
26
|
-
assert !File.
|
26
|
+
assert !File.exist?("#{@@cache_dir}/asdf/foo.scssc")
|
27
27
|
file_store.store("asdf/foo.scssc", "fakesha1", root_node)
|
28
|
-
assert File.
|
28
|
+
assert File.exist?("#{@@cache_dir}/asdf/foo.scssc")
|
29
29
|
assert_kind_of Sass::Tree::RootNode, file_store.retrieve("asdf/foo.scssc", "fakesha1")
|
30
30
|
end
|
31
31
|
|
32
32
|
def test_file_cache_miss_returns_nil
|
33
33
|
file_store = Sass::CacheStores::Filesystem.new(@@cache_dir)
|
34
|
-
assert !File.
|
34
|
+
assert !File.exist?("#{@@cache_dir}/asdf/foo.scssc")
|
35
35
|
assert_nil file_store.retrieve("asdf/foo.scssc", "fakesha1")
|
36
36
|
end
|
37
37
|
|
38
38
|
def test_sha_change_invalidates_cache_and_cleans_up
|
39
39
|
file_store = Sass::CacheStores::Filesystem.new(@@cache_dir)
|
40
|
-
assert !File.
|
40
|
+
assert !File.exist?("#{@@cache_dir}/asdf/foo.scssc")
|
41
41
|
file_store.store("asdf/foo.scssc", "fakesha1", root_node)
|
42
|
-
assert File.
|
42
|
+
assert File.exist?("#{@@cache_dir}/asdf/foo.scssc")
|
43
43
|
assert_nil file_store.retrieve("asdf/foo.scssc", "differentsha1")
|
44
|
-
assert !File.
|
44
|
+
assert !File.exist?("#{@@cache_dir}/asdf/foo.scssc")
|
45
45
|
end
|
46
46
|
|
47
47
|
def test_version_change_invalidates_cache_and_cleans_up
|
48
48
|
file_store = Sass::CacheStores::Filesystem.new(@@cache_dir)
|
49
|
-
assert !File.
|
49
|
+
assert !File.exist?("#{@@cache_dir}/asdf/foo.scssc")
|
50
50
|
file_store.store("asdf/foo.scssc", "fakesha1", root_node)
|
51
|
-
assert File.
|
51
|
+
assert File.exist?("#{@@cache_dir}/asdf/foo.scssc")
|
52
52
|
real_version = Sass::VERSION
|
53
53
|
begin
|
54
54
|
Sass::VERSION.replace("a different version")
|
55
55
|
assert_nil file_store.retrieve("asdf/foo.scssc", "fakesha1")
|
56
|
-
assert !File.
|
56
|
+
assert !File.exist?("#{@@cache_dir}/asdf/foo.scssc")
|
57
57
|
ensure
|
58
58
|
Sass::VERSION.replace(real_version)
|
59
59
|
end
|
@@ -66,17 +66,52 @@ class CacheTest < Test::Unit::TestCase
|
|
66
66
|
assert_equal an_object, cache.retrieve("an_object", "")
|
67
67
|
end
|
68
68
|
|
69
|
-
|
70
|
-
|
71
|
-
raise 'Unmarshalable'
|
72
|
-
end
|
69
|
+
def test_cache_node_with_unmarshalable_option
|
70
|
+
engine_with_unmarshalable_options("foo {a: b + c}").to_tree
|
73
71
|
end
|
74
72
|
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
73
|
+
# Regression tests
|
74
|
+
|
75
|
+
def test_cache_mixin_def_splat_sass_node_with_unmarshalable_option
|
76
|
+
engine_with_unmarshalable_options(<<SASS, :syntax => :sass).to_tree
|
77
|
+
=color($args...)
|
78
|
+
color: red
|
79
|
+
SASS
|
80
|
+
end
|
81
|
+
|
82
|
+
def test_cache_mixin_def_splat_scss_node_with_unmarshalable_option
|
83
|
+
engine_with_unmarshalable_options(<<SCSS, :syntax => :scss).to_tree
|
84
|
+
@mixin color($args...) {
|
85
|
+
color: red;
|
86
|
+
}
|
87
|
+
SCSS
|
88
|
+
end
|
89
|
+
|
90
|
+
def test_cache_function_splat_sass_node_with_unmarshalable_option
|
91
|
+
engine_with_unmarshalable_options(<<SASS, :syntax => :sass).to_tree
|
92
|
+
@function color($args...)
|
93
|
+
@return red
|
94
|
+
SASS
|
95
|
+
end
|
96
|
+
|
97
|
+
def test_cache_function_splat_scss_node_with_unmarshalable_option
|
98
|
+
engine_with_unmarshalable_options(<<SCSS, :syntax => :scss).to_tree
|
99
|
+
@function color($args...) {
|
100
|
+
@return red;
|
101
|
+
}
|
102
|
+
SCSS
|
103
|
+
end
|
104
|
+
|
105
|
+
def test_cache_include_splat_sass_node_with_unmarshalable_option
|
106
|
+
engine_with_unmarshalable_options(<<SASS, :syntax => :sass).to_tree
|
107
|
+
@include color($args..., $kwargs...)
|
108
|
+
SASS
|
109
|
+
end
|
110
|
+
|
111
|
+
def test_cache_include_splat_scss_node_with_unmarshalable_option
|
112
|
+
engine_with_unmarshalable_options(<<SCSS, :syntax => :scss).to_tree
|
113
|
+
@include color($args..., $kwargs...);
|
114
|
+
SCSS
|
80
115
|
end
|
81
116
|
|
82
117
|
private
|
@@ -86,4 +121,11 @@ class CacheTest < Test::Unit::TestCase
|
|
86
121
|
div { @include color(red); }
|
87
122
|
SCSS
|
88
123
|
end
|
124
|
+
|
125
|
+
def engine_with_unmarshalable_options(src, options={})
|
126
|
+
Sass::Engine.new(src, {
|
127
|
+
:syntax => :scss, :object => Class.new.new, :filename => 'file.scss',
|
128
|
+
:importer => Sass::Importers::Filesystem.new(absolutize('templates'))
|
129
|
+
}.merge(options))
|
130
|
+
end
|
89
131
|
end
|
data/test/sass/callbacks_test.rb
CHANGED
data/test/sass/compiler_test.rb
CHANGED
@@ -1,10 +1,10 @@
|
|
1
1
|
#!/usr/bin/env ruby
|
2
|
-
require '
|
2
|
+
require 'minitest/autorun'
|
3
3
|
require File.dirname(__FILE__) + '/../test_helper'
|
4
4
|
require 'sass/plugin'
|
5
5
|
require 'sass/plugin/compiler'
|
6
6
|
|
7
|
-
class CompilerTest < Test
|
7
|
+
class CompilerTest < MiniTest::Test
|
8
8
|
class FakeListener
|
9
9
|
attr_accessor :options
|
10
10
|
attr_accessor :directories
|
@@ -18,7 +18,7 @@ class CompilerTest < Test::Unit::TestCase
|
|
18
18
|
@start_called = false
|
19
19
|
reset_events!
|
20
20
|
end
|
21
|
-
|
21
|
+
|
22
22
|
def fire_events!(*args)
|
23
23
|
@on_filesystem_event.call(@modified, @added, @removed)
|
24
24
|
reset_events!
|
@@ -82,9 +82,18 @@ class CompilerTest < Test::Unit::TestCase
|
|
82
82
|
|
83
83
|
private
|
84
84
|
def create_listener(*args, &on_filesystem_event)
|
85
|
-
|
86
|
-
|
87
|
-
|
85
|
+
if Sass::Util.listen_geq_2?
|
86
|
+
options = args.pop if args.last.is_a?(Hash)
|
87
|
+
args.map do |dir|
|
88
|
+
@fake_listener = FakeListener.new(*args, &on_filesystem_event)
|
89
|
+
@fake_listener.on_start!(&run_during_start)
|
90
|
+
@fake_listener
|
91
|
+
end
|
92
|
+
else
|
93
|
+
@fake_listener = FakeListener.new(*args, &on_filesystem_event)
|
94
|
+
@fake_listener.on_start!(&run_during_start)
|
95
|
+
@fake_listener
|
96
|
+
end
|
88
97
|
end
|
89
98
|
end
|
90
99
|
|
@@ -174,12 +183,12 @@ class CompilerTest < Test::Unit::TestCase
|
|
174
183
|
directories = nil
|
175
184
|
c = watcher do |listener|
|
176
185
|
directories = listener.directories
|
177
|
-
listener.removed "
|
186
|
+
listener.removed File.expand_path("./foo.scss")
|
178
187
|
listener.fire_events!
|
179
188
|
end
|
180
|
-
c.watch([["
|
181
|
-
assert directories.include?("
|
182
|
-
assert_equal "
|
189
|
+
c.watch([[File.expand_path("./foo.scss"), File.expand_path("./foo.css"), nil]])
|
190
|
+
assert directories.include?(File.expand_path(".")), directories.inspect
|
191
|
+
assert_equal File.expand_path("./foo.css"), c.deleted_css_files.first, "the corresponding css file was not deleted"
|
183
192
|
assert_equal [], c.update_stylesheets_called_with[1], "the sass file should not have been compiled"
|
184
193
|
end
|
185
194
|
|
@@ -1,7 +1,7 @@
|
|
1
1
|
#!/usr/bin/env ruby
|
2
2
|
require File.dirname(__FILE__) + '/../test_helper'
|
3
3
|
|
4
|
-
class ConversionTest < Test
|
4
|
+
class ConversionTest < MiniTest::Test
|
5
5
|
def test_basic
|
6
6
|
assert_renders <<SASS, <<SCSS
|
7
7
|
foo bar
|
@@ -589,6 +589,19 @@ foo {
|
|
589
589
|
SCSS
|
590
590
|
end
|
591
591
|
|
592
|
+
def test_error
|
593
|
+
assert_renders <<SASS, <<SCSS
|
594
|
+
foo
|
595
|
+
@error "oh no!"
|
596
|
+
bar: baz
|
597
|
+
SASS
|
598
|
+
foo {
|
599
|
+
@error "oh no!";
|
600
|
+
bar: baz;
|
601
|
+
}
|
602
|
+
SCSS
|
603
|
+
end
|
604
|
+
|
592
605
|
def test_directive_without_children
|
593
606
|
assert_renders <<SASS, <<SCSS
|
594
607
|
foo
|
@@ -1267,6 +1280,17 @@ $val: 20;
|
|
1267
1280
|
SCSS
|
1268
1281
|
end
|
1269
1282
|
|
1283
|
+
def test_media_with_feature
|
1284
|
+
assert_sass_to_scss <<SCSS, <<SASS
|
1285
|
+
@media screen and (-webkit-transform-3d) {
|
1286
|
+
a: b;
|
1287
|
+
}
|
1288
|
+
SCSS
|
1289
|
+
@media screen and (-webkit-transform-3d)
|
1290
|
+
a: b
|
1291
|
+
SASS
|
1292
|
+
end
|
1293
|
+
|
1270
1294
|
def test_supports_with_expressions
|
1271
1295
|
assert_renders <<SASS, <<SCSS
|
1272
1296
|
$query: "(feature1: val)"
|
@@ -1808,6 +1832,39 @@ SASS
|
|
1808
1832
|
SCSS
|
1809
1833
|
end
|
1810
1834
|
|
1835
|
+
def test_keyframes
|
1836
|
+
assert_renders(<<SASS, <<SCSS)
|
1837
|
+
@keyframes identifier
|
1838
|
+
0%
|
1839
|
+
top: 0
|
1840
|
+
left: 0
|
1841
|
+
30%
|
1842
|
+
top: 50px
|
1843
|
+
68%, 72%
|
1844
|
+
left: 50px
|
1845
|
+
100%
|
1846
|
+
top: 100px
|
1847
|
+
left: 100%
|
1848
|
+
SASS
|
1849
|
+
@keyframes identifier {
|
1850
|
+
0% {
|
1851
|
+
top: 0;
|
1852
|
+
left: 0;
|
1853
|
+
}
|
1854
|
+
30% {
|
1855
|
+
top: 50px;
|
1856
|
+
}
|
1857
|
+
68%, 72% {
|
1858
|
+
left: 50px;
|
1859
|
+
}
|
1860
|
+
100% {
|
1861
|
+
top: 100px;
|
1862
|
+
left: 100%;
|
1863
|
+
}
|
1864
|
+
}
|
1865
|
+
SCSS
|
1866
|
+
end
|
1867
|
+
|
1811
1868
|
## Regression Tests
|
1812
1869
|
|
1813
1870
|
def test_list_in_args
|
data/test/sass/css2sass_test.rb
CHANGED
@@ -1,9 +1,9 @@
|
|
1
1
|
#!/usr/bin/env ruby
|
2
|
-
require '
|
2
|
+
require 'minitest/autorun'
|
3
3
|
require File.dirname(__FILE__) + '/../test_helper'
|
4
4
|
require 'sass/css'
|
5
5
|
|
6
|
-
class CSS2SassTest < Test
|
6
|
+
class CSS2SassTest < MiniTest::Test
|
7
7
|
def test_basic
|
8
8
|
css = <<CSS
|
9
9
|
h1 {
|
@@ -62,7 +62,7 @@ div .debug
|
|
62
62
|
SASS
|
63
63
|
div .warning {
|
64
64
|
color: #d21a19; }
|
65
|
-
span .debug {
|
65
|
+
span .debug {
|
66
66
|
cursor: crosshair;}
|
67
67
|
div .debug {
|
68
68
|
cursor: default; }
|
@@ -238,7 +238,7 @@ CSS
|
|
238
238
|
end
|
239
239
|
|
240
240
|
def test_subject
|
241
|
-
assert_equal(<<SASS, css2sass(<<CSS))
|
241
|
+
silence_warnings {assert_equal(<<SASS, css2sass(<<CSS))}
|
242
242
|
.foo
|
243
243
|
.bar!
|
244
244
|
.baz
|
@@ -265,6 +265,25 @@ CSS
|
|
265
265
|
|
266
266
|
# Regressions
|
267
267
|
|
268
|
+
def test_nesting_with_matching_property
|
269
|
+
assert_equal(<<SASS, css2sass(<<CSS))
|
270
|
+
ul
|
271
|
+
width: 10px
|
272
|
+
div
|
273
|
+
width: 20px
|
274
|
+
|
275
|
+
article
|
276
|
+
width: 10px
|
277
|
+
p
|
278
|
+
width: 20px
|
279
|
+
SASS
|
280
|
+
ul {width: 10px}
|
281
|
+
ul div {width: 20px}
|
282
|
+
article {width: 10px}
|
283
|
+
article p {width: 20px}
|
284
|
+
CSS
|
285
|
+
end
|
286
|
+
|
268
287
|
def test_empty_rule
|
269
288
|
assert_equal(<<SASS, css2sass(<<CSS))
|
270
289
|
a
|
@@ -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
|