sass 3.3.0 → 3.4.25
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.yardopts +3 -1
- data/CODE_OF_CONDUCT.md +10 -0
- data/CONTRIBUTING.md +148 -0
- data/MIT-LICENSE +1 -1
- data/README.md +76 -62
- data/Rakefile +104 -24
- data/VERSION +1 -1
- data/VERSION_DATE +1 -1
- data/VERSION_NAME +1 -1
- data/bin/sass +1 -1
- data/bin/scss +1 -1
- data/extra/sass-spec-ref.sh +32 -0
- data/extra/update_watch.rb +1 -1
- data/lib/sass/cache_stores/filesystem.rb +9 -5
- data/lib/sass/cache_stores/memory.rb +4 -5
- data/lib/sass/callbacks.rb +2 -2
- data/lib/sass/css.rb +12 -13
- data/lib/sass/deprecation.rb +55 -0
- data/lib/sass/engine.rb +106 -70
- data/lib/sass/environment.rb +39 -19
- data/lib/sass/error.rb +17 -20
- data/lib/sass/exec/base.rb +199 -0
- data/lib/sass/exec/sass_convert.rb +283 -0
- data/lib/sass/exec/sass_scss.rb +440 -0
- data/lib/sass/exec.rb +5 -771
- data/lib/sass/features.rb +9 -2
- data/lib/sass/importers/base.rb +8 -3
- data/lib/sass/importers/filesystem.rb +30 -38
- data/lib/sass/logger/base.rb +8 -2
- data/lib/sass/logger/delayed.rb +50 -0
- data/lib/sass/logger.rb +8 -3
- data/lib/sass/media.rb +1 -4
- data/lib/sass/plugin/compiler.rb +224 -90
- data/lib/sass/plugin/configuration.rb +38 -22
- data/lib/sass/plugin/merb.rb +2 -2
- data/lib/sass/plugin/rack.rb +3 -3
- data/lib/sass/plugin/rails.rb +1 -1
- data/lib/sass/plugin/staleness_checker.rb +4 -4
- data/lib/sass/plugin.rb +6 -5
- data/lib/sass/script/css_lexer.rb +1 -1
- data/lib/sass/script/css_parser.rb +2 -3
- data/lib/sass/script/css_variable_warning.rb +52 -0
- data/lib/sass/script/functions.rb +739 -318
- data/lib/sass/script/lexer.rb +134 -54
- data/lib/sass/script/parser.rb +252 -56
- data/lib/sass/script/tree/funcall.rb +13 -6
- data/lib/sass/script/tree/interpolation.rb +127 -4
- data/lib/sass/script/tree/list_literal.rb +31 -4
- data/lib/sass/script/tree/literal.rb +4 -0
- data/lib/sass/script/tree/node.rb +21 -3
- data/lib/sass/script/tree/operation.rb +54 -1
- data/lib/sass/script/tree/selector.rb +26 -0
- data/lib/sass/script/tree/string_interpolation.rb +59 -38
- data/lib/sass/script/tree/variable.rb +1 -1
- data/lib/sass/script/tree.rb +1 -0
- data/lib/sass/script/value/base.rb +17 -14
- data/lib/sass/script/value/bool.rb +0 -5
- data/lib/sass/script/value/color.rb +78 -42
- data/lib/sass/script/value/helpers.rb +119 -2
- data/lib/sass/script/value/list.rb +0 -15
- data/lib/sass/script/value/map.rb +1 -1
- data/lib/sass/script/value/null.rb +0 -5
- data/lib/sass/script/value/number.rb +112 -31
- data/lib/sass/script/value/string.rb +102 -13
- data/lib/sass/script/value.rb +0 -1
- data/lib/sass/script.rb +3 -3
- data/lib/sass/scss/css_parser.rb +24 -4
- data/lib/sass/scss/parser.rb +290 -383
- data/lib/sass/scss/rx.rb +17 -9
- data/lib/sass/scss/static_parser.rb +306 -4
- data/lib/sass/scss.rb +0 -2
- data/lib/sass/selector/abstract_sequence.rb +35 -18
- data/lib/sass/selector/comma_sequence.rb +114 -19
- data/lib/sass/selector/pseudo.rb +266 -0
- data/lib/sass/selector/sequence.rb +146 -40
- data/lib/sass/selector/simple.rb +22 -33
- data/lib/sass/selector/simple_sequence.rb +122 -39
- data/lib/sass/selector.rb +57 -197
- data/lib/sass/shared.rb +2 -2
- data/lib/sass/source/map.rb +31 -14
- data/lib/sass/source/position.rb +4 -4
- data/lib/sass/stack.rb +2 -8
- data/lib/sass/supports.rb +10 -13
- data/lib/sass/tree/at_root_node.rb +1 -0
- data/lib/sass/tree/charset_node.rb +1 -1
- data/lib/sass/tree/comment_node.rb +1 -1
- data/lib/sass/tree/css_import_node.rb +9 -1
- data/lib/sass/tree/directive_node.rb +8 -2
- data/lib/sass/tree/error_node.rb +18 -0
- data/lib/sass/tree/extend_node.rb +1 -1
- data/lib/sass/tree/function_node.rb +9 -0
- data/lib/sass/tree/import_node.rb +6 -5
- data/lib/sass/tree/keyframe_rule_node.rb +15 -0
- data/lib/sass/tree/node.rb +5 -3
- data/lib/sass/tree/prop_node.rb +6 -7
- data/lib/sass/tree/rule_node.rb +26 -11
- data/lib/sass/tree/visitors/check_nesting.rb +56 -32
- data/lib/sass/tree/visitors/convert.rb +59 -44
- data/lib/sass/tree/visitors/cssize.rb +34 -30
- data/lib/sass/tree/visitors/deep_copy.rb +6 -1
- data/lib/sass/tree/visitors/extend.rb +15 -13
- data/lib/sass/tree/visitors/perform.rb +87 -50
- data/lib/sass/tree/visitors/set_options.rb +15 -1
- data/lib/sass/tree/visitors/to_css.rb +72 -43
- data/lib/sass/util/multibyte_string_scanner.rb +0 -2
- data/lib/sass/util/normalized_map.rb +0 -1
- data/lib/sass/util/subset_map.rb +2 -3
- data/lib/sass/util.rb +334 -154
- data/lib/sass/version.rb +7 -7
- data/lib/sass.rb +10 -8
- data/test/sass/cache_test.rb +62 -20
- data/test/sass/callbacks_test.rb +1 -1
- data/test/sass/compiler_test.rb +24 -11
- data/test/sass/conversion_test.rb +241 -50
- data/test/sass/css2sass_test.rb +73 -5
- data/test/sass/css_variable_test.rb +132 -0
- data/test/sass/encoding_test.rb +219 -0
- data/test/sass/engine_test.rb +343 -260
- data/test/sass/exec_test.rb +12 -2
- data/test/sass/extend_test.rb +333 -44
- data/test/sass/functions_test.rb +353 -260
- data/test/sass/importer_test.rb +40 -21
- data/test/sass/logger_test.rb +1 -1
- data/test/sass/more_results/more_import.css +1 -1
- data/test/sass/more_templates/more1.sass +10 -10
- data/test/sass/more_templates/more_import.sass +2 -2
- data/test/sass/plugin_test.rb +24 -21
- data/test/sass/results/compact.css +1 -1
- data/test/sass/results/complex.css +4 -4
- data/test/sass/results/expanded.css +1 -1
- data/test/sass/results/import.css +1 -1
- data/test/sass/results/import_charset_ibm866.css +2 -2
- data/test/sass/results/mixins.css +17 -17
- data/test/sass/results/nested.css +1 -1
- data/test/sass/results/parent_ref.css +2 -2
- data/test/sass/results/script.css +5 -5
- data/test/sass/results/scss_import.css +1 -1
- data/test/sass/script_conversion_test.rb +71 -39
- data/test/sass/script_test.rb +714 -123
- data/test/sass/scss/css_test.rb +213 -30
- data/test/sass/scss/rx_test.rb +8 -4
- data/test/sass/scss/scss_test.rb +766 -22
- data/test/sass/source_map_test.rb +263 -95
- data/test/sass/superselector_test.rb +210 -0
- data/test/sass/templates/_partial.sass +1 -1
- data/test/sass/templates/basic.sass +10 -10
- data/test/sass/templates/bork1.sass +1 -1
- data/test/sass/templates/bork5.sass +1 -1
- data/test/sass/templates/compact.sass +10 -10
- data/test/sass/templates/complex.sass +187 -187
- data/test/sass/templates/compressed.sass +10 -10
- data/test/sass/templates/expanded.sass +10 -10
- data/test/sass/templates/import.sass +2 -2
- data/test/sass/templates/importee.sass +3 -3
- data/test/sass/templates/mixins.sass +22 -22
- data/test/sass/templates/multiline.sass +4 -4
- data/test/sass/templates/nested.sass +13 -13
- data/test/sass/templates/parent_ref.sass +12 -12
- data/test/sass/templates/script.sass +70 -70
- data/test/sass/templates/scss_import.scss +2 -1
- data/test/sass/templates/subdir/nested_subdir/_nested_partial.sass +1 -1
- data/test/sass/templates/subdir/nested_subdir/nested_subdir.sass +2 -2
- data/test/sass/templates/subdir/subdir.sass +3 -3
- data/test/sass/templates/units.sass +10 -10
- data/test/sass/test_helper.rb +1 -1
- data/test/sass/util/multibyte_string_scanner_test.rb +11 -3
- data/test/sass/util/normalized_map_test.rb +1 -1
- data/test/sass/util/subset_map_test.rb +2 -2
- data/test/sass/util_test.rb +46 -45
- data/test/sass/value_helpers_test.rb +5 -7
- data/test/sass-spec.yml +3 -0
- data/test/test_helper.rb +7 -6
- data/vendor/listen/CHANGELOG.md +1 -228
- data/vendor/listen/Gemfile +5 -15
- data/vendor/listen/README.md +111 -77
- data/vendor/listen/Rakefile +0 -42
- data/vendor/listen/lib/listen/adapter.rb +195 -82
- data/vendor/listen/lib/listen/adapters/bsd.rb +27 -64
- data/vendor/listen/lib/listen/adapters/darwin.rb +21 -58
- data/vendor/listen/lib/listen/adapters/linux.rb +23 -55
- data/vendor/listen/lib/listen/adapters/polling.rb +25 -34
- data/vendor/listen/lib/listen/adapters/windows.rb +50 -46
- data/vendor/listen/lib/listen/directory_record.rb +96 -61
- data/vendor/listen/lib/listen/listener.rb +135 -37
- data/vendor/listen/lib/listen/turnstile.rb +9 -5
- data/vendor/listen/lib/listen/version.rb +1 -1
- data/vendor/listen/lib/listen.rb +33 -19
- data/vendor/listen/listen.gemspec +6 -0
- data/vendor/listen/spec/listen/adapter_spec.rb +43 -77
- data/vendor/listen/spec/listen/adapters/polling_spec.rb +8 -8
- data/vendor/listen/spec/listen/directory_record_spec.rb +81 -56
- data/vendor/listen/spec/listen/listener_spec.rb +128 -39
- data/vendor/listen/spec/listen_spec.rb +15 -21
- data/vendor/listen/spec/spec_helper.rb +4 -0
- data/vendor/listen/spec/support/adapter_helper.rb +52 -15
- data/vendor/listen/spec/support/directory_record_helper.rb +7 -5
- data/vendor/listen/spec/support/listeners_helper.rb +30 -7
- metadata +310 -300
- data/CONTRIBUTING +0 -3
- data/ext/mkrf_conf.rb +0 -27
- data/lib/sass/script/value/deprecated_false.rb +0 -55
- data/lib/sass/scss/script_lexer.rb +0 -15
- data/lib/sass/scss/script_parser.rb +0 -25
- data/vendor/listen/lib/listen/dependency_manager.rb +0 -126
- data/vendor/listen/lib/listen/multi_listener.rb +0 -143
- data/vendor/listen/spec/listen/dependency_manager_spec.rb +0 -107
- data/vendor/listen/spec/listen/multi_listener_spec.rb +0 -174
data/test/sass/exec_test.rb
CHANGED
@@ -1,9 +1,10 @@
|
|
1
1
|
#!/usr/bin/env ruby
|
2
2
|
require File.dirname(__FILE__) + '/../test_helper'
|
3
|
+
require 'fileutils'
|
3
4
|
require 'sass/util/test'
|
4
5
|
require 'tmpdir'
|
5
6
|
|
6
|
-
class ExecTest < Test
|
7
|
+
class ExecTest < MiniTest::Test
|
7
8
|
include Sass::Util::Test
|
8
9
|
|
9
10
|
def setup
|
@@ -19,7 +20,7 @@ class ExecTest < Test::Unit::TestCase
|
|
19
20
|
src = get_path("src.scss")
|
20
21
|
dest = get_path("dest.css")
|
21
22
|
write(src, ".ruleset { margin: 0 }")
|
22
|
-
assert(exec(*%w[scss -t expanded --unix-newlines].push(src, dest)))
|
23
|
+
assert(exec(*%w[scss --sourcemap=none -t expanded --unix-newlines].push(src, dest)))
|
23
24
|
assert_equal(".ruleset {\n margin: 0;\n}\n", read(dest))
|
24
25
|
end
|
25
26
|
|
@@ -64,6 +65,14 @@ class ExecTest < Test::Unit::TestCase
|
|
64
65
|
assert_equal(".ruleset\r\n margin: 0\r\n", read(src))
|
65
66
|
end
|
66
67
|
|
68
|
+
def test_sass_convert_R
|
69
|
+
Dir.chdir(@dir) do
|
70
|
+
src = get_path("styles/src.css")
|
71
|
+
write(src, ".ruleset { margin: 0 }")
|
72
|
+
assert(exec(*%w[sass-convert -Rq --from css --to scss --trace styles]))
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
67
76
|
private
|
68
77
|
|
69
78
|
def get_path(name)
|
@@ -75,6 +84,7 @@ class ExecTest < Test::Unit::TestCase
|
|
75
84
|
end
|
76
85
|
|
77
86
|
def write(file, content)
|
87
|
+
FileUtils.mkdir_p(File.dirname(file))
|
78
88
|
open(file, 'wb') {|f| f.write(content)}
|
79
89
|
end
|
80
90
|
|
data/test/sass/extend_test.rb
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
#!/usr/bin/env ruby
|
2
2
|
require File.dirname(__FILE__) + '/../test_helper'
|
3
3
|
|
4
|
-
class ExtendTest < Test
|
4
|
+
class ExtendTest < MiniTest::Test
|
5
5
|
def test_basic
|
6
6
|
assert_equal <<CSS, render(<<SCSS)
|
7
7
|
.foo, .bar {
|
@@ -145,8 +145,8 @@ SCSS
|
|
145
145
|
end
|
146
146
|
|
147
147
|
def test_class_unification
|
148
|
-
assert_unification '.foo.bar', '.baz {@extend .foo}', '.foo.bar, .bar.baz'
|
149
|
-
assert_unification '.foo.baz', '.baz {@extend .foo}', '.baz'
|
148
|
+
assert_unification '.foo.bar', '.baz {@extend .foo}', '.foo.bar, .bar.baz'
|
149
|
+
assert_unification '.foo.baz', '.baz {@extend .foo}', '.baz'
|
150
150
|
end
|
151
151
|
|
152
152
|
def test_id_unification
|
@@ -167,42 +167,52 @@ SCSS
|
|
167
167
|
end
|
168
168
|
|
169
169
|
def test_universal_unification_with_namespaceless_universal_target
|
170
|
+
assert_extend_doesnt_match('ns|*', '.foo', :failed_to_unify, 2) do
|
171
|
+
render_unification '*.foo', 'ns|* {@extend .foo}'
|
172
|
+
end
|
173
|
+
|
170
174
|
assert_unification '*.foo', '* {@extend .foo}', '*'
|
171
175
|
assert_unification '*.foo', '*|* {@extend .foo}', '*'
|
172
176
|
assert_unification '*|*.foo', '* {@extend .foo}', '*|*.foo, *'
|
173
177
|
assert_unification '*|*.foo', '*|* {@extend .foo}', '*|*'
|
174
|
-
assert_unification '*.foo', 'ns|* {@extend .foo}', '*.foo, ns|*'
|
175
178
|
assert_unification '*|*.foo', 'ns|* {@extend .foo}', '*|*.foo, ns|*'
|
176
179
|
end
|
177
180
|
|
178
181
|
def test_universal_unification_with_namespaced_universal_target
|
179
|
-
|
180
|
-
|
182
|
+
assert_extend_doesnt_match('*', '.foo', :failed_to_unify, 2) do
|
183
|
+
render_unification 'ns|*.foo', '* {@extend .foo}'
|
184
|
+
end
|
181
185
|
|
182
186
|
assert_extend_doesnt_match('ns2|*', '.foo', :failed_to_unify, 2) do
|
183
187
|
render_unification 'ns1|*.foo', 'ns2|* {@extend .foo}'
|
184
188
|
end
|
185
189
|
|
190
|
+
assert_unification 'ns|*.foo', '*|* {@extend .foo}', 'ns|*'
|
186
191
|
assert_unification 'ns|*.foo', 'ns|* {@extend .foo}', 'ns|*'
|
187
192
|
end
|
188
193
|
|
189
194
|
def test_universal_unification_with_namespaceless_element_target
|
195
|
+
assert_extend_doesnt_match('ns|*', '.foo', :failed_to_unify, 2) do
|
196
|
+
render_unification 'a.foo', 'ns|* {@extend .foo}'
|
197
|
+
end
|
198
|
+
|
190
199
|
assert_unification 'a.foo', '* {@extend .foo}', 'a'
|
191
200
|
assert_unification 'a.foo', '*|* {@extend .foo}', 'a'
|
192
201
|
assert_unification '*|a.foo', '* {@extend .foo}', '*|a.foo, a'
|
193
202
|
assert_unification '*|a.foo', '*|* {@extend .foo}', '*|a'
|
194
|
-
assert_unification 'a.foo', 'ns|* {@extend .foo}', 'a.foo, ns|a'
|
195
203
|
assert_unification '*|a.foo', 'ns|* {@extend .foo}', '*|a.foo, ns|a'
|
196
204
|
end
|
197
205
|
|
198
206
|
def test_universal_unification_with_namespaced_element_target
|
199
|
-
|
200
|
-
|
207
|
+
assert_extend_doesnt_match('*', '.foo', :failed_to_unify, 2) do
|
208
|
+
render_unification 'ns|a.foo', '* {@extend .foo}'
|
209
|
+
end
|
201
210
|
|
202
211
|
assert_extend_doesnt_match('ns2|*', '.foo', :failed_to_unify, 2) do
|
203
212
|
render_unification 'ns1|a.foo', 'ns2|* {@extend .foo}'
|
204
213
|
end
|
205
214
|
|
215
|
+
assert_unification 'ns|a.foo', '*|* {@extend .foo}', 'ns|a'
|
206
216
|
assert_unification 'ns|a.foo', 'ns|* {@extend .foo}', 'ns|a'
|
207
217
|
end
|
208
218
|
|
@@ -214,46 +224,56 @@ SCSS
|
|
214
224
|
end
|
215
225
|
|
216
226
|
def test_element_unification_with_namespaceless_universal_target
|
227
|
+
assert_extend_doesnt_match('ns|a', '.foo', :failed_to_unify, 2) do
|
228
|
+
render_unification '*.foo', 'ns|a {@extend .foo}'
|
229
|
+
end
|
230
|
+
|
217
231
|
assert_unification '*.foo', 'a {@extend .foo}', '*.foo, a'
|
218
232
|
assert_unification '*.foo', '*|a {@extend .foo}', '*.foo, a'
|
219
233
|
assert_unification '*|*.foo', 'a {@extend .foo}', '*|*.foo, a'
|
220
234
|
assert_unification '*|*.foo', '*|a {@extend .foo}', '*|*.foo, *|a'
|
221
|
-
assert_unification '*.foo', 'ns|a {@extend .foo}', '*.foo, ns|a'
|
222
235
|
assert_unification '*|*.foo', 'ns|a {@extend .foo}', '*|*.foo, ns|a'
|
223
236
|
end
|
224
237
|
|
225
238
|
def test_element_unification_with_namespaced_universal_target
|
226
|
-
|
227
|
-
|
239
|
+
assert_extend_doesnt_match('a', '.foo', :failed_to_unify, 2) do
|
240
|
+
render_unification 'ns|*.foo', 'a {@extend .foo}'
|
241
|
+
end
|
228
242
|
|
229
243
|
assert_extend_doesnt_match('ns2|a', '.foo', :failed_to_unify, 2) do
|
230
244
|
render_unification 'ns1|*.foo', 'ns2|a {@extend .foo}'
|
231
245
|
end
|
232
246
|
|
247
|
+
assert_unification 'ns|*.foo', '*|a {@extend .foo}', 'ns|*.foo, ns|a'
|
233
248
|
assert_unification 'ns|*.foo', 'ns|a {@extend .foo}', 'ns|*.foo, ns|a'
|
234
249
|
end
|
235
250
|
|
236
251
|
def test_element_unification_with_namespaceless_element_target
|
252
|
+
assert_extend_doesnt_match('ns|a', '.foo', :failed_to_unify, 2) do
|
253
|
+
render_unification 'a.foo', 'ns|a {@extend .foo}'
|
254
|
+
end
|
255
|
+
|
256
|
+
assert_extend_doesnt_match('h1', '.foo', :failed_to_unify, 2) do
|
257
|
+
render_unification 'a.foo', 'h1 {@extend .foo}'
|
258
|
+
end
|
259
|
+
|
237
260
|
assert_unification 'a.foo', 'a {@extend .foo}', 'a'
|
238
261
|
assert_unification 'a.foo', '*|a {@extend .foo}', 'a'
|
239
262
|
assert_unification '*|a.foo', 'a {@extend .foo}', '*|a.foo, a'
|
240
263
|
assert_unification '*|a.foo', '*|a {@extend .foo}', '*|a'
|
241
|
-
assert_unification 'a.foo', 'ns|a {@extend .foo}', 'a.foo, ns|a'
|
242
264
|
assert_unification '*|a.foo', 'ns|a {@extend .foo}', '*|a.foo, ns|a'
|
243
|
-
|
244
|
-
assert_extend_doesnt_match('h1', '.foo', :failed_to_unify, 2) do
|
245
|
-
render_unification 'a.foo', 'h1 {@extend .foo}'
|
246
|
-
end
|
247
265
|
end
|
248
266
|
|
249
267
|
def test_element_unification_with_namespaced_element_target
|
250
|
-
|
251
|
-
|
268
|
+
assert_extend_doesnt_match('a', '.foo', :failed_to_unify, 2) do
|
269
|
+
render_unification 'ns|a.foo', 'a {@extend .foo}'
|
270
|
+
end
|
252
271
|
|
253
272
|
assert_extend_doesnt_match('ns2|a', '.foo', :failed_to_unify, 2) do
|
254
273
|
render_unification 'ns1|a.foo', 'ns2|a {@extend .foo}'
|
255
274
|
end
|
256
275
|
|
276
|
+
assert_unification 'ns|a.foo', '*|a {@extend .foo}', 'ns|a'
|
257
277
|
assert_unification 'ns|a.foo', 'ns|a {@extend .foo}', 'ns|a'
|
258
278
|
end
|
259
279
|
|
@@ -310,9 +330,207 @@ SCSS
|
|
310
330
|
end
|
311
331
|
|
312
332
|
def test_negation_unification
|
313
|
-
|
314
|
-
|
315
|
-
|
333
|
+
assert_extends ':not(.foo).baz', ':not(.bar) {@extend .baz}', ':not(.foo).baz, :not(.foo):not(.bar)'
|
334
|
+
# Unifying to :not(.foo) here would reduce the specificity of the original selector.
|
335
|
+
assert_extends ':not(.foo).baz', ':not(.foo) {@extend .baz}', ':not(.foo).baz, :not(.foo)'
|
336
|
+
end
|
337
|
+
|
338
|
+
def test_prefixed_pseudoclass_unification
|
339
|
+
assert_unification(
|
340
|
+
':nth-child(2n+1 of .foo).baz',
|
341
|
+
':nth-child(2n of .foo) {@extend .baz}',
|
342
|
+
':nth-child(2n+1 of .foo).baz, :nth-child(2n+1 of .foo):nth-child(2n of .foo)')
|
343
|
+
|
344
|
+
assert_unification(
|
345
|
+
':nth-child(2n+1 of .foo).baz',
|
346
|
+
':nth-child(2n+1 of .bar) {@extend .baz}',
|
347
|
+
':nth-child(2n+1 of .foo).baz, :nth-child(2n+1 of .foo):nth-child(2n+1 of .bar)')
|
348
|
+
|
349
|
+
assert_unification(
|
350
|
+
':nth-child(2n+1 of .foo).baz',
|
351
|
+
':nth-child(2n+1 of .foo) {@extend .baz}',
|
352
|
+
':nth-child(2n+1 of .foo)')
|
353
|
+
end
|
354
|
+
|
355
|
+
def test_extend_into_not
|
356
|
+
assert_extends(':not(.foo)', '.x {@extend .foo}', ':not(.foo):not(.x)')
|
357
|
+
assert_extends(':not(.foo.bar)', '.x {@extend .bar}', ':not(.foo.bar):not(.foo.x)')
|
358
|
+
assert_extends(
|
359
|
+
':not(.foo.bar, .baz.bar)',
|
360
|
+
'.x {@extend .bar}',
|
361
|
+
':not(.foo.bar, .foo.x, .baz.bar, .baz.x)')
|
362
|
+
end
|
363
|
+
|
364
|
+
def test_extend_into_mergeable_pseudoclasses
|
365
|
+
assert_extends(':matches(.foo)', '.x {@extend .foo}', ':matches(.foo, .x)')
|
366
|
+
assert_extends(':matches(.foo.bar)', '.x {@extend .bar}', ':matches(.foo.bar, .foo.x)')
|
367
|
+
assert_extends(
|
368
|
+
':matches(.foo.bar, .baz.bar)',
|
369
|
+
'.x {@extend .bar}',
|
370
|
+
':matches(.foo.bar, .foo.x, .baz.bar, .baz.x)')
|
371
|
+
|
372
|
+
assert_extends(':-moz-any(.foo)', '.x {@extend .foo}', ':-moz-any(.foo, .x)')
|
373
|
+
assert_extends(':current(.foo)', '.x {@extend .foo}', ':current(.foo, .x)')
|
374
|
+
assert_extends(':has(.foo)', '.x {@extend .foo}', ':has(.foo, .x)')
|
375
|
+
assert_extends(':host(.foo)', '.x {@extend .foo}', ':host(.foo, .x)')
|
376
|
+
assert_extends(':host-context(.foo)', '.x {@extend .foo}', ':host-context(.foo, .x)')
|
377
|
+
assert_extends(':nth-child(n of .foo)', '.x {@extend .foo}', ':nth-child(n of .foo, .x)')
|
378
|
+
assert_extends(
|
379
|
+
':nth-last-child(n of .foo)',
|
380
|
+
'.x {@extend .foo}',
|
381
|
+
':nth-last-child(n of .foo, .x)')
|
382
|
+
end
|
383
|
+
|
384
|
+
def test_complex_extend_into_pseudoclass
|
385
|
+
# Unlike other selectors, we don't allow complex selectors to be
|
386
|
+
# added to `:not` if they weren't there before. At time of
|
387
|
+
# writing, most browsers don't support that and will throw away
|
388
|
+
# the entire selector if it exists.
|
389
|
+
#assert_extends(':not(.bar)', '.x .y {@extend .bar}', ':not(.bar)')
|
390
|
+
|
391
|
+
# If the `:not()` already has a complex selector, we won't break
|
392
|
+
# anything by adding a new one.
|
393
|
+
assert_extends(':not(.baz .bar)', '.x .y {@extend .bar}',
|
394
|
+
':not(.baz .bar):not(.baz .x .y):not(.x .baz .y)')
|
395
|
+
|
396
|
+
# If the `:not()` would only contain complex selectors, there's no
|
397
|
+
# harm in letting it continue to exist.
|
398
|
+
assert_extends(':not(%bar)', '.x .y {@extend %bar}', ':not(.x .y)')
|
399
|
+
|
400
|
+
assert_extends(':matches(.bar)', '.x .y {@extend .bar}', ':matches(.bar, .x .y)')
|
401
|
+
assert_extends(':current(.bar)', '.x .y {@extend .bar}', ':current(.bar, .x .y)')
|
402
|
+
assert_extends(':has(.bar)', '.x .y {@extend .bar}', ':has(.bar, .x .y)')
|
403
|
+
assert_extends(':host(.bar)', '.x .y {@extend .bar}', ':host(.bar, .x .y)')
|
404
|
+
assert_extends(':host-context(.bar)', '.x .y {@extend .bar}', ':host-context(.bar, .x .y)')
|
405
|
+
assert_extends(
|
406
|
+
':-moz-any(.bar)',
|
407
|
+
'.x .y {@extend .bar}',
|
408
|
+
':-moz-any(.bar, .x .y)')
|
409
|
+
assert_extends(
|
410
|
+
':nth-child(n of .bar)',
|
411
|
+
'.x .y {@extend .bar}',
|
412
|
+
':nth-child(n of .bar, .x .y)')
|
413
|
+
assert_extends(
|
414
|
+
':nth-last-child(n of .bar)',
|
415
|
+
'.x .y {@extend .bar}',
|
416
|
+
':nth-last-child(n of .bar, .x .y)')
|
417
|
+
end
|
418
|
+
|
419
|
+
def test_extend_over_selector_pseudoclass
|
420
|
+
assert_extends(':not(.foo)', '.x {@extend :not(.foo)}', ':not(.foo), .x')
|
421
|
+
assert_extends(
|
422
|
+
':matches(.foo, .bar)',
|
423
|
+
'.x {@extend :matches(.foo, .bar)}',
|
424
|
+
':matches(.foo, .bar), .x')
|
425
|
+
end
|
426
|
+
|
427
|
+
def test_matches_within_not
|
428
|
+
assert_extends(
|
429
|
+
':not(.foo, .bar)',
|
430
|
+
':matches(.x, .y) {@extend .foo}',
|
431
|
+
':not(.foo, .x, .y, .bar)')
|
432
|
+
end
|
433
|
+
|
434
|
+
def test_pseudoclasses_merge
|
435
|
+
assert_extends(':matches(.foo)', ':matches(.bar) {@extend .foo}', ':matches(.foo, .bar)')
|
436
|
+
assert_extends(':-moz-any(.foo)', ':-moz-any(.bar) {@extend .foo}', ':-moz-any(.foo, .bar)')
|
437
|
+
assert_extends(':current(.foo)', ':current(.bar) {@extend .foo}', ':current(.foo, .bar)')
|
438
|
+
assert_extends(
|
439
|
+
':nth-child(n of .foo)',
|
440
|
+
':nth-child(n of .bar) {@extend .foo}',
|
441
|
+
':nth-child(n of .foo, .bar)')
|
442
|
+
assert_extends(
|
443
|
+
':nth-last-child(n of .foo)',
|
444
|
+
':nth-last-child(n of .bar) {@extend .foo}',
|
445
|
+
':nth-last-child(n of .foo, .bar)')
|
446
|
+
end
|
447
|
+
|
448
|
+
def test_nesting_pseudoclasses_merge
|
449
|
+
assert_extends(':has(.foo)', ':has(.bar) {@extend .foo}', ':has(.foo, :has(.bar))')
|
450
|
+
assert_extends(':host(.foo)', ':host(.bar) {@extend .foo}', ':host(.foo, :host(.bar))')
|
451
|
+
assert_extends(
|
452
|
+
':host-context(.foo)',
|
453
|
+
':host-context(.bar) {@extend .foo}',
|
454
|
+
':host-context(.foo, :host-context(.bar))')
|
455
|
+
end
|
456
|
+
|
457
|
+
def test_not_unifies_with_unique_values
|
458
|
+
assert_unification('foo', ':not(bar) {@extend foo}', ':not(bar)')
|
459
|
+
assert_unification('#foo', ':not(#bar) {@extend #foo}', ':not(#bar)')
|
460
|
+
end
|
461
|
+
|
462
|
+
def test_not_adds_no_specificity
|
463
|
+
assert_specificity_equals(':not(.foo)', '.foo')
|
464
|
+
end
|
465
|
+
|
466
|
+
def test_matches_has_a_specificity_range
|
467
|
+
# `:matches(.foo, #bar)` has minimum specificity equal to that of `.foo`,
|
468
|
+
# which means `:matches(.foo, #bar) .a` can have less specificity than
|
469
|
+
# `#b.a`. Thus the selector generated by `#b.a` should be preserved.
|
470
|
+
assert_equal <<CSS, render(<<SCSS)
|
471
|
+
:matches(.foo, #bar) .a, :matches(.foo, #bar) #b.a {
|
472
|
+
a: b; }
|
473
|
+
CSS
|
474
|
+
:matches(.foo, #bar) %x {a: b}
|
475
|
+
.a {@extend %x}
|
476
|
+
#b.a {@extend %x}
|
477
|
+
SCSS
|
478
|
+
|
479
|
+
# `:matches(.foo, #bar)` has maximum specificity equal to that of `#bar`,
|
480
|
+
# which means `:matches(.foo, #bar).b` can have greater specificity than `.a
|
481
|
+
# .b`. Thus the selector generated by `:matches(.foo, #bar).b` should be
|
482
|
+
# preserved.
|
483
|
+
assert_equal <<CSS, render(<<SCSS)
|
484
|
+
.a .b, .a .b:matches(.foo, #bar) {
|
485
|
+
a: b; }
|
486
|
+
CSS
|
487
|
+
.a %x {a: b}
|
488
|
+
.b {@extend %x}
|
489
|
+
.b:matches(.foo, #bar) {@extend %x}
|
490
|
+
SCSS
|
491
|
+
end
|
492
|
+
|
493
|
+
def test_extend_into_not_and_normal_extend
|
494
|
+
assert_equal <<CSS, render(<<SCSS)
|
495
|
+
.x:not(.y):not(.bar), .foo:not(.y):not(.bar) {
|
496
|
+
a: b; }
|
497
|
+
CSS
|
498
|
+
.x:not(.y) {a: b}
|
499
|
+
.foo {@extend .x}
|
500
|
+
.bar {@extend .y}
|
501
|
+
SCSS
|
502
|
+
end
|
503
|
+
|
504
|
+
def test_extend_into_matches_and_normal_extend
|
505
|
+
assert_equal <<CSS, render(<<SCSS)
|
506
|
+
.x:matches(.y, .bar), .foo:matches(.y, .bar) {
|
507
|
+
a: b; }
|
508
|
+
CSS
|
509
|
+
.x:matches(.y) {a: b}
|
510
|
+
.foo {@extend .x}
|
511
|
+
.bar {@extend .y}
|
512
|
+
SCSS
|
513
|
+
end
|
514
|
+
|
515
|
+
def test_multilayer_pseudoclass_extend
|
516
|
+
assert_equal <<CSS, render(<<SCSS)
|
517
|
+
:matches(.x, .foo, .bar) {
|
518
|
+
a: b; }
|
519
|
+
CSS
|
520
|
+
:matches(.x) {a: b}
|
521
|
+
.foo {@extend .x}
|
522
|
+
.bar {@extend .foo}
|
523
|
+
SCSS
|
524
|
+
end
|
525
|
+
|
526
|
+
def test_root_only_allowed_at_root
|
527
|
+
assert_extends(':root .foo', '.bar .baz {@extend .foo}',
|
528
|
+
':root .foo, :root .bar .baz')
|
529
|
+
assert_extends('.foo:root .bar', '.baz:root .bang {@extend .bar}',
|
530
|
+
'.foo:root .bar, .baz.foo:root .bang')
|
531
|
+
assert_extends('html:root .bar', 'xml:root .bang {@extend .bar}', 'html:root .bar')
|
532
|
+
assert_extends('.foo:root > .bar .x', '.baz:root .bang .y {@extend .x}',
|
533
|
+
'.foo:root > .bar .x, .baz.foo:root > .bar .bang .y')
|
316
534
|
end
|
317
535
|
|
318
536
|
def test_comma_extendee
|
@@ -340,24 +558,42 @@ CSS
|
|
340
558
|
SCSS
|
341
559
|
end
|
342
560
|
|
561
|
+
def test_nested_pseudo_selectors
|
562
|
+
assert_equal <<CSS, render(<<SCSS)
|
563
|
+
.foo .bar:not(.baz), .bang .bar:not(.baz) {
|
564
|
+
a: b; }
|
565
|
+
CSS
|
566
|
+
.foo {
|
567
|
+
.bar:not(.baz) {a: b}
|
568
|
+
}
|
569
|
+
.bang {@extend .foo}
|
570
|
+
SCSS
|
571
|
+
end
|
572
|
+
|
343
573
|
## Long Extendees
|
344
574
|
|
345
575
|
def test_long_extendee
|
346
|
-
assert_extends '.foo.bar', '.baz {@extend .foo.bar}', '.foo.bar, .baz'
|
576
|
+
assert_warning(<<WARNING) {assert_extends '.foo.bar', '.baz {@extend .foo.bar}', '.foo.bar, .baz'}
|
577
|
+
DEPRECATION WARNING on line 2 of test_long_extendee_inline.scss:
|
578
|
+
Extending a compound selector, .foo.bar, is deprecated and will not be supported in a future release.
|
579
|
+
See https://github.com/sass/sass/issues/1599 for details.
|
580
|
+
WARNING
|
347
581
|
end
|
348
582
|
|
349
583
|
def test_long_extendee_requires_all_selectors
|
350
|
-
|
351
|
-
|
584
|
+
silence_warnings do
|
585
|
+
assert_extend_doesnt_match('.baz', '.foo.bar', :not_found, 2) do
|
586
|
+
render_extends '.foo', '.baz {@extend .foo.bar}'
|
587
|
+
end
|
352
588
|
end
|
353
589
|
end
|
354
590
|
|
355
591
|
def test_long_extendee_matches_supersets
|
356
|
-
assert_extends '.foo.bar.bap', '.baz {@extend .foo.bar}', '.foo.bar.bap, .bap.baz'
|
592
|
+
silence_warnings {assert_extends '.foo.bar.bap', '.baz {@extend .foo.bar}', '.foo.bar.bap, .bap.baz'}
|
357
593
|
end
|
358
594
|
|
359
595
|
def test_long_extendee_runs_unification
|
360
|
-
assert_extends 'ns|*.foo.bar', 'a.baz {@extend .foo.bar}', 'ns|*.foo.bar, ns|a.baz'
|
596
|
+
silence_warnings {assert_extends 'ns|*.foo.bar', '*|a.baz {@extend .foo.bar}', 'ns|*.foo.bar, ns|a.baz'}
|
361
597
|
end
|
362
598
|
|
363
599
|
## Long Extenders
|
@@ -367,7 +603,7 @@ SCSS
|
|
367
603
|
end
|
368
604
|
|
369
605
|
def test_long_extender_runs_unification
|
370
|
-
assert_extends 'ns|*.foo.bar', 'a.baz {@extend .foo}', 'ns|*.foo.bar, ns|a.bar.baz'
|
606
|
+
assert_extends 'ns|*.foo.bar', '*|a.baz {@extend .foo}', 'ns|*.foo.bar, ns|a.bar.baz'
|
371
607
|
end
|
372
608
|
|
373
609
|
def test_long_extender_aborts_unification
|
@@ -453,9 +689,9 @@ SCSS
|
|
453
689
|
end
|
454
690
|
|
455
691
|
def test_nested_extender_doesnt_find_common_selectors_around_reference_selector
|
456
|
-
assert_extends 'a /for/ b c .c1', 'a c .c2 {@extend .c1}', 'a /for/ b c .c1, a /for/ b a c .c2, a a /for/ b c .c2'
|
457
|
-
assert_extends 'a /for/ b c .c1', 'a b .c2 {@extend .c1}', 'a /for/ b c .c1, a a /for/ b c .c2'
|
458
|
-
assert_extends 'a /for/ b c .c1', 'b c .c2 {@extend .c1}', 'a /for/ b c .c1, a /for/ b c .c2'
|
692
|
+
silence_warnings {assert_extends 'a /for/ b c .c1', 'a c .c2 {@extend .c1}', 'a /for/ b c .c1, a /for/ b a c .c2, a a /for/ b c .c2'}
|
693
|
+
silence_warnings {assert_extends 'a /for/ b c .c1', 'a b .c2 {@extend .c1}', 'a /for/ b c .c1, a a /for/ b c .c2'}
|
694
|
+
silence_warnings {assert_extends 'a /for/ b c .c1', 'b c .c2 {@extend .c1}', 'a /for/ b c .c1, a /for/ b c .c2'}
|
459
695
|
end
|
460
696
|
|
461
697
|
def test_nested_extender_with_early_child_selectors_doesnt_subseq_them
|
@@ -516,7 +752,7 @@ SCSS
|
|
516
752
|
end
|
517
753
|
|
518
754
|
def test_nested_extender_with_trailing_child_selector
|
519
|
-
|
755
|
+
assert_raises(Sass::SyntaxError, "bar > can't extend: invalid selector") do
|
520
756
|
render("bar > {@extend .baz}")
|
521
757
|
end
|
522
758
|
end
|
@@ -650,10 +886,10 @@ SCSS
|
|
650
886
|
|
651
887
|
def test_basic_extend_loop
|
652
888
|
assert_equal <<CSS, render(<<SCSS)
|
653
|
-
.
|
889
|
+
.foo, .bar {
|
654
890
|
a: b; }
|
655
891
|
|
656
|
-
.
|
892
|
+
.bar, .foo {
|
657
893
|
c: d; }
|
658
894
|
CSS
|
659
895
|
.foo {a: b; @extend .bar}
|
@@ -663,13 +899,13 @@ SCSS
|
|
663
899
|
|
664
900
|
def test_three_level_extend_loop
|
665
901
|
assert_equal <<CSS, render(<<SCSS)
|
666
|
-
.
|
902
|
+
.foo, .baz, .bar {
|
667
903
|
a: b; }
|
668
904
|
|
669
|
-
.
|
905
|
+
.bar, .foo, .baz {
|
670
906
|
c: d; }
|
671
907
|
|
672
|
-
.
|
908
|
+
.baz, .bar, .foo {
|
673
909
|
e: f; }
|
674
910
|
CSS
|
675
911
|
.foo {a: b; @extend .bar}
|
@@ -692,6 +928,18 @@ CSS
|
|
692
928
|
SCSS
|
693
929
|
end
|
694
930
|
|
931
|
+
def test_cross_loop
|
932
|
+
# The first law of extend means the selector should stick around.
|
933
|
+
assert_equal <<CSS, render(<<SCSS)
|
934
|
+
.foo.bar, .foo, .bar {
|
935
|
+
a: b; }
|
936
|
+
CSS
|
937
|
+
.foo.bar {a: b}
|
938
|
+
.foo {@extend .bar}
|
939
|
+
.bar {@extend .foo}
|
940
|
+
SCSS
|
941
|
+
end
|
942
|
+
|
695
943
|
def test_multiple_extender_merges_with_superset_selector
|
696
944
|
assert_equal <<CSS, render(<<SCSS)
|
697
945
|
a.bar.baz, a.foo {
|
@@ -830,6 +1078,17 @@ $foo: foo;
|
|
830
1078
|
SCSS
|
831
1079
|
end
|
832
1080
|
|
1081
|
+
def test_placeholder_in_selector_pseudoclass
|
1082
|
+
assert_equal <<CSS, render(<<SCSS)
|
1083
|
+
:matches(.bar, .baz) {
|
1084
|
+
color: blue; }
|
1085
|
+
CSS
|
1086
|
+
:matches(%foo) {color: blue}
|
1087
|
+
.bar {@extend %foo}
|
1088
|
+
.baz {@extend %foo}
|
1089
|
+
SCSS
|
1090
|
+
end
|
1091
|
+
|
833
1092
|
def test_media_in_placeholder_selector
|
834
1093
|
assert_equal <<CSS, render(<<SCSS)
|
835
1094
|
.baz {
|
@@ -1005,7 +1264,7 @@ SCSS
|
|
1005
1264
|
end
|
1006
1265
|
|
1007
1266
|
def test_extend_with_subject_transfers_subject_to_extender
|
1008
|
-
assert_equal(<<CSS, render(<<SCSS))
|
1267
|
+
silence_warnings {assert_equal(<<CSS, render(<<SCSS))}
|
1009
1268
|
foo bar! baz, foo .bip .bap! baz, .bip foo .bap! baz {
|
1010
1269
|
a: b; }
|
1011
1270
|
CSS
|
@@ -1013,7 +1272,7 @@ foo bar! baz {a: b}
|
|
1013
1272
|
.bip .bap {@extend bar}
|
1014
1273
|
SCSS
|
1015
1274
|
|
1016
|
-
assert_equal(<<CSS, render(<<SCSS))
|
1275
|
+
silence_warnings {assert_equal(<<CSS, render(<<SCSS))}
|
1017
1276
|
foo.x bar.y! baz.z, foo.x .bip bar.bap! baz.z, .bip foo.x bar.bap! baz.z {
|
1018
1277
|
a: b; }
|
1019
1278
|
CSS
|
@@ -1023,7 +1282,7 @@ SCSS
|
|
1023
1282
|
end
|
1024
1283
|
|
1025
1284
|
def test_extend_with_subject_retains_subject_on_target
|
1026
|
-
assert_equal(<<CSS, render(<<SCSS))
|
1285
|
+
silence_warnings {assert_equal(<<CSS, render(<<SCSS))}
|
1027
1286
|
.foo! .bar, .foo! .bip .bap, .bip .foo! .bap {
|
1028
1287
|
a: b; }
|
1029
1288
|
CSS
|
@@ -1033,7 +1292,7 @@ SCSS
|
|
1033
1292
|
end
|
1034
1293
|
|
1035
1294
|
def test_extend_with_subject_transfers_subject_to_target
|
1036
|
-
assert_equal(<<CSS, render(<<SCSS))
|
1295
|
+
silence_warnings {assert_equal(<<CSS, render(<<SCSS))}
|
1037
1296
|
a.foo .bar, .bip a.bap! .bar {
|
1038
1297
|
a: b; }
|
1039
1298
|
CSS
|
@@ -1043,7 +1302,7 @@ SCSS
|
|
1043
1302
|
end
|
1044
1303
|
|
1045
1304
|
def test_extend_with_subject_retains_subject_on_extender
|
1046
|
-
assert_equal(<<CSS, render(<<SCSS))
|
1305
|
+
silence_warnings {assert_equal(<<CSS, render(<<SCSS))}
|
1047
1306
|
.foo .bar, .foo .bip! .bap, .bip! .foo .bap {
|
1048
1307
|
a: b; }
|
1049
1308
|
CSS
|
@@ -1053,7 +1312,7 @@ SCSS
|
|
1053
1312
|
end
|
1054
1313
|
|
1055
1314
|
def test_extend_with_subject_fails_with_conflicting_subject
|
1056
|
-
assert_equal(<<CSS, render(<<SCSS))
|
1315
|
+
silence_warnings {assert_equal(<<CSS, render(<<SCSS))}
|
1057
1316
|
x! .bar {
|
1058
1317
|
a: b; }
|
1059
1318
|
CSS
|
@@ -1115,6 +1374,16 @@ SCSS
|
|
1115
1374
|
|
1116
1375
|
# Regression Tests
|
1117
1376
|
|
1377
|
+
def test_extend_with_middle_pseudo
|
1378
|
+
assert_equal(<<CSS, render(<<SCSS))
|
1379
|
+
.btn:active.focus, :active.focus:before {
|
1380
|
+
a: b; }
|
1381
|
+
CSS
|
1382
|
+
.btn:active.focus {a: b}
|
1383
|
+
:before {@extend .btn}
|
1384
|
+
SCSS
|
1385
|
+
end
|
1386
|
+
|
1118
1387
|
def test_extend_parent_selector_suffix
|
1119
1388
|
assert_equal <<CSS, render(<<SCSS)
|
1120
1389
|
.a-b, .c {
|
@@ -1408,7 +1677,7 @@ Use "@extend #{target} !optional" if the extend should be able to fail.
|
|
1408
1677
|
ERR
|
1409
1678
|
end
|
1410
1679
|
|
1411
|
-
def assert_unification(selector, extension, unified)
|
1680
|
+
def assert_unification(selector, extension, unified, nested = true)
|
1412
1681
|
# Do some trickery so the first law of extend doesn't get in our way.
|
1413
1682
|
assert_extends(
|
1414
1683
|
"%-a #{selector}",
|
@@ -1416,6 +1685,22 @@ ERR
|
|
1416
1685
|
unified.split(', ').map {|s| "-a #{s}"}.join(', '))
|
1417
1686
|
end
|
1418
1687
|
|
1688
|
+
def assert_specificity_equals(sel1, sel2)
|
1689
|
+
assert_specificity_gte(sel1, sel2)
|
1690
|
+
assert_specificity_gte(sel2, sel1)
|
1691
|
+
end
|
1692
|
+
|
1693
|
+
def assert_specificity_gte(sel1, sel2)
|
1694
|
+
assert_equal <<CSS, render(<<SCSS)
|
1695
|
+
#{sel1} .a {
|
1696
|
+
a: b; }
|
1697
|
+
CSS
|
1698
|
+
#{sel1} %-a {a: b}
|
1699
|
+
.a {@extend %-a}
|
1700
|
+
#{sel2}.a {@extend %-a}
|
1701
|
+
SCSS
|
1702
|
+
end
|
1703
|
+
|
1419
1704
|
def render_unification(selector, extension)
|
1420
1705
|
render_extends(
|
1421
1706
|
"%-a #{selector}",
|
@@ -1429,6 +1714,10 @@ ERR
|
|
1429
1714
|
CSS
|
1430
1715
|
end
|
1431
1716
|
|
1717
|
+
def assert_extends_to_nothing(selector, extension)
|
1718
|
+
assert_equal '', render_extends(selector, extension)
|
1719
|
+
end
|
1720
|
+
|
1432
1721
|
def render_extends(selector, extension)
|
1433
1722
|
render(<<SCSS)
|
1434
1723
|
#{selector} {a: b}
|