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/importer_test.rb
CHANGED
@@ -1,34 +1,57 @@
|
|
1
1
|
#!/usr/bin/env ruby
|
2
2
|
require File.dirname(__FILE__) + '/../test_helper'
|
3
3
|
require File.dirname(__FILE__) + '/test_helper'
|
4
|
+
require 'mock_importer'
|
5
|
+
require 'sass/plugin'
|
4
6
|
|
5
7
|
class ImporterTest < Test::Unit::TestCase
|
6
|
-
|
8
|
+
|
7
9
|
class FruitImporter < Sass::Importers::Base
|
8
10
|
def find(name, context = nil)
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
end
|
19
|
-
contents = %Q{
|
20
|
-
$#{fruit}-color: #{color} !default;
|
21
|
-
@mixin #{fruit} {
|
22
|
-
color: $#{fruit}-color;
|
23
|
-
}
|
24
|
-
}
|
25
|
-
Sass::Engine.new(contents, :filename => name, :syntax => :scss, :importer => self)
|
11
|
+
fruit = parse(name)
|
12
|
+
return unless fruit
|
13
|
+
color = case fruit
|
14
|
+
when "apple"
|
15
|
+
"red"
|
16
|
+
when "orange"
|
17
|
+
"orange"
|
18
|
+
else
|
19
|
+
"blue"
|
26
20
|
end
|
21
|
+
contents = %Q{
|
22
|
+
$#{fruit}-color: #{color} !default;
|
23
|
+
@mixin #{fruit} {
|
24
|
+
color: $#{fruit}-color;
|
25
|
+
}
|
26
|
+
}
|
27
|
+
Sass::Engine.new(contents, :filename => name, :syntax => :scss, :importer => self)
|
27
28
|
end
|
28
29
|
|
29
30
|
def key(name, context)
|
30
31
|
[self.class.name, name]
|
31
32
|
end
|
33
|
+
|
34
|
+
def public_url(name, sourcemap_directory = nil)
|
35
|
+
"http://#{parse(name)}.example.com/style.scss"
|
36
|
+
end
|
37
|
+
|
38
|
+
private
|
39
|
+
|
40
|
+
def parse(name)
|
41
|
+
name[%r{fruits/(\w+)(\.s[ac]ss)?}, 1]
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
class NoPublicUrlImporter < FruitImporter
|
46
|
+
def public_url(name, sourcemap_directory = nil)
|
47
|
+
nil
|
48
|
+
end
|
49
|
+
|
50
|
+
private
|
51
|
+
|
52
|
+
def parse(name)
|
53
|
+
name[%r{ephemeral/(\w+)(\.s[ac]ss)?}, 1]
|
54
|
+
end
|
32
55
|
end
|
33
56
|
|
34
57
|
# This class proves that you can override the extension scheme for importers
|
@@ -38,6 +61,72 @@ class ImporterTest < Test::Unit::TestCase
|
|
38
61
|
end
|
39
62
|
end
|
40
63
|
|
64
|
+
# This importer maps one import to another import
|
65
|
+
# based on the mappings passed to importer's constructor.
|
66
|
+
class IndirectImporter < Sass::Importers::Base
|
67
|
+
def initialize(mappings, mtimes)
|
68
|
+
@mappings = mappings
|
69
|
+
@mtimes = mtimes
|
70
|
+
end
|
71
|
+
def find_relative(uri, base, options)
|
72
|
+
nil
|
73
|
+
end
|
74
|
+
def find(name, options)
|
75
|
+
if @mappings.has_key?(name)
|
76
|
+
Sass::Engine.new(
|
77
|
+
%Q[@import "#{@mappings[name]}";],
|
78
|
+
options.merge(
|
79
|
+
:filename => name,
|
80
|
+
:syntax => :scss,
|
81
|
+
:importer => self
|
82
|
+
)
|
83
|
+
)
|
84
|
+
end
|
85
|
+
end
|
86
|
+
def mtime(uri, options)
|
87
|
+
@mtimes.fetch(uri, @mtimes.has_key?(uri) ? Time.now : nil)
|
88
|
+
end
|
89
|
+
def key(uri, options)
|
90
|
+
[self.class.name, uri]
|
91
|
+
end
|
92
|
+
def to_s
|
93
|
+
"IndirectImporter(#{@mappings.keys.join(", ")})"
|
94
|
+
end
|
95
|
+
end
|
96
|
+
|
97
|
+
# This importer maps the import to single class
|
98
|
+
# based on the mappings passed to importer's constructor.
|
99
|
+
class ClassImporter < Sass::Importers::Base
|
100
|
+
def initialize(mappings, mtimes)
|
101
|
+
@mappings = mappings
|
102
|
+
@mtimes = mtimes
|
103
|
+
end
|
104
|
+
def find_relative(uri, base, options)
|
105
|
+
nil
|
106
|
+
end
|
107
|
+
def find(name, options)
|
108
|
+
if @mappings.has_key?(name)
|
109
|
+
Sass::Engine.new(
|
110
|
+
%Q[.#{name}{#{@mappings[name]}}],
|
111
|
+
options.merge(
|
112
|
+
:filename => name,
|
113
|
+
:syntax => :scss,
|
114
|
+
:importer => self
|
115
|
+
)
|
116
|
+
)
|
117
|
+
end
|
118
|
+
end
|
119
|
+
def mtime(uri, options)
|
120
|
+
@mtimes.fetch(uri, @mtimes.has_key?(uri) ? Time.now : nil)
|
121
|
+
end
|
122
|
+
def key(uri, options)
|
123
|
+
[self.class.name, uri]
|
124
|
+
end
|
125
|
+
def to_s
|
126
|
+
"ClassImporter(#{@mappings.keys.join(", ")})"
|
127
|
+
end
|
128
|
+
end
|
129
|
+
|
41
130
|
def test_can_resolve_generated_imports
|
42
131
|
scss_file = %Q{
|
43
132
|
$pear-color: green;
|
@@ -79,4 +168,235 @@ CSS
|
|
79
168
|
ensure
|
80
169
|
FileUtils.rm_rf(absolutize("tmp"))
|
81
170
|
end
|
171
|
+
|
172
|
+
def test_staleness_check_across_importers
|
173
|
+
file_system_importer = Sass::Importers::Filesystem.new(fixture_dir)
|
174
|
+
# Make sure the first import is older
|
175
|
+
indirect_importer = IndirectImporter.new({"apple" => "pear"}, {"apple" => Time.now - 1})
|
176
|
+
# Make css file is newer so the dependencies are the only way for the css file to be out of date.
|
177
|
+
FileUtils.touch(fixture_file("test_staleness_check_across_importers.css"))
|
178
|
+
# Make sure the first import is older
|
179
|
+
class_importer = ClassImporter.new({"pear" => %Q{color: green;}}, {"pear" => Time.now + 1})
|
180
|
+
|
181
|
+
options = {
|
182
|
+
:style => :compact,
|
183
|
+
:filename => fixture_file("test_staleness_check_across_importers.scss"),
|
184
|
+
:importer => file_system_importer,
|
185
|
+
:load_paths => [file_system_importer, indirect_importer, class_importer],
|
186
|
+
:syntax => :scss
|
187
|
+
}
|
188
|
+
|
189
|
+
assert_equal File.read(fixture_file("test_staleness_check_across_importers.css")),
|
190
|
+
Sass::Engine.new(File.read(fixture_file("test_staleness_check_across_importers.scss")), options).render
|
191
|
+
|
192
|
+
checker = Sass::Plugin::StalenessChecker.new(options)
|
193
|
+
|
194
|
+
assert checker.stylesheet_needs_update?(
|
195
|
+
fixture_file("test_staleness_check_across_importers.css"),
|
196
|
+
fixture_file("test_staleness_check_across_importers.scss"),
|
197
|
+
file_system_importer
|
198
|
+
)
|
199
|
+
end
|
200
|
+
|
201
|
+
def test_source_map_with_only_css_uri_supports_public_url_imports
|
202
|
+
fruit_importer = FruitImporter.new
|
203
|
+
|
204
|
+
options = {
|
205
|
+
:filename => 'fruits/orange',
|
206
|
+
:importer => fruit_importer,
|
207
|
+
:syntax => :scss
|
208
|
+
}
|
209
|
+
|
210
|
+
engine = Sass::Engine.new(<<SCSS, options)
|
211
|
+
.orchard {
|
212
|
+
color: blue;
|
213
|
+
}
|
214
|
+
SCSS
|
215
|
+
|
216
|
+
_, sourcemap = engine.render_with_sourcemap('sourcemap_uri')
|
217
|
+
assert_equal <<JSON.strip, sourcemap.to_json(:css_uri => 'css_uri')
|
218
|
+
{
|
219
|
+
"version": 3,
|
220
|
+
"mappings": "AAAA,QAAS;EACP,KAAK,EAAE,IAAI",
|
221
|
+
"sources": ["http://orange.example.com/style.scss"],
|
222
|
+
"names": [],
|
223
|
+
"file": "css_uri"
|
224
|
+
}
|
225
|
+
JSON
|
226
|
+
end
|
227
|
+
|
228
|
+
def test_source_map_with_only_css_uri_can_have_no_public_url_without_warning
|
229
|
+
ephemeral_importer = NoPublicUrlImporter.new
|
230
|
+
mock_importer = MockImporter.new
|
231
|
+
def mock_importer.public_url(name, sourcemap_directory = nil)
|
232
|
+
"css_uri"
|
233
|
+
end
|
234
|
+
|
235
|
+
options = {
|
236
|
+
:filename => filename_for_test,
|
237
|
+
:sourcemap_filename => sourcemap_filename_for_test,
|
238
|
+
:importer => mock_importer,
|
239
|
+
:syntax => :scss,
|
240
|
+
:load_paths => [ephemeral_importer],
|
241
|
+
:cache => false
|
242
|
+
}
|
243
|
+
|
244
|
+
engine = Sass::Engine.new(<<SCSS, options)
|
245
|
+
@import "ephemeral/orange";
|
246
|
+
.orange {
|
247
|
+
@include orange;
|
248
|
+
}
|
249
|
+
SCSS
|
250
|
+
|
251
|
+
assert_warning("") do
|
252
|
+
css_output, sourcemap = engine.render_with_sourcemap('sourcemap_uri')
|
253
|
+
assert_equal <<CSS.strip, css_output.strip
|
254
|
+
.orange {
|
255
|
+
color: orange; }
|
256
|
+
|
257
|
+
/*# sourceMappingURL=sourcemap_uri */
|
258
|
+
CSS
|
259
|
+
map = sourcemap.to_json(:css_uri => 'css_uri')
|
260
|
+
assert_equal <<JSON.strip, map
|
261
|
+
{
|
262
|
+
"version": 3,
|
263
|
+
"mappings": "AACA,OAAQ",
|
264
|
+
"sources": ["css_uri"],
|
265
|
+
"names": [],
|
266
|
+
"file": "css_uri"
|
267
|
+
}
|
268
|
+
JSON
|
269
|
+
end
|
270
|
+
end
|
271
|
+
|
272
|
+
def test_source_map_with_only_css_uri_doesnt_support_filesystem_importer
|
273
|
+
file_system_importer = Sass::Importers::Filesystem.new('.')
|
274
|
+
options = {
|
275
|
+
:filename => filename_for_test(:scss),
|
276
|
+
:sourcemap_filename => sourcemap_filename_for_test,
|
277
|
+
:importer => file_system_importer,
|
278
|
+
:syntax => :scss
|
279
|
+
}
|
280
|
+
|
281
|
+
engine = Sass::Engine.new(<<SCSS, options)
|
282
|
+
.foo {a: b}
|
283
|
+
SCSS
|
284
|
+
|
285
|
+
_, sourcemap = engine.render_with_sourcemap('http://1.example.com/style.map')
|
286
|
+
|
287
|
+
assert_warning(<<WARNING) {sourcemap.to_json(:css_uri => 'css_uri')}
|
288
|
+
WARNING: Couldn't determine public URL for "#{filename_for_test(:scss)}" while generating sourcemap.
|
289
|
+
Without a public URL, there's nothing for the source map to link to.
|
290
|
+
WARNING
|
291
|
+
end
|
292
|
+
|
293
|
+
def test_source_map_with_css_uri_and_css_path_doesnt_support_filesystem_importer
|
294
|
+
file_system_importer = Sass::Importers::Filesystem.new('.')
|
295
|
+
options = {
|
296
|
+
:filename => filename_for_test(:scss),
|
297
|
+
:sourcemap_filename => sourcemap_filename_for_test,
|
298
|
+
:importer => file_system_importer,
|
299
|
+
:syntax => :scss
|
300
|
+
}
|
301
|
+
|
302
|
+
engine = Sass::Engine.new(<<SCSS, options)
|
303
|
+
.foo {a: b}
|
304
|
+
SCSS
|
305
|
+
|
306
|
+
_, sourcemap = engine.render_with_sourcemap('http://1.example.com/style.map')
|
307
|
+
|
308
|
+
assert_warning(<<WARNING) {sourcemap.to_json(:css_uri => 'css_uri', :css_path => 'css_path')}
|
309
|
+
WARNING: Couldn't determine public URL for "#{filename_for_test(:scss)}" while generating sourcemap.
|
310
|
+
Without a public URL, there's nothing for the source map to link to.
|
311
|
+
WARNING
|
312
|
+
end
|
313
|
+
|
314
|
+
def test_source_map_with_css_uri_and_sourcemap_path_supports_filesystem_importer
|
315
|
+
file_system_importer = Sass::Importers::Filesystem.new('.')
|
316
|
+
css_uri = 'css_uri'
|
317
|
+
sourcemap_path = 'map/style.map'
|
318
|
+
options = {
|
319
|
+
:filename => 'sass/style.scss',
|
320
|
+
:sourcemap_filename => sourcemap_path,
|
321
|
+
:importer => file_system_importer,
|
322
|
+
:syntax => :scss
|
323
|
+
}
|
324
|
+
|
325
|
+
engine = Sass::Engine.new(<<SCSS, options)
|
326
|
+
.foo {a: b}
|
327
|
+
SCSS
|
328
|
+
|
329
|
+
rendered, sourcemap = engine.render_with_sourcemap('http://1.example.com/style.map')
|
330
|
+
|
331
|
+
|
332
|
+
rendered, sourcemap = engine.render_with_sourcemap('http://map.example.com/map/style.map')
|
333
|
+
assert_equal <<JSON.strip, sourcemap.to_json(:css_uri => css_uri, :sourcemap_path => sourcemap_path)
|
334
|
+
{
|
335
|
+
"version": 3,
|
336
|
+
"mappings": "AAAA,IAAK;EAAC,CAAC,EAAE,CAAC",
|
337
|
+
"sources": ["../sass/style.scss"],
|
338
|
+
"names": [],
|
339
|
+
"file": "css_uri"
|
340
|
+
}
|
341
|
+
JSON
|
342
|
+
end
|
343
|
+
|
344
|
+
def test_source_map_with_css_path_and_sourcemap_path_supports_file_system_importer
|
345
|
+
file_system_importer = Sass::Importers::Filesystem.new('.')
|
346
|
+
sass_path = 'sass/style.scss'
|
347
|
+
css_path = 'static/style.css'
|
348
|
+
sourcemap_path = 'map/style.map'
|
349
|
+
options = {
|
350
|
+
:filename => sass_path,
|
351
|
+
:sourcemap_filename => sourcemap_path,
|
352
|
+
:importer => file_system_importer,
|
353
|
+
:syntax => :scss
|
354
|
+
}
|
355
|
+
|
356
|
+
engine = Sass::Engine.new(<<SCSS, options)
|
357
|
+
.foo {a: b}
|
358
|
+
SCSS
|
359
|
+
|
360
|
+
_, sourcemap = engine.render_with_sourcemap('http://map.example.com/map/style.map')
|
361
|
+
assert_equal <<JSON.strip, sourcemap.to_json(:css_path => css_path, :sourcemap_path => sourcemap_path)
|
362
|
+
{
|
363
|
+
"version": 3,
|
364
|
+
"mappings": "AAAA,IAAK;EAAC,CAAC,EAAE,CAAC",
|
365
|
+
"sources": ["../sass/style.scss"],
|
366
|
+
"names": [],
|
367
|
+
"file": "../static/style.css"
|
368
|
+
}
|
369
|
+
JSON
|
370
|
+
end
|
371
|
+
|
372
|
+
def test_render_with_sourcemap_requires_filename
|
373
|
+
file_system_importer = Sass::Importers::Filesystem.new('.')
|
374
|
+
engine = Sass::Engine.new(".foo {a: b}", :syntax => :scss, :importer => file_system_importer)
|
375
|
+
assert_raise_message(Sass::SyntaxError, <<MESSAGE) {engine.render_with_sourcemap('sourcemap_url')}
|
376
|
+
Error generating source map: couldn't determine public URL for the source stylesheet.
|
377
|
+
No filename is available so there's nothing for the source map to link to.
|
378
|
+
MESSAGE
|
379
|
+
end
|
380
|
+
|
381
|
+
def test_render_with_sourcemap_requires_importer_with_public_url
|
382
|
+
class_importer = ClassImporter.new({"pear" => "color: green;"}, {"pear" => Time.now})
|
383
|
+
assert_raise_message(Sass::SyntaxError, <<MESSAGE) {class_importer.find("pear", {}).render_with_sourcemap('sourcemap_url')}
|
384
|
+
Error generating source map: couldn't determine public URL for "pear".
|
385
|
+
Without a public URL, there's nothing for the source map to link to.
|
386
|
+
Custom importers should define the #public_url method.
|
387
|
+
MESSAGE
|
388
|
+
end
|
389
|
+
|
390
|
+
def fixture_dir
|
391
|
+
File.join(File.dirname(__FILE__), "fixtures")
|
392
|
+
end
|
393
|
+
|
394
|
+
def fixture_file(path)
|
395
|
+
File.join(fixture_dir, path)
|
396
|
+
end
|
397
|
+
|
398
|
+
def test_absolute_files_across_template_locations
|
399
|
+
importer = Sass::Importers::Filesystem.new(absolutize 'templates')
|
400
|
+
assert_not_nil importer.mtime(absolutize('more_templates/more1.sass'), {})
|
401
|
+
end
|
82
402
|
end
|
@@ -0,0 +1,58 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
require File.dirname(__FILE__) + '/../test_helper'
|
3
|
+
require 'pathname'
|
4
|
+
|
5
|
+
class LoggerTest < Test::Unit::TestCase
|
6
|
+
|
7
|
+
class InterceptedLogger < Sass::Logger::Base
|
8
|
+
|
9
|
+
attr_accessor :messages
|
10
|
+
|
11
|
+
def initialize(*args)
|
12
|
+
super
|
13
|
+
self.messages = []
|
14
|
+
end
|
15
|
+
|
16
|
+
def reset!
|
17
|
+
self.messages = []
|
18
|
+
end
|
19
|
+
|
20
|
+
def _log(*args)
|
21
|
+
messages << [args]
|
22
|
+
end
|
23
|
+
|
24
|
+
end
|
25
|
+
|
26
|
+
def test_global_sass_logger_instance_exists
|
27
|
+
assert Sass.logger.respond_to?(:warn)
|
28
|
+
end
|
29
|
+
|
30
|
+
def test_log_level_orders
|
31
|
+
logged_levels = {
|
32
|
+
:trace => [ [], [:trace, :debug, :info, :warn, :error]],
|
33
|
+
:debug => [ [:trace], [:debug, :info, :warn, :error]],
|
34
|
+
:info => [ [:trace, :debug], [:info, :warn, :error]],
|
35
|
+
:warn => [ [:trace, :debug, :info], [:warn, :error]],
|
36
|
+
:error => [ [:trace, :debug, :info, :warn], [:error]]
|
37
|
+
}
|
38
|
+
logged_levels.each do |level, (should_not_be_logged, should_be_logged)|
|
39
|
+
logger = Sass::Logger::Base.new(level)
|
40
|
+
should_not_be_logged.each do |should_level|
|
41
|
+
assert !logger.logging_level?(should_level)
|
42
|
+
end
|
43
|
+
should_be_logged.each do |should_level|
|
44
|
+
assert logger.logging_level?(should_level)
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
def test_logging_can_be_disabled
|
50
|
+
logger = InterceptedLogger.new
|
51
|
+
logger.error("message #1")
|
52
|
+
assert_equal 1, logger.messages.size
|
53
|
+
logger.reset!
|
54
|
+
logger.disabled = true
|
55
|
+
logger.error("message #2")
|
56
|
+
assert_equal 0, logger.messages.size
|
57
|
+
end
|
58
|
+
end
|
@@ -1,3 +1,5 @@
|
|
1
|
+
@import url(basic.css);
|
2
|
+
@import url(../results/complex.css);
|
1
3
|
imported { otherconst: hello; myconst: goodbye; pre-mixin: here; }
|
2
4
|
|
3
5
|
body { font: Arial; background: blue; }
|
@@ -22,8 +24,6 @@ body { font: Arial; background: blue; }
|
|
22
24
|
#content.user.show #container.top #column.right { width: 600px; }
|
23
25
|
#content.user.show #container.bottom { background: brown; }
|
24
26
|
|
25
|
-
@import url(basic.css);
|
26
|
-
@import url(../results/complex.css);
|
27
27
|
#foo { background-color: #bbaaff; }
|
28
28
|
|
29
29
|
nonimported { myconst: hello; otherconst: goodbye; post-mixin: here; }
|
data/test/sass/plugin_test.rb
CHANGED
@@ -4,11 +4,24 @@ require File.dirname(__FILE__) + '/test_helper'
|
|
4
4
|
require 'sass/plugin'
|
5
5
|
require 'fileutils'
|
6
6
|
|
7
|
+
module Sass::Script::Functions
|
8
|
+
def filename
|
9
|
+
filename = options[:filename].gsub(%r{.*((/[^/]+){4})}, '\1')
|
10
|
+
Sass::Script::Value::String.new(filename)
|
11
|
+
end
|
12
|
+
|
13
|
+
def whatever
|
14
|
+
custom = options[:custom]
|
15
|
+
whatever = custom && custom[:whatever]
|
16
|
+
Sass::Script::Value::String.new(whatever || "incorrect")
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
7
20
|
class SassPluginTest < Test::Unit::TestCase
|
8
21
|
@@templates = %w{
|
9
22
|
complex script parent_ref import scss_import alt
|
10
23
|
subdir/subdir subdir/nested_subdir/nested_subdir
|
11
|
-
options
|
24
|
+
options import_content filename_fn
|
12
25
|
}
|
13
26
|
@@templates += %w[import_charset import_charset_ibm866] unless Sass::Util.ruby1_8?
|
14
27
|
@@templates << 'import_charset_1_8' if Sass::Util.ruby1_8?
|
@@ -110,6 +123,61 @@ CSS
|
|
110
123
|
File.delete(tempfile_loc('bork1'))
|
111
124
|
end
|
112
125
|
|
126
|
+
def test_full_exception_with_block_comment
|
127
|
+
File.delete(tempfile_loc('bork5'))
|
128
|
+
check_for_updates!
|
129
|
+
File.open(tempfile_loc('bork5')) do |file|
|
130
|
+
assert_equal(<<CSS.strip, file.read.split("\n")[0...7].join("\n"))
|
131
|
+
/*
|
132
|
+
Syntax error: Undefined variable: "$bork".
|
133
|
+
on line 3 of #{template_loc('bork5')}
|
134
|
+
|
135
|
+
1: bork
|
136
|
+
2: /* foo *\\/
|
137
|
+
3: :bork $bork
|
138
|
+
CSS
|
139
|
+
end
|
140
|
+
File.delete(tempfile_loc('bork1'))
|
141
|
+
end
|
142
|
+
|
143
|
+
def test_single_level_import_loop
|
144
|
+
File.delete(tempfile_loc('single_import_loop'))
|
145
|
+
check_for_updates!
|
146
|
+
File.open(tempfile_loc('single_import_loop')) do |file|
|
147
|
+
assert_equal(<<CSS.strip, file.read.split("\n")[0...2].join("\n"))
|
148
|
+
/*
|
149
|
+
Syntax error: An @import loop has been found: #{template_loc('single_import_loop')} imports itself
|
150
|
+
CSS
|
151
|
+
end
|
152
|
+
end
|
153
|
+
|
154
|
+
def test_double_level_import_loop
|
155
|
+
File.delete(tempfile_loc('double_import_loop1'))
|
156
|
+
check_for_updates!
|
157
|
+
File.open(tempfile_loc('double_import_loop1')) do |file|
|
158
|
+
assert_equal(<<CSS.strip, file.read.split("\n")[0...4].join("\n"))
|
159
|
+
/*
|
160
|
+
Syntax error: An @import loop has been found:
|
161
|
+
#{template_loc('double_import_loop1')} imports #{template_loc('_double_import_loop2')}
|
162
|
+
#{template_loc('_double_import_loop2')} imports #{template_loc('double_import_loop1')}
|
163
|
+
CSS
|
164
|
+
end
|
165
|
+
end
|
166
|
+
|
167
|
+
def test_import_name_cleanup
|
168
|
+
File.delete(tempfile_loc('subdir/import_up1'))
|
169
|
+
check_for_updates!
|
170
|
+
File.open(tempfile_loc('subdir/import_up1')) do |file|
|
171
|
+
assert_equal(<<CSS.strip, file.read.split("\n")[0...5].join("\n"))
|
172
|
+
/*
|
173
|
+
Syntax error: File to import not found or unreadable: ../subdir/import_up3.scss.
|
174
|
+
Load path: #{template_loc}
|
175
|
+
on line 1 of #{template_loc 'subdir/import_up2'}
|
176
|
+
from line 1 of #{template_loc 'subdir/import_up1'}
|
177
|
+
CSS
|
178
|
+
end
|
179
|
+
end
|
180
|
+
|
113
181
|
def test_nonfull_exception_handling
|
114
182
|
old_full_exception = Sass::Plugin.options[:full_exception]
|
115
183
|
Sass::Plugin.options[:full_exception] = false
|
@@ -179,42 +247,39 @@ CSS
|
|
179
247
|
assert_needs_update "basic"
|
180
248
|
end
|
181
249
|
|
182
|
-
|
183
|
-
|
184
|
-
|
185
|
-
|
186
|
-
|
187
|
-
|
188
|
-
|
189
|
-
|
190
|
-
|
191
|
-
|
250
|
+
def test_import_same_name
|
251
|
+
assert_warning <<WARNING do
|
252
|
+
WARNING: In #{template_loc}:
|
253
|
+
There are multiple files that match the name "same_name_different_partiality.scss":
|
254
|
+
_same_name_different_partiality.scss
|
255
|
+
same_name_different_partiality.scss
|
256
|
+
WARNING
|
257
|
+
touch "_same_name_different_partiality"
|
258
|
+
assert_needs_update "same_name_different_partiality"
|
259
|
+
end
|
192
260
|
end
|
193
261
|
|
194
|
-
|
195
|
-
Sass::Plugin.options[:never_update] = true
|
196
|
-
assert_no_callback :updating_stylesheets
|
197
|
-
end
|
262
|
+
# Callbacks
|
198
263
|
|
199
|
-
def
|
264
|
+
def test_updated_stylesheet_callback_for_updated_template
|
200
265
|
Sass::Plugin.options[:always_update] = false
|
201
266
|
touch 'basic'
|
202
|
-
assert_no_callback :
|
267
|
+
assert_no_callback :updated_stylesheet, template_loc("complex"), tempfile_loc("complex") do
|
203
268
|
assert_callbacks(
|
204
|
-
[:
|
205
|
-
[:
|
269
|
+
[:updated_stylesheet, template_loc("basic"), tempfile_loc("basic")],
|
270
|
+
[:updated_stylesheet, template_loc("import"), tempfile_loc("import")])
|
206
271
|
end
|
207
272
|
end
|
208
273
|
|
209
|
-
def
|
274
|
+
def test_updated_stylesheet_callback_for_fresh_template
|
210
275
|
Sass::Plugin.options[:always_update] = false
|
211
|
-
assert_no_callback :
|
276
|
+
assert_no_callback :updated_stylesheet
|
212
277
|
end
|
213
278
|
|
214
|
-
def
|
279
|
+
def test_updated_stylesheet_callback_for_error_template
|
215
280
|
Sass::Plugin.options[:always_update] = false
|
216
281
|
touch 'bork1'
|
217
|
-
assert_no_callback :
|
282
|
+
assert_no_callback :updated_stylesheet
|
218
283
|
end
|
219
284
|
|
220
285
|
def test_not_updating_stylesheet_callback_for_fresh_template
|
@@ -226,8 +291,8 @@ CSS
|
|
226
291
|
Sass::Plugin.options[:always_update] = false
|
227
292
|
assert_callback :not_updating_stylesheet, template_loc("complex"), tempfile_loc("complex") do
|
228
293
|
assert_no_callbacks(
|
229
|
-
[:
|
230
|
-
[:
|
294
|
+
[:updated_stylesheet, template_loc("basic"), tempfile_loc("basic")],
|
295
|
+
[:updated_stylesheet, template_loc("import"), tempfile_loc("import")])
|
231
296
|
end
|
232
297
|
end
|
233
298
|
|
@@ -301,7 +366,24 @@ CSS
|
|
301
366
|
check_for_updates!
|
302
367
|
assert_renders_correctly 'if'
|
303
368
|
ensure
|
304
|
-
set_plugin_opts
|
369
|
+
set_plugin_opts
|
370
|
+
end
|
371
|
+
|
372
|
+
def test_cached_import_option
|
373
|
+
set_plugin_opts :custom => {:whatever => "correct"}
|
374
|
+
check_for_updates!
|
375
|
+
assert_renders_correctly "cached_import_option"
|
376
|
+
|
377
|
+
@@cache_store.reset!
|
378
|
+
set_plugin_opts :custom => nil, :always_update => false
|
379
|
+
check_for_updates!
|
380
|
+
assert_renders_correctly "cached_import_option"
|
381
|
+
|
382
|
+
set_plugin_opts :custom => {:whatever => "correct"}, :always_update => true
|
383
|
+
check_for_updates!
|
384
|
+
assert_renders_correctly "cached_import_option"
|
385
|
+
ensure
|
386
|
+
set_plugin_opts :custom => nil
|
305
387
|
end
|
306
388
|
|
307
389
|
private
|
@@ -347,19 +429,21 @@ CSS
|
|
347
429
|
|
348
430
|
def assert_callback(name, *expected_args)
|
349
431
|
run = false
|
432
|
+
received_args = nil
|
350
433
|
Sass::Plugin.send("on_#{name}") do |*args|
|
351
|
-
|
352
|
-
|
434
|
+
received_args = args
|
435
|
+
run ||= expected_args.zip(received_args).all? do |ea, ra|
|
436
|
+
ea.respond_to?(:call) ? ea.call(ra) : ea == ra
|
353
437
|
end
|
354
438
|
end
|
355
439
|
|
356
440
|
if block_given?
|
357
|
-
yield
|
441
|
+
Sass::Util.silence_sass_warnings {yield}
|
358
442
|
else
|
359
443
|
check_for_updates!
|
360
444
|
end
|
361
445
|
|
362
|
-
assert run, "Expected #{name} callback to be run with arguments:\n #{expected_args.inspect}"
|
446
|
+
assert run, "Expected #{name} callback to be run with arguments:\n #{expected_args.inspect}\nHowever, it got:\n #{received_args.inspect}"
|
363
447
|
end
|
364
448
|
|
365
449
|
def assert_no_callback(name, *unexpected_args)
|
@@ -0,0 +1,3 @@
|
|
1
|
+
filename { imported: /test/sass/templates/_filename_fn_import.scss; }
|
2
|
+
|
3
|
+
filename { local: /test/sass/templates/filename_fn.scss; local-mixin: /test/sass/templates/filename_fn.scss; local-function: /test/sass/templates/filename_fn.scss; imported-mixin: /test/sass/templates/_filename_fn_import.scss; imported-function: /test/sass/templates/_filename_fn_import.scss; }
|
@@ -1,3 +1,5 @@
|
|
1
|
+
@import url(basic.css);
|
2
|
+
@import url(../results/complex.css);
|
1
3
|
imported { otherconst: hello; myconst: goodbye; pre-mixin: here; }
|
2
4
|
|
3
5
|
body { font: Arial; background: blue; }
|
@@ -24,8 +26,6 @@ body { font: Arial; background: blue; }
|
|
24
26
|
#content.user.show #container.top #column.right { width: 600px; }
|
25
27
|
#content.user.show #container.bottom { background: brown; }
|
26
28
|
|
27
|
-
@import url(basic.css);
|
28
|
-
@import url(../results/complex.css);
|
29
29
|
#foo { background-color: #bbaaff; }
|
30
30
|
|
31
31
|
nonimported { myconst: hello; otherconst: goodbye; post-mixin: here; }
|