sass 3.2.0.alpha.261 → 3.2.0.alpha.268

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.
data/REVISION CHANGED
@@ -1 +1 @@
1
- fe4e2a9b7d9b0cc0eceb20e97dc43875258d6424
1
+ bdee97a283eb9a69301f0bd60e8dc28db78517c3
data/VERSION CHANGED
@@ -1 +1 @@
1
- 3.2.0.alpha.261
1
+ 3.2.0.alpha.268
@@ -683,8 +683,9 @@ WARNING
683
683
  raise SyntaxError.new("Invalid extend directive '@extend': expected expression.") unless value
684
684
  raise SyntaxError.new("Illegal nesting: Nothing may be nested beneath extend directives.",
685
685
  :line => @line + 1) unless line.children.empty?
686
+ optional = !!value.gsub!(/\s+#{Sass::SCSS::RX::OPTIONAL}$/, '')
686
687
  offset = line.offset + line.text.index(value).to_i
687
- Tree::ExtendNode.new(parse_interp(value, offset))
688
+ Tree::ExtendNode.new(parse_interp(value, offset), optional)
688
689
  when 'warn'
689
690
  raise SyntaxError.new("Invalid warn directive '@warn': expected expression.") unless value
690
691
  raise SyntaxError.new("Illegal nesting: Nothing may be nested beneath warn directives.",
@@ -25,14 +25,14 @@ module Less
25
25
  sel = selector_str(path)
26
26
  base = selector_str(selector_base(path))
27
27
  if base == sel
28
- env << Node::SassNode.new(Sass::Tree::ExtendNode.new([sel]))
28
+ env << Node::SassNode.new(Sass::Tree::ExtendNode.new([sel], false))
29
29
  else
30
30
  Sass::Util.sass_warn <<WARNING
31
31
  WARNING: Sass doesn't support mixing in selector sequences.
32
32
  Replacing "#{sel}" with "@extend #{base}"
33
33
  WARNING
34
34
  env << Node::SassNode.new(Sass::Tree::CommentNode.new(["// #{sel};"], :silent))
35
- env << Node::SassNode.new(Sass::Tree::ExtendNode.new([base]))
35
+ env << Node::SassNode.new(Sass::Tree::ExtendNode.new([base], false))
36
36
  end
37
37
  end
38
38
  end
@@ -289,7 +289,10 @@ module Sass
289
289
  end
290
290
 
291
291
  def extend_directive
292
- node(Sass::Tree::ExtendNode.new(expr!(:selector_sequence)))
292
+ selector = expr!(:selector_sequence)
293
+ optional = tok(OPTIONAL)
294
+ ss
295
+ node(Sass::Tree::ExtendNode.new(selector, !!optional))
293
296
  end
294
297
 
295
298
  def import_directive
@@ -118,6 +118,7 @@ module Sass
118
118
  HEXCOLOR = /\#[0-9a-fA-F]+/
119
119
  INTERP_START = /#\{/
120
120
  ANY = /:(-[-\w]+-)?any\(/i
121
+ OPTIONAL = /!#{W}optional/i
121
122
 
122
123
  IDENT_HYPHEN_INTERP = /-(#\{)/
123
124
  STRING1_NOINTERP = /\"((?:[^\n\r\f\\"#]|#(?!\{)|\\#{NL}|#{ESCAPE})*)\"/
@@ -102,7 +102,9 @@ module Sass
102
102
  # seq is A, sels is B, and self is C
103
103
 
104
104
  self_without_sel = self.members - sels
105
+ group.each {|e, _| e.result = :failed_to_unify}
105
106
  next unless unified = seq.members.last.unify(self_without_sel, subject?)
107
+ group.each {|e, _| e.result = :succeeded}
106
108
  next if group.map {|e, _| check_directives_match!(e, parent_directives)}.none?
107
109
  new_seq = Sequence.new(seq.members[0...-1] + [unified])
108
110
  new_seq.add_sources!(sources + [seq])
@@ -17,12 +17,19 @@ module Sass::Tree
17
17
  # @return [Array<String, Sass::Script::Node>]
18
18
  attr_accessor :selector
19
19
 
20
+ # Whether the `@extend` is allowed to match no selectors or not.
21
+ #
22
+ # @return [Boolean]
23
+ def optional?; @optional; end
24
+
20
25
  # @param selector [Array<String, Sass::Script::Node>]
21
26
  # The CSS selector to extend,
22
27
  # interspersed with {Sass::Script::Node}s
23
28
  # representing `#{}`-interpolation.
24
- def initialize(selector)
29
+ # @param optional [Boolean] See \{#optional}
30
+ def initialize(selector, optional)
25
31
  @selector = selector
32
+ @optional = optional
26
33
  super()
27
34
  end
28
35
  end
@@ -109,7 +109,7 @@ class Sass::Tree::Visitors::Convert < Sass::Tree::Visitors::Base
109
109
  end
110
110
 
111
111
  def visit_extend(node)
112
- "#{tab_str}@extend #{selector_to_src(node.selector).lstrip}#{semi}\n"
112
+ "#{tab_str}@extend #{selector_to_src(node.selector).lstrip}#{semi}#{" !optional" if node.optional?}\n"
113
113
  end
114
114
 
115
115
  def visit_for(node)
@@ -88,13 +88,17 @@ class Sass::Tree::Visitors::Cssize < Sass::Tree::Visitors::Base
88
88
  # single [ExtendNode] can have multiple Extends if either the parent node or
89
89
  # the extended selector is a comma sequence.
90
90
  #
91
- # @attr extender [Array<Sass::Selector::SimpleSequence, String>]
91
+ # @attr extender [Sass::Selector::Sequence]
92
92
  # The selector of the CSS rule containing the `@extend`.
93
93
  # @attr target [Array<Sass::Selector::Simple>] The selector being `@extend`ed.
94
94
  # @attr node [Sass::Tree::ExtendNode] The node that produced this extend.
95
95
  # @attr directives [Array<Sass::Tree::DirectiveNode>]
96
96
  # The directives containing the `@extend`.
97
- Extend = Struct.new(:extender, :target, :node, :directives)
97
+ # @attr result [Symbol]
98
+ # The result of this extend. One of `:not_found` (the target doesn't exist
99
+ # in the document), `:failed_to_unify` (the target exists but cannot be
100
+ # unified with the extender), or `:succeeded`.
101
+ Extend = Struct.new(:extender, :target, :node, :directives, :result)
98
102
 
99
103
  # Registers an extension in the `@extends` subset map.
100
104
  def visit_extend(node)
@@ -116,7 +120,7 @@ class Sass::Tree::Visitors::Cssize < Sass::Tree::Visitors::Base
116
120
  raise Sass::SyntaxError.new("#{seq} can't extend: invalid selector")
117
121
  end
118
122
 
119
- @extends[sel] = Extend.new(seq, sel, node, @parent_directives.dup)
123
+ @extends[sel] = Extend.new(seq, sel, node, @parent_directives.dup, :not_found)
120
124
  end
121
125
  end
122
126
 
@@ -2,6 +2,9 @@
2
2
  #
3
3
  # Destructively modifies the tree.
4
4
  class Sass::Tree::Visitors::Extend < Sass::Tree::Visitors::Base
5
+ # Performs the given extensions on the static CSS tree based in `root`, then
6
+ # validates that all extends matched some selector.
7
+ #
5
8
  # @param root [Tree::Node] The root node of the tree to visit.
6
9
  # @param extends [Sass::Util::SubsetMap{Selector::Simple =>
7
10
  # Sass::Tree::Visitors::Cssize::Extend}]
@@ -10,6 +13,7 @@ class Sass::Tree::Visitors::Extend < Sass::Tree::Visitors::Base
10
13
  def self.visit(root, extends)
11
14
  return if extends.empty?
12
15
  new(extends).send(:visit, root)
16
+ check_extends_fired! extends
13
17
  end
14
18
 
15
19
  protected
@@ -39,4 +43,25 @@ class Sass::Tree::Visitors::Extend < Sass::Tree::Visitors::Base
39
43
  def visit_rule(node)
40
44
  node.resolved_rules = node.resolved_rules.do_extend(@extends, @parent_directives)
41
45
  end
46
+
47
+ private
48
+
49
+ def self.check_extends_fired!(extends)
50
+ extends.each_value do |ex|
51
+ next if ex.result == :succeeded || ex.node.optional?
52
+ warn = "\"#{ex.extender}\" failed to @extend \"#{ex.target}\"."
53
+ reason =
54
+ if ex.result == :not_found
55
+ "The selector \"#{ex.target}\" was not found."
56
+ else
57
+ "No selectors matching \"#{ex.target}\" could be unified with \"#{ex.extender}\"."
58
+ end
59
+
60
+ Sass::Util.sass_warn <<WARN
61
+ WARNING on line #{ex.node.line}#{" of #{ex.node.filename}" if ex.node.filename}: #{warn}
62
+ #{reason}
63
+ This will be an error in future releases of Sass.
64
+ WARN
65
+ end
66
+ end
42
67
  end
@@ -96,6 +96,14 @@ module Sass
96
96
  def [](set)
97
97
  get(set).map {|v, _| v}
98
98
  end
99
+
100
+ # Iterates over each value in the subset map. Ignores keys completely. If
101
+ # multiple keys have the same value, this will return them multiple times.
102
+ #
103
+ # @yield [Object] Each value in the map.
104
+ def each_value
105
+ @vals.each {|v| yield v}
106
+ end
99
107
  end
100
108
  end
101
109
  end
@@ -1552,6 +1552,17 @@ foo bar {
1552
1552
  SCSS
1553
1553
  end
1554
1554
 
1555
+ def test_extend_with_optional
1556
+ assert_scss_to_sass <<SASS, <<SCSS
1557
+ foo
1558
+ @extend .bar !optional
1559
+ SASS
1560
+ foo {
1561
+ @extend .bar !optional;
1562
+ }
1563
+ SCSS
1564
+ end
1565
+
1555
1566
  ## Regression Tests
1556
1567
 
1557
1568
  def test_empty_lists
@@ -152,7 +152,10 @@ SCSS
152
152
  def test_id_unification
153
153
  assert_unification '.foo.bar', '#baz {@extend .foo}', '.foo.bar, .bar#baz'
154
154
  assert_unification '.foo#baz', '#baz {@extend .foo}', '#baz'
155
- assert_unification '.foo#baz', '#bar {@extend .foo}', '.foo#baz'
155
+
156
+ assert_extend_doesnt_match('#bar', '.foo', :failed_to_unify, 2) do
157
+ assert_unification '.foo#baz', '#bar {@extend .foo}', '.foo#baz'
158
+ end
156
159
  end
157
160
 
158
161
  def test_universal_unification_with_simple_target
@@ -175,7 +178,11 @@ SCSS
175
178
  def test_universal_unification_with_namespaced_universal_target
176
179
  assert_unification 'ns|*.foo', '* {@extend .foo}', 'ns|*'
177
180
  assert_unification 'ns|*.foo', '*|* {@extend .foo}', 'ns|*'
178
- assert_unification 'ns1|*.foo', 'ns2|* {@extend .foo}', 'ns1|*.foo'
181
+
182
+ assert_extend_doesnt_match('ns2|*', '.foo', :failed_to_unify, 2) do
183
+ assert_unification 'ns1|*.foo', 'ns2|* {@extend .foo}', 'ns1|*.foo'
184
+ end
185
+
179
186
  assert_unification 'ns|*.foo', 'ns|* {@extend .foo}', 'ns|*'
180
187
  end
181
188
 
@@ -191,7 +198,11 @@ SCSS
191
198
  def test_universal_unification_with_namespaced_element_target
192
199
  assert_unification 'ns|a.foo', '* {@extend .foo}', 'ns|a'
193
200
  assert_unification 'ns|a.foo', '*|* {@extend .foo}', 'ns|a'
194
- assert_unification 'ns1|a.foo', 'ns2|* {@extend .foo}', 'ns1|a.foo'
201
+
202
+ assert_extend_doesnt_match('ns2|*', '.foo', :failed_to_unify, 2) do
203
+ assert_unification 'ns1|a.foo', 'ns2|* {@extend .foo}', 'ns1|a.foo'
204
+ end
205
+
195
206
  assert_unification 'ns|a.foo', 'ns|* {@extend .foo}', 'ns|a'
196
207
  end
197
208
 
@@ -214,7 +225,11 @@ SCSS
214
225
  def test_element_unification_with_namespaced_universal_target
215
226
  assert_unification 'ns|*.foo', 'a {@extend .foo}', 'ns|*.foo, ns|a'
216
227
  assert_unification 'ns|*.foo', '*|a {@extend .foo}', 'ns|*.foo, ns|a'
217
- assert_unification 'ns1|*.foo', 'ns2|a {@extend .foo}', 'ns1|*.foo'
228
+
229
+ assert_extend_doesnt_match('ns2|a', '.foo', :failed_to_unify, 2) do
230
+ assert_unification 'ns1|*.foo', 'ns2|a {@extend .foo}', 'ns1|*.foo'
231
+ end
232
+
218
233
  assert_unification 'ns|*.foo', 'ns|a {@extend .foo}', 'ns|*.foo, ns|a'
219
234
  end
220
235
 
@@ -225,13 +240,20 @@ SCSS
225
240
  assert_unification '*|a.foo', '*|a {@extend .foo}', '*|a'
226
241
  assert_unification 'a.foo', 'ns|a {@extend .foo}', 'a.foo, ns|a'
227
242
  assert_unification '*|a.foo', 'ns|a {@extend .foo}', '*|a.foo, ns|a'
228
- assert_unification 'a.foo', 'h1 {@extend .foo}', 'a.foo'
243
+
244
+ assert_extend_doesnt_match('h1', '.foo', :failed_to_unify, 2) do
245
+ assert_unification 'a.foo', 'h1 {@extend .foo}', 'a.foo'
246
+ end
229
247
  end
230
248
 
231
249
  def test_element_unification_with_namespaced_element_target
232
250
  assert_unification 'ns|a.foo', 'a {@extend .foo}', 'ns|a'
233
251
  assert_unification 'ns|a.foo', '*|a {@extend .foo}', 'ns|a'
234
- assert_unification 'ns1|a.foo', 'ns2|a {@extend .foo}', 'ns1|a.foo'
252
+
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'
255
+ end
256
+
235
257
  assert_unification 'ns|a.foo', 'ns|a {@extend .foo}', 'ns|a'
236
258
  end
237
259
 
@@ -246,8 +268,15 @@ SCSS
246
268
  def test_pseudo_unification
247
269
  assert_unification ':foo.baz', ':foo(2n+1) {@extend .baz}', ':foo.baz, :foo:foo(2n+1)'
248
270
  assert_unification ':foo.baz', '::foo {@extend .baz}', ':foo.baz, :foo::foo'
249
- assert_unification '::foo.baz', '::bar {@extend .baz}', '::foo.baz'
250
- assert_unification '::foo.baz', '::foo(2n+1) {@extend .baz}', '::foo.baz'
271
+
272
+ assert_extend_doesnt_match('::bar', '.baz', :failed_to_unify, 2) do
273
+ assert_unification '::foo.baz', '::bar {@extend .baz}', '::foo.baz'
274
+ end
275
+
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'
278
+ end
279
+
251
280
  assert_unification '::foo.baz', '::foo {@extend .baz}', '::foo'
252
281
  assert_unification '::foo(2n+1).baz', '::foo(2n+1) {@extend .baz}', '::foo(2n+1)'
253
282
  assert_unification ':foo.baz', ':bar {@extend .baz}', ':foo.baz, :foo:bar'
@@ -318,7 +347,9 @@ SCSS
318
347
  end
319
348
 
320
349
  def test_long_extendee_requires_all_selectors
321
- assert_extends '.foo', '.baz {@extend .foo.bar}', '.foo'
350
+ assert_extend_doesnt_match('.baz', '.foo.bar', :not_found, 2) do
351
+ assert_extends '.foo', '.baz {@extend .foo.bar}', '.foo'
352
+ end
322
353
  end
323
354
 
324
355
  def test_long_extendee_matches_supersets
@@ -340,8 +371,13 @@ SCSS
340
371
  end
341
372
 
342
373
  def test_long_extender_aborts_unification
343
- assert_extends 'a.foo#bar', 'h1.baz {@extend .foo}', 'a.foo#bar'
344
- assert_extends 'a.foo#bar', '.bang#baz {@extend .foo}', 'a.foo#bar'
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'
376
+ end
377
+
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'
380
+ end
345
381
  end
346
382
 
347
383
  ## Nested Extenders
@@ -355,7 +391,9 @@ SCSS
355
391
  end
356
392
 
357
393
  def test_nested_extender_aborts_unification
358
- assert_extends 'baz.foo', 'foo bar {@extend .foo}', 'baz.foo'
394
+ assert_extend_doesnt_match('foo bar', '.foo', :failed_to_unify, 2) do
395
+ assert_extends 'baz.foo', 'foo bar {@extend .foo}', 'baz.foo'
396
+ end
359
397
  end
360
398
 
361
399
  def test_nested_extender_alternates_parents
@@ -771,7 +809,8 @@ SCSS
771
809
  end
772
810
 
773
811
  def test_placeholder_selector_as_modifier
774
- assert_equal <<CSS, render(<<SCSS)
812
+ assert_extend_doesnt_match('div', '%foo', :failed_to_unify, 3) do
813
+ assert_equal <<CSS, render(<<SCSS)
775
814
  a.baz.bar {
776
815
  color: blue; }
777
816
  CSS
@@ -779,6 +818,7 @@ a%foo.baz {color: blue}
779
818
  .bar {@extend %foo}
780
819
  div {@extend %foo}
781
820
  SCSS
821
+ end
782
822
  end
783
823
 
784
824
  def test_placeholder_interpolation
@@ -805,7 +845,7 @@ SCSS
805
845
 
806
846
  def test_extend_out_of_media
807
847
  assert_warning(<<WARN) {assert_equal(<<CSS, render(<<SCSS))}
808
- DEPRECATION WARNING on line 3 of test_extend_out_of_media_inline.sass:
848
+ DEPRECATION WARNING on line 3 of test_extend_out_of_media_inline.scss:
809
849
  @extending an outer selector from within @media is deprecated.
810
850
  You may only @extend selectors within the same directive.
811
851
  This will be an error in Sass 3.3.
@@ -823,7 +863,7 @@ SCSS
823
863
 
824
864
  def test_extend_out_of_unknown_directive
825
865
  assert_warning(<<WARN) {assert_equal(<<CSS, render(<<SCSS))}
826
- DEPRECATION WARNING on line 3 of test_extend_out_of_unknown_directive_inline.sass:
866
+ DEPRECATION WARNING on line 3 of test_extend_out_of_unknown_directive_inline.scss:
827
867
  @extending an outer selector from within @flooblehoof is deprecated.
828
868
  You may only @extend selectors within the same directive.
829
869
  This will be an error in Sass 3.3.
@@ -843,7 +883,7 @@ SCSS
843
883
 
844
884
  def test_extend_out_of_nested_directives
845
885
  assert_warning(<<WARN) {assert_equal(<<CSS, render(<<SCSS))}
846
- DEPRECATION WARNING on line 4 of test_extend_out_of_nested_directives_inline.sass:
886
+ DEPRECATION WARNING on line 4 of test_extend_out_of_nested_directives_inline.scss:
847
887
  @extending an outer selector from within @flooblehoof is deprecated.
848
888
  You may only @extend selectors within the same directive.
849
889
  This will be an error in Sass 3.3.
@@ -946,7 +986,7 @@ SCSS
946
986
 
947
987
  def test_extend_within_and_without_media
948
988
  assert_warning(<<WARN) {assert_equal(<<CSS, render(<<SCSS))}
949
- DEPRECATION WARNING on line 4 of test_extend_within_and_without_media_inline.sass:
989
+ DEPRECATION WARNING on line 4 of test_extend_within_and_without_media_inline.scss:
950
990
  @extending an outer selector from within @media is deprecated.
951
991
  You may only @extend selectors within the same directive.
952
992
  This will be an error in Sass 3.3.
@@ -969,7 +1009,7 @@ SCSS
969
1009
 
970
1010
  def test_extend_within_and_without_unknown_directive
971
1011
  assert_warning(<<WARN) {assert_equal(<<CSS, render(<<SCSS))}
972
- DEPRECATION WARNING on line 4 of test_extend_within_and_without_unknown_directive_inline.sass:
1012
+ DEPRECATION WARNING on line 4 of test_extend_within_and_without_unknown_directive_inline.scss:
973
1013
  @extending an outer selector from within @flooblehoof is deprecated.
974
1014
  You may only @extend selectors within the same directive.
975
1015
  This will be an error in Sass 3.3.
@@ -992,7 +1032,7 @@ SCSS
992
1032
 
993
1033
  def test_extend_within_and_without_nested_directives
994
1034
  assert_warning(<<WARN) {assert_equal(<<CSS, render(<<SCSS))}
995
- DEPRECATION WARNING on line 5 of test_extend_within_and_without_nested_directives_inline.sass:
1035
+ DEPRECATION WARNING on line 5 of test_extend_within_and_without_nested_directives_inline.scss:
996
1036
  @extending an outer selector from within @flooblehoof is deprecated.
997
1037
  You may only @extend selectors within the same directive.
998
1038
  This will be an error in Sass 3.3.
@@ -1071,6 +1111,74 @@ x! .bar {
1071
1111
  CSS
1072
1112
  x! .bar {a: b}
1073
1113
  y! .bap {@extend .bar}
1114
+ SCSS
1115
+ end
1116
+
1117
+ 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
+ WARN
1123
+ .foo {@extend .bar}
1124
+ SCSS
1125
+ end
1126
+
1127
+ def test_extend_warns_when_extension_fails
1128
+ assert_warning(<<WARN) {assert_equal(<<CSS, render(<<SCSS))}
1129
+ WARNING on line 2 of test_extend_warns_when_extension_fails_inline.scss: "b.foo" failed to @extend ".bar".
1130
+ No selectors matching ".bar" could be unified with "b.foo".
1131
+ This will be an error in future releases of Sass.
1132
+ WARN
1133
+ a.bar {
1134
+ a: b; }
1135
+ CSS
1136
+ a.bar {a: b}
1137
+ b.foo {@extend .bar}
1138
+ SCSS
1139
+ end
1140
+
1141
+ def test_extend_does_not_warn_when_one_extension_fails_but_others_dont
1142
+ assert_no_warning {assert_equal(<<CSS, render(<<SCSS))}
1143
+ a.bar {
1144
+ a: b; }
1145
+
1146
+ .bar, b.foo {
1147
+ c: d; }
1148
+ CSS
1149
+ a.bar {a: b}
1150
+ .bar {c: d}
1151
+ b.foo {@extend .bar}
1152
+ SCSS
1153
+ end
1154
+
1155
+ def test_extend_does_not_warn_when_one_extension_fails_but_others_dont
1156
+ assert_no_warning {assert_equal(<<CSS, render(<<SCSS))}
1157
+ a.bar {
1158
+ a: b; }
1159
+
1160
+ .bar, b.foo {
1161
+ c: d; }
1162
+ CSS
1163
+ a.bar {a: b}
1164
+ .bar {c: d}
1165
+ b.foo {@extend .bar}
1166
+ SCSS
1167
+ end
1168
+
1169
+ def test_optional_extend_does_not_warn_when_extendee_doesnt_exist
1170
+ assert_no_warning {assert_equal("", render(<<SCSS))}
1171
+ .foo {@extend .bar !optional}
1172
+ SCSS
1173
+ end
1174
+
1175
+ def test_optional_extend_does_not_warn_when_extension_fails
1176
+ assert_no_warning {assert_equal(<<CSS, render(<<SCSS))}
1177
+ a.bar {
1178
+ a: b; }
1179
+ CSS
1180
+ a.bar {a: b}
1181
+ b.foo {@extend .bar !optional}
1074
1182
  SCSS
1075
1183
  end
1076
1184
 
@@ -1184,6 +1292,22 @@ SCSS
1184
1292
 
1185
1293
  private
1186
1294
 
1295
+ def assert_extend_doesnt_match(extender, target, reason, line, syntax = :scss)
1296
+ warn = "\"#{extender}\" failed to @extend \"#{target}\"."
1297
+ reason =
1298
+ if reason == :not_found
1299
+ "The selector \"#{target}\" was not found."
1300
+ else
1301
+ "No selectors matching \"#{target}\" could be unified with \"#{extender}\"."
1302
+ end
1303
+
1304
+ assert_warning(<<WARNING) {yield}
1305
+ WARNING on line #{line} of #{filename_for_test syntax}: #{warn}
1306
+ #{reason}
1307
+ This will be an error in future releases of Sass.
1308
+ WARNING
1309
+ end
1310
+
1187
1311
  def assert_unification(selector, extension, unified)
1188
1312
  # Do some trickery so the first law of extend doesn't get in our way.
1189
1313
  assert_extends(
@@ -1203,7 +1327,8 @@ SCSS
1203
1327
  end
1204
1328
 
1205
1329
  def render(sass, options = {})
1330
+ options = {:syntax => :scss}.merge(options)
1206
1331
  munge_filename options
1207
- Sass::Engine.new(sass, {:syntax => :scss}.merge(options)).render
1332
+ Sass::Engine.new(sass, options).render
1208
1333
  end
1209
1334
  end
@@ -47,6 +47,15 @@ class Test::Unit::TestCase
47
47
  $stderr = the_real_stderr
48
48
  end
49
49
 
50
+ def assert_no_warning
51
+ the_real_stderr, $stderr = $stderr, StringIO.new
52
+ yield
53
+
54
+ assert_equal '', $stderr.string
55
+ ensure
56
+ $stderr = the_real_stderr
57
+ end
58
+
50
59
  def silence_warnings(&block)
51
60
  Sass::Util.silence_warnings(&block)
52
61
  end
metadata CHANGED
@@ -1,15 +1,15 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: sass
3
3
  version: !ruby/object:Gem::Version
4
- hash: 592302359
4
+ hash: 592302341
5
5
  prerelease: 6
6
6
  segments:
7
7
  - 3
8
8
  - 2
9
9
  - 0
10
10
  - alpha
11
- - 261
12
- version: 3.2.0.alpha.261
11
+ - 268
12
+ version: 3.2.0.alpha.268
13
13
  platform: ruby
14
14
  authors:
15
15
  - Nathan Weizenbaum
@@ -19,7 +19,7 @@ autorequire:
19
19
  bindir: bin
20
20
  cert_chain: []
21
21
 
22
- date: 2012-06-29 00:00:00 -04:00
22
+ date: 2012-07-13 00:00:00 -04:00
23
23
  default_executable:
24
24
  dependencies:
25
25
  - !ruby/object:Gem::Dependency