sass 3.1.0 → 3.3.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 +7 -0
- data/CONTRIBUTING +1 -1
- data/MIT-LICENSE +2 -2
- data/README.md +29 -17
- data/Rakefile +43 -9
- data/VERSION +1 -1
- data/VERSION_DATE +1 -0
- data/VERSION_NAME +1 -1
- data/bin/sass +6 -1
- data/bin/sass-convert +6 -1
- data/bin/scss +6 -1
- data/ext/mkrf_conf.rb +27 -0
- data/lib/sass/cache_stores/base.rb +7 -3
- data/lib/sass/cache_stores/chain.rb +3 -2
- data/lib/sass/cache_stores/filesystem.rb +5 -7
- data/lib/sass/cache_stores/memory.rb +1 -1
- data/lib/sass/cache_stores/null.rb +2 -2
- data/lib/sass/callbacks.rb +2 -1
- data/lib/sass/css.rb +168 -53
- data/lib/sass/engine.rb +502 -174
- data/lib/sass/environment.rb +151 -111
- data/lib/sass/error.rb +7 -7
- data/lib/sass/exec.rb +176 -60
- data/lib/sass/features.rb +40 -0
- data/lib/sass/importers/base.rb +46 -7
- data/lib/sass/importers/deprecated_path.rb +51 -0
- data/lib/sass/importers/filesystem.rb +113 -30
- data/lib/sass/importers.rb +1 -0
- data/lib/sass/logger/base.rb +30 -0
- data/lib/sass/logger/log_level.rb +45 -0
- data/lib/sass/logger.rb +12 -0
- data/lib/sass/media.rb +213 -0
- data/lib/sass/plugin/compiler.rb +194 -104
- data/lib/sass/plugin/configuration.rb +18 -25
- data/lib/sass/plugin/merb.rb +1 -1
- data/lib/sass/plugin/staleness_checker.rb +37 -11
- data/lib/sass/plugin.rb +10 -13
- data/lib/sass/railtie.rb +2 -1
- data/lib/sass/repl.rb +5 -6
- data/lib/sass/script/css_lexer.rb +8 -4
- data/lib/sass/script/css_parser.rb +5 -2
- data/lib/sass/script/functions.rb +1547 -618
- data/lib/sass/script/lexer.rb +122 -72
- data/lib/sass/script/parser.rb +304 -135
- data/lib/sass/script/tree/funcall.rb +306 -0
- data/lib/sass/script/{interpolation.rb → tree/interpolation.rb} +43 -13
- data/lib/sass/script/tree/list_literal.rb +77 -0
- data/lib/sass/script/tree/literal.rb +45 -0
- data/lib/sass/script/tree/map_literal.rb +64 -0
- data/lib/sass/script/{node.rb → tree/node.rb} +30 -12
- data/lib/sass/script/{operation.rb → tree/operation.rb} +33 -21
- data/lib/sass/script/{string_interpolation.rb → tree/string_interpolation.rb} +14 -4
- data/lib/sass/script/{unary_operation.rb → tree/unary_operation.rb} +21 -9
- data/lib/sass/script/tree/variable.rb +57 -0
- data/lib/sass/script/tree.rb +15 -0
- data/lib/sass/script/value/arg_list.rb +36 -0
- data/lib/sass/script/value/base.rb +238 -0
- data/lib/sass/script/value/bool.rb +40 -0
- data/lib/sass/script/{color.rb → value/color.rb} +256 -74
- data/lib/sass/script/value/deprecated_false.rb +55 -0
- data/lib/sass/script/value/helpers.rb +155 -0
- data/lib/sass/script/value/list.rb +128 -0
- data/lib/sass/script/value/map.rb +70 -0
- data/lib/sass/script/value/null.rb +49 -0
- data/lib/sass/script/{number.rb → value/number.rb} +115 -62
- data/lib/sass/script/{string.rb → value/string.rb} +9 -11
- data/lib/sass/script/value.rb +12 -0
- data/lib/sass/script.rb +35 -9
- data/lib/sass/scss/css_parser.rb +2 -12
- data/lib/sass/scss/parser.rb +657 -230
- data/lib/sass/scss/rx.rb +17 -12
- data/lib/sass/scss/static_parser.rb +37 -6
- data/lib/sass/scss.rb +0 -1
- data/lib/sass/selector/abstract_sequence.rb +35 -3
- data/lib/sass/selector/comma_sequence.rb +29 -14
- data/lib/sass/selector/sequence.rb +371 -74
- data/lib/sass/selector/simple.rb +28 -13
- data/lib/sass/selector/simple_sequence.rb +163 -36
- data/lib/sass/selector.rb +138 -36
- data/lib/sass/shared.rb +3 -5
- data/lib/sass/source/map.rb +196 -0
- data/lib/sass/source/position.rb +39 -0
- data/lib/sass/source/range.rb +41 -0
- data/lib/sass/stack.rb +126 -0
- data/lib/sass/supports.rb +228 -0
- data/lib/sass/tree/at_root_node.rb +82 -0
- data/lib/sass/tree/comment_node.rb +34 -29
- data/lib/sass/tree/content_node.rb +9 -0
- data/lib/sass/tree/css_import_node.rb +60 -0
- data/lib/sass/tree/debug_node.rb +3 -3
- data/lib/sass/tree/directive_node.rb +33 -3
- data/lib/sass/tree/each_node.rb +9 -9
- data/lib/sass/tree/extend_node.rb +20 -6
- data/lib/sass/tree/for_node.rb +6 -6
- data/lib/sass/tree/function_node.rb +12 -4
- data/lib/sass/tree/if_node.rb +2 -15
- data/lib/sass/tree/import_node.rb +11 -5
- data/lib/sass/tree/media_node.rb +27 -11
- data/lib/sass/tree/mixin_def_node.rb +15 -4
- data/lib/sass/tree/mixin_node.rb +27 -7
- data/lib/sass/tree/node.rb +69 -35
- data/lib/sass/tree/prop_node.rb +47 -31
- data/lib/sass/tree/return_node.rb +4 -3
- data/lib/sass/tree/root_node.rb +20 -4
- data/lib/sass/tree/rule_node.rb +37 -26
- data/lib/sass/tree/supports_node.rb +38 -0
- data/lib/sass/tree/trace_node.rb +33 -0
- data/lib/sass/tree/variable_node.rb +10 -4
- data/lib/sass/tree/visitors/base.rb +5 -8
- data/lib/sass/tree/visitors/check_nesting.rb +67 -52
- data/lib/sass/tree/visitors/convert.rb +134 -53
- data/lib/sass/tree/visitors/cssize.rb +245 -51
- data/lib/sass/tree/visitors/deep_copy.rb +102 -0
- data/lib/sass/tree/visitors/extend.rb +68 -0
- data/lib/sass/tree/visitors/perform.rb +331 -105
- data/lib/sass/tree/visitors/set_options.rb +125 -0
- data/lib/sass/tree/visitors/to_css.rb +259 -95
- data/lib/sass/tree/warn_node.rb +3 -3
- data/lib/sass/tree/while_node.rb +3 -3
- data/lib/sass/util/cross_platform_random.rb +19 -0
- data/lib/sass/util/multibyte_string_scanner.rb +157 -0
- data/lib/sass/util/normalized_map.rb +130 -0
- data/lib/sass/util/ordered_hash.rb +192 -0
- data/lib/sass/util/subset_map.rb +11 -2
- data/lib/sass/util/test.rb +9 -0
- data/lib/sass/util.rb +565 -39
- data/lib/sass/version.rb +27 -15
- data/lib/sass.rb +39 -4
- data/test/sass/cache_test.rb +15 -0
- data/test/sass/compiler_test.rb +223 -0
- data/test/sass/conversion_test.rb +901 -107
- data/test/sass/css2sass_test.rb +94 -0
- data/test/sass/engine_test.rb +1059 -164
- data/test/sass/exec_test.rb +86 -0
- data/test/sass/extend_test.rb +933 -837
- data/test/sass/fixtures/test_staleness_check_across_importers.css +1 -0
- data/test/sass/fixtures/test_staleness_check_across_importers.scss +1 -0
- data/test/sass/functions_test.rb +995 -136
- data/test/sass/importer_test.rb +338 -18
- data/test/sass/logger_test.rb +58 -0
- data/test/sass/more_results/more_import.css +2 -2
- data/test/sass/plugin_test.rb +114 -30
- data/test/sass/results/cached_import_option.css +3 -0
- data/test/sass/results/filename_fn.css +3 -0
- data/test/sass/results/import.css +2 -2
- data/test/sass/results/import_charset.css +1 -0
- data/test/sass/results/import_charset_1_8.css +1 -0
- data/test/sass/results/import_charset_ibm866.css +1 -0
- data/test/sass/results/import_content.css +1 -0
- data/test/sass/results/script.css +1 -1
- data/test/sass/results/scss_import.css +2 -2
- data/test/sass/results/units.css +2 -2
- data/test/sass/script_conversion_test.rb +43 -1
- data/test/sass/script_test.rb +380 -36
- data/test/sass/scss/css_test.rb +257 -75
- data/test/sass/scss/scss_test.rb +2322 -110
- data/test/sass/source_map_test.rb +887 -0
- data/test/sass/templates/_cached_import_option_partial.scss +1 -0
- data/test/sass/templates/_double_import_loop2.sass +1 -0
- data/test/sass/templates/_filename_fn_import.scss +11 -0
- data/test/sass/templates/_imported_content.sass +3 -0
- data/test/sass/templates/_same_name_different_partiality.scss +1 -0
- data/test/sass/templates/bork5.sass +3 -0
- data/test/sass/templates/cached_import_option.scss +3 -0
- data/test/sass/templates/double_import_loop1.sass +1 -0
- data/test/sass/templates/filename_fn.scss +18 -0
- data/test/sass/templates/import_charset.sass +2 -0
- data/test/sass/templates/import_charset_1_8.sass +2 -0
- data/test/sass/templates/import_charset_ibm866.sass +2 -0
- data/test/sass/templates/import_content.sass +4 -0
- data/test/sass/templates/same_name_different_ext.sass +2 -0
- data/test/sass/templates/same_name_different_ext.scss +1 -0
- data/test/sass/templates/same_name_different_partiality.scss +1 -0
- data/test/sass/templates/single_import_loop.sass +1 -0
- data/test/sass/templates/subdir/import_up1.scss +1 -0
- data/test/sass/templates/subdir/import_up2.scss +1 -0
- data/test/sass/test_helper.rb +1 -1
- data/test/sass/util/multibyte_string_scanner_test.rb +147 -0
- data/test/sass/util/normalized_map_test.rb +51 -0
- data/test/sass/util_test.rb +183 -0
- data/test/sass/value_helpers_test.rb +181 -0
- data/test/test_helper.rb +45 -5
- data/vendor/listen/CHANGELOG.md +228 -0
- data/vendor/listen/CONTRIBUTING.md +38 -0
- data/vendor/listen/Gemfile +30 -0
- data/vendor/listen/Guardfile +8 -0
- data/vendor/{fssm → listen}/LICENSE +1 -1
- data/vendor/listen/README.md +315 -0
- data/vendor/listen/Rakefile +47 -0
- data/vendor/listen/Vagrantfile +96 -0
- data/vendor/listen/lib/listen/adapter.rb +214 -0
- data/vendor/listen/lib/listen/adapters/bsd.rb +112 -0
- data/vendor/listen/lib/listen/adapters/darwin.rb +85 -0
- data/vendor/listen/lib/listen/adapters/linux.rb +113 -0
- data/vendor/listen/lib/listen/adapters/polling.rb +67 -0
- data/vendor/listen/lib/listen/adapters/windows.rb +87 -0
- data/vendor/listen/lib/listen/dependency_manager.rb +126 -0
- data/vendor/listen/lib/listen/directory_record.rb +371 -0
- data/vendor/listen/lib/listen/listener.rb +225 -0
- data/vendor/listen/lib/listen/multi_listener.rb +143 -0
- data/vendor/listen/lib/listen/turnstile.rb +28 -0
- data/vendor/listen/lib/listen/version.rb +3 -0
- data/vendor/listen/lib/listen.rb +40 -0
- data/vendor/listen/listen.gemspec +22 -0
- data/vendor/listen/spec/listen/adapter_spec.rb +183 -0
- data/vendor/listen/spec/listen/adapters/bsd_spec.rb +36 -0
- data/vendor/listen/spec/listen/adapters/darwin_spec.rb +37 -0
- data/vendor/listen/spec/listen/adapters/linux_spec.rb +47 -0
- data/vendor/listen/spec/listen/adapters/polling_spec.rb +68 -0
- data/vendor/listen/spec/listen/adapters/windows_spec.rb +30 -0
- data/vendor/listen/spec/listen/dependency_manager_spec.rb +107 -0
- data/vendor/listen/spec/listen/directory_record_spec.rb +1225 -0
- data/vendor/listen/spec/listen/listener_spec.rb +169 -0
- data/vendor/listen/spec/listen/multi_listener_spec.rb +174 -0
- data/vendor/listen/spec/listen/turnstile_spec.rb +56 -0
- data/vendor/listen/spec/listen_spec.rb +73 -0
- data/vendor/listen/spec/spec_helper.rb +21 -0
- data/vendor/listen/spec/support/adapter_helper.rb +629 -0
- data/vendor/listen/spec/support/directory_record_helper.rb +55 -0
- data/vendor/listen/spec/support/fixtures_helper.rb +29 -0
- data/vendor/listen/spec/support/listeners_helper.rb +156 -0
- data/vendor/listen/spec/support/platform_helper.rb +15 -0
- metadata +344 -271
- data/lib/sass/less.rb +0 -382
- data/lib/sass/script/bool.rb +0 -18
- data/lib/sass/script/funcall.rb +0 -162
- data/lib/sass/script/list.rb +0 -76
- data/lib/sass/script/literal.rb +0 -245
- data/lib/sass/script/variable.rb +0 -54
- data/lib/sass/scss/sass_parser.rb +0 -11
- data/test/sass/less_conversion_test.rb +0 -653
- data/vendor/fssm/README.markdown +0 -55
- data/vendor/fssm/Rakefile +0 -59
- data/vendor/fssm/VERSION.yml +0 -5
- data/vendor/fssm/example.rb +0 -9
- data/vendor/fssm/fssm.gemspec +0 -77
- data/vendor/fssm/lib/fssm/backends/fsevents.rb +0 -36
- data/vendor/fssm/lib/fssm/backends/inotify.rb +0 -26
- data/vendor/fssm/lib/fssm/backends/polling.rb +0 -25
- data/vendor/fssm/lib/fssm/backends/rubycocoa/fsevents.rb +0 -131
- data/vendor/fssm/lib/fssm/monitor.rb +0 -26
- data/vendor/fssm/lib/fssm/path.rb +0 -91
- data/vendor/fssm/lib/fssm/pathname.rb +0 -502
- data/vendor/fssm/lib/fssm/state/directory.rb +0 -57
- data/vendor/fssm/lib/fssm/state/file.rb +0 -24
- data/vendor/fssm/lib/fssm/support.rb +0 -63
- data/vendor/fssm/lib/fssm/tree.rb +0 -176
- data/vendor/fssm/lib/fssm.rb +0 -33
- data/vendor/fssm/profile/prof-cache.rb +0 -40
- data/vendor/fssm/profile/prof-fssm-pathname.html +0 -1231
- data/vendor/fssm/profile/prof-pathname.rb +0 -68
- data/vendor/fssm/profile/prof-plain-pathname.html +0 -988
- data/vendor/fssm/profile/prof.html +0 -2379
- data/vendor/fssm/spec/path_spec.rb +0 -75
- data/vendor/fssm/spec/root/duck/quack.txt +0 -0
- data/vendor/fssm/spec/root/file.css +0 -0
- data/vendor/fssm/spec/root/file.rb +0 -0
- data/vendor/fssm/spec/root/file.yml +0 -0
- data/vendor/fssm/spec/root/moo/cow.txt +0 -0
- data/vendor/fssm/spec/spec_helper.rb +0 -14
data/test/sass/engine_test.rb
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
#!/usr/bin/env ruby
|
2
2
|
# -*- coding: utf-8 -*-
|
3
|
-
require 'test_helper'
|
4
|
-
require '
|
3
|
+
require File.dirname(__FILE__) + '/../test_helper'
|
4
|
+
require File.dirname(__FILE__) + '/test_helper'
|
5
5
|
require 'sass/engine'
|
6
6
|
require 'stringio'
|
7
7
|
require 'mock_importer'
|
@@ -9,10 +9,23 @@ require 'pathname'
|
|
9
9
|
|
10
10
|
module Sass::Script::Functions::UserFunctions
|
11
11
|
def option(name)
|
12
|
-
Sass::Script::String.new(@options[name.value.to_sym].to_s)
|
12
|
+
Sass::Script::Value::String.new(@options[name.value.to_sym].to_s)
|
13
|
+
end
|
14
|
+
|
15
|
+
def set_a_variable(name, value)
|
16
|
+
environment.set_var(name.value, value)
|
17
|
+
return Sass::Script::Value::Null.new
|
18
|
+
end
|
19
|
+
|
20
|
+
def get_a_variable(name)
|
21
|
+
environment.var(name.value) || Sass::Script::Value::String.new("undefined")
|
13
22
|
end
|
14
23
|
end
|
15
24
|
|
25
|
+
module Sass::Script::Functions
|
26
|
+
include Sass::Script::Functions::UserFunctions
|
27
|
+
end
|
28
|
+
|
16
29
|
class SassEngineTest < Test::Unit::TestCase
|
17
30
|
FAKE_FILE_NAME = __FILE__.gsub(/rb$/,"sass")
|
18
31
|
# A map of erroneous Sass documents to the error messages they should produce.
|
@@ -39,8 +52,11 @@ MSG
|
|
39
52
|
"a\n b: c;" => 'Invalid CSS after "c": expected expression (e.g. 1px, bold), was ";"',
|
40
53
|
".foo ^bar\n a: b" => ['Invalid CSS after ".foo ": expected selector, was "^bar"', 1],
|
41
54
|
"a\n @extend .foo ^bar" => 'Invalid CSS after ".foo ": expected selector, was "^bar"',
|
42
|
-
"a
|
43
|
-
"
|
55
|
+
"a\n @extend .foo .bar" => "Can't extend .foo .bar: can't extend nested selectors",
|
56
|
+
"a\n @extend >" => "Can't extend >: invalid selector",
|
57
|
+
"a\n @extend &.foo" => "Can't extend &.foo: can't extend parent selectors",
|
58
|
+
"a: b" => 'Properties are only allowed within rules, directives, mixin includes, or other properties.',
|
59
|
+
":a b" => 'Properties are only allowed within rules, directives, mixin includes, or other properties.',
|
44
60
|
"$" => 'Invalid variable: "$".',
|
45
61
|
"$a" => 'Invalid variable: "$a".',
|
46
62
|
"$ a" => 'Invalid variable: "$ a".',
|
@@ -51,29 +67,26 @@ MSG
|
|
51
67
|
"$a: 1b <= 2c" => "Incompatible units: 'c' and 'b'.",
|
52
68
|
"$a: 1b >= 2c" => "Incompatible units: 'c' and 'b'.",
|
53
69
|
"a\n b: 1b * 2c" => "2b*c isn't a valid CSS value.",
|
54
|
-
"a\n b: 1b % 2c" => "
|
70
|
+
"a\n b: 1b % 2c" => "Incompatible units: 'c' and 'b'.",
|
55
71
|
"$a: 2px + #ccc" => "Cannot add a number with units (2px) to a color (#cccccc).",
|
56
72
|
"$a: #ccc + 2px" => "Cannot add a number with units (2px) to a color (#cccccc).",
|
57
73
|
"& a\n :b c" => ["Base-level rules cannot contain the parent-selector-referencing character '&'.", 1],
|
58
74
|
"a\n :b\n c" => "Illegal nesting: Only properties may be nested beneath properties.",
|
59
75
|
"$a: b\n :c d\n" => "Illegal nesting: Nothing may be nested beneath variable declarations.",
|
60
|
-
"@import foo.sass" => "File to import not found or unreadable: foo.sass.",
|
61
76
|
"$a: b\n :c d\n" => "Illegal nesting: Nothing may be nested beneath variable declarations.",
|
62
|
-
"@import foo.sass" => <<MSG,
|
63
|
-
File to import not found or unreadable: foo.sass.
|
64
|
-
Load path: .
|
65
|
-
MSG
|
66
77
|
"@import templates/basic\n foo" => "Illegal nesting: Nothing may be nested beneath import directives.",
|
67
78
|
"foo\n @import foo.css" => "CSS import directives may only be used at the root of a document.",
|
68
79
|
"@if true\n @import foo" => "Import directives may not be used within control directives or mixins.",
|
80
|
+
"@if true\n .foo\n @import foo" => "Import directives may not be used within control directives or mixins.",
|
69
81
|
"@mixin foo\n @import foo" => "Import directives may not be used within control directives or mixins.",
|
82
|
+
"@mixin foo\n .foo\n @import foo" => "Import directives may not be used within control directives or mixins.",
|
83
|
+
"@import foo;" => "Invalid @import: expected end of line, was \";\".",
|
70
84
|
'$foo: "bar" "baz" !' => %Q{Invalid CSS after ""bar" "baz" ": expected expression (e.g. 1px, bold), was "!"},
|
71
|
-
'$foo: "bar" "baz" $' => %Q{Invalid CSS after ""bar" "baz" ": expected expression (e.g. 1px, bold), was "$"},
|
85
|
+
'$foo: "bar" "baz" $' => %Q{Invalid CSS after ""bar" "baz" ": expected expression (e.g. 1px, bold), was "$"}, #'
|
72
86
|
"=foo\n :color red\n.bar\n +bang" => "Undefined mixin 'bang'.",
|
73
87
|
"=foo\n :color red\n.bar\n +bang_bop" => "Undefined mixin 'bang_bop'.",
|
74
88
|
"=foo\n :color red\n.bar\n +bang-bop" => "Undefined mixin 'bang-bop'.",
|
75
|
-
".
|
76
|
-
"=foo\n :color red\n.bar\n +foo\n :color red" => "Illegal nesting: Nothing may be nested beneath mixin directives.",
|
89
|
+
".foo\n =foo\n :color red\n.bar\n +foo" => "Undefined mixin 'foo'.",
|
77
90
|
" a\n b: c" => ["Indenting at the beginning of the document is illegal.", 1],
|
78
91
|
" \n \n\t\n a\n b: c" => ["Indenting at the beginning of the document is illegal.", 4],
|
79
92
|
"a\n b: c\n b: c" => ["Inconsistent indentation: 1 space was used for indentation, but the rest of the document was indented using 2 spaces.", 3],
|
@@ -89,12 +102,12 @@ MSG
|
|
89
102
|
"=a(,)" => 'Invalid CSS after "(": expected variable (e.g. $foo), was ",)"',
|
90
103
|
"=a($)" => 'Invalid CSS after "(": expected variable (e.g. $foo), was "$)"',
|
91
104
|
"=a($foo bar)" => 'Invalid CSS after "($foo ": expected ")", was "bar)"',
|
92
|
-
"=foo\n bar: baz\n+foo" => ["Properties are only allowed within rules, directives, or other properties.", 2],
|
105
|
+
"=foo\n bar: baz\n+foo" => ["Properties are only allowed within rules, directives, mixin includes, or other properties.", 2],
|
93
106
|
"a-\#{$b\n c: d" => ['Invalid CSS after "a-#{$b": expected "}", was ""', 1],
|
94
107
|
"=a($b: 1, $c)" => "Required argument $c must come before any optional arguments.",
|
95
108
|
"=a($b: 1)\n a: $b\ndiv\n +a(1,2)" => "Mixin a takes 1 argument but 2 were passed.",
|
96
|
-
"=a($b: 1)\n a: $b\ndiv\n +a(1,$c: 3)" => "Mixin a doesn't have an argument named $c",
|
97
|
-
"=a($b)\n a: $b\ndiv\n +a" => "Mixin a is missing
|
109
|
+
"=a($b: 1)\n a: $b\ndiv\n +a(1,$c: 3)" => "Mixin a doesn't have an argument named $c.",
|
110
|
+
"=a($b)\n a: $b\ndiv\n +a" => "Mixin a is missing argument $b.",
|
98
111
|
"@function foo()\n 1 + 2" => "Functions can only contain variable declarations and control directives.",
|
99
112
|
"@function foo()\n foo: bar" => "Functions can only contain variable declarations and control directives.",
|
100
113
|
"@function foo()\n foo: bar\n @return 3" => ["Functions can only contain variable declarations and control directives.", 2],
|
@@ -105,9 +118,10 @@ MSG
|
|
105
118
|
"@function foo($)\n @return 1" => ['Invalid CSS after "(": expected variable (e.g. $foo), was "$)"', 1],
|
106
119
|
"@function foo()\n @return" => 'Invalid @return: expected expression.',
|
107
120
|
"@function foo()\n @return 1\n $var: val" => 'Illegal nesting: Nothing may be nested beneath return directives.',
|
108
|
-
"
|
109
|
-
"@function foo(
|
110
|
-
"@function foo()\n @return 1\na\n b: foo(
|
121
|
+
"@function foo($a)\n @return 1\na\n b: foo()" => 'Function foo is missing argument $a.',
|
122
|
+
"@function foo()\n @return 1\na\n b: foo(2)" => 'Function foo takes 0 arguments but 1 was passed.',
|
123
|
+
"@function foo()\n @return 1\na\n b: foo($a: 1)" => "Function foo doesn't have an argument named $a.",
|
124
|
+
"@function foo()\n @return 1\na\n b: foo($a: 1, $b: 2)" => "Function foo doesn't have the following arguments: $a, $b.",
|
111
125
|
"@return 1" => '@return may only be used within a function.',
|
112
126
|
"@if true\n @return 1" => '@return may only be used within a function.',
|
113
127
|
"@mixin foo\n @return 1\n@include foo" => ['@return may only be used within a function.', 2],
|
@@ -121,7 +135,7 @@ MSG
|
|
121
135
|
'@for $a from "foo" to 1' => '"foo" is not an integer.',
|
122
136
|
'@for $a from 1 to "2"' => '"2" is not an integer.',
|
123
137
|
'@for $a from 1 to "foo"' => '"foo" is not an integer.',
|
124
|
-
'@for $a from 1 to 1.232323' => '1.
|
138
|
+
'@for $a from 1 to 1.232323' => '1.23232 is not an integer.',
|
125
139
|
'@for $a from 1px to 3em' => "Incompatible units: 'em' and 'px'.",
|
126
140
|
'@if' => "Invalid if directive '@if': expected expression.",
|
127
141
|
'@while' => "Invalid while directive '@while': expected expression.",
|
@@ -133,22 +147,30 @@ MSG
|
|
133
147
|
'+foo(1 + 1: 2)' => 'Invalid CSS after "(1 + 1": expected comma, was ": 2)"',
|
134
148
|
'+foo($var: )' => 'Invalid CSS after "($var: ": expected mixin argument, was ")"',
|
135
149
|
'+foo($var: a, $var: b)' => 'Keyword argument "$var" passed more than once',
|
136
|
-
'+foo($var-var: a, $var_var: b)' => 'Keyword argument "$
|
137
|
-
'+foo($var_var: a, $var-var: b)' => 'Keyword argument "$
|
150
|
+
'+foo($var-var: a, $var_var: b)' => 'Keyword argument "$var_var" passed more than once',
|
151
|
+
'+foo($var_var: a, $var-var: b)' => 'Keyword argument "$var-var" passed more than once',
|
138
152
|
"a\n b: foo(1 + 1: 2)" => 'Invalid CSS after "foo(1 + 1": expected comma, was ": 2)"',
|
139
153
|
"a\n b: foo($var: )" => 'Invalid CSS after "foo($var: ": expected function argument, was ")"',
|
140
154
|
"a\n b: foo($var: a, $var: b)" => 'Keyword argument "$var" passed more than once',
|
141
|
-
"a\n b: foo($var-var: a, $var_var: b)" => 'Keyword argument "$
|
142
|
-
"a\n b: foo($var_var: a, $var-var: b)" => 'Keyword argument "$
|
155
|
+
"a\n b: foo($var-var: a, $var_var: b)" => 'Keyword argument "$var_var" passed more than once',
|
156
|
+
"a\n b: foo($var_var: a, $var-var: b)" => 'Keyword argument "$var-var" passed more than once',
|
143
157
|
"@if foo\n @extend .bar" => ["Extend directives may only be used within rules.", 2],
|
144
158
|
"$var: true\n@while $var\n @extend .bar\n $var: false" => ["Extend directives may only be used within rules.", 3],
|
145
159
|
"@for $i from 0 to 1\n @extend .bar" => ["Extend directives may only be used within rules.", 2],
|
146
160
|
"@mixin foo\n @extend .bar\n@include foo" => ["Extend directives may only be used within rules.", 2],
|
161
|
+
"foo %\n a: b" => ['Invalid CSS after "foo %": expected placeholder name, was ""', 1],
|
162
|
+
"=foo\n @content error" => "Invalid content directive. Trailing characters found: \"error\".",
|
163
|
+
"=foo\n @content\n b: c" => "Illegal nesting: Nothing may be nested beneath @content directives.",
|
164
|
+
"@content" => '@content may only be used within a mixin.',
|
165
|
+
"=simple\n .simple\n color: red\n+simple\n color: blue" => ['Mixin "simple" does not accept a content block.', 4],
|
166
|
+
"@import \"foo\" // bar" => "Invalid CSS after \"\"foo\" \": expected media query list, was \"// bar\"",
|
167
|
+
"@at-root\n a: b" => "Properties are only allowed within rules, directives, mixin includes, or other properties.",
|
147
168
|
|
148
169
|
# Regression tests
|
149
170
|
"a\n b:\n c\n d" => ["Illegal nesting: Only properties may be nested beneath properties.", 3],
|
150
171
|
"& foo\n bar: baz\n blat: bang" => ["Base-level rules cannot contain the parent-selector-referencing character '&'.", 1],
|
151
172
|
"a\n b: c\n& foo\n bar: baz\n blat: bang" => ["Base-level rules cannot contain the parent-selector-referencing character '&'.", 3],
|
173
|
+
"@" => "Invalid directive: '@'.",
|
152
174
|
}
|
153
175
|
|
154
176
|
def teardown
|
@@ -208,7 +230,35 @@ MSG
|
|
208
230
|
assert_equal("p {\n a: b; }\n p q {\n c: d; }\n",
|
209
231
|
render("p\n\ta: b\n\tq\n\t\tc: d\n"))
|
210
232
|
end
|
211
|
-
|
233
|
+
|
234
|
+
def test_import_same_name_different_ext
|
235
|
+
assert_raise_message Sass::SyntaxError, <<ERROR do
|
236
|
+
It's not clear which file to import for '@import "same_name_different_ext"'.
|
237
|
+
Candidates:
|
238
|
+
same_name_different_ext.sass
|
239
|
+
same_name_different_ext.scss
|
240
|
+
Please delete or rename all but one of these files.
|
241
|
+
ERROR
|
242
|
+
options = {:load_paths => [File.dirname(__FILE__) + '/templates/']}
|
243
|
+
munge_filename options
|
244
|
+
Sass::Engine.new("@import 'same_name_different_ext'", options).render
|
245
|
+
end
|
246
|
+
end
|
247
|
+
|
248
|
+
def test_import_same_name_different_partiality
|
249
|
+
assert_raise_message Sass::SyntaxError, <<ERROR do
|
250
|
+
It's not clear which file to import for '@import "same_name_different_partiality"'.
|
251
|
+
Candidates:
|
252
|
+
_same_name_different_partiality.scss
|
253
|
+
same_name_different_partiality.scss
|
254
|
+
Please delete or rename all but one of these files.
|
255
|
+
ERROR
|
256
|
+
options = {:load_paths => [File.dirname(__FILE__) + '/templates/']}
|
257
|
+
munge_filename options
|
258
|
+
Sass::Engine.new("@import 'same_name_different_partiality'", options).render
|
259
|
+
end
|
260
|
+
end
|
261
|
+
|
212
262
|
EXCEPTION_MAP.each do |key, value|
|
213
263
|
define_method("test_exception (#{key.inspect})") do
|
214
264
|
line = 10
|
@@ -310,6 +360,23 @@ SASS
|
|
310
360
|
end
|
311
361
|
end
|
312
362
|
|
363
|
+
def test_selector_tracing
|
364
|
+
actual_css = render(<<-SCSS, :syntax => :scss, :trace_selectors => true)
|
365
|
+
@mixin mixed {
|
366
|
+
.mixed { color: red; }
|
367
|
+
}
|
368
|
+
.context {
|
369
|
+
@include mixed;
|
370
|
+
}
|
371
|
+
SCSS
|
372
|
+
assert_equal(<<CSS,actual_css)
|
373
|
+
/* on line 2 of test_selector_tracing_inline.scss, in `mixed'
|
374
|
+
from line 5 of test_selector_tracing_inline.scss */
|
375
|
+
.context .mixed {
|
376
|
+
color: red; }
|
377
|
+
CSS
|
378
|
+
end
|
379
|
+
|
313
380
|
def test_mixin_exception
|
314
381
|
render(<<SASS)
|
315
382
|
=error-mixin($a)
|
@@ -400,61 +467,59 @@ SASS
|
|
400
467
|
assert_hash_has(err.sass_backtrace[4], :filename => nil, :mixin => nil, :line => 1)
|
401
468
|
end
|
402
469
|
|
403
|
-
def
|
404
|
-
|
405
|
-
|
406
|
-
|
407
|
-
|
408
|
-
|
409
|
-
|
410
|
-
|
411
|
-
|
412
|
-
|
413
|
-
|
470
|
+
def test_recursive_mixin
|
471
|
+
assert_equal <<CSS, render(<<SASS)
|
472
|
+
.foo .bar .baz {
|
473
|
+
color: blue; }
|
474
|
+
.foo .bar .qux {
|
475
|
+
color: red; }
|
476
|
+
.foo .zap {
|
477
|
+
color: green; }
|
478
|
+
CSS
|
479
|
+
@mixin map-to-rule($map-or-color)
|
480
|
+
@if type-of($map-or-color) == map
|
481
|
+
@each $key, $value in $map-or-color
|
482
|
+
.\#{$key}
|
483
|
+
@include map-to-rule($value)
|
484
|
+
@else
|
485
|
+
color: $map-or-color
|
414
486
|
|
415
|
-
|
416
|
-
render <<SASS
|
417
|
-
@mixin foo
|
418
|
-
@include bar
|
419
|
-
@mixin bar
|
420
|
-
@include foo
|
421
|
-
@include foo
|
487
|
+
@include map-to-rule((foo: (bar: (baz: blue, qux: red), zap: green)))
|
422
488
|
SASS
|
423
|
-
assert(false, "Exception not raised")
|
424
|
-
rescue Sass::SyntaxError => err
|
425
|
-
assert_equal(<<MESSAGE.rstrip, err.message)
|
426
|
-
An @include loop has been found:
|
427
|
-
foo includes bar
|
428
|
-
bar includes foo
|
429
|
-
MESSAGE
|
430
|
-
assert_hash_has(err.sass_backtrace[0], :mixin => "bar", :line => 4)
|
431
|
-
assert_hash_has(err.sass_backtrace[1], :mixin => "foo", :line => 2)
|
432
489
|
end
|
433
490
|
|
434
|
-
def
|
435
|
-
|
436
|
-
@
|
437
|
-
|
491
|
+
def test_double_import_loop_exception
|
492
|
+
importer = MockImporter.new
|
493
|
+
importer.add_import("foo", "@import 'bar'")
|
494
|
+
importer.add_import("bar", "@import 'foo'")
|
438
495
|
|
439
|
-
@
|
440
|
-
|
496
|
+
engine = Sass::Engine.new('@import "foo"', :filename => filename_for_test,
|
497
|
+
:load_paths => [importer], :importer => importer)
|
441
498
|
|
442
|
-
|
443
|
-
|
499
|
+
assert_raise_message(Sass::SyntaxError, <<ERR.rstrip) {engine.render}
|
500
|
+
An @import loop has been found:
|
501
|
+
#{filename_for_test} imports foo
|
502
|
+
foo imports bar
|
503
|
+
bar imports foo
|
504
|
+
ERR
|
505
|
+
end
|
444
506
|
|
445
|
-
|
446
|
-
|
447
|
-
|
448
|
-
|
449
|
-
|
450
|
-
|
451
|
-
foo
|
452
|
-
|
453
|
-
|
454
|
-
|
455
|
-
|
456
|
-
|
457
|
-
|
507
|
+
def test_deep_import_loop_exception
|
508
|
+
importer = MockImporter.new
|
509
|
+
importer.add_import("foo", "@import 'bar'")
|
510
|
+
importer.add_import("bar", "@import 'baz'")
|
511
|
+
importer.add_import("baz", "@import 'foo'")
|
512
|
+
|
513
|
+
engine = Sass::Engine.new('@import "foo"', :filename => filename_for_test,
|
514
|
+
:load_paths => [importer], :importer => importer)
|
515
|
+
|
516
|
+
assert_raise_message(Sass::SyntaxError, <<ERR.rstrip) {engine.render}
|
517
|
+
An @import loop has been found:
|
518
|
+
#{filename_for_test} imports foo
|
519
|
+
foo imports bar
|
520
|
+
bar imports baz
|
521
|
+
baz imports foo
|
522
|
+
ERR
|
458
523
|
end
|
459
524
|
|
460
525
|
def test_exception_css_with_offset
|
@@ -528,7 +593,7 @@ SASS
|
|
528
593
|
rescue Sass::SyntaxError => e
|
529
594
|
assert_equal(<<CSS, Sass::SyntaxError.exception_to_css(e, opts).split("\n")[0..11].join("\n"))
|
530
595
|
/*
|
531
|
-
Syntax error: Properties are only allowed within rules, directives, or other properties.
|
596
|
+
Syntax error: Properties are only allowed within rules, directives, mixin includes, or other properties.
|
532
597
|
on line 4 of test_cssize_exception_css_inline.sass
|
533
598
|
|
534
599
|
1: .filler
|
@@ -552,11 +617,29 @@ CSS
|
|
552
617
|
render("@import \"http://fonts.googleapis.com/css?family=Droid+Sans\""))
|
553
618
|
end
|
554
619
|
|
555
|
-
def
|
556
|
-
assert_equal("@import url(
|
557
|
-
render("
|
558
|
-
|
559
|
-
|
620
|
+
def test_protocol_relative_import
|
621
|
+
assert_equal("@import url(//fonts.googleapis.com/css?family=Droid+Sans);\n",
|
622
|
+
render("@import \"//fonts.googleapis.com/css?family=Droid+Sans\""))
|
623
|
+
end
|
624
|
+
|
625
|
+
def test_import_with_interpolation
|
626
|
+
assert_equal(<<CSS, render(<<SASS))
|
627
|
+
@import url("http://fonts.googleapis.com/css?family=Droid+Sans");
|
628
|
+
CSS
|
629
|
+
$family: unquote("Droid+Sans")
|
630
|
+
@import url("http://fonts.googleapis.com/css?family=\#{$family}")
|
631
|
+
SASS
|
632
|
+
end
|
633
|
+
|
634
|
+
def test_import_with_dynamic_media_query
|
635
|
+
assert_equal(<<CSS, render(<<SASS))
|
636
|
+
@import "foo" print and (-webkit-min-device-pixel-ratio-foo: 25);
|
637
|
+
CSS
|
638
|
+
$media: print
|
639
|
+
$key: -webkit-min-device-pixel-ratio
|
640
|
+
$value: 20
|
641
|
+
@import "foo" \#{$media} and ($key + "-foo": $value + 5)
|
642
|
+
SASS
|
560
643
|
end
|
561
644
|
|
562
645
|
def test_url_import
|
@@ -579,12 +662,31 @@ CSS
|
|
579
662
|
assert File.exists?(sassc_file)
|
580
663
|
end
|
581
664
|
|
665
|
+
def test_import_from_global_load_paths
|
666
|
+
importer = MockImporter.new
|
667
|
+
importer.add_import("imported", "div{color:red}")
|
668
|
+
Sass.load_paths << importer
|
669
|
+
|
670
|
+
assert_equal "div {\n color: red; }\n", Sass::Engine.new('@import "imported"', :importer => importer).render
|
671
|
+
ensure
|
672
|
+
Sass.load_paths.clear
|
673
|
+
end
|
674
|
+
|
675
|
+
def test_nonexistent_import
|
676
|
+
assert_raise_message(Sass::SyntaxError, <<ERR.rstrip) do
|
677
|
+
File to import not found or unreadable: nonexistent.sass.
|
678
|
+
Load path: #{Dir.pwd}
|
679
|
+
ERR
|
680
|
+
render("@import nonexistent.sass")
|
681
|
+
end
|
682
|
+
end
|
683
|
+
|
582
684
|
def test_nonexistent_extensionless_import
|
583
685
|
assert_raise_message(Sass::SyntaxError, <<ERR.rstrip) do
|
584
686
|
File to import not found or unreadable: nonexistent.
|
585
|
-
Load path: .
|
687
|
+
Load path: #{Dir.pwd}
|
586
688
|
ERR
|
587
|
-
|
689
|
+
render("@import nonexistent")
|
588
690
|
end
|
589
691
|
end
|
590
692
|
|
@@ -616,24 +718,6 @@ CSS
|
|
616
718
|
SASS
|
617
719
|
end
|
618
720
|
|
619
|
-
def test_nested_import_with_toplevel_constructs
|
620
|
-
Sass::Engine.new(".foo\n @import importee", :load_paths => [File.dirname(__FILE__) + '/templates/']).render
|
621
|
-
rescue Sass::SyntaxError => err
|
622
|
-
assert_equal(3, err.sass_line)
|
623
|
-
assert_match(/(\/|^)importee\.sass$/, err.sass_filename)
|
624
|
-
|
625
|
-
assert_hash_has(err.sass_backtrace.first,
|
626
|
-
:filename => err.sass_filename, :line => err.sass_line)
|
627
|
-
|
628
|
-
assert_nil(err.sass_backtrace[1][:filename])
|
629
|
-
assert_equal(2, err.sass_backtrace[1][:line])
|
630
|
-
|
631
|
-
assert_match(/(\/|^)importee\.sass:3$/, err.backtrace.first)
|
632
|
-
assert_equal("(sass):2", err.backtrace[1])
|
633
|
-
else
|
634
|
-
assert(false, "Exception not raised for importing mixins nested")
|
635
|
-
end
|
636
|
-
|
637
721
|
def test_units
|
638
722
|
renders_correctly "units"
|
639
723
|
end
|
@@ -906,7 +990,7 @@ SASS
|
|
906
990
|
|
907
991
|
def test_debug_info_without_filename
|
908
992
|
assert_equal(<<CSS, Sass::Engine.new(<<SASS, :debug_info => true).render)
|
909
|
-
@media -sass-debug-info{filename{
|
993
|
+
@media -sass-debug-info{filename{}line{font-family:\\000031}}
|
910
994
|
foo {
|
911
995
|
a: b; }
|
912
996
|
CSS
|
@@ -937,6 +1021,23 @@ foo
|
|
937
1021
|
SASS
|
938
1022
|
end
|
939
1023
|
|
1024
|
+
def test_debug_info_in_keyframes
|
1025
|
+
assert_equal(<<CSS, render(<<SASS, :debug_info => true))
|
1026
|
+
@-webkit-keyframes warm {
|
1027
|
+
from {
|
1028
|
+
color: black; }
|
1029
|
+
|
1030
|
+
to {
|
1031
|
+
color: red; } }
|
1032
|
+
CSS
|
1033
|
+
@-webkit-keyframes warm
|
1034
|
+
from
|
1035
|
+
color: black
|
1036
|
+
to
|
1037
|
+
color: red
|
1038
|
+
SASS
|
1039
|
+
end
|
1040
|
+
|
940
1041
|
def test_empty_first_line
|
941
1042
|
assert_equal("#a {\n b: c; }\n", render("#a\n\n b: c"))
|
942
1043
|
end
|
@@ -978,6 +1079,7 @@ SASS
|
|
978
1079
|
def test_guarded_assign
|
979
1080
|
assert_equal("foo {\n a: b; }\n", render(%Q{$foo: b\n$foo: c !default\nfoo\n a: $foo}))
|
980
1081
|
assert_equal("foo {\n a: b; }\n", render(%Q{$foo: b !default\nfoo\n a: $foo}))
|
1082
|
+
assert_equal("foo {\n a: b; }\n", render(%Q{$foo: null\n$foo: b !default\nfoo\n a: $foo}))
|
981
1083
|
end
|
982
1084
|
|
983
1085
|
def test_mixins
|
@@ -1063,6 +1165,35 @@ two
|
|
1063
1165
|
+foo(#fff, 2px)
|
1064
1166
|
three
|
1065
1167
|
+foo(#fff, 2px, 3px)
|
1168
|
+
SASS
|
1169
|
+
assert_equal(<<CSS, render(<<SASS))
|
1170
|
+
one {
|
1171
|
+
color: white;
|
1172
|
+
padding: 1px;
|
1173
|
+
margin: 4px; }
|
1174
|
+
|
1175
|
+
two {
|
1176
|
+
color: white;
|
1177
|
+
padding: 2px;
|
1178
|
+
margin: 5px; }
|
1179
|
+
|
1180
|
+
three {
|
1181
|
+
color: white;
|
1182
|
+
padding: 2px;
|
1183
|
+
margin: 3px; }
|
1184
|
+
CSS
|
1185
|
+
$a: 5px
|
1186
|
+
=foo($a, $b: 1px, $c: null)
|
1187
|
+
$c: 3px + $b !default
|
1188
|
+
color: $a
|
1189
|
+
padding: $b
|
1190
|
+
margin: $c
|
1191
|
+
one
|
1192
|
+
+foo(#fff)
|
1193
|
+
two
|
1194
|
+
+foo(#fff, 2px)
|
1195
|
+
three
|
1196
|
+
+foo(#fff, 2px, 3px)
|
1066
1197
|
SASS
|
1067
1198
|
end
|
1068
1199
|
|
@@ -1149,6 +1280,58 @@ bar
|
|
1149
1280
|
SASS
|
1150
1281
|
end
|
1151
1282
|
|
1283
|
+
def test_function_with_missing_argument
|
1284
|
+
render(<<SASS)
|
1285
|
+
@function plus($var1, $var2)
|
1286
|
+
@return $var1 + $var2
|
1287
|
+
|
1288
|
+
bar
|
1289
|
+
a: plus($var2: bar)
|
1290
|
+
SASS
|
1291
|
+
flunk("Expected exception")
|
1292
|
+
rescue Sass::SyntaxError => e
|
1293
|
+
assert_equal("Function plus is missing argument $var1.", e.message)
|
1294
|
+
end
|
1295
|
+
|
1296
|
+
def test_function_with_extra_argument
|
1297
|
+
render(<<SASS)
|
1298
|
+
@function plus($var1, $var2)
|
1299
|
+
@return $var1 + $var2
|
1300
|
+
|
1301
|
+
bar
|
1302
|
+
a: plus($var1: foo, $var2: bar, $var3: baz)
|
1303
|
+
SASS
|
1304
|
+
flunk("Expected exception")
|
1305
|
+
rescue Sass::SyntaxError => e
|
1306
|
+
assert_equal("Function plus doesn't have an argument named $var3.", e.message)
|
1307
|
+
end
|
1308
|
+
|
1309
|
+
def test_function_with_positional_and_keyword_argument
|
1310
|
+
render(<<SASS)
|
1311
|
+
@function plus($var1, $var2)
|
1312
|
+
@return $var1 + $var2
|
1313
|
+
|
1314
|
+
bar
|
1315
|
+
a: plus(foo, bar, $var2: baz)
|
1316
|
+
SASS
|
1317
|
+
flunk("Expected exception")
|
1318
|
+
rescue Sass::SyntaxError => e
|
1319
|
+
assert_equal("Function plus was passed argument $var2 both by position and by name.", e.message)
|
1320
|
+
end
|
1321
|
+
|
1322
|
+
def test_function_with_keyword_before_positional_argument
|
1323
|
+
render(<<SASS)
|
1324
|
+
@function plus($var1, $var2)
|
1325
|
+
@return $var1 + $var2
|
1326
|
+
|
1327
|
+
bar
|
1328
|
+
a: plus($var2: foo, bar)
|
1329
|
+
SASS
|
1330
|
+
flunk("Expected exception")
|
1331
|
+
rescue Sass::SyntaxError => e
|
1332
|
+
assert_equal("Positional arguments must come before keyword arguments.", e.message)
|
1333
|
+
end
|
1334
|
+
|
1152
1335
|
def test_function_with_if
|
1153
1336
|
assert_equal(<<CSS, render(<<SASS))
|
1154
1337
|
bar {
|
@@ -1181,6 +1364,56 @@ bar
|
|
1181
1364
|
SASS
|
1182
1365
|
end
|
1183
1366
|
|
1367
|
+
def test_user_defined_function_variable_scope
|
1368
|
+
render(<<SASS)
|
1369
|
+
bar
|
1370
|
+
-no-op: set-a-variable(variable, 5)
|
1371
|
+
a: $variable
|
1372
|
+
SASS
|
1373
|
+
flunk("Exception not raised for test_user_defined_function_variable_scope")
|
1374
|
+
rescue Sass::SyntaxError => e
|
1375
|
+
assert_equal('Undefined variable: "$variable".', e.message)
|
1376
|
+
end
|
1377
|
+
|
1378
|
+
def test_user_defined_function_can_change_global_variable
|
1379
|
+
assert_equal(<<CSS, render(<<SASS))
|
1380
|
+
bar {
|
1381
|
+
a: 5; }
|
1382
|
+
CSS
|
1383
|
+
$variable: 0
|
1384
|
+
bar
|
1385
|
+
$local: 10
|
1386
|
+
-no-op: set-a-variable(variable, 5)
|
1387
|
+
a: $variable
|
1388
|
+
SASS
|
1389
|
+
end
|
1390
|
+
|
1391
|
+
def test_user_defined_function_cannot_read_local_variable
|
1392
|
+
assert_equal(<<CSS, render(<<SASS))
|
1393
|
+
bar {
|
1394
|
+
global: 0;
|
1395
|
+
local: undefined; }
|
1396
|
+
CSS
|
1397
|
+
$global: 0
|
1398
|
+
bar
|
1399
|
+
$local: 10
|
1400
|
+
global: get-a-variable(global)
|
1401
|
+
local: get-a-variable(local)
|
1402
|
+
SASS
|
1403
|
+
end
|
1404
|
+
|
1405
|
+
def test_control_directive_in_nested_property
|
1406
|
+
assert_equal(<<CSS, render(<<SASS))
|
1407
|
+
foo {
|
1408
|
+
a-b: c; }
|
1409
|
+
CSS
|
1410
|
+
foo
|
1411
|
+
a:
|
1412
|
+
@if true
|
1413
|
+
b: c
|
1414
|
+
SASS
|
1415
|
+
end
|
1416
|
+
|
1184
1417
|
def test_interpolation
|
1185
1418
|
assert_equal("a-1 {\n b-2-3: c-3; }\n", render(<<SASS))
|
1186
1419
|
$a: 1
|
@@ -1207,6 +1440,15 @@ SASS
|
|
1207
1440
|
def test_if_directive
|
1208
1441
|
assert_equal("a {\n b: 1; }\n", render(<<SASS))
|
1209
1442
|
$var: true
|
1443
|
+
a
|
1444
|
+
@if $var
|
1445
|
+
b: 1
|
1446
|
+
@if not $var
|
1447
|
+
b: 2
|
1448
|
+
SASS
|
1449
|
+
|
1450
|
+
assert_equal("a {\n b: 2; }\n", render(<<SASS))
|
1451
|
+
$var: null
|
1210
1452
|
a
|
1211
1453
|
@if $var
|
1212
1454
|
b: 1
|
@@ -1273,7 +1515,7 @@ $a: 5
|
|
1273
1515
|
@while $a != 0
|
1274
1516
|
a-\#{$a}
|
1275
1517
|
blooble: gloop
|
1276
|
-
$a: $a - 1
|
1518
|
+
$a: $a - 1 !global
|
1277
1519
|
SASS
|
1278
1520
|
end
|
1279
1521
|
|
@@ -1340,14 +1582,35 @@ a
|
|
1340
1582
|
SASS
|
1341
1583
|
end
|
1342
1584
|
|
1585
|
+
def test_destructuring_each
|
1586
|
+
assert_equal <<CSS, render(<<SCSS)
|
1587
|
+
a {
|
1588
|
+
foo: 1px;
|
1589
|
+
bar: 2px;
|
1590
|
+
baz: 3px; }
|
1591
|
+
|
1592
|
+
c {
|
1593
|
+
foo: "Value is bar";
|
1594
|
+
bar: "Value is baz";
|
1595
|
+
bang: "Value is "; }
|
1596
|
+
CSS
|
1597
|
+
a
|
1598
|
+
@each $name, $number in (foo: 1px, bar: 2px, baz: 3px)
|
1599
|
+
\#{$name}: $number
|
1600
|
+
c
|
1601
|
+
@each $key, $value in (foo bar) (bar, baz) bang
|
1602
|
+
\#{$key}: "Value is \#{$value}"
|
1603
|
+
SCSS
|
1604
|
+
end
|
1605
|
+
|
1343
1606
|
def test_variable_reassignment
|
1344
1607
|
assert_equal(<<CSS, render(<<SASS))
|
1345
1608
|
a {
|
1346
1609
|
b: 1;
|
1347
1610
|
c: 2; }
|
1348
1611
|
CSS
|
1349
|
-
$a: 1
|
1350
1612
|
a
|
1613
|
+
$a: 1
|
1351
1614
|
b: $a
|
1352
1615
|
$a: 2
|
1353
1616
|
c: $a
|
@@ -1355,7 +1618,7 @@ SASS
|
|
1355
1618
|
end
|
1356
1619
|
|
1357
1620
|
def test_variable_scope
|
1358
|
-
assert_equal(<<CSS, render(<<SASS))
|
1621
|
+
silence_warnings {assert_equal(<<CSS, render(<<SASS))}
|
1359
1622
|
a {
|
1360
1623
|
b-1: c;
|
1361
1624
|
b-2: c;
|
@@ -1381,9 +1644,6 @@ SASS
|
|
1381
1644
|
|
1382
1645
|
def test_hyphen_underscore_insensitive_variables
|
1383
1646
|
assert_equal(<<CSS, render(<<SASS))
|
1384
|
-
a {
|
1385
|
-
b: c; }
|
1386
|
-
|
1387
1647
|
d {
|
1388
1648
|
e: 13;
|
1389
1649
|
f: foobar; }
|
@@ -1391,10 +1651,8 @@ CSS
|
|
1391
1651
|
$var-hyphen: 12
|
1392
1652
|
$var_under: foo
|
1393
1653
|
|
1394
|
-
|
1395
|
-
|
1396
|
-
$var-under: $var-under + bar
|
1397
|
-
b: c
|
1654
|
+
$var_hyphen: 1 + $var_hyphen
|
1655
|
+
$var-under: $var-under + bar
|
1398
1656
|
|
1399
1657
|
d
|
1400
1658
|
e: $var-hyphen
|
@@ -1537,7 +1795,7 @@ SASS
|
|
1537
1795
|
|
1538
1796
|
def test_loud_comment_in_compressed_mode
|
1539
1797
|
assert_equal <<CSS, render(<<SASS, :style => :compressed)
|
1540
|
-
foo{color:blue
|
1798
|
+
foo{color:blue;/*! foo
|
1541
1799
|
* bar
|
1542
1800
|
*/}
|
1543
1801
|
CSS
|
@@ -1548,31 +1806,12 @@ foo
|
|
1548
1806
|
*/
|
1549
1807
|
SASS
|
1550
1808
|
end
|
1551
|
-
def test_loud_comment_in_silent_comment
|
1552
|
-
assert_equal <<CSS, render(<<SASS, :style => :compressed)
|
1553
|
-
foo{color:blue;/* foo */
|
1554
|
-
/* bar */
|
1555
|
-
/* */
|
1556
|
-
/* bip */
|
1557
|
-
/* baz */}
|
1558
|
-
CSS
|
1559
|
-
foo
|
1560
|
-
color: blue
|
1561
|
-
//! foo
|
1562
|
-
//! bar
|
1563
|
-
//!
|
1564
|
-
bip
|
1565
|
-
baz
|
1566
|
-
SASS
|
1567
|
-
end
|
1568
1809
|
|
1569
1810
|
def test_loud_comment_is_evaluated
|
1570
1811
|
assert_equal <<CSS, render(<<SASS)
|
1571
|
-
|
1572
|
-
* Hue: 327.216deg */
|
1812
|
+
/*! Hue: 327.21649deg */
|
1573
1813
|
CSS
|
1574
|
-
/*!
|
1575
|
-
Hue: \#{hue(#f836a0)}
|
1814
|
+
/*! Hue: \#{hue(#f836a0)}
|
1576
1815
|
SASS
|
1577
1816
|
end
|
1578
1817
|
|
@@ -1627,6 +1866,26 @@ This selector doesn't have any properties and will not be rendered.
|
|
1627
1866
|
END
|
1628
1867
|
end
|
1629
1868
|
|
1869
|
+
def test_nonprinting_empty_property
|
1870
|
+
assert_equal(<<CSS, render(<<SASS))
|
1871
|
+
a {
|
1872
|
+
c: "";
|
1873
|
+
e: f; }
|
1874
|
+
CSS
|
1875
|
+
$null-value: null
|
1876
|
+
$empty-string: ''
|
1877
|
+
$empty-list: (null)
|
1878
|
+
a
|
1879
|
+
b: $null-value
|
1880
|
+
c: $empty-string
|
1881
|
+
d: $empty-list
|
1882
|
+
e: f
|
1883
|
+
|
1884
|
+
g
|
1885
|
+
h: null
|
1886
|
+
SASS
|
1887
|
+
end
|
1888
|
+
|
1630
1889
|
def test_root_level_pseudo_class_with_new_properties
|
1631
1890
|
assert_equal(<<CSS, render(<<SASS, :property_syntax => :new))
|
1632
1891
|
:focus {
|
@@ -1772,22 +2031,22 @@ SASS
|
|
1772
2031
|
|
1773
2032
|
def test_interpolation_doesnt_deep_unquote_strings
|
1774
2033
|
assert_equal(<<CSS, render(<<SASS))
|
1775
|
-
.foo
|
1776
|
-
a:
|
2034
|
+
.foo {
|
2035
|
+
a: "bar" "baz"; }
|
1777
2036
|
CSS
|
1778
|
-
.foo
|
1779
|
-
a:
|
2037
|
+
.foo
|
2038
|
+
a: \#{"bar" "baz"}
|
1780
2039
|
SASS
|
1781
2040
|
end
|
1782
2041
|
|
1783
2042
|
def test_warn_directive
|
1784
2043
|
expected_warning = <<EXPECTATION
|
1785
2044
|
WARNING: this is a warning
|
1786
|
-
|
2045
|
+
on line 4 of test_warn_directive_inline.sass
|
1787
2046
|
|
1788
2047
|
WARNING: this is a mixin warning
|
1789
|
-
|
1790
|
-
|
2048
|
+
on line 2 of test_warn_directive_inline.sass, in `foo'
|
2049
|
+
from line 7 of test_warn_directive_inline.sass
|
1791
2050
|
EXPECTATION
|
1792
2051
|
assert_warning expected_warning do
|
1793
2052
|
assert_equal <<CSS, render(<<SASS)
|
@@ -1817,15 +2076,15 @@ SASS
|
|
1817
2076
|
def test_warn_with_imports
|
1818
2077
|
expected_warning = <<WARN
|
1819
2078
|
WARNING: In the main file
|
1820
|
-
|
2079
|
+
on line 1 of #{File.dirname(__FILE__)}/templates/warn.sass
|
1821
2080
|
|
1822
2081
|
WARNING: Imported
|
1823
|
-
|
1824
|
-
|
2082
|
+
on line 1 of #{File.dirname(__FILE__)}/templates/warn_imported.sass
|
2083
|
+
from line 2 of #{File.dirname(__FILE__)}/templates/warn.sass
|
1825
2084
|
|
1826
2085
|
WARNING: In an imported mixin
|
1827
|
-
|
1828
|
-
|
2086
|
+
on line 4 of #{File.dirname(__FILE__)}/templates/warn_imported.sass, in `emits-a-warning'
|
2087
|
+
from line 3 of #{File.dirname(__FILE__)}/templates/warn.sass
|
1829
2088
|
WARN
|
1830
2089
|
assert_warning expected_warning do
|
1831
2090
|
renders_correctly "warn", :style => :compact, :load_paths => [File.dirname(__FILE__) + "/templates"]
|
@@ -1920,12 +2179,12 @@ SASS
|
|
1920
2179
|
|
1921
2180
|
def test_double_media_bubbling
|
1922
2181
|
assert_equal <<CSS, render(<<SASS)
|
1923
|
-
@media bar and
|
2182
|
+
@media bar and (a: b) {
|
1924
2183
|
.foo {
|
1925
2184
|
c: d; } }
|
1926
2185
|
CSS
|
1927
2186
|
@media bar
|
1928
|
-
@media
|
2187
|
+
@media (a: b)
|
1929
2188
|
.foo
|
1930
2189
|
c: d
|
1931
2190
|
SASS
|
@@ -1934,18 +2193,61 @@ SASS
|
|
1934
2193
|
@media bar {
|
1935
2194
|
.foo {
|
1936
2195
|
a: b; } }
|
1937
|
-
@media bar and
|
2196
|
+
@media bar and (a: b) {
|
1938
2197
|
.foo {
|
1939
2198
|
c: d; } }
|
1940
2199
|
CSS
|
1941
2200
|
.foo
|
1942
2201
|
@media bar
|
1943
2202
|
a: b
|
1944
|
-
@media
|
2203
|
+
@media (a: b)
|
1945
2204
|
c: d
|
1946
2205
|
SASS
|
1947
2206
|
end
|
1948
2207
|
|
2208
|
+
def test_double_media_bubbling_with_commas
|
2209
|
+
assert_equal <<CSS, render(<<SASS)
|
2210
|
+
@media (a: b) and (e: f), (c: d) and (e: f), (a: b) and (g: h), (c: d) and (g: h) {
|
2211
|
+
.foo {
|
2212
|
+
c: d; } }
|
2213
|
+
CSS
|
2214
|
+
@media (a: b), (c: d)
|
2215
|
+
@media (e: f), (g: h)
|
2216
|
+
.foo
|
2217
|
+
c: d
|
2218
|
+
SASS
|
2219
|
+
end
|
2220
|
+
|
2221
|
+
def test_double_media_bubbling_with_surrounding_rules
|
2222
|
+
assert_equal <<CSS, render(<<SASS)
|
2223
|
+
@media (min-width: 0) {
|
2224
|
+
a {
|
2225
|
+
a: a; }
|
2226
|
+
|
2227
|
+
b {
|
2228
|
+
before: b;
|
2229
|
+
after: b; } }
|
2230
|
+
@media (min-width: 0) and (max-width: 5000px) {
|
2231
|
+
b {
|
2232
|
+
x: x; } }
|
2233
|
+
|
2234
|
+
@media (min-width: 0) {
|
2235
|
+
c {
|
2236
|
+
c: c; } }
|
2237
|
+
CSS
|
2238
|
+
@media (min-width: 0)
|
2239
|
+
a
|
2240
|
+
a: a
|
2241
|
+
b
|
2242
|
+
before: b
|
2243
|
+
@media (max-width: 5000px)
|
2244
|
+
x: x
|
2245
|
+
after: b
|
2246
|
+
c
|
2247
|
+
c: c
|
2248
|
+
SASS
|
2249
|
+
end
|
2250
|
+
|
1949
2251
|
def test_rule_media_rule_bubbling
|
1950
2252
|
assert_equal <<CSS, render(<<SASS)
|
1951
2253
|
@media bar {
|
@@ -1972,9 +2274,10 @@ SASS
|
|
1972
2274
|
@media print {
|
1973
2275
|
.outside {
|
1974
2276
|
color: black; } }
|
1975
|
-
|
1976
|
-
|
1977
|
-
|
2277
|
+
@media print and (a: b) {
|
2278
|
+
.outside .inside {
|
2279
|
+
border: 1px solid black; } }
|
2280
|
+
|
1978
2281
|
.outside .middle {
|
1979
2282
|
display: block; }
|
1980
2283
|
CSS
|
@@ -1983,7 +2286,7 @@ CSS
|
|
1983
2286
|
@media print
|
1984
2287
|
color: black
|
1985
2288
|
.inside
|
1986
|
-
@media
|
2289
|
+
@media (a: b)
|
1987
2290
|
border: 1px solid black
|
1988
2291
|
background: blue
|
1989
2292
|
.middle
|
@@ -2006,8 +2309,277 @@ CSS
|
|
2006
2309
|
assert_equal css_str, render(sass_str)
|
2007
2310
|
end
|
2008
2311
|
|
2312
|
+
def test_eliminated_media_bubbling
|
2313
|
+
assert_equal <<CSS, render(<<SASS)
|
2314
|
+
@media screen {
|
2315
|
+
a: b; }
|
2316
|
+
CSS
|
2317
|
+
@media screen
|
2318
|
+
a: b
|
2319
|
+
@media print
|
2320
|
+
c: d
|
2321
|
+
SASS
|
2322
|
+
|
2323
|
+
assert_equal <<CSS, render(<<SASS)
|
2324
|
+
@media not print {
|
2325
|
+
a: b; }
|
2326
|
+
CSS
|
2327
|
+
@media not print
|
2328
|
+
a: b
|
2329
|
+
@media print
|
2330
|
+
c: d
|
2331
|
+
SASS
|
2332
|
+
|
2333
|
+
assert_equal <<CSS, render(<<SASS)
|
2334
|
+
@media not print {
|
2335
|
+
a: b; }
|
2336
|
+
CSS
|
2337
|
+
@media not print
|
2338
|
+
a: b
|
2339
|
+
@media not screen
|
2340
|
+
c: d
|
2341
|
+
SASS
|
2342
|
+
end
|
2343
|
+
|
2344
|
+
def test_non_eliminated_media_bubbling
|
2345
|
+
assert_equal <<CSS, render(<<SASS)
|
2346
|
+
@media screen {
|
2347
|
+
a: b; }
|
2348
|
+
@media screen and (a: b) {
|
2349
|
+
c: d; }
|
2350
|
+
CSS
|
2351
|
+
@media screen
|
2352
|
+
a: b
|
2353
|
+
@media screen and (a: b)
|
2354
|
+
c: d
|
2355
|
+
SASS
|
2356
|
+
|
2357
|
+
assert_equal <<CSS, render(<<SASS)
|
2358
|
+
@media not print {
|
2359
|
+
a: b; }
|
2360
|
+
@media screen {
|
2361
|
+
c: d; }
|
2362
|
+
CSS
|
2363
|
+
@media not print
|
2364
|
+
a: b
|
2365
|
+
@media screen
|
2366
|
+
c: d
|
2367
|
+
SASS
|
2368
|
+
|
2369
|
+
assert_equal <<CSS, render(<<SASS)
|
2370
|
+
@media only screen {
|
2371
|
+
a: b; }
|
2372
|
+
@media only screen and (a: b) {
|
2373
|
+
c: d; }
|
2374
|
+
CSS
|
2375
|
+
@media only screen
|
2376
|
+
a: b
|
2377
|
+
@media screen and (a: b)
|
2378
|
+
c: d
|
2379
|
+
SASS
|
2380
|
+
end
|
2381
|
+
|
2382
|
+
def test_directive_interpolation
|
2383
|
+
assert_equal <<CSS, render(<<SASS)
|
2384
|
+
@foo bar12 qux {
|
2385
|
+
a: b; }
|
2386
|
+
CSS
|
2387
|
+
$baz: 12
|
2388
|
+
@foo bar\#{$baz} qux
|
2389
|
+
a: b
|
2390
|
+
SASS
|
2391
|
+
end
|
2392
|
+
|
2393
|
+
def test_media_interpolation
|
2394
|
+
assert_equal <<CSS, render(<<SASS)
|
2395
|
+
@media bar12 {
|
2396
|
+
a: b; }
|
2397
|
+
CSS
|
2398
|
+
$baz: 12
|
2399
|
+
@media bar\#{$baz}
|
2400
|
+
a: b
|
2401
|
+
SASS
|
2402
|
+
end
|
2403
|
+
|
2404
|
+
def test_variables_in_media
|
2405
|
+
assert_equal <<CSS, render(<<SASS)
|
2406
|
+
@media screen and (-webkit-min-device-pixel-ratio-foo: 25), only print {
|
2407
|
+
a: b; }
|
2408
|
+
CSS
|
2409
|
+
$media1: screen
|
2410
|
+
$media2: print
|
2411
|
+
$var: -webkit-min-device-pixel-ratio
|
2412
|
+
$val: 20
|
2413
|
+
@media \#{$media1} and ($var + "-foo": $val + 5), only \#{$media2}
|
2414
|
+
a: b
|
2415
|
+
SASS
|
2416
|
+
end
|
2417
|
+
|
2418
|
+
def test_at_root
|
2419
|
+
assert_equal <<CSS, render(<<SASS)
|
2420
|
+
.bar {
|
2421
|
+
a: b; }
|
2422
|
+
CSS
|
2423
|
+
.foo
|
2424
|
+
@at-root
|
2425
|
+
.bar
|
2426
|
+
a: b
|
2427
|
+
SASS
|
2428
|
+
end
|
2429
|
+
|
2430
|
+
def test_at_root_with_selector
|
2431
|
+
assert_equal <<CSS, render(<<SASS)
|
2432
|
+
.bar {
|
2433
|
+
a: b; }
|
2434
|
+
CSS
|
2435
|
+
.foo
|
2436
|
+
@at-root .bar
|
2437
|
+
a: b
|
2438
|
+
SASS
|
2439
|
+
end
|
2440
|
+
|
2441
|
+
def test_at_root_with_query
|
2442
|
+
assert_equal <<CSS, render(<<SASS)
|
2443
|
+
.foo .bar {
|
2444
|
+
a: b; }
|
2445
|
+
CSS
|
2446
|
+
.foo
|
2447
|
+
@media screen
|
2448
|
+
@at-root (without: media)
|
2449
|
+
.bar
|
2450
|
+
a: b
|
2451
|
+
SASS
|
2452
|
+
end
|
2453
|
+
|
2454
|
+
def test_variable_assignment_with_global
|
2455
|
+
assert_no_warning {assert_equal(<<CSS, render(<<SASS))}
|
2456
|
+
.foo {
|
2457
|
+
a: x; }
|
2458
|
+
|
2459
|
+
.bar {
|
2460
|
+
b: x; }
|
2461
|
+
CSS
|
2462
|
+
$var: 1
|
2463
|
+
|
2464
|
+
.foo
|
2465
|
+
$var: x !global
|
2466
|
+
a: $var
|
2467
|
+
|
2468
|
+
.bar
|
2469
|
+
b: $var
|
2470
|
+
SASS
|
2471
|
+
end
|
2472
|
+
|
2009
2473
|
# Regression tests
|
2010
2474
|
|
2475
|
+
def test_list_separator_with_arg_list
|
2476
|
+
assert_equal(<<CSS, render(<<SASS))
|
2477
|
+
.test {
|
2478
|
+
separator: comma; }
|
2479
|
+
CSS
|
2480
|
+
@mixin arglist-test($args...)
|
2481
|
+
separator: list-separator($args)
|
2482
|
+
|
2483
|
+
.test
|
2484
|
+
@include arglist-test(this, is, comma, separated)
|
2485
|
+
SASS
|
2486
|
+
end
|
2487
|
+
|
2488
|
+
def test_parent_mixin_in_content_nested
|
2489
|
+
assert_equal(<<CSS, render(<<SASS))
|
2490
|
+
a {
|
2491
|
+
b: c; }
|
2492
|
+
CSS
|
2493
|
+
=foo
|
2494
|
+
@content
|
2495
|
+
|
2496
|
+
=bar
|
2497
|
+
+foo
|
2498
|
+
+foo
|
2499
|
+
a
|
2500
|
+
b: c
|
2501
|
+
|
2502
|
+
+bar
|
2503
|
+
SASS
|
2504
|
+
end
|
2505
|
+
|
2506
|
+
def test_supports_bubbles
|
2507
|
+
assert_equal <<CSS, render(<<SASS)
|
2508
|
+
parent {
|
2509
|
+
background: orange; }
|
2510
|
+
@supports (perspective: 10px) or (-moz-perspective: 10px) {
|
2511
|
+
parent child {
|
2512
|
+
background: blue; } }
|
2513
|
+
CSS
|
2514
|
+
parent
|
2515
|
+
background: orange
|
2516
|
+
@supports (perspective: 10px) or (-moz-perspective: 10px)
|
2517
|
+
child
|
2518
|
+
background: blue
|
2519
|
+
SASS
|
2520
|
+
end
|
2521
|
+
|
2522
|
+
def test_line_numbers_with_dos_line_endings
|
2523
|
+
assert_equal <<CSS, render(<<SASS, :line_comments => true)
|
2524
|
+
/* line 5, test_line_numbers_with_dos_line_endings_inline.sass */
|
2525
|
+
.foo {
|
2526
|
+
a: b; }
|
2527
|
+
CSS
|
2528
|
+
\r
|
2529
|
+
\r
|
2530
|
+
\r
|
2531
|
+
\r
|
2532
|
+
.foo
|
2533
|
+
a: b
|
2534
|
+
SASS
|
2535
|
+
end
|
2536
|
+
|
2537
|
+
def test_variable_in_media_in_mixin
|
2538
|
+
assert_equal <<CSS, render(<<SASS)
|
2539
|
+
@media screen and (min-width: 10px) {
|
2540
|
+
body {
|
2541
|
+
background: red; } }
|
2542
|
+
@media screen and (min-width: 20px) {
|
2543
|
+
body {
|
2544
|
+
background: blue; } }
|
2545
|
+
CSS
|
2546
|
+
@mixin respond-to($width)
|
2547
|
+
@media screen and (min-width: $width)
|
2548
|
+
@content
|
2549
|
+
|
2550
|
+
body
|
2551
|
+
@include respond-to(10px)
|
2552
|
+
background: red
|
2553
|
+
@include respond-to(20px)
|
2554
|
+
background: blue
|
2555
|
+
SASS
|
2556
|
+
end
|
2557
|
+
|
2558
|
+
def test_interpolated_comment_in_mixin
|
2559
|
+
assert_equal <<CSS, render(<<SASS)
|
2560
|
+
/*! color: red */
|
2561
|
+
.foo {
|
2562
|
+
color: red; }
|
2563
|
+
|
2564
|
+
/*! color: blue */
|
2565
|
+
.foo {
|
2566
|
+
color: blue; }
|
2567
|
+
|
2568
|
+
/*! color: green */
|
2569
|
+
.foo {
|
2570
|
+
color: green; }
|
2571
|
+
CSS
|
2572
|
+
=foo($var)
|
2573
|
+
/*! color: \#{$var}
|
2574
|
+
.foo
|
2575
|
+
color: $var
|
2576
|
+
|
2577
|
+
+foo(red)
|
2578
|
+
+foo(blue)
|
2579
|
+
+foo(green)
|
2580
|
+
SASS
|
2581
|
+
end
|
2582
|
+
|
2011
2583
|
def test_parens_in_mixins
|
2012
2584
|
assert_equal(<<CSS, render(<<SASS))
|
2013
2585
|
.foo {
|
@@ -2148,6 +2720,16 @@ CSS
|
|
2148
2720
|
SASS
|
2149
2721
|
end
|
2150
2722
|
|
2723
|
+
def test_silent_comment_in_prop_val_after_important
|
2724
|
+
assert_equal(<<CSS, render(<<SASS))
|
2725
|
+
.advanced {
|
2726
|
+
display: none !important; }
|
2727
|
+
CSS
|
2728
|
+
.advanced
|
2729
|
+
display: none !important // yeah, yeah. it's not really a style anyway.
|
2730
|
+
SASS
|
2731
|
+
end
|
2732
|
+
|
2151
2733
|
def test_mixin_with_keyword_args
|
2152
2734
|
assert_equal <<CSS, render(<<SASS)
|
2153
2735
|
.mixed {
|
@@ -2271,15 +2853,6 @@ CSS
|
|
2271
2853
|
SASS
|
2272
2854
|
end
|
2273
2855
|
|
2274
|
-
def test_comment_interpolation_warning
|
2275
|
-
assert_warning(<<END) {render("/* \#{foo}")}
|
2276
|
-
WARNING:
|
2277
|
-
On line 1 of 'test_comment_interpolation_warning_inline.sass'
|
2278
|
-
Comments will evaluate the contents of interpolations (\#{ ... }) in Sass 3.2.
|
2279
|
-
Please escape the interpolation by adding a backslash before the hash sign.
|
2280
|
-
END
|
2281
|
-
end
|
2282
|
-
|
2283
2856
|
def test_loud_comment_interpolations_can_be_escaped
|
2284
2857
|
assert_equal <<CSS, render(<<SASS)
|
2285
2858
|
/* \#{foo} */
|
@@ -2287,12 +2860,44 @@ CSS
|
|
2287
2860
|
/* \\\#{foo}
|
2288
2861
|
SASS
|
2289
2862
|
assert_equal <<CSS, render(<<SASS)
|
2290
|
-
|
2863
|
+
/*! \#{foo} */
|
2291
2864
|
CSS
|
2292
2865
|
/*! \\\#{foo}
|
2293
2866
|
SASS
|
2294
2867
|
end
|
2295
2868
|
|
2869
|
+
def test_selector_compression
|
2870
|
+
assert_equal <<CSS, render(<<SASS, :style => :compressed)
|
2871
|
+
a>b,c+d,:-moz-any(e,f,g){h:i}
|
2872
|
+
CSS
|
2873
|
+
a > b, c + d, :-moz-any(e, f, g)
|
2874
|
+
h: i
|
2875
|
+
SASS
|
2876
|
+
end
|
2877
|
+
|
2878
|
+
def test_comment_like_selector
|
2879
|
+
assert_raise_message(Sass::SyntaxError, 'Invalid CSS after "/": expected identifier, was " foo"') {render(<<SASS)}
|
2880
|
+
/ foo
|
2881
|
+
a: b
|
2882
|
+
SASS
|
2883
|
+
end
|
2884
|
+
|
2885
|
+
def test_nested_empty_directive
|
2886
|
+
assert_equal <<CSS, render(<<SASS)
|
2887
|
+
@media screen {
|
2888
|
+
.foo {
|
2889
|
+
a: b; }
|
2890
|
+
|
2891
|
+
@unknown-directive; }
|
2892
|
+
CSS
|
2893
|
+
@media screen
|
2894
|
+
.foo
|
2895
|
+
a: b
|
2896
|
+
|
2897
|
+
@unknown-directive
|
2898
|
+
SASS
|
2899
|
+
end
|
2900
|
+
|
2296
2901
|
# Encodings
|
2297
2902
|
|
2298
2903
|
unless Sass::Util.ruby1_8?
|
@@ -2405,6 +3010,31 @@ CSS
|
|
2405
3010
|
a: b
|
2406
3011
|
SASS
|
2407
3012
|
end
|
3013
|
+
|
3014
|
+
# Encoding Regression Test
|
3015
|
+
|
3016
|
+
def test_multibyte_prop_name
|
3017
|
+
assert_equal(<<CSS, render(<<SASS))
|
3018
|
+
@charset "UTF-8";
|
3019
|
+
#bar {
|
3020
|
+
cölor: blue; }
|
3021
|
+
CSS
|
3022
|
+
#bar
|
3023
|
+
cölor: blue
|
3024
|
+
SASS
|
3025
|
+
end
|
3026
|
+
|
3027
|
+
def test_multibyte_and_interpolation
|
3028
|
+
assert_equal(<<CSS, render(<<SCSS, :syntax => :scss))
|
3029
|
+
#bar {
|
3030
|
+
background: a 0%; }
|
3031
|
+
CSS
|
3032
|
+
#bar {
|
3033
|
+
//
|
3034
|
+
background: \#{a} 0%;
|
3035
|
+
}
|
3036
|
+
SCSS
|
3037
|
+
end
|
2408
3038
|
end
|
2409
3039
|
|
2410
3040
|
def test_original_filename_set
|
@@ -2413,13 +3043,277 @@ SASS
|
|
2413
3043
|
|
2414
3044
|
original_filename = filename_for_test
|
2415
3045
|
engine = Sass::Engine.new('@import "imported"; div{color:blue}',
|
2416
|
-
:filename => original_filename, :load_paths => [importer], :syntax => :scss)
|
3046
|
+
:filename => original_filename, :load_paths => [importer], :syntax => :scss, :importer => importer)
|
2417
3047
|
engine.render
|
2418
3048
|
|
2419
3049
|
assert_equal original_filename, engine.options[:original_filename]
|
2420
3050
|
assert_equal original_filename, importer.engine("imported").options[:original_filename]
|
2421
3051
|
end
|
2422
3052
|
|
3053
|
+
def test_changing_precision
|
3054
|
+
old_precision = Sass::Script::Value::Number.precision
|
3055
|
+
begin
|
3056
|
+
Sass::Script::Value::Number.precision = 8
|
3057
|
+
assert_equal <<CSS, render(<<SASS)
|
3058
|
+
div {
|
3059
|
+
maximum: 1.00000001;
|
3060
|
+
too-much: 1.0; }
|
3061
|
+
CSS
|
3062
|
+
div
|
3063
|
+
maximum : 1.00000001
|
3064
|
+
too-much: 1.000000001
|
3065
|
+
SASS
|
3066
|
+
ensure
|
3067
|
+
Sass::Script::Value::Number.precision = old_precision
|
3068
|
+
end
|
3069
|
+
end
|
3070
|
+
|
3071
|
+
def test_content
|
3072
|
+
assert_equal <<CSS, render(<<SASS)
|
3073
|
+
.children {
|
3074
|
+
background-color: red;
|
3075
|
+
color: blue;
|
3076
|
+
border-color: red; }
|
3077
|
+
CSS
|
3078
|
+
$color: blue
|
3079
|
+
=context($class, $color: red)
|
3080
|
+
.\#{$class}
|
3081
|
+
background-color: $color
|
3082
|
+
@content
|
3083
|
+
border-color: $color
|
3084
|
+
+context(children)
|
3085
|
+
color: $color
|
3086
|
+
SASS
|
3087
|
+
end
|
3088
|
+
|
3089
|
+
def test_selector_in_content
|
3090
|
+
assert_equal <<CSS, render(<<SASS)
|
3091
|
+
.parent {
|
3092
|
+
background-color: red;
|
3093
|
+
border-color: red; }
|
3094
|
+
.parent .children {
|
3095
|
+
color: blue; }
|
3096
|
+
CSS
|
3097
|
+
$color: blue
|
3098
|
+
=context($class, $color: red)
|
3099
|
+
.\#{$class}
|
3100
|
+
background-color: $color
|
3101
|
+
@content
|
3102
|
+
border-color: $color
|
3103
|
+
+context(parent)
|
3104
|
+
.children
|
3105
|
+
color: $color
|
3106
|
+
SASS
|
3107
|
+
end
|
3108
|
+
|
3109
|
+
def test_using_parent_mixin_in_content
|
3110
|
+
assert_equal <<CSS, render(<<SASS)
|
3111
|
+
.parent {
|
3112
|
+
before-color: red;
|
3113
|
+
after-color: red; }
|
3114
|
+
.parent .sibling {
|
3115
|
+
before-color: yellow;
|
3116
|
+
after-color: yellow; }
|
3117
|
+
.parent .sibling .child {
|
3118
|
+
before-color: green;
|
3119
|
+
color: blue;
|
3120
|
+
after-color: green; }
|
3121
|
+
CSS
|
3122
|
+
$color: blue
|
3123
|
+
=context($class, $color: red)
|
3124
|
+
.\#{$class}
|
3125
|
+
before-color: $color
|
3126
|
+
@content
|
3127
|
+
after-color: $color
|
3128
|
+
+context(parent)
|
3129
|
+
+context(sibling, $color: yellow)
|
3130
|
+
+context(child, $color: green)
|
3131
|
+
color: $color
|
3132
|
+
SASS
|
3133
|
+
end
|
3134
|
+
|
3135
|
+
def test_content_more_than_once
|
3136
|
+
assert_equal <<CSS, render(<<SASS)
|
3137
|
+
.once {
|
3138
|
+
color: blue; }
|
3139
|
+
|
3140
|
+
.twice {
|
3141
|
+
color: blue; }
|
3142
|
+
CSS
|
3143
|
+
$color: blue
|
3144
|
+
=context($class, $color: red)
|
3145
|
+
.once
|
3146
|
+
@content
|
3147
|
+
.twice
|
3148
|
+
@content
|
3149
|
+
+context(parent)
|
3150
|
+
color: $color
|
3151
|
+
SASS
|
3152
|
+
end
|
3153
|
+
|
3154
|
+
def test_content_with_variable
|
3155
|
+
assert_equal <<CSS, render(<<SASS)
|
3156
|
+
.foo {
|
3157
|
+
a: 1px; }
|
3158
|
+
CSS
|
3159
|
+
=foo
|
3160
|
+
.foo
|
3161
|
+
@content
|
3162
|
+
+foo
|
3163
|
+
$a: 1px
|
3164
|
+
a: $a
|
3165
|
+
SASS
|
3166
|
+
end
|
3167
|
+
|
3168
|
+
def test_nested_content_blocks
|
3169
|
+
assert_equal <<CSS, render(<<SASS)
|
3170
|
+
.foo {
|
3171
|
+
a: foo; }
|
3172
|
+
.foo .bar {
|
3173
|
+
a: bar; }
|
3174
|
+
.foo .bar .baz {
|
3175
|
+
a: baz; }
|
3176
|
+
.foo .bar .baz .outside {
|
3177
|
+
a: outside;
|
3178
|
+
color: red; }
|
3179
|
+
CSS
|
3180
|
+
$a: outside
|
3181
|
+
=baz($a: baz)
|
3182
|
+
.baz
|
3183
|
+
a: $a
|
3184
|
+
@content
|
3185
|
+
=bar($a: bar)
|
3186
|
+
.bar
|
3187
|
+
a: $a
|
3188
|
+
+baz
|
3189
|
+
@content
|
3190
|
+
=foo($a: foo)
|
3191
|
+
.foo
|
3192
|
+
a: $a
|
3193
|
+
+bar
|
3194
|
+
@content
|
3195
|
+
+foo
|
3196
|
+
.outside
|
3197
|
+
a: $a
|
3198
|
+
color: red
|
3199
|
+
SASS
|
3200
|
+
end
|
3201
|
+
|
3202
|
+
def test_content_not_seen_through_mixin
|
3203
|
+
assert_equal <<CSS, render(<<SASS)
|
3204
|
+
a foo {
|
3205
|
+
mixin: foo;
|
3206
|
+
a: b; }
|
3207
|
+
a foo bar {
|
3208
|
+
mixin: bar; }
|
3209
|
+
CSS
|
3210
|
+
=foo
|
3211
|
+
foo
|
3212
|
+
mixin: foo
|
3213
|
+
@content
|
3214
|
+
+bar
|
3215
|
+
=bar
|
3216
|
+
bar
|
3217
|
+
mixin: bar
|
3218
|
+
@content
|
3219
|
+
a
|
3220
|
+
+foo
|
3221
|
+
a: b
|
3222
|
+
SASS
|
3223
|
+
end
|
3224
|
+
|
3225
|
+
def test_content_backtrace_for_perform
|
3226
|
+
render(<<SASS)
|
3227
|
+
=foo
|
3228
|
+
@content
|
3229
|
+
|
3230
|
+
a
|
3231
|
+
+foo
|
3232
|
+
b: 1em + 2px
|
3233
|
+
SASS
|
3234
|
+
assert(false, "Expected exception")
|
3235
|
+
rescue Sass::SyntaxError => e
|
3236
|
+
assert_equal([
|
3237
|
+
{:mixin => '@content', :line => 6, :filename => 'test_content_backtrace_for_perform_inline.sass'},
|
3238
|
+
{:mixin => 'foo', :line => 2, :filename => 'test_content_backtrace_for_perform_inline.sass'},
|
3239
|
+
{:line => 5, :filename => 'test_content_backtrace_for_perform_inline.sass'},
|
3240
|
+
], e.sass_backtrace)
|
3241
|
+
end
|
3242
|
+
|
3243
|
+
def test_content_backtrace_for_cssize
|
3244
|
+
render(<<SASS)
|
3245
|
+
=foo
|
3246
|
+
@content
|
3247
|
+
|
3248
|
+
a
|
3249
|
+
+foo
|
3250
|
+
@extend foo bar baz
|
3251
|
+
SASS
|
3252
|
+
assert(false, "Expected exception")
|
3253
|
+
rescue Sass::SyntaxError => e
|
3254
|
+
assert_equal([
|
3255
|
+
{:mixin => '@content', :line => 6, :filename => 'test_content_backtrace_for_cssize_inline.sass'},
|
3256
|
+
{:mixin => 'foo', :line => 2, :filename => 'test_content_backtrace_for_cssize_inline.sass'},
|
3257
|
+
{:line => 5, :filename => 'test_content_backtrace_for_cssize_inline.sass'},
|
3258
|
+
], e.sass_backtrace)
|
3259
|
+
end
|
3260
|
+
|
3261
|
+
def test_mixin_with_args_and_varargs_passed_no_var_args
|
3262
|
+
assert_equal <<CSS, render(<<SASS, :syntax => :scss)
|
3263
|
+
.foo {
|
3264
|
+
a: 1;
|
3265
|
+
b: 2;
|
3266
|
+
c: 3; }
|
3267
|
+
CSS
|
3268
|
+
@mixin three-or-more-args($a, $b, $c, $rest...) {
|
3269
|
+
a: $a;
|
3270
|
+
b: $b;
|
3271
|
+
c: $c;
|
3272
|
+
}
|
3273
|
+
|
3274
|
+
.foo {
|
3275
|
+
@include three-or-more-args($a: 1, $b: 2, $c: 3);
|
3276
|
+
}
|
3277
|
+
SASS
|
3278
|
+
|
3279
|
+
end
|
3280
|
+
|
3281
|
+
def test_debug_inspects_sass_objects
|
3282
|
+
assert_warning(<<END) {render("@debug (a: 1, b: 2)")}
|
3283
|
+
test_debug_inspects_sass_objects_inline.sass:1 DEBUG: (a: 1, b: 2)
|
3284
|
+
END
|
3285
|
+
assert_warning(<<END) {render("$map: (a: 1, b: 2); @debug $map", :syntax => :scss)}
|
3286
|
+
test_debug_inspects_sass_objects_inline.scss:1 DEBUG: (a: 1, b: 2)
|
3287
|
+
END
|
3288
|
+
end
|
3289
|
+
|
3290
|
+
def test_default_arg_before_splat
|
3291
|
+
assert_equal <<CSS, render(<<SASS, :syntax => :scss)
|
3292
|
+
.foo-positional {
|
3293
|
+
a: 1;
|
3294
|
+
b: 2;
|
3295
|
+
positional-arguments: 3, 4;
|
3296
|
+
keyword-arguments: (); }
|
3297
|
+
|
3298
|
+
.foo-keywords {
|
3299
|
+
a: true;
|
3300
|
+
positional-arguments: ();
|
3301
|
+
keyword-arguments: (c: c, d: d); }
|
3302
|
+
CSS
|
3303
|
+
@mixin foo($a: true, $b: null, $arguments...) {
|
3304
|
+
a: $a;
|
3305
|
+
b: $b;
|
3306
|
+
positional-arguments: inspect($arguments);
|
3307
|
+
keyword-arguments: inspect(keywords($arguments));
|
3308
|
+
}
|
3309
|
+
.foo-positional {
|
3310
|
+
@include foo(1, 2, 3, 4);
|
3311
|
+
}
|
3312
|
+
.foo-keywords {
|
3313
|
+
@include foo($c: c, $d: d);
|
3314
|
+
}
|
3315
|
+
SASS
|
3316
|
+
end
|
2423
3317
|
|
2424
3318
|
private
|
2425
3319
|
|
@@ -2435,6 +3329,7 @@ SASS
|
|
2435
3329
|
|
2436
3330
|
def render(sass, options = {})
|
2437
3331
|
munge_filename options
|
3332
|
+
options[:importer] ||= MockImporter.new
|
2438
3333
|
Sass::Engine.new(sass, options).render
|
2439
3334
|
end
|
2440
3335
|
|