haml 3.0.0.beta.1 → 3.0.0.beta.2

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of haml might be problematic. Click here for more details.

Files changed (67) hide show
  1. data/README.md +7 -7
  2. data/REMEMBER +2 -1
  3. data/Rakefile +6 -4
  4. data/VERSION +1 -1
  5. data/lib/haml/exec.rb +119 -24
  6. data/lib/haml/filters.rb +5 -1
  7. data/lib/haml/helpers.rb +4 -2
  8. data/lib/haml/helpers/action_view_mods.rb +2 -3
  9. data/lib/haml/precompiler.rb +1 -0
  10. data/lib/sass.rb +1 -1
  11. data/lib/sass/css.rb +25 -6
  12. data/lib/sass/engine.rb +23 -7
  13. data/lib/sass/environment.rb +47 -1
  14. data/lib/sass/files.rb +9 -10
  15. data/lib/sass/plugin.rb +6 -27
  16. data/lib/sass/plugin/merb.rb +1 -0
  17. data/lib/sass/plugin/rails.rb +1 -0
  18. data/lib/sass/plugin/staleness_checker.rb +123 -0
  19. data/lib/sass/script/bool.rb +1 -1
  20. data/lib/sass/script/color.rb +1 -1
  21. data/lib/sass/script/css_lexer.rb +1 -4
  22. data/lib/sass/script/funcall.rb +2 -2
  23. data/lib/sass/script/functions.rb +102 -7
  24. data/lib/sass/script/interpolation.rb +5 -5
  25. data/lib/sass/script/lexer.rb +10 -8
  26. data/lib/sass/script/literal.rb +11 -1
  27. data/lib/sass/script/node.rb +10 -1
  28. data/lib/sass/script/number.rb +25 -10
  29. data/lib/sass/script/operation.rb +7 -6
  30. data/lib/sass/script/parser.rb +37 -28
  31. data/lib/sass/script/string.rb +12 -7
  32. data/lib/sass/script/string_interpolation.rb +70 -0
  33. data/lib/sass/script/unary_operation.rb +3 -3
  34. data/lib/sass/script/variable.rb +2 -2
  35. data/lib/sass/scss/css_parser.rb +1 -0
  36. data/lib/sass/scss/parser.rb +58 -44
  37. data/lib/sass/scss/rx.rb +1 -0
  38. data/lib/sass/tree/comment_node.rb +3 -2
  39. data/lib/sass/tree/debug_node.rb +1 -1
  40. data/lib/sass/tree/for_node.rb +1 -1
  41. data/lib/sass/tree/if_node.rb +1 -1
  42. data/lib/sass/tree/import_node.rb +3 -0
  43. data/lib/sass/tree/mixin_def_node.rb +3 -3
  44. data/lib/sass/tree/mixin_node.rb +7 -3
  45. data/lib/sass/tree/node.rb +8 -0
  46. data/lib/sass/tree/prop_node.rb +21 -16
  47. data/lib/sass/tree/rule_node.rb +3 -3
  48. data/lib/sass/tree/variable_node.rb +1 -1
  49. data/lib/sass/tree/warn_node.rb +41 -0
  50. data/lib/sass/tree/while_node.rb +1 -1
  51. data/test/haml/engine_test.rb +9 -0
  52. data/test/sass/conversion_test.rb +127 -15
  53. data/test/sass/css2sass_test.rb +34 -3
  54. data/test/sass/engine_test.rb +82 -5
  55. data/test/sass/functions_test.rb +31 -0
  56. data/test/sass/plugin_test.rb +25 -24
  57. data/test/sass/results/script.css +4 -4
  58. data/test/sass/results/warn.css +0 -0
  59. data/test/sass/results/warn_imported.css +0 -0
  60. data/test/sass/script_conversion_test.rb +43 -1
  61. data/test/sass/script_test.rb +3 -3
  62. data/test/sass/scss/css_test.rb +46 -5
  63. data/test/sass/scss/scss_test.rb +72 -0
  64. data/test/sass/templates/import.sass +1 -1
  65. data/test/sass/templates/warn.sass +3 -0
  66. data/test/sass/templates/warn_imported.sass +4 -0
  67. metadata +10 -3
@@ -505,6 +505,37 @@ The #options attribute is not set on this Sass::Script::String.
505
505
  MSG
506
506
  end
507
507
 
508
+ def test_type_of
509
+ assert_equal("string", evaluate("type-of(\"asdf\")"))
510
+ assert_equal("string", evaluate("type-of(asdf)"))
511
+ assert_equal("number", evaluate("type-of(1px)"))
512
+ assert_equal("bool", evaluate("type-of(true)"))
513
+ assert_equal("color", evaluate("type-of(#fff)"))
514
+ end
515
+
516
+ def test_unit
517
+ assert_equal(%Q{""}, evaluate("unit(100)"))
518
+ assert_equal(%Q{"px"}, evaluate("unit(100px)"))
519
+ assert_equal(%Q{"em*px"}, evaluate("unit(10px * 5em)"))
520
+ assert_equal(%Q{"em*px"}, evaluate("unit(5em * 10px)"))
521
+ assert_equal(%Q{"em*px/cm*rem"}, evaluate("unit(10px * 5em / 30cm / 1rem)"))
522
+ assert_error_message("#ff0000 is not a number for `unit'", "unit(#f00)")
523
+ end
524
+
525
+ def test_unitless
526
+ assert_equal(%Q{true}, evaluate("unitless(100)"))
527
+ assert_equal(%Q{false}, evaluate("unitless(100px)"))
528
+ assert_error_message("#ff0000 is not a number for `unitless'", "unitless(#f00)")
529
+ end
530
+
531
+ def test_comparable
532
+ assert_equal(%Q{true}, evaluate("comparable(2px, 1px)"))
533
+ assert_equal(%Q{true}, evaluate("comparable(10cm, 3mm)"))
534
+ assert_equal(%Q{false}, evaluate("comparable(100px, 3em)"))
535
+ assert_error_message("#ff0000 is not a number for `comparable'", "comparable(#f00, 1px)")
536
+ assert_error_message("#ff0000 is not a number for `comparable'", "comparable(1px, #f00)")
537
+ end
538
+
508
539
  private
509
540
 
510
541
  def evaluate(value)
@@ -14,7 +14,7 @@ class SassPluginTest < Test::Unit::TestCase
14
14
  FileUtils.mkdir tempfile_loc
15
15
  FileUtils.mkdir tempfile_loc(nil,"more_")
16
16
  set_plugin_opts
17
- Sass::Plugin.update_stylesheets
17
+ update_all_stylesheets!
18
18
  reset_mtimes
19
19
  end
20
20
 
@@ -34,21 +34,21 @@ class SassPluginTest < Test::Unit::TestCase
34
34
  def test_no_update
35
35
  File.delete(tempfile_loc('basic'))
36
36
  assert_needs_update 'basic'
37
- Sass::Plugin.update_stylesheets
37
+ update_all_stylesheets!
38
38
  assert_stylesheet_updated 'basic'
39
39
  end
40
40
 
41
41
  def test_update_needed_when_modified
42
42
  touch 'basic'
43
43
  assert_needs_update 'basic'
44
- Sass::Plugin.update_stylesheets
44
+ update_all_stylesheets!
45
45
  assert_stylesheet_updated 'basic'
46
46
  end
47
47
 
48
48
  def test_update_needed_when_dependency_modified
49
49
  touch 'basic'
50
50
  assert_needs_update 'import'
51
- Sass::Plugin.update_stylesheets
51
+ update_all_stylesheets!
52
52
  assert_stylesheet_updated 'basic'
53
53
  assert_stylesheet_updated 'import'
54
54
  end
@@ -56,7 +56,7 @@ class SassPluginTest < Test::Unit::TestCase
56
56
  def test_update_needed_when_scss_dependency_modified
57
57
  touch 'scss_importee'
58
58
  assert_needs_update 'import'
59
- Sass::Plugin.update_stylesheets
59
+ update_all_stylesheets!
60
60
  assert_stylesheet_updated 'scss_importee'
61
61
  assert_stylesheet_updated 'import'
62
62
  end
@@ -64,14 +64,14 @@ class SassPluginTest < Test::Unit::TestCase
64
64
  def test_scss_update_needed_when_dependency_modified
65
65
  touch 'basic'
66
66
  assert_needs_update 'scss_import'
67
- Sass::Plugin.update_stylesheets
67
+ update_all_stylesheets!
68
68
  assert_stylesheet_updated 'basic'
69
69
  assert_stylesheet_updated 'scss_import'
70
70
  end
71
71
 
72
72
  def test_full_exception_handling
73
73
  File.delete(tempfile_loc('bork1'))
74
- Sass::Plugin.update_stylesheets
74
+ update_all_stylesheets!
75
75
  File.open(tempfile_loc('bork1')) do |file|
76
76
  assert_equal(<<CSS.strip, file.read.split("\n")[0...6].join("\n"))
77
77
  /*
@@ -90,7 +90,7 @@ CSS
90
90
  Sass::Plugin.options[:full_exception] = false
91
91
 
92
92
  File.delete(tempfile_loc('bork1'))
93
- assert_raise(Sass::SyntaxError) {Sass::Plugin.update_stylesheets}
93
+ assert_raise(Sass::SyntaxError) {update_all_stylesheets!}
94
94
  ensure
95
95
  Sass::Plugin.options[:full_exception] = old_full_exception
96
96
  end
@@ -100,7 +100,7 @@ CSS
100
100
  template_loc => tempfile_loc,
101
101
  template_loc(nil,'more_') => tempfile_loc(nil,'more_')
102
102
  }
103
- Sass::Plugin.update_stylesheets
103
+ update_all_stylesheets!
104
104
  ['more1', 'more_import'].each { |name| assert_renders_correctly(name, :prefix => 'more_') }
105
105
  end
106
106
 
@@ -111,7 +111,7 @@ CSS
111
111
  template_loc => tempfile_loc,
112
112
  template_loc(nil,'more_') => tempfile_loc(nil,'more_')
113
113
  }
114
- Sass::Plugin.update_stylesheets
114
+ update_all_stylesheets!
115
115
  assert_renders_correctly('more1_with_line_comments', 'more1', :prefix => 'more_')
116
116
  end
117
117
 
@@ -157,7 +157,7 @@ CSS
157
157
 
158
158
  def test_updating_stylesheets_callback_with_individual_files
159
159
  files = [[template_loc("basic"), tempfile_loc("basic")]]
160
- assert_callback(:updating_stylesheets, files) {Sass::Plugin.update_stylesheets(files)}
160
+ assert_callback(:updating_stylesheets, files) {Haml::Util.silence_haml_warnings{Sass::Plugin.update_stylesheets(files)}}
161
161
  end
162
162
 
163
163
  def test_updating_stylesheets_callback_with_never_update
@@ -248,7 +248,7 @@ CSS
248
248
 
249
249
  touch 'basic', 'more_'
250
250
  assert_needs_update "import"
251
- Sass::Plugin.update_stylesheets
251
+ update_all_stylesheets!
252
252
  assert_renders_correctly("import")
253
253
  ensure
254
254
  FileUtils.mv(template_loc("basic", "more_"), template_loc("basic"))
@@ -299,7 +299,7 @@ CSS
299
299
  if block_given?
300
300
  yield
301
301
  else
302
- Sass::Plugin.update_stylesheets
302
+ update_all_stylesheets!
303
303
  end
304
304
 
305
305
  assert run, "Expected #{name} callback to be run with arguments:\n #{expected_args.inspect}"
@@ -322,17 +322,17 @@ CSS
322
322
  if block_given?
323
323
  yield
324
324
  else
325
- Sass::Plugin.update_stylesheets
325
+ update_all_stylesheets!
326
326
  end
327
327
  end
328
328
 
329
329
  def assert_callbacks(*args)
330
- return Sass::Plugin.update_stylesheets if args.empty?
330
+ return update_all_stylesheets! if args.empty?
331
331
  assert_callback(*args.pop) {assert_callbacks(*args)}
332
332
  end
333
333
 
334
334
  def assert_no_callbacks(*args)
335
- return Sass::Plugin.update_stylesheets if args.empty?
335
+ return update_all_stylesheets! if args.empty?
336
336
  assert_no_callback(*args.pop) {assert_no_callbacks(*args)}
337
337
  end
338
338
 
@@ -340,13 +340,19 @@ CSS
340
340
  Sass::Plugin.instance_variable_set('@_sass_callbacks', {})
341
341
  end
342
342
 
343
+ def update_all_stylesheets!
344
+ Haml::Util.silence_haml_warnings do
345
+ Sass::Plugin.update_stylesheets
346
+ end
347
+ end
348
+
343
349
  def assert_needs_update(name)
344
- assert(Sass::Plugin.stylesheet_needs_update?(tempfile_loc(name), template_loc(name)),
350
+ assert(Sass::Plugin::StalenessChecker.stylesheet_needs_update?(tempfile_loc(name), template_loc(name)),
345
351
  "Expected #{template_loc(name)} to need an update.")
346
352
  end
347
353
 
348
354
  def assert_doesnt_need_update(name)
349
- assert(!Sass::Plugin.stylesheet_needs_update?(tempfile_loc(name), template_loc(name)),
355
+ assert(!Sass::Plugin::StalenessChecker.stylesheet_needs_update?(tempfile_loc(name), template_loc(name)),
350
356
  "Expected #{template_loc(name)} not to need an update.")
351
357
  end
352
358
 
@@ -355,6 +361,7 @@ CSS
355
361
  end
356
362
 
357
363
  def reset_mtimes
364
+ Sass::Plugin::StalenessChecker.dependencies_cache = {}
358
365
  atime = Time.now
359
366
  mtime = Time.now - 5
360
367
  Dir["{#{template_loc},#{tempfile_loc}}/**/*.{css,sass,scss}"].each {|f| File.utime(atime, mtime, f)}
@@ -401,12 +408,6 @@ CSS
401
408
  end
402
409
  end
403
410
 
404
- module Sass::Plugin
405
- class << self
406
- public :stylesheet_needs_update?
407
- end
408
- end
409
-
410
411
  class Sass::Engine
411
412
  alias_method :old_render, :render
412
413
 
@@ -1,7 +1,7 @@
1
- #main { content: Hello!; qstr: 'Quo"ted"!'; hstr: Hyph-en!; width: 30em; background-color: black; color: #ffffaa; short-color: #112233; named-color: olive; con: "foo" bar(9 hi there "boom"); con2: "noquo" quo; }
2
- #main #sidebar { background-color: #00ff98; num-normal: 10; num-dec: 10.2; num-dec0: 99; num-neg: -10; esc: 10 +12; many: 6; order: 7; complex: #4c9db1hi16; }
1
+ #main { content: Hello\!; qstr: 'Quo"ted"!'; hstr: Hyph-en\!; width: 30em; background-color: black; color: #ffffaa; short-color: #112233; named-color: olive; con: "foo" bar(9 hi there "boom"); con2: "noquo" quo; }
2
+ #main #sidebar { background-color: #00ff98; num-normal: 10; num-dec: 10.2; num-dec0: 99; num-neg: -10; esc: 10 \+12; many: 6; order: 7; complex: #4c9db1hi16; }
3
3
 
4
- #plus { num-num: 7; num-num-un: 25em; num-num-un2: 23em; num-num-neg: 9.87; num-str: 100px; num-col: #b7b7b7; num-perc: 31%; str-str: "hi there"; str-str2: "hi there"; str-col: "14em solid #112233"; str-num: "times: 13"; col-num: #ff7b9d; col-col: #5173ff; }
4
+ #plus { num-num: 7; num-num-un: 25em; num-num-un2: 23em; num-num-neg: 9.87; num-str: 100px; num-col: #b7b7b7; num-perc: 31%; str-str: "hi\ there"; str-str2: "hi there"; str-col: "14em solid #112233"; str-num: "times: 13"; col-num: #ff7b9d; col-col: #5173ff; }
5
5
 
6
6
  #minus { num-num: 900; col-num: #f9f9f4; col-col: #000035; unary-num: -1; unary-const: 10; unary-paren: -11; unary-two: 12; unary-many: 12; unary-crazy: -15; }
7
7
 
@@ -11,6 +11,6 @@
11
11
 
12
12
  #mod { num-num: 2; col-col: #0f0e05; col-num: #020001; }
13
13
 
14
- #const { escaped-quote: $foo !bar; default: Hello! !important; }
14
+ #const { escaped-quote: \$foo \!bar; default: Hello\! !important; }
15
15
 
16
16
  #regression { a: 4; }
File without changes
File without changes
@@ -140,6 +140,46 @@ RUBY
140
140
  assert_equal 'not (true or false)', render('not (true or false)')
141
141
  end
142
142
 
143
+ def test_interpolation
144
+ assert_renders "$foo\#{$bar}$baz"
145
+ assert_renders "$foo\#{$bar} $baz"
146
+ assert_renders "$foo \#{$bar}$baz"
147
+ assert_renders "$foo \#{$bar} $baz"
148
+ assert_renders "$foo \#{$bar}\#{$bang} $baz"
149
+ assert_renders "$foo \#{$bar} \#{$bang} $baz"
150
+ assert_renders "\#{$bar}$baz"
151
+ assert_renders "$foo\#{$bar}"
152
+ assert_renders "\#{$bar}"
153
+ end
154
+
155
+ def test_string_interpolation
156
+ assert_renders '"foo#{$bar}baz"'
157
+ assert_renders '"foo #{$bar}baz"'
158
+ assert_renders '"foo#{$bar} baz"'
159
+ assert_renders '"foo #{$bar} baz"'
160
+ assert_renders '"foo #{$bar}#{$bang} baz"'
161
+ assert_renders '"foo #{$bar} #{$bang} baz"'
162
+ assert_renders '"#{$bar}baz"'
163
+ assert_renders '"foo#{$bar}"'
164
+ assert_equal '#{$bar}', render('"#{$bar}"')
165
+
166
+ assert_equal '"foo#{$bar}baz"', render("'foo\#{$bar}baz'")
167
+ end
168
+
169
+ def test_sass2_string_interpolation
170
+ assert_equal 'foo#{$bar}baz', render('"foo#{$bar}baz"', :context => :equals)
171
+ assert_equal '#{$bar}baz', render('"#{$bar}baz"', :context => :equals)
172
+ assert_equal 'foo#{$bar}', render('"foo#{$bar}"', :context => :equals)
173
+
174
+ assert_equal 'unquote(".foo#{$bar}.bar")', render('".foo#{$bar}.bar"', :context => :equals)
175
+ assert_equal 'unquote(".foo#{$bar}")', render('".foo#{$bar}"', :context => :equals)
176
+ assert_equal 'unquote("#{$bar}.bar")', render('"#{$bar}.bar"', :context => :equals)
177
+
178
+ assert_equal "unquote(\"f'o\#{$bar}b'z\")", render("'f\\'o\#{$bar}b\\'z'", :context => :equals)
179
+ assert_equal "unquote('f\"o\#{$bar}b\"z')", render("'f\\\"o\#{$bar}b\\\"z'", :context => :equals)
180
+ assert_equal "unquote(\"f'o\#{$bar}b\\\"z\")", render("'f\\'o\#{$bar}b\\\"z'", :context => :equals)
181
+ end
182
+
143
183
  private
144
184
 
145
185
  def assert_renders(script, options = {})
@@ -148,6 +188,8 @@ RUBY
148
188
 
149
189
  def render(script, options = {})
150
190
  munge_filename(options)
151
- Sass::Script.parse(script, 1, 0, options).to_sass
191
+ node = Sass::Script.parse(script, 1, 0, options)
192
+ node.context = options[:context] if options[:context]
193
+ node.to_sass
152
194
  end
153
195
  end
@@ -25,12 +25,12 @@ class SassScriptTest < Test::Unit::TestCase
25
25
  def test_string_escapes
26
26
  assert_equal "'", resolve("\"'\"")
27
27
  assert_equal '"', resolve("\"\\\"\"")
28
- assert_equal "\\", resolve("\"\\\\\"")
28
+ assert_equal "\\\\", resolve("\"\\\\\"")
29
29
  assert_equal "\\02fa", resolve("\"\\02fa\"")
30
30
 
31
31
  assert_equal "'", resolve("'\\''")
32
32
  assert_equal '"', resolve("'\"'")
33
- assert_equal "\\", resolve("'\\\\'")
33
+ assert_equal "\\\\", resolve("'\\\\'")
34
34
  assert_equal "\\02fa", resolve("'\\02fa'")
35
35
  end
36
36
 
@@ -290,7 +290,7 @@ SASS
290
290
  assert_equal "teal(12)", resolve("teal(12)")
291
291
  assert_equal "tealbang(12)", resolve("tealbang(12)")
292
292
  assert_equal "teal-bang(12)", resolve("teal-bang(12)")
293
- assert_equal "teal+bang(12)", resolve("teal\\+bang(12)")
293
+ assert_equal "teal\\+bang(12)", resolve("teal\\+bang(12)")
294
294
  end
295
295
 
296
296
  def test_interpolation_after_hash
@@ -320,7 +320,7 @@ foo {
320
320
  SCSS
321
321
  end
322
322
 
323
- def test_ms_filter_syntax
323
+ def test_ms_long_filter_syntax
324
324
  assert_equal <<CSS, render(<<SCSS)
325
325
  foo {
326
326
  filter: progid:DXImageTransform.Microsoft.gradient(GradientType=1, startColorstr=#c0ff3300, endColorstr=#ff000000);
@@ -332,6 +332,15 @@ foo {
332
332
  SCSS
333
333
  end
334
334
 
335
+ def test_ms_short_filter_syntax
336
+ assert_parses <<SCSS
337
+ foo {
338
+ filter: alpha(opacity=20);
339
+ filter: alpha(opacity=20, enabled=true);
340
+ filter: blaznicate(foo=bar, baz=bang bip, bart=#fa4600); }
341
+ SCSS
342
+ end
343
+
335
344
  def test_declaration_hacks
336
345
  assert_parses <<SCSS
337
346
  foo {
@@ -339,10 +348,20 @@ foo {
339
348
  *name: val;
340
349
  :name: val;
341
350
  .name: val;
351
+ #name: val;
342
352
  name: val; }
343
353
  SCSS
344
354
  end
345
355
 
356
+ def test_trailing_hash_hack
357
+ assert_parses <<SCSS
358
+ foo {
359
+ foo: bar;
360
+ #baz: bang;
361
+ #bip: bop; }
362
+ SCSS
363
+ end
364
+
346
365
  def test_zero_arg_functions
347
366
  assert_parses <<SCSS
348
367
  foo {
@@ -381,6 +400,28 @@ foo {
381
400
  SCSS
382
401
  end
383
402
 
403
+ def test_css_string_escapes
404
+ assert_parses <<SCSS
405
+ foo {
406
+ a: "\\foo bar";
407
+ b: "foo\\ bar";
408
+ c: "\\2022 \\0020";
409
+ d: "foo\\\\bar";
410
+ e: "foo\\"'bar"; }
411
+ SCSS
412
+ end
413
+
414
+ def test_css_ident_escapes
415
+ assert_parses <<SCSS
416
+ foo {
417
+ a: \\foo bar;
418
+ b: foo\\ bar;
419
+ c: \\2022 \\0020;
420
+ d: foo\\\\bar;
421
+ e: foo\\"\\'bar; }
422
+ SCSS
423
+ end
424
+
384
425
  ## Directives
385
426
 
386
427
  def test_charset_directive
@@ -717,12 +758,12 @@ SCSS
717
758
  end
718
759
 
719
760
  def test_invalid_classes
720
- assert_not_parses("identifier", 'p.<err> foo {a: b}')
721
- assert_not_parses("identifier", 'p.<err>1foo {a: b}')
761
+ assert_not_parses("class name", 'p.<err> foo {a: b}')
762
+ assert_not_parses("class name", 'p.<err>1foo {a: b}')
722
763
  end
723
764
 
724
765
  def test_invalid_ids
725
- assert_not_parses('"{"', 'p<err># foo {a: b}')
766
+ assert_not_parses("id name", 'p#<err> foo {a: b}')
726
767
  end
727
768
 
728
769
  def test_no_properties_at_toplevel
@@ -771,7 +812,7 @@ SCSS
771
812
 
772
813
  def test_no_nested_rules
773
814
  assert_not_parses('":"', 'foo {bar <err>{a: b}}')
774
- assert_not_parses('"}"', 'foo {<err>#bar {a: b}}')
815
+ assert_not_parses('"}"', 'foo {<err>[bar=baz] {a: b}}')
775
816
  end
776
817
 
777
818
  def test_no_nested_properties
@@ -113,6 +113,27 @@ SCSS
113
113
  end
114
114
  end
115
115
 
116
+ def test_warn_directive
117
+ expected_warning = <<EXPECTATION
118
+ WARNING: this is a warning
119
+ on line 2 of test_warn_directive_inline.scss
120
+
121
+ WARNING: this is a mixin
122
+ on line 1 of test_warn_directive_inline.scss, in `foo'
123
+ from line 3 of test_warn_directive_inline.scss
124
+ EXPECTATION
125
+ assert_warning expected_warning do
126
+ assert_equal <<CSS, render(<<SCSS)
127
+ bar {
128
+ c: d; }
129
+ CSS
130
+ @mixin foo { @warn "this is a mixin";}
131
+ @warn "this is a warning";
132
+ bar {c: d; @include foo;}
133
+ SCSS
134
+ end
135
+ end
136
+
116
137
  def test_for_directive
117
138
  assert_equal <<CSS, render(<<SCSS)
118
139
  .foo {
@@ -631,6 +652,57 @@ foo:nth-child(\#{5 + "n"}) {a: b}
631
652
  SCSS
632
653
  end
633
654
 
655
+ def test_selector_interpolation_at_class_begininng
656
+ assert_equal <<CSS, render(<<SCSS)
657
+ .zzz {
658
+ a: b; }
659
+ CSS
660
+ $zzz: zzz;
661
+ .\#{$zzz} { a: b; }
662
+ SCSS
663
+ end
664
+
665
+ def test_selector_interpolation_at_id_begininng
666
+ assert_equal <<CSS, render(<<SCSS)
667
+ #zzz {
668
+ a: b; }
669
+ CSS
670
+ $zzz: zzz;
671
+ #\#{$zzz} { a: b; }
672
+ SCSS
673
+ end
674
+
675
+ def test_selector_interpolation_at_pseudo_begininng
676
+ assert_equal <<CSS, render(<<SCSS)
677
+ :zzz::zzz {
678
+ a: b; }
679
+ CSS
680
+ $zzz: zzz;
681
+ :\#{$zzz}::\#{$zzz} { a: b; }
682
+ SCSS
683
+ end
684
+
685
+ def test_selector_interpolation_at_attr_beginning
686
+ assert_equal <<CSS, render(<<SCSS)
687
+ [zzz=foo] {
688
+ a: b; }
689
+ CSS
690
+ $zzz: zzz;
691
+ [\#{$zzz}=foo] { a: b; }
692
+ SCSS
693
+ end
694
+
695
+ def test_selector_interpolation_at_dashes
696
+ assert_equal <<CSS, render(<<SCSS)
697
+ div {
698
+ -foo-a-b-foo: foo; }
699
+ CSS
700
+ $a : a;
701
+ $b : b;
702
+ div { -foo-\#{$a}-\#{$b}-foo: foo }
703
+ SCSS
704
+ end
705
+
634
706
  def test_basic_prop_val_interpolation
635
707
  assert_equal <<CSS, render(<<SCSS)
636
708
  foo {