sass 3.2.7 → 3.3.0.rc.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (184) hide show
  1. data/MIT-LICENSE +2 -2
  2. data/README.md +14 -2
  3. data/Rakefile +25 -1
  4. data/VERSION +1 -1
  5. data/VERSION_DATE +1 -1
  6. data/VERSION_NAME +1 -1
  7. data/lib/sass/cache_stores/base.rb +4 -2
  8. data/lib/sass/cache_stores/chain.rb +2 -1
  9. data/lib/sass/cache_stores/filesystem.rb +2 -6
  10. data/lib/sass/cache_stores/memory.rb +1 -1
  11. data/lib/sass/cache_stores/null.rb +2 -2
  12. data/lib/sass/callbacks.rb +1 -0
  13. data/lib/sass/css.rb +10 -10
  14. data/lib/sass/engine.rb +403 -150
  15. data/lib/sass/environment.rb +136 -57
  16. data/lib/sass/error.rb +7 -7
  17. data/lib/sass/exec.rb +123 -39
  18. data/lib/sass/features.rb +41 -0
  19. data/lib/sass/importers/base.rb +33 -2
  20. data/lib/sass/importers/deprecated_path.rb +45 -0
  21. data/lib/sass/importers/filesystem.rb +25 -14
  22. data/lib/sass/importers.rb +1 -0
  23. data/lib/sass/logger/base.rb +3 -3
  24. data/lib/sass/logger/log_level.rb +4 -6
  25. data/lib/sass/media.rb +19 -19
  26. data/lib/sass/plugin/compiler.rb +141 -101
  27. data/lib/sass/plugin/configuration.rb +18 -22
  28. data/lib/sass/plugin/merb.rb +1 -1
  29. data/lib/sass/plugin/staleness_checker.rb +24 -8
  30. data/lib/sass/plugin.rb +4 -2
  31. data/lib/sass/repl.rb +3 -3
  32. data/lib/sass/script/css_lexer.rb +9 -4
  33. data/lib/sass/script/css_parser.rb +6 -2
  34. data/lib/sass/script/functions.rb +1343 -590
  35. data/lib/sass/script/lexer.rb +84 -52
  36. data/lib/sass/script/parser.rb +217 -97
  37. data/lib/sass/script/tree/funcall.rb +290 -0
  38. data/lib/sass/script/{interpolation.rb → tree/interpolation.rb} +34 -13
  39. data/lib/sass/script/tree/list_literal.rb +80 -0
  40. data/lib/sass/script/tree/literal.rb +47 -0
  41. data/lib/sass/script/tree/map_literal.rb +64 -0
  42. data/lib/sass/script/{node.rb → tree/node.rb} +22 -12
  43. data/lib/sass/script/{operation.rb → tree/operation.rb} +17 -25
  44. data/lib/sass/script/tree/selector.rb +30 -0
  45. data/lib/sass/script/{string_interpolation.rb → tree/string_interpolation.rb} +5 -4
  46. data/lib/sass/script/{unary_operation.rb → tree/unary_operation.rb} +14 -9
  47. data/lib/sass/script/tree/variable.rb +57 -0
  48. data/lib/sass/script/tree.rb +16 -0
  49. data/lib/sass/script/{arg_list.rb → value/arg_list.rb} +4 -24
  50. data/lib/sass/script/value/base.rb +248 -0
  51. data/lib/sass/script/value/bool.rb +36 -0
  52. data/lib/sass/script/{color.rb → value/color.rb} +239 -195
  53. data/lib/sass/script/value/helpers.rb +155 -0
  54. data/lib/sass/script/value/list.rb +119 -0
  55. data/lib/sass/script/value/map.rb +70 -0
  56. data/lib/sass/script/value/null.rb +45 -0
  57. data/lib/sass/script/{number.rb → value/number.rb} +91 -65
  58. data/lib/sass/script/{string.rb → value/string.rb} +9 -11
  59. data/lib/sass/script/value.rb +11 -0
  60. data/lib/sass/script.rb +35 -8
  61. data/lib/sass/scss/css_parser.rb +2 -1
  62. data/lib/sass/scss/parser.rb +338 -170
  63. data/lib/sass/scss/rx.rb +5 -6
  64. data/lib/sass/scss/script_lexer.rb +1 -0
  65. data/lib/sass/scss/script_parser.rb +1 -0
  66. data/lib/sass/scss/static_parser.rb +23 -6
  67. data/lib/sass/selector/abstract_sequence.rb +2 -2
  68. data/lib/sass/selector/comma_sequence.rb +21 -16
  69. data/lib/sass/selector/sequence.rb +60 -34
  70. data/lib/sass/selector/simple.rb +11 -12
  71. data/lib/sass/selector/simple_sequence.rb +55 -33
  72. data/lib/sass/selector.rb +52 -48
  73. data/lib/sass/source/map.rb +211 -0
  74. data/lib/sass/source/position.rb +39 -0
  75. data/lib/sass/source/range.rb +41 -0
  76. data/lib/sass/stack.rb +120 -0
  77. data/lib/sass/supports.rb +12 -13
  78. data/lib/sass/tree/at_root_node.rb +82 -0
  79. data/lib/sass/tree/comment_node.rb +3 -3
  80. data/lib/sass/tree/css_import_node.rb +11 -11
  81. data/lib/sass/tree/debug_node.rb +2 -2
  82. data/lib/sass/tree/directive_node.rb +13 -2
  83. data/lib/sass/tree/each_node.rb +8 -8
  84. data/lib/sass/tree/extend_node.rb +13 -6
  85. data/lib/sass/tree/for_node.rb +4 -4
  86. data/lib/sass/tree/function_node.rb +5 -4
  87. data/lib/sass/tree/if_node.rb +1 -1
  88. data/lib/sass/tree/import_node.rb +4 -5
  89. data/lib/sass/tree/media_node.rb +4 -14
  90. data/lib/sass/tree/mixin_def_node.rb +4 -4
  91. data/lib/sass/tree/mixin_node.rb +21 -8
  92. data/lib/sass/tree/node.rb +29 -12
  93. data/lib/sass/tree/prop_node.rb +38 -18
  94. data/lib/sass/tree/return_node.rb +3 -2
  95. data/lib/sass/tree/root_node.rb +19 -3
  96. data/lib/sass/tree/rule_node.rb +25 -17
  97. data/lib/sass/tree/supports_node.rb +0 -13
  98. data/lib/sass/tree/trace_node.rb +2 -1
  99. data/lib/sass/tree/variable_node.rb +9 -3
  100. data/lib/sass/tree/visitors/base.rb +6 -6
  101. data/lib/sass/tree/visitors/check_nesting.rb +12 -9
  102. data/lib/sass/tree/visitors/convert.rb +63 -38
  103. data/lib/sass/tree/visitors/cssize.rb +63 -23
  104. data/lib/sass/tree/visitors/deep_copy.rb +6 -5
  105. data/lib/sass/tree/visitors/extend.rb +7 -7
  106. data/lib/sass/tree/visitors/perform.rb +256 -151
  107. data/lib/sass/tree/visitors/set_options.rb +6 -6
  108. data/lib/sass/tree/visitors/to_css.rb +231 -81
  109. data/lib/sass/tree/warn_node.rb +2 -2
  110. data/lib/sass/tree/while_node.rb +2 -2
  111. data/lib/sass/util/multibyte_string_scanner.rb +2 -0
  112. data/lib/sass/util/normalized_map.rb +65 -0
  113. data/lib/sass/util/ordered_hash.rb +188 -0
  114. data/lib/sass/util/subset_map.rb +3 -2
  115. data/lib/sass/util/test.rb +9 -0
  116. data/lib/sass/util.rb +220 -34
  117. data/lib/sass/version.rb +9 -9
  118. data/lib/sass.rb +14 -7
  119. data/test/sass/compiler_test.rb +213 -0
  120. data/test/sass/conversion_test.rb +235 -9
  121. data/test/sass/engine_test.rb +230 -60
  122. data/test/sass/exec_test.rb +86 -0
  123. data/test/sass/extend_test.rb +215 -147
  124. data/test/sass/functions_test.rb +584 -99
  125. data/test/sass/importer_test.rb +165 -17
  126. data/test/sass/plugin_test.rb +19 -13
  127. data/test/sass/script_conversion_test.rb +40 -0
  128. data/test/sass/script_test.rb +231 -21
  129. data/test/sass/scss/css_test.rb +14 -5
  130. data/test/sass/scss/scss_test.rb +1266 -66
  131. data/test/sass/source_map_test.rb +879 -0
  132. data/test/sass/templates/bork5.sass +3 -0
  133. data/test/sass/util/normalized_map_test.rb +30 -0
  134. data/test/sass/util_test.rb +90 -0
  135. data/test/sass/value_helpers_test.rb +181 -0
  136. data/test/test_helper.rb +7 -2
  137. metadata +316 -291
  138. data/lib/sass/script/bool.rb +0 -18
  139. data/lib/sass/script/funcall.rb +0 -231
  140. data/lib/sass/script/list.rb +0 -84
  141. data/lib/sass/script/literal.rb +0 -239
  142. data/lib/sass/script/null.rb +0 -34
  143. data/lib/sass/script/variable.rb +0 -58
  144. data/test/Gemfile +0 -3
  145. data/vendor/listen/CHANGELOG.md +0 -221
  146. data/vendor/listen/CONTRIBUTING.md +0 -38
  147. data/vendor/listen/Gemfile +0 -30
  148. data/vendor/listen/Guardfile +0 -8
  149. data/vendor/listen/LICENSE +0 -20
  150. data/vendor/listen/README.md +0 -315
  151. data/vendor/listen/Rakefile +0 -47
  152. data/vendor/listen/Vagrantfile +0 -96
  153. data/vendor/listen/lib/listen/adapter.rb +0 -214
  154. data/vendor/listen/lib/listen/adapters/bsd.rb +0 -112
  155. data/vendor/listen/lib/listen/adapters/darwin.rb +0 -85
  156. data/vendor/listen/lib/listen/adapters/linux.rb +0 -113
  157. data/vendor/listen/lib/listen/adapters/polling.rb +0 -67
  158. data/vendor/listen/lib/listen/adapters/windows.rb +0 -87
  159. data/vendor/listen/lib/listen/dependency_manager.rb +0 -126
  160. data/vendor/listen/lib/listen/directory_record.rb +0 -371
  161. data/vendor/listen/lib/listen/listener.rb +0 -225
  162. data/vendor/listen/lib/listen/multi_listener.rb +0 -143
  163. data/vendor/listen/lib/listen/turnstile.rb +0 -28
  164. data/vendor/listen/lib/listen/version.rb +0 -3
  165. data/vendor/listen/lib/listen.rb +0 -40
  166. data/vendor/listen/listen.gemspec +0 -22
  167. data/vendor/listen/spec/listen/adapter_spec.rb +0 -183
  168. data/vendor/listen/spec/listen/adapters/bsd_spec.rb +0 -36
  169. data/vendor/listen/spec/listen/adapters/darwin_spec.rb +0 -37
  170. data/vendor/listen/spec/listen/adapters/linux_spec.rb +0 -47
  171. data/vendor/listen/spec/listen/adapters/polling_spec.rb +0 -68
  172. data/vendor/listen/spec/listen/adapters/windows_spec.rb +0 -30
  173. data/vendor/listen/spec/listen/dependency_manager_spec.rb +0 -107
  174. data/vendor/listen/spec/listen/directory_record_spec.rb +0 -1225
  175. data/vendor/listen/spec/listen/listener_spec.rb +0 -169
  176. data/vendor/listen/spec/listen/multi_listener_spec.rb +0 -174
  177. data/vendor/listen/spec/listen/turnstile_spec.rb +0 -56
  178. data/vendor/listen/spec/listen_spec.rb +0 -73
  179. data/vendor/listen/spec/spec_helper.rb +0 -21
  180. data/vendor/listen/spec/support/adapter_helper.rb +0 -629
  181. data/vendor/listen/spec/support/directory_record_helper.rb +0 -55
  182. data/vendor/listen/spec/support/fixtures_helper.rb +0 -29
  183. data/vendor/listen/spec/support/listeners_helper.rb +0 -156
  184. data/vendor/listen/spec/support/platform_helper.rb +0 -15
@@ -154,7 +154,7 @@ SCSS
154
154
  assert_unification '.foo#baz', '#baz {@extend .foo}', '#baz'
155
155
 
156
156
  assert_extend_doesnt_match('#bar', '.foo', :failed_to_unify, 2) do
157
- assert_unification '.foo#baz', '#bar {@extend .foo}', '.foo#baz'
157
+ render_unification '.foo#baz', '#bar {@extend .foo}'
158
158
  end
159
159
  end
160
160
 
@@ -180,7 +180,7 @@ SCSS
180
180
  assert_unification 'ns|*.foo', '*|* {@extend .foo}', 'ns|*'
181
181
 
182
182
  assert_extend_doesnt_match('ns2|*', '.foo', :failed_to_unify, 2) do
183
- assert_unification 'ns1|*.foo', 'ns2|* {@extend .foo}', 'ns1|*.foo'
183
+ render_unification 'ns1|*.foo', 'ns2|* {@extend .foo}'
184
184
  end
185
185
 
186
186
  assert_unification 'ns|*.foo', 'ns|* {@extend .foo}', 'ns|*'
@@ -200,7 +200,7 @@ SCSS
200
200
  assert_unification 'ns|a.foo', '*|* {@extend .foo}', 'ns|a'
201
201
 
202
202
  assert_extend_doesnt_match('ns2|*', '.foo', :failed_to_unify, 2) do
203
- assert_unification 'ns1|a.foo', 'ns2|* {@extend .foo}', 'ns1|a.foo'
203
+ render_unification 'ns1|a.foo', 'ns2|* {@extend .foo}'
204
204
  end
205
205
 
206
206
  assert_unification 'ns|a.foo', 'ns|* {@extend .foo}', 'ns|a'
@@ -227,7 +227,7 @@ SCSS
227
227
  assert_unification 'ns|*.foo', '*|a {@extend .foo}', 'ns|*.foo, ns|a'
228
228
 
229
229
  assert_extend_doesnt_match('ns2|a', '.foo', :failed_to_unify, 2) do
230
- assert_unification 'ns1|*.foo', 'ns2|a {@extend .foo}', 'ns1|*.foo'
230
+ render_unification 'ns1|*.foo', 'ns2|a {@extend .foo}'
231
231
  end
232
232
 
233
233
  assert_unification 'ns|*.foo', 'ns|a {@extend .foo}', 'ns|*.foo, ns|a'
@@ -242,7 +242,7 @@ SCSS
242
242
  assert_unification '*|a.foo', 'ns|a {@extend .foo}', '*|a.foo, ns|a'
243
243
 
244
244
  assert_extend_doesnt_match('h1', '.foo', :failed_to_unify, 2) do
245
- assert_unification 'a.foo', 'h1 {@extend .foo}', 'a.foo'
245
+ render_unification 'a.foo', 'h1 {@extend .foo}'
246
246
  end
247
247
  end
248
248
 
@@ -251,7 +251,7 @@ SCSS
251
251
  assert_unification 'ns|a.foo', '*|a {@extend .foo}', 'ns|a'
252
252
 
253
253
  assert_extend_doesnt_match('ns2|a', '.foo', :failed_to_unify, 2) do
254
- assert_unification 'ns1|a.foo', 'ns2|a {@extend .foo}', 'ns1|a.foo'
254
+ render_unification 'ns1|a.foo', 'ns2|a {@extend .foo}'
255
255
  end
256
256
 
257
257
  assert_unification 'ns|a.foo', 'ns|a {@extend .foo}', 'ns|a'
@@ -270,11 +270,11 @@ SCSS
270
270
  assert_unification ':foo.baz', '::foo {@extend .baz}', ':foo.baz, :foo::foo'
271
271
 
272
272
  assert_extend_doesnt_match('::bar', '.baz', :failed_to_unify, 2) do
273
- assert_unification '::foo.baz', '::bar {@extend .baz}', '::foo.baz'
273
+ render_unification '::foo.baz', '::bar {@extend .baz}'
274
274
  end
275
275
 
276
276
  assert_extend_doesnt_match('::foo(2n+1)', '.baz', :failed_to_unify, 2) do
277
- assert_unification '::foo.baz', '::foo(2n+1) {@extend .baz}', '::foo.baz'
277
+ render_unification '::foo.baz', '::foo(2n+1) {@extend .baz}'
278
278
  end
279
279
 
280
280
  assert_unification '::foo.baz', '::foo {@extend .baz}', '::foo'
@@ -348,7 +348,7 @@ SCSS
348
348
 
349
349
  def test_long_extendee_requires_all_selectors
350
350
  assert_extend_doesnt_match('.baz', '.foo.bar', :not_found, 2) do
351
- assert_extends '.foo', '.baz {@extend .foo.bar}', '.foo'
351
+ render_extends '.foo', '.baz {@extend .foo.bar}'
352
352
  end
353
353
  end
354
354
 
@@ -372,11 +372,11 @@ SCSS
372
372
 
373
373
  def test_long_extender_aborts_unification
374
374
  assert_extend_doesnt_match('h1.baz', '.foo', :failed_to_unify, 2) do
375
- assert_extends 'a.foo#bar', 'h1.baz {@extend .foo}', 'a.foo#bar'
375
+ render_extends 'a.foo#bar', 'h1.baz {@extend .foo}'
376
376
  end
377
377
 
378
378
  assert_extend_doesnt_match('.bang#baz', '.foo', :failed_to_unify, 2) do
379
- assert_extends 'a.foo#bar', '.bang#baz {@extend .foo}', 'a.foo#bar'
379
+ render_extends 'a.foo#bar', '.bang#baz {@extend .foo}'
380
380
  end
381
381
  end
382
382
 
@@ -392,7 +392,7 @@ SCSS
392
392
 
393
393
  def test_nested_extender_aborts_unification
394
394
  assert_extend_doesnt_match('foo bar', '.foo', :failed_to_unify, 2) do
395
- assert_extends 'baz.foo', 'foo bar {@extend .foo}', 'baz.foo'
395
+ render_extends 'baz.foo', 'foo bar {@extend .foo}'
396
396
  end
397
397
  end
398
398
 
@@ -489,7 +489,7 @@ CSS
489
489
  SCSS
490
490
  end
491
491
 
492
- def test_nested_extender_with_early_child_selectors_doesnt_subseq_them
492
+ def test_nested_extender_with_early_child_selector
493
493
  assert_equal <<CSS, render(<<SCSS)
494
494
  .foo .bar, .foo .bip > .baz {
495
495
  a: b; }
@@ -810,10 +810,7 @@ SCSS
810
810
 
811
811
  def test_placeholder_selector_as_modifier
812
812
  assert_extend_doesnt_match('div', '%foo', :failed_to_unify, 3) do
813
- assert_equal <<CSS, render(<<SCSS)
814
- a.baz.bar {
815
- color: blue; }
816
- CSS
813
+ render(<<SCSS)
817
814
  a%foo.baz {color: blue}
818
815
  .bar {@extend %foo}
819
816
  div {@extend %foo}
@@ -844,16 +841,11 @@ SCSS
844
841
  end
845
842
 
846
843
  def test_extend_out_of_media
847
- assert_warning(<<WARN) {assert_equal(<<CSS, render(<<SCSS))}
848
- DEPRECATION WARNING on line 3 of test_extend_out_of_media_inline.scss:
849
- @extending an outer selector from within @media is deprecated.
850
- You may only @extend selectors within the same directive.
851
- This will be an error in Sass 3.3.
852
- It can only work once @extend is supported natively in the browser.
853
- WARN
854
- .foo {
855
- a: b; }
856
- CSS
844
+ assert_raise_message(Sass::SyntaxError, <<ERR) {render(<<SCSS)}
845
+ You may not @extend an outer selector from within @media.
846
+ You may only @extend selectors within the same directive.
847
+ From "@extend .foo" on line 3 of test_extend_out_of_media_inline.scss.
848
+ ERR
857
849
  .foo {a: b}
858
850
  @media screen {
859
851
  .bar {@extend .foo}
@@ -862,18 +854,11 @@ SCSS
862
854
  end
863
855
 
864
856
  def test_extend_out_of_unknown_directive
865
- assert_warning(<<WARN) {assert_equal(<<CSS, render(<<SCSS))}
866
- DEPRECATION WARNING on line 3 of test_extend_out_of_unknown_directive_inline.scss:
867
- @extending an outer selector from within @flooblehoof is deprecated.
868
- You may only @extend selectors within the same directive.
869
- This will be an error in Sass 3.3.
870
- It can only work once @extend is supported natively in the browser.
871
- WARN
872
- .foo {
873
- a: b; }
874
-
875
- @flooblehoof {}
876
- CSS
857
+ assert_raise_message(Sass::SyntaxError, <<ERR) {render(<<SCSS)}
858
+ You may not @extend an outer selector from within @flooblehoof.
859
+ You may only @extend selectors within the same directive.
860
+ From "@extend .foo" on line 3 of test_extend_out_of_unknown_directive_inline.scss.
861
+ ERR
877
862
  .foo {a: b}
878
863
  @flooblehoof {
879
864
  .bar {@extend .foo}
@@ -882,19 +867,11 @@ SCSS
882
867
  end
883
868
 
884
869
  def test_extend_out_of_nested_directives
885
- assert_warning(<<WARN) {assert_equal(<<CSS, render(<<SCSS))}
886
- DEPRECATION WARNING on line 4 of test_extend_out_of_nested_directives_inline.scss:
887
- @extending an outer selector from within @flooblehoof is deprecated.
888
- You may only @extend selectors within the same directive.
889
- This will be an error in Sass 3.3.
890
- It can only work once @extend is supported natively in the browser.
891
- WARN
892
- @media screen {
893
- .foo {
894
- a: b; }
895
-
896
- @flooblehoof {} }
897
- CSS
870
+ assert_raise_message(Sass::SyntaxError, <<ERR) {render(<<SCSS)}
871
+ You may not @extend an outer selector from within @flooblehoof.
872
+ You may only @extend selectors within the same directive.
873
+ From "@extend .foo" on line 4 of test_extend_out_of_nested_directives_inline.scss.
874
+ ERR
898
875
  @media screen {
899
876
  .foo {a: b}
900
877
  @flooblehoof {
@@ -962,7 +939,6 @@ SCSS
962
939
  @flooblehoof {
963
940
  .foo, .bar {
964
941
  a: b; } }
965
-
966
942
  @flooblehoof {}
967
943
  CSS
968
944
  @flooblehoof {.foo {a: b}}
@@ -985,20 +961,11 @@ SCSS
985
961
  end
986
962
 
987
963
  def test_extend_within_and_without_media
988
- assert_warning(<<WARN) {assert_equal(<<CSS, render(<<SCSS))}
989
- DEPRECATION WARNING on line 4 of test_extend_within_and_without_media_inline.scss:
990
- @extending an outer selector from within @media is deprecated.
991
- You may only @extend selectors within the same directive.
992
- This will be an error in Sass 3.3.
993
- It can only work once @extend is supported natively in the browser.
994
- WARN
995
- .foo {
996
- a: b; }
997
-
998
- @media screen {
999
- .foo, .bar {
1000
- c: d; } }
1001
- CSS
964
+ assert_raise_message(Sass::SyntaxError, <<ERR) {render(<<SCSS)}
965
+ You may not @extend an outer selector from within @media.
966
+ You may only @extend selectors within the same directive.
967
+ From "@extend .foo" on line 4 of test_extend_within_and_without_media_inline.scss.
968
+ ERR
1002
969
  .foo {a: b}
1003
970
  @media screen {
1004
971
  .foo {c: d}
@@ -1008,20 +975,11 @@ SCSS
1008
975
  end
1009
976
 
1010
977
  def test_extend_within_and_without_unknown_directive
1011
- assert_warning(<<WARN) {assert_equal(<<CSS, render(<<SCSS))}
1012
- DEPRECATION WARNING on line 4 of test_extend_within_and_without_unknown_directive_inline.scss:
1013
- @extending an outer selector from within @flooblehoof is deprecated.
1014
- You may only @extend selectors within the same directive.
1015
- This will be an error in Sass 3.3.
1016
- It can only work once @extend is supported natively in the browser.
1017
- WARN
1018
- .foo {
1019
- a: b; }
1020
-
1021
- @flooblehoof {
1022
- .foo, .bar {
1023
- c: d; } }
1024
- CSS
978
+ assert_raise_message(Sass::SyntaxError, <<ERR) {render(<<SCSS)}
979
+ You may not @extend an outer selector from within @flooblehoof.
980
+ You may only @extend selectors within the same directive.
981
+ From "@extend .foo" on line 4 of test_extend_within_and_without_unknown_directive_inline.scss.
982
+ ERR
1025
983
  .foo {a: b}
1026
984
  @flooblehoof {
1027
985
  .foo {c: d}
@@ -1031,21 +989,11 @@ SCSS
1031
989
  end
1032
990
 
1033
991
  def test_extend_within_and_without_nested_directives
1034
- assert_warning(<<WARN) {assert_equal(<<CSS, render(<<SCSS))}
1035
- DEPRECATION WARNING on line 5 of test_extend_within_and_without_nested_directives_inline.scss:
1036
- @extending an outer selector from within @flooblehoof is deprecated.
1037
- You may only @extend selectors within the same directive.
1038
- This will be an error in Sass 3.3.
1039
- It can only work once @extend is supported natively in the browser.
1040
- WARN
1041
- @media screen {
1042
- .foo {
1043
- a: b; }
1044
-
1045
- @flooblehoof {
1046
- .foo, .bar {
1047
- c: d; } } }
1048
- CSS
992
+ assert_raise_message(Sass::SyntaxError, <<ERR) {render(<<SCSS)}
993
+ You may not @extend an outer selector from within @flooblehoof.
994
+ You may only @extend selectors within the same directive.
995
+ From "@extend .foo" on line 5 of test_extend_within_and_without_nested_directives_inline.scss.
996
+ ERR
1049
997
  @media screen {
1050
998
  .foo {a: b}
1051
999
  @flooblehoof {
@@ -1112,36 +1060,31 @@ CSS
1112
1060
  x! .bar {a: b}
1113
1061
  y! .bap {@extend .bar}
1114
1062
  SCSS
1115
- end
1063
+ end
1116
1064
 
1117
1065
  def test_extend_warns_when_extendee_doesnt_exist
1118
- assert_warning(<<WARN) {assert_equal("", render(<<SCSS))}
1119
- WARNING on line 1 of test_extend_warns_when_extendee_doesnt_exist_inline.scss: ".foo" failed to @extend ".bar".
1120
- The selector ".bar" was not found.
1121
- This will be an error in future releases of Sass.
1122
- Use "@extend .bar !optional" if the extend should be able to fail.
1123
- WARN
1066
+ assert_raise_message(Sass::SyntaxError, <<ERR) {render(<<SCSS)}
1067
+ ".foo" failed to @extend ".bar".
1068
+ The selector ".bar" was not found.
1069
+ Use "@extend .bar !optional" if the extend should be able to fail.
1070
+ ERR
1124
1071
  .foo {@extend .bar}
1125
1072
  SCSS
1126
1073
  end
1127
1074
 
1128
1075
  def test_extend_warns_when_extension_fails
1129
- assert_warning(<<WARN) {assert_equal(<<CSS, render(<<SCSS))}
1130
- WARNING on line 2 of test_extend_warns_when_extension_fails_inline.scss: "b.foo" failed to @extend ".bar".
1131
- No selectors matching ".bar" could be unified with "b.foo".
1132
- This will be an error in future releases of Sass.
1133
- Use "@extend .bar !optional" if the extend should be able to fail.
1134
- WARN
1135
- a.bar {
1136
- a: b; }
1137
- CSS
1076
+ assert_raise_message(Sass::SyntaxError, <<ERR) {render(<<SCSS)}
1077
+ "b.foo" failed to @extend ".bar".
1078
+ No selectors matching ".bar" could be unified with "b.foo".
1079
+ Use "@extend .bar !optional" if the extend should be able to fail.
1080
+ ERR
1138
1081
  a.bar {a: b}
1139
1082
  b.foo {@extend .bar}
1140
1083
  SCSS
1141
1084
  end
1142
1085
 
1143
- def test_extend_does_not_warn_when_one_extension_fails_but_others_dont
1144
- assert_no_warning {assert_equal(<<CSS, render(<<SCSS))}
1086
+ def test_extend_succeeds_when_one_extension_fails_but_others_dont
1087
+ assert_equal(<<CSS, render(<<SCSS))
1145
1088
  a.bar {
1146
1089
  a: b; }
1147
1090
 
@@ -1154,37 +1097,153 @@ b.foo {@extend .bar}
1154
1097
  SCSS
1155
1098
  end
1156
1099
 
1157
- def test_extend_does_not_warn_when_one_extension_fails_but_others_dont
1158
- assert_no_warning {assert_equal(<<CSS, render(<<SCSS))}
1100
+ def test_optional_extend_succeeds_when_extendee_doesnt_exist
1101
+ assert_equal("", render(<<SCSS))
1102
+ .foo {@extend .bar !optional}
1103
+ SCSS
1104
+ end
1105
+
1106
+ def test_optional_extend_succeeds_when_extension_fails
1107
+ assert_equal(<<CSS, render(<<SCSS))
1159
1108
  a.bar {
1160
1109
  a: b; }
1161
-
1162
- .bar, b.foo {
1163
- c: d; }
1164
1110
  CSS
1165
1111
  a.bar {a: b}
1166
- .bar {c: d}
1167
- b.foo {@extend .bar}
1112
+ b.foo {@extend .bar !optional}
1168
1113
  SCSS
1169
1114
  end
1170
1115
 
1171
- def test_optional_extend_does_not_warn_when_extendee_doesnt_exist
1172
- assert_no_warning {assert_equal("", render(<<SCSS))}
1173
- .foo {@extend .bar !optional}
1116
+ # Regression Tests
1117
+
1118
+ def test_pseudo_element_superselector
1119
+ # Pseudo-elements shouldn't be removed in superselector calculations.
1120
+ assert_equal <<CSS, render(<<SCSS)
1121
+ a#bar, a#bar::fblthp {
1122
+ a: b; }
1123
+ CSS
1124
+ %x#bar {a: b} // Add an id to make the results have high specificity
1125
+ %y, %y::fblthp {@extend %x}
1126
+ a {@extend %y}
1127
+ SCSS
1128
+
1129
+ # Pseudo-classes can be removed when the second law allows.
1130
+ assert_equal <<CSS, render(<<SCSS)
1131
+ a#bar {
1132
+ a: b; }
1133
+ CSS
1134
+ %x#bar {a: b}
1135
+ %y, %y:fblthp {@extend %x}
1136
+ a {@extend %y}
1174
1137
  SCSS
1138
+
1139
+ # A few pseudo-elements can be written as pseudo-elements for historical
1140
+ # reasons. See http://www.w3.org/TR/selectors4/#pseudo-elements.
1141
+ %w[first-line first-letter before after].each do |pseudo|
1142
+ assert_equal <<CSS, render(<<SCSS)
1143
+ a#bar, a#bar:#{pseudo} {
1144
+ a: b; }
1145
+ CSS
1146
+ %x#bar {a: b}
1147
+ %y, %y:#{pseudo} {@extend %x}
1148
+ a {@extend %y}
1149
+ SCSS
1150
+ end
1175
1151
  end
1176
1152
 
1177
- def test_optional_extend_does_not_warn_when_extension_fails
1178
- assert_no_warning {assert_equal(<<CSS, render(<<SCSS))}
1179
- a.bar {
1153
+ def test_multiple_source_redundancy_elimination
1154
+ assert_equal <<CSS, render(<<SCSS)
1155
+ .test-case, .test-case:active {
1156
+ color: red; }
1157
+
1158
+ .test-case:hover {
1159
+ color: green; }
1160
+ CSS
1161
+ %default-color {color: red}
1162
+ %alt-color {color: green}
1163
+
1164
+ %default-style {
1165
+ @extend %default-color;
1166
+ &:hover {@extend %alt-color}
1167
+ &:active {@extend %default-color}
1168
+ }
1169
+
1170
+ .test-case {@extend %default-style}
1171
+ SCSS
1172
+ end
1173
+
1174
+ def test_nested_sibling_extend
1175
+ assert_equal <<CSS, render(<<SCSS)
1176
+ .parent .bar, .parent .foo {
1177
+ width: 2000px; }
1178
+ CSS
1179
+ .foo {@extend .bar}
1180
+
1181
+ .parent {
1182
+ .bar {
1183
+ width: 2000px;
1184
+ }
1185
+ .foo {
1186
+ @extend .bar
1187
+ }
1188
+ }
1189
+ SCSS
1190
+ end
1191
+
1192
+ def test_parent_and_sibling_extend
1193
+ assert_equal <<CSS, render(<<SCSS)
1194
+ .parent1 .parent2 .child1.child2, .parent2 .parent1 .child1.child2 {
1195
+ c: d; }
1196
+ CSS
1197
+ %foo %bar%baz {c: d}
1198
+
1199
+ .parent1 {
1200
+ @extend %foo;
1201
+ .child1 {@extend %bar}
1202
+ }
1203
+
1204
+ .parent2 {
1205
+ @extend %foo;
1206
+ .child2 {@extend %baz}
1207
+ }
1208
+ SCSS
1209
+ end
1210
+
1211
+ def test_nested_extend_specificity
1212
+ assert_equal <<CSS, render(<<SCSS)
1213
+ a :b, a :b:c {
1180
1214
  a: b; }
1181
1215
  CSS
1182
- a.bar {a: b}
1183
- b.foo {@extend .bar !optional}
1216
+ %foo {a: b}
1217
+
1218
+ a {
1219
+ :b {@extend %foo}
1220
+ :b:c {@extend %foo}
1221
+ }
1184
1222
  SCSS
1185
1223
  end
1186
1224
 
1187
- # Regression Tests
1225
+ def test_nested_double_extend_optimization
1226
+ assert_equal <<CSS, render(<<SCSS)
1227
+ .parent1 .child {
1228
+ a: b; }
1229
+ CSS
1230
+ %foo %bar {
1231
+ a: b;
1232
+ }
1233
+
1234
+ .parent1 {
1235
+ @extend %foo;
1236
+
1237
+ .child {
1238
+ @extend %bar;
1239
+ }
1240
+ }
1241
+
1242
+ .parent2 {
1243
+ @extend %foo;
1244
+ }
1245
+ SCSS
1246
+ end
1188
1247
 
1189
1248
  def test_extend_in_double_nested_media_query
1190
1249
  assert_equal <<CSS, render(<<SCSS)
@@ -1302,29 +1361,29 @@ SCSS
1302
1361
 
1303
1362
  def test_extend_cross_branch_redundancy_elimination
1304
1363
  assert_equal <<CSS, render(<<SCSS)
1305
- a c d, b c a d {
1364
+ .a .c .d, .b .c .a .d {
1306
1365
  a: b; }
1307
1366
  CSS
1308
- %x c %y {a: b}
1309
- a, b {@extend %x}
1310
- a d {@extend %y}
1367
+ %x .c %y {a: b}
1368
+ .a, .b {@extend %x}
1369
+ .a .d {@extend %y}
1311
1370
  SCSS
1312
1371
 
1313
1372
  assert_equal <<CSS, render(<<SCSS)
1314
- e a c d, a c e d, e b c a d, b c a e d {
1373
+ .e .a .c .d, .a .c .e .d, .e .b .c .a .d, .b .c .a .e .d {
1315
1374
  a: b; }
1316
1375
  CSS
1317
- e %z {a: b}
1318
- %x c %y {@extend %z}
1319
- a, b {@extend %x}
1320
- a d {@extend %y}
1376
+ .e %z {a: b}
1377
+ %x .c %y {@extend %z}
1378
+ .a, .b {@extend %x}
1379
+ .a .d {@extend %y}
1321
1380
  SCSS
1322
1381
  end
1323
1382
 
1324
1383
  private
1325
1384
 
1326
1385
  def assert_extend_doesnt_match(extender, target, reason, line, syntax = :scss)
1327
- warn = "\"#{extender}\" failed to @extend \"#{target}\"."
1386
+ message = "\"#{extender}\" failed to @extend \"#{target}\"."
1328
1387
  reason =
1329
1388
  if reason == :not_found
1330
1389
  "The selector \"#{target}\" was not found."
@@ -1332,12 +1391,11 @@ SCSS
1332
1391
  "No selectors matching \"#{target}\" could be unified with \"#{extender}\"."
1333
1392
  end
1334
1393
 
1335
- assert_warning(<<WARNING) {yield}
1336
- WARNING on line #{line} of #{filename_for_test syntax}: #{warn}
1337
- #{reason}
1338
- This will be an error in future releases of Sass.
1339
- Use "@extend #{target} !optional" if the extend should be able to fail.
1340
- WARNING
1394
+ assert_raise_message(Sass::SyntaxError, <<ERR) {yield}
1395
+ #{message}
1396
+ #{reason}
1397
+ Use "@extend #{target} !optional" if the extend should be able to fail.
1398
+ ERR
1341
1399
  end
1342
1400
 
1343
1401
  def assert_unification(selector, extension, unified)
@@ -1348,11 +1406,21 @@ WARNING
1348
1406
  unified.split(', ').map {|s| "-a #{s}"}.join(', '))
1349
1407
  end
1350
1408
 
1409
+ def render_unification(selector, extension)
1410
+ render_extends(
1411
+ "%-a #{selector}",
1412
+ extension + " -a {@extend %-a}")
1413
+ end
1414
+
1351
1415
  def assert_extends(selector, extension, result)
1352
- assert_equal <<CSS, render(<<SCSS)
1416
+ assert_equal <<CSS, render_extends(selector, extension)
1353
1417
  #{result} {
1354
1418
  a: b; }
1355
1419
  CSS
1420
+ end
1421
+
1422
+ def render_extends(selector, extension)
1423
+ render(<<SCSS)
1356
1424
  #{selector} {a: b}
1357
1425
  #{extension}
1358
1426
  SCSS