sass 3.2.0.alpha.11 → 3.2.0.alpha.21

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 (81) hide show
  1. data/REVISION +1 -1
  2. data/VERSION +1 -1
  3. data/lib/sass/cache_stores/base.rb +4 -9
  4. data/lib/sass/cache_stores/filesystem.rb +2 -0
  5. data/lib/sass/css.rb +2 -1
  6. data/lib/sass/engine.rb +28 -8
  7. data/lib/sass/environment.rb +26 -0
  8. data/lib/sass/exec.rb +13 -0
  9. data/lib/sass/importers/base.rb +2 -1
  10. data/lib/sass/script/funcall.rb +8 -0
  11. data/lib/sass/script/interpolation.rb +9 -0
  12. data/lib/sass/script/list.rb +7 -0
  13. data/lib/sass/script/literal.rb +5 -0
  14. data/lib/sass/script/node.rb +8 -0
  15. data/lib/sass/script/number.rb +28 -5
  16. data/lib/sass/script/operation.rb +8 -0
  17. data/lib/sass/script/string_interpolation.rb +9 -0
  18. data/lib/sass/script/unary_operation.rb +7 -0
  19. data/lib/sass/script/variable.rb +5 -0
  20. data/lib/sass/scss/parser.rb +26 -13
  21. data/lib/sass/scss/rx.rb +1 -1
  22. data/lib/sass/scss/static_parser.rb +2 -2
  23. data/lib/sass/tree/content_node.rb +9 -0
  24. data/lib/sass/tree/debug_node.rb +1 -6
  25. data/lib/sass/tree/each_node.rb +1 -7
  26. data/lib/sass/tree/extend_node.rb +1 -1
  27. data/lib/sass/tree/for_node.rb +2 -7
  28. data/lib/sass/tree/function_node.rb +1 -6
  29. data/lib/sass/tree/if_node.rb +1 -19
  30. data/lib/sass/tree/mixin_def_node.rb +5 -6
  31. data/lib/sass/tree/mixin_node.rb +2 -7
  32. data/lib/sass/tree/node.rb +4 -19
  33. data/lib/sass/tree/prop_node.rb +0 -5
  34. data/lib/sass/tree/return_node.rb +1 -6
  35. data/lib/sass/tree/rule_node.rb +9 -7
  36. data/lib/sass/tree/trace_node.rb +32 -0
  37. data/lib/sass/tree/variable_node.rb +1 -7
  38. data/lib/sass/tree/visitors/check_nesting.rb +30 -13
  39. data/lib/sass/tree/visitors/convert.rb +5 -1
  40. data/lib/sass/tree/visitors/cssize.rb +3 -3
  41. data/lib/sass/tree/visitors/deep_copy.rb +87 -0
  42. data/lib/sass/tree/visitors/perform.rb +36 -16
  43. data/lib/sass/tree/visitors/set_options.rb +97 -0
  44. data/lib/sass/tree/visitors/to_css.rb +5 -1
  45. data/lib/sass/tree/warn_node.rb +1 -7
  46. data/lib/sass/tree/while_node.rb +1 -7
  47. data/test/sass/cache_test.rb +15 -0
  48. data/test/sass/conversion_test.rb +38 -0
  49. data/test/sass/css2sass_test.rb +9 -0
  50. data/test/sass/engine_test.rb +248 -17
  51. data/test/sass/scss/css_test.rb +4 -2
  52. data/test/sass/scss/scss_test.rb +53 -12
  53. data/vendor/fssm/Gemfile +3 -0
  54. data/vendor/fssm/LICENSE +1 -1
  55. data/vendor/fssm/README.markdown +55 -27
  56. data/vendor/fssm/Rakefile +6 -54
  57. data/vendor/fssm/example.rb +6 -3
  58. data/vendor/fssm/fssm.gemspec +17 -70
  59. data/vendor/fssm/lib/fssm.rb +7 -3
  60. data/vendor/fssm/lib/fssm/backends/fsevents.rb +1 -1
  61. data/vendor/fssm/lib/fssm/backends/inotify.rb +2 -2
  62. data/vendor/fssm/lib/fssm/backends/polling.rb +2 -2
  63. data/vendor/fssm/lib/fssm/backends/rbfsevent.rb +42 -0
  64. data/vendor/fssm/lib/fssm/backends/rubycocoa/fsevents.rb +10 -10
  65. data/vendor/fssm/lib/fssm/monitor.rb +19 -9
  66. data/vendor/fssm/lib/fssm/path.rb +24 -21
  67. data/vendor/fssm/lib/fssm/pathname.rb +13 -479
  68. data/vendor/fssm/lib/fssm/state/directory.rb +29 -11
  69. data/vendor/fssm/lib/fssm/state/file.rb +1 -1
  70. data/vendor/fssm/lib/fssm/support.rb +41 -12
  71. data/vendor/fssm/lib/fssm/tree.rb +6 -6
  72. data/vendor/fssm/lib/fssm/version.rb +3 -0
  73. data/vendor/fssm/profile/prof-cache.rb +3 -3
  74. data/vendor/fssm/profile/prof-pathname-rubinius.rb +35 -0
  75. data/vendor/fssm/profile/prof-pathname.rb +7 -7
  76. data/vendor/fssm/spec/count_down_latch.rb +151 -0
  77. data/vendor/fssm/spec/monitor_spec.rb +202 -0
  78. data/vendor/fssm/spec/path_spec.rb +36 -15
  79. data/vendor/fssm/spec/spec_helper.rb +6 -6
  80. metadata +14 -4
  81. data/vendor/fssm/VERSION.yml +0 -5
@@ -268,6 +268,15 @@ SASS
268
268
  CSS
269
269
  end
270
270
 
271
+ def test_double_comma
272
+ assert_equal(<<SASS, css2sass(<<CSS))
273
+ foo, bar
274
+ a: b
275
+ SASS
276
+ foo, , bar { a: b }
277
+ CSS
278
+ end
279
+
271
280
  # Error reporting
272
281
 
273
282
  def test_error_reporting
@@ -39,8 +39,8 @@ MSG
39
39
  "a\n b: c;" => 'Invalid CSS after "c": expected expression (e.g. 1px, bold), was ";"',
40
40
  ".foo ^bar\n a: b" => ['Invalid CSS after ".foo ": expected selector, was "^bar"', 1],
41
41
  "a\n @extend .foo ^bar" => 'Invalid CSS after ".foo ": expected selector, was "^bar"',
42
- "a: b" => 'Properties are only allowed within rules, directives, or other properties.',
43
- ":a b" => 'Properties are only allowed within rules, directives, or other properties.',
42
+ "a: b" => 'Properties are only allowed within rules, directives, mixin includes, or other properties.',
43
+ ":a b" => 'Properties are only allowed within rules, directives, mixin includes, or other properties.',
44
44
  "$" => 'Invalid variable: "$".',
45
45
  "$a" => 'Invalid variable: "$a".',
46
46
  "$ a" => 'Invalid variable: "$ a".',
@@ -62,13 +62,13 @@ MSG
62
62
  "foo\n @import foo.css" => "CSS import directives may only be used at the root of a document.",
63
63
  "@if true\n @import foo" => "Import directives may not be used within control directives or mixins.",
64
64
  "@mixin foo\n @import foo" => "Import directives may not be used within control directives or mixins.",
65
+ "@import foo;" => "Invalid @import: expected end of line, was \";\".",
65
66
  '$foo: "bar" "baz" !' => %Q{Invalid CSS after ""bar" "baz" ": expected expression (e.g. 1px, bold), was "!"},
66
67
  '$foo: "bar" "baz" $' => %Q{Invalid CSS after ""bar" "baz" ": expected expression (e.g. 1px, bold), was "$"},
67
68
  "=foo\n :color red\n.bar\n +bang" => "Undefined mixin 'bang'.",
68
69
  "=foo\n :color red\n.bar\n +bang_bop" => "Undefined mixin 'bang_bop'.",
69
70
  "=foo\n :color red\n.bar\n +bang-bop" => "Undefined mixin 'bang-bop'.",
70
71
  ".bar\n =foo\n :color red\n" => ["Mixins may only be defined at the root of a document.", 2],
71
- "=foo\n :color red\n.bar\n +foo\n :color red" => "Illegal nesting: Nothing may be nested beneath mixin directives.",
72
72
  " a\n b: c" => ["Indenting at the beginning of the document is illegal.", 1],
73
73
  " \n \n\t\n a\n b: c" => ["Indenting at the beginning of the document is illegal.", 4],
74
74
  "a\n b: c\n b: c" => ["Inconsistent indentation: 1 space was used for indentation, but the rest of the document was indented using 2 spaces.", 3],
@@ -84,7 +84,7 @@ MSG
84
84
  "=a(,)" => 'Invalid CSS after "(": expected variable (e.g. $foo), was ",)"',
85
85
  "=a($)" => 'Invalid CSS after "(": expected variable (e.g. $foo), was "$)"',
86
86
  "=a($foo bar)" => 'Invalid CSS after "($foo ": expected ")", was "bar)"',
87
- "=foo\n bar: baz\n+foo" => ["Properties are only allowed within rules, directives, or other properties.", 2],
87
+ "=foo\n bar: baz\n+foo" => ["Properties are only allowed within rules, directives, mixin includes, or other properties.", 2],
88
88
  "a-\#{$b\n c: d" => ['Invalid CSS after "a-#{$b": expected "}", was ""', 1],
89
89
  "=a($b: 1, $c)" => "Required argument $c must come before any optional arguments.",
90
90
  "=a($b: 1)\n a: $b\ndiv\n +a(1,2)" => "Mixin a takes 1 argument but 2 were passed.",
@@ -139,6 +139,13 @@ MSG
139
139
  "$var: true\n@while $var\n @extend .bar\n $var: false" => ["Extend directives may only be used within rules.", 3],
140
140
  "@for $i from 0 to 1\n @extend .bar" => ["Extend directives may only be used within rules.", 2],
141
141
  "@mixin foo\n @extend .bar\n@include foo" => ["Extend directives may only be used within rules.", 2],
142
+ "foo\n &a\n b: c" => ["Invalid CSS after \"&\": expected \"{\", was \"a\"\n\n\"a\" may only be used at the beginning of a selector.", 2],
143
+ "foo\n &1\n b: c" => ["Invalid CSS after \"&\": expected \"{\", was \"1\"\n\n\"1\" may only be used at the beginning of a selector.", 2],
144
+ "=foo\n @content error" => "Invalid content directive. Trailing characters found: \"error\".",
145
+ "=foo\n @content\n b: c" => "Illegal nesting: Nothing may be nested beneath @content directives.",
146
+ "@content" => '@content may only be used within a mixin.',
147
+ "=simple\n .simple\n color: red\n+simple\n color: blue" => ['Mixin "simple" does not accept a content block.', 4],
148
+ "=foo\n @content\n+foo" => ["No @content passed.", 2],
142
149
 
143
150
  # Regression tests
144
151
  "a\n b:\n c\n d" => ["Illegal nesting: Only properties may be nested beneath properties.", 3],
@@ -305,6 +312,23 @@ SASS
305
312
  end
306
313
  end
307
314
 
315
+ def test_selector_tracing
316
+ actual_css = render(<<-SCSS, :syntax => :scss, :trace_selectors => true)
317
+ @mixin mixed {
318
+ .mixed { color: red; }
319
+ }
320
+ .context {
321
+ @include mixed;
322
+ }
323
+ SCSS
324
+ assert_equal(<<CSS,actual_css)
325
+ /* on line 2 of test_selector_tracing_inline.scss, in `mixed'
326
+ from line 5 of test_selector_tracing_inline.scss */
327
+ .context .mixed {
328
+ color: red; }
329
+ CSS
330
+ end
331
+
308
332
  def test_mixin_exception
309
333
  render(<<SASS)
310
334
  =error-mixin($a)
@@ -523,7 +547,7 @@ SASS
523
547
  rescue Sass::SyntaxError => e
524
548
  assert_equal(<<CSS, Sass::SyntaxError.exception_to_css(e, opts).split("\n")[0..11].join("\n"))
525
549
  /*
526
- Syntax error: Properties are only allowed within rules, directives, or other properties.
550
+ Syntax error: Properties are only allowed within rules, directives, mixin includes, or other properties.
527
551
  on line 4 of test_cssize_exception_css_inline.sass
528
552
 
529
553
  1: .filler
@@ -1776,22 +1800,22 @@ SASS
1776
1800
 
1777
1801
  def test_interpolation_doesnt_deep_unquote_strings
1778
1802
  assert_equal(<<CSS, render(<<SASS))
1779
- .foo- "bar" "baz" {
1780
- a: b; }
1803
+ .foo {
1804
+ a: "bar" "baz"; }
1781
1805
  CSS
1782
- .foo-\#{"bar" "baz"}
1783
- a: b
1806
+ .foo
1807
+ a: \#{"bar" "baz"}
1784
1808
  SASS
1785
1809
  end
1786
1810
 
1787
1811
  def test_warn_directive
1788
1812
  expected_warning = <<EXPECTATION
1789
1813
  WARNING: this is a warning
1790
- on line 4 of test_warn_directive_inline.sass
1814
+ on line 4 of test_warn_directive_inline.sass
1791
1815
 
1792
1816
  WARNING: this is a mixin warning
1793
- on line 2 of test_warn_directive_inline.sass, in `foo'
1794
- from line 7 of test_warn_directive_inline.sass
1817
+ on line 2 of test_warn_directive_inline.sass, in `foo'
1818
+ from line 7 of test_warn_directive_inline.sass
1795
1819
  EXPECTATION
1796
1820
  assert_warning expected_warning do
1797
1821
  assert_equal <<CSS, render(<<SASS)
@@ -1821,15 +1845,15 @@ SASS
1821
1845
  def test_warn_with_imports
1822
1846
  expected_warning = <<WARN
1823
1847
  WARNING: In the main file
1824
- on line 1 of #{File.dirname(__FILE__)}/templates/warn.sass
1848
+ on line 1 of #{File.dirname(__FILE__)}/templates/warn.sass
1825
1849
 
1826
1850
  WARNING: Imported
1827
- on line 1 of #{File.dirname(__FILE__)}/templates/warn_imported.sass
1828
- from line 2 of #{File.dirname(__FILE__)}/templates/warn.sass
1851
+ on line 1 of #{File.dirname(__FILE__)}/templates/warn_imported.sass
1852
+ from line 2 of #{File.dirname(__FILE__)}/templates/warn.sass
1829
1853
 
1830
1854
  WARNING: In an imported mixin
1831
- on line 4 of #{File.dirname(__FILE__)}/templates/warn_imported.sass, in `emits-a-warning'
1832
- from line 3 of #{File.dirname(__FILE__)}/templates/warn.sass
1855
+ on line 4 of #{File.dirname(__FILE__)}/templates/warn_imported.sass, in `emits-a-warning'
1856
+ from line 3 of #{File.dirname(__FILE__)}/templates/warn.sass
1833
1857
  WARN
1834
1858
  assert_warning expected_warning do
1835
1859
  renders_correctly "warn", :style => :compact, :load_paths => [File.dirname(__FILE__) + "/templates"]
@@ -2434,6 +2458,213 @@ SASS
2434
2458
  assert_equal original_filename, importer.engine("imported").options[:original_filename]
2435
2459
  end
2436
2460
 
2461
+ def test_deprecated_PRECISION
2462
+ assert_warning(<<END) {assert_equal 1000.0, Sass::Script::Number::PRECISION}
2463
+ Sass::Script::Number::PRECISION is deprecated and will be removed in a future release. Use Sass::Script::Number.precision_factor instead.
2464
+ END
2465
+ end
2466
+ def test_changing_precision
2467
+ begin
2468
+ Sass::Script::Number.precision = 8
2469
+ assert_equal <<CSS, render(<<SASS)
2470
+ div {
2471
+ maximum: 1.00000001;
2472
+ too-much: 1.0; }
2473
+ CSS
2474
+ div
2475
+ maximum : 1.00000001
2476
+ too-much: 1.000000001
2477
+ SASS
2478
+ ensure
2479
+ Sass::Script::Number.precision = 3
2480
+ end
2481
+ end
2482
+
2483
+ def test_content
2484
+ assert_equal <<CSS, render(<<SASS)
2485
+ .children {
2486
+ background-color: red;
2487
+ color: blue;
2488
+ border-color: red; }
2489
+ CSS
2490
+ $color: blue
2491
+ =context($class, $color: red)
2492
+ .\#{$class}
2493
+ background-color: $color
2494
+ @content
2495
+ border-color: $color
2496
+ +context(children)
2497
+ color: $color
2498
+ SASS
2499
+ end
2500
+
2501
+ def test_selector_in_content
2502
+ assert_equal <<CSS, render(<<SASS)
2503
+ .parent {
2504
+ background-color: red;
2505
+ border-color: red; }
2506
+ .parent .children {
2507
+ color: blue; }
2508
+ CSS
2509
+ $color: blue
2510
+ =context($class, $color: red)
2511
+ .\#{$class}
2512
+ background-color: $color
2513
+ @content
2514
+ border-color: $color
2515
+ +context(parent)
2516
+ .children
2517
+ color: $color
2518
+ SASS
2519
+ end
2520
+
2521
+ def test_using_parent_mixin_in_content
2522
+ assert_equal <<CSS, render(<<SASS)
2523
+ .parent {
2524
+ before-color: red;
2525
+ after-color: red; }
2526
+ .parent .sibling {
2527
+ before-color: yellow;
2528
+ after-color: yellow; }
2529
+ .parent .sibling .child {
2530
+ before-color: green;
2531
+ color: blue;
2532
+ after-color: green; }
2533
+ CSS
2534
+ $color: blue
2535
+ =context($class, $color: red)
2536
+ .\#{$class}
2537
+ before-color: $color
2538
+ @content
2539
+ after-color: $color
2540
+ +context(parent)
2541
+ +context(sibling, $color: yellow)
2542
+ +context(child, $color: green)
2543
+ color: $color
2544
+ SASS
2545
+ end
2546
+
2547
+ def test_content_more_than_once
2548
+ assert_equal <<CSS, render(<<SASS)
2549
+ .once {
2550
+ color: blue; }
2551
+
2552
+ .twice {
2553
+ color: blue; }
2554
+ CSS
2555
+ $color: blue
2556
+ =context($class, $color: red)
2557
+ .once
2558
+ @content
2559
+ .twice
2560
+ @content
2561
+ +context(parent)
2562
+ color: $color
2563
+ SASS
2564
+ end
2565
+
2566
+ def test_content_with_variable
2567
+ assert_equal <<CSS, render(<<SASS)
2568
+ .foo {
2569
+ a: 1px; }
2570
+ CSS
2571
+ =foo
2572
+ .foo
2573
+ @content
2574
+ +foo
2575
+ $a: 1px
2576
+ a: $a
2577
+ SASS
2578
+ end
2579
+
2580
+ def test_nested_content_blocks
2581
+ assert_equal <<CSS, render(<<SASS)
2582
+ .foo {
2583
+ a: foo; }
2584
+ .foo .bar {
2585
+ a: bar; }
2586
+ .foo .bar .baz {
2587
+ a: baz; }
2588
+ .foo .bar .baz .outside {
2589
+ a: outside;
2590
+ color: red; }
2591
+ CSS
2592
+ $a: outside
2593
+ =baz($a: baz)
2594
+ .baz
2595
+ a: $a
2596
+ @content
2597
+ =bar($a: bar)
2598
+ .bar
2599
+ a: $a
2600
+ +baz
2601
+ @content
2602
+ =foo($a: foo)
2603
+ .foo
2604
+ a: $a
2605
+ +bar
2606
+ @content
2607
+ +foo
2608
+ .outside
2609
+ a: $a
2610
+ color: red
2611
+ SASS
2612
+ end
2613
+
2614
+ def test_content_not_seen_through_mixin
2615
+ render(<<SASS)
2616
+ =foo
2617
+ foo
2618
+ @content
2619
+ +bar
2620
+ =bar
2621
+ bar
2622
+ @content
2623
+ a
2624
+ +foo
2625
+ a: b
2626
+ SASS
2627
+ assert(false, "Expected exception")
2628
+ rescue Sass::SyntaxError => e
2629
+ assert_equal("No @content passed.", e.message)
2630
+ assert_equal(7, e.sass_line)
2631
+ end
2632
+
2633
+ def test_content_backtrace_for_perform
2634
+ render(<<SASS)
2635
+ =foo
2636
+ @content
2637
+
2638
+ a
2639
+ +foo
2640
+ b: 1em + 2px
2641
+ SASS
2642
+ assert(false, "Expected exception")
2643
+ rescue Sass::SyntaxError => e
2644
+ assert_equal([
2645
+ {:mixin => '@content', :line => 6, :filename => 'test_content_backtrace_for_perform_inline.sass'},
2646
+ {:mixin => 'foo', :line => 2, :filename => 'test_content_backtrace_for_perform_inline.sass'},
2647
+ {:line => 5, :filename => 'test_content_backtrace_for_perform_inline.sass'},
2648
+ ], e.sass_backtrace)
2649
+ end
2650
+
2651
+ def test_content_backtrace_for_cssize
2652
+ render(<<SASS)
2653
+ =foo
2654
+ @content
2655
+
2656
+ a
2657
+ +foo
2658
+ @extend foo bar baz
2659
+ SASS
2660
+ assert(false, "Expected exception")
2661
+ rescue Sass::SyntaxError => e
2662
+ assert_equal([
2663
+ {:mixin => '@content', :line => 6, :filename => 'test_content_backtrace_for_cssize_inline.sass'},
2664
+ {:mixin => 'foo', :line => 2, :filename => 'test_content_backtrace_for_cssize_inline.sass'},
2665
+ {:line => 5, :filename => 'test_content_backtrace_for_cssize_inline.sass'},
2666
+ ], e.sass_backtrace)
2667
+ end
2437
2668
 
2438
2669
  private
2439
2670
 
@@ -733,10 +733,12 @@ SCSS
733
733
  assert_selector_parses(':not(h1, h2, h3)')
734
734
  end
735
735
 
736
- def test_moz_any_selector
736
+ def test_any_selector
737
737
  assert_selector_parses(':-moz-any(h1, h2, h3)')
738
738
  assert_selector_parses(':-moz-any(.foo)')
739
739
  assert_selector_parses(':-moz-any(foo bar, .baz > .bang)')
740
+ assert_selector_parses(':-webkit-any(foo bar, .baz > .bang)')
741
+ assert_selector_parses(':any(foo bar, .baz > .bang)')
740
742
  end
741
743
 
742
744
  def test_namespaced_selectors
@@ -909,7 +911,7 @@ SCSS
909
911
  end
910
912
 
911
913
  def render(scss, options = {})
912
- tree = Sass::SCSS::CssParser.new(scss).parse
914
+ tree = Sass::SCSS::CssParser.new(scss, options[:filename]).parse
913
915
  tree.options = Sass::Engine::DEFAULT_OPTIONS.merge(options)
914
916
  tree.render
915
917
  end
@@ -118,11 +118,11 @@ SCSS
118
118
  def test_warn_directive
119
119
  expected_warning = <<EXPECTATION
120
120
  WARNING: this is a warning
121
- on line 2 of test_warn_directive_inline.scss
121
+ on line 2 of test_warn_directive_inline.scss
122
122
 
123
123
  WARNING: this is a mixin
124
- on line 1 of test_warn_directive_inline.scss, in `foo'
125
- from line 3 of test_warn_directive_inline.scss
124
+ on line 1 of test_warn_directive_inline.scss, in `foo'
125
+ from line 3 of test_warn_directive_inline.scss
126
126
  EXPECTATION
127
127
  assert_warning expected_warning do
128
128
  assert_equal <<CSS, render(<<SCSS)
@@ -1029,11 +1029,10 @@ SCSS
1029
1029
  end
1030
1030
 
1031
1031
  def test_parent_in_mid_selector_error
1032
- assert_raise_message(Sass::SyntaxError, <<MESSAGE) {render <<SCSS}
1032
+ assert_raise_message(Sass::SyntaxError, <<MESSAGE.rstrip) {render <<SCSS}
1033
1033
  Invalid CSS after ".foo": expected "{", was "&.bar"
1034
1034
 
1035
- In Sass 3, the parent selector & can only be used where element names are valid,
1036
- since it could potentially be replaced by an element name.
1035
+ "&" may only be used at the beginning of a selector.
1037
1036
  MESSAGE
1038
1037
  flim {
1039
1038
  .foo&.bar {a: b}
@@ -1042,11 +1041,10 @@ SCSS
1042
1041
  end
1043
1042
 
1044
1043
  def test_parent_in_mid_selector_error
1045
- assert_raise_message(Sass::SyntaxError, <<MESSAGE) {render <<SCSS}
1044
+ assert_raise_message(Sass::SyntaxError, <<MESSAGE.rstrip) {render <<SCSS}
1046
1045
  Invalid CSS after " .foo.bar": expected "{", was "& {a: b}"
1047
1046
 
1048
- In Sass 3, the parent selector & can only be used where element names are valid,
1049
- since it could potentially be replaced by an element name.
1047
+ "&" may only be used at the beginning of a selector.
1050
1048
  MESSAGE
1051
1049
  flim {
1052
1050
  .foo.bar& {a: b}
@@ -1055,11 +1053,10 @@ SCSS
1055
1053
  end
1056
1054
 
1057
1055
  def test_double_parent_selector_error
1058
- assert_raise_message(Sass::SyntaxError, <<MESSAGE) {render <<SCSS}
1056
+ assert_raise_message(Sass::SyntaxError, <<MESSAGE.rstrip) {render <<SCSS}
1059
1057
  Invalid CSS after " &": expected "{", was "& {a: b}"
1060
1058
 
1061
- In Sass 3, the parent selector & can only be used where element names are valid,
1062
- since it could potentially be replaced by an element name.
1059
+ "&" may only be used at the beginning of a selector.
1063
1060
  MESSAGE
1064
1061
  flim {
1065
1062
  && {a: b}
@@ -1244,6 +1241,50 @@ foo {
1244
1241
  a: $var1;
1245
1242
  b: $var2;
1246
1243
  c: $var3; }
1244
+ SCSS
1245
+ end
1246
+
1247
+ def test_mixin_content
1248
+ assert_equal <<CSS, render(<<SASS)
1249
+ .parent {
1250
+ background-color: red;
1251
+ border-color: red; }
1252
+ .parent .child {
1253
+ background-color: yellow;
1254
+ color: blue;
1255
+ border-color: yellow; }
1256
+ CSS
1257
+ $color: blue;
1258
+ @mixin context($class, $color: red) {
1259
+ .\#{$class} {
1260
+ background-color: $color;
1261
+ @content;
1262
+ border-color: $color;
1263
+ }
1264
+ }
1265
+ @include context(parent) {
1266
+ @include context(child, $color: yellow) {
1267
+ color: $color;
1268
+ }
1269
+ }
1270
+ SASS
1271
+ end
1272
+
1273
+ def test_empty_content
1274
+ assert_equal <<CSS, render(<<SCSS)
1275
+ a {
1276
+ b: c; }
1277
+ CSS
1278
+ @mixin foo { @content }
1279
+ a { b: c; @include foo {} }
1280
+ SCSS
1281
+ end
1282
+
1283
+ def test_options_passed_to_script
1284
+ assert_equal <<CSS, render(<<SCSS, :style => :compressed)
1285
+ foo{color:#000}
1286
+ CSS
1287
+ foo {color: darken(black, 10%)}
1247
1288
  SCSS
1248
1289
  end
1249
1290
  end