sass 3.3.0 → 3.4.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (151) hide show
  1. checksums.yaml +4 -4
  2. data/MIT-LICENSE +1 -1
  3. data/README.md +58 -50
  4. data/Rakefile +1 -4
  5. data/VERSION +1 -1
  6. data/VERSION_DATE +1 -1
  7. data/VERSION_NAME +1 -1
  8. data/bin/sass +1 -1
  9. data/bin/scss +1 -1
  10. data/lib/sass/cache_stores/filesystem.rb +6 -2
  11. data/lib/sass/css.rb +1 -3
  12. data/lib/sass/engine.rb +37 -46
  13. data/lib/sass/environment.rb +13 -17
  14. data/lib/sass/error.rb +6 -9
  15. data/lib/sass/exec/base.rb +187 -0
  16. data/lib/sass/exec/sass_convert.rb +264 -0
  17. data/lib/sass/exec/sass_scss.rb +424 -0
  18. data/lib/sass/exec.rb +5 -771
  19. data/lib/sass/features.rb +7 -0
  20. data/lib/sass/importers/base.rb +7 -2
  21. data/lib/sass/importers/filesystem.rb +9 -25
  22. data/lib/sass/importers.rb +0 -1
  23. data/lib/sass/media.rb +1 -4
  24. data/lib/sass/plugin/compiler.rb +200 -83
  25. data/lib/sass/plugin/staleness_checker.rb +1 -1
  26. data/lib/sass/plugin.rb +3 -3
  27. data/lib/sass/script/css_lexer.rb +1 -1
  28. data/lib/sass/script/functions.rb +622 -268
  29. data/lib/sass/script/lexer.rb +99 -34
  30. data/lib/sass/script/parser.rb +24 -23
  31. data/lib/sass/script/tree/funcall.rb +1 -1
  32. data/lib/sass/script/tree/interpolation.rb +20 -2
  33. data/lib/sass/script/tree/selector.rb +26 -0
  34. data/lib/sass/script/tree/string_interpolation.rb +1 -1
  35. data/lib/sass/script/tree.rb +1 -0
  36. data/lib/sass/script/value/base.rb +7 -5
  37. data/lib/sass/script/value/bool.rb +0 -5
  38. data/lib/sass/script/value/color.rb +39 -21
  39. data/lib/sass/script/value/helpers.rb +107 -0
  40. data/lib/sass/script/value/list.rb +0 -15
  41. data/lib/sass/script/value/null.rb +0 -5
  42. data/lib/sass/script/value/number.rb +62 -14
  43. data/lib/sass/script/value/string.rb +59 -11
  44. data/lib/sass/script/value.rb +0 -1
  45. data/lib/sass/scss/css_parser.rb +8 -2
  46. data/lib/sass/scss/parser.rb +190 -328
  47. data/lib/sass/scss/rx.rb +15 -6
  48. data/lib/sass/scss/static_parser.rb +298 -1
  49. data/lib/sass/selector/abstract_sequence.rb +28 -13
  50. data/lib/sass/selector/comma_sequence.rb +92 -13
  51. data/lib/sass/selector/pseudo.rb +256 -0
  52. data/lib/sass/selector/sequence.rb +94 -24
  53. data/lib/sass/selector/simple.rb +14 -25
  54. data/lib/sass/selector/simple_sequence.rb +97 -33
  55. data/lib/sass/selector.rb +57 -194
  56. data/lib/sass/shared.rb +1 -1
  57. data/lib/sass/source/map.rb +26 -12
  58. data/lib/sass/stack.rb +0 -6
  59. data/lib/sass/supports.rb +2 -3
  60. data/lib/sass/tree/at_root_node.rb +1 -0
  61. data/lib/sass/tree/charset_node.rb +1 -1
  62. data/lib/sass/tree/directive_node.rb +8 -2
  63. data/lib/sass/tree/error_node.rb +18 -0
  64. data/lib/sass/tree/extend_node.rb +1 -1
  65. data/lib/sass/tree/function_node.rb +4 -0
  66. data/lib/sass/tree/keyframe_rule_node.rb +15 -0
  67. data/lib/sass/tree/prop_node.rb +1 -1
  68. data/lib/sass/tree/rule_node.rb +12 -7
  69. data/lib/sass/tree/visitors/check_nesting.rb +38 -10
  70. data/lib/sass/tree/visitors/convert.rb +16 -18
  71. data/lib/sass/tree/visitors/cssize.rb +29 -29
  72. data/lib/sass/tree/visitors/deep_copy.rb +5 -0
  73. data/lib/sass/tree/visitors/perform.rb +45 -33
  74. data/lib/sass/tree/visitors/set_options.rb +14 -0
  75. data/lib/sass/tree/visitors/to_css.rb +15 -14
  76. data/lib/sass/util/subset_map.rb +1 -1
  77. data/lib/sass/util.rb +222 -99
  78. data/lib/sass/version.rb +5 -5
  79. data/lib/sass.rb +0 -5
  80. data/test/sass/cache_test.rb +62 -20
  81. data/test/sass/callbacks_test.rb +1 -1
  82. data/test/sass/compiler_test.rb +19 -10
  83. data/test/sass/conversion_test.rb +58 -1
  84. data/test/sass/css2sass_test.rb +23 -4
  85. data/test/sass/encoding_test.rb +219 -0
  86. data/test/sass/engine_test.rb +136 -199
  87. data/test/sass/exec_test.rb +2 -2
  88. data/test/sass/extend_test.rb +236 -19
  89. data/test/sass/functions_test.rb +295 -253
  90. data/test/sass/importer_test.rb +31 -21
  91. data/test/sass/logger_test.rb +1 -1
  92. data/test/sass/more_results/more_import.css +1 -1
  93. data/test/sass/plugin_test.rb +14 -13
  94. data/test/sass/results/compact.css +1 -1
  95. data/test/sass/results/complex.css +4 -4
  96. data/test/sass/results/expanded.css +1 -1
  97. data/test/sass/results/import.css +1 -1
  98. data/test/sass/results/import_charset_ibm866.css +2 -2
  99. data/test/sass/results/mixins.css +17 -17
  100. data/test/sass/results/nested.css +1 -1
  101. data/test/sass/results/parent_ref.css +2 -2
  102. data/test/sass/results/script.css +3 -3
  103. data/test/sass/results/scss_import.css +1 -1
  104. data/test/sass/script_conversion_test.rb +10 -7
  105. data/test/sass/script_test.rb +288 -74
  106. data/test/sass/scss/css_test.rb +141 -24
  107. data/test/sass/scss/rx_test.rb +4 -4
  108. data/test/sass/scss/scss_test.rb +457 -18
  109. data/test/sass/source_map_test.rb +115 -25
  110. data/test/sass/superselector_test.rb +191 -0
  111. data/test/sass/templates/scss_import.scss +2 -1
  112. data/test/sass/test_helper.rb +1 -1
  113. data/test/sass/util/multibyte_string_scanner_test.rb +1 -1
  114. data/test/sass/util/normalized_map_test.rb +1 -1
  115. data/test/sass/util/subset_map_test.rb +2 -2
  116. data/test/sass/util_test.rb +31 -1
  117. data/test/sass/value_helpers_test.rb +5 -7
  118. data/test/test_helper.rb +2 -2
  119. data/vendor/listen/CHANGELOG.md +1 -228
  120. data/vendor/listen/Gemfile +5 -15
  121. data/vendor/listen/README.md +111 -77
  122. data/vendor/listen/Rakefile +0 -42
  123. data/vendor/listen/lib/listen/adapter.rb +195 -82
  124. data/vendor/listen/lib/listen/adapters/bsd.rb +27 -64
  125. data/vendor/listen/lib/listen/adapters/darwin.rb +21 -58
  126. data/vendor/listen/lib/listen/adapters/linux.rb +23 -55
  127. data/vendor/listen/lib/listen/adapters/polling.rb +25 -34
  128. data/vendor/listen/lib/listen/adapters/windows.rb +50 -46
  129. data/vendor/listen/lib/listen/directory_record.rb +96 -61
  130. data/vendor/listen/lib/listen/listener.rb +135 -37
  131. data/vendor/listen/lib/listen/turnstile.rb +9 -5
  132. data/vendor/listen/lib/listen/version.rb +1 -1
  133. data/vendor/listen/lib/listen.rb +33 -19
  134. data/vendor/listen/listen.gemspec +6 -0
  135. data/vendor/listen/spec/listen/adapter_spec.rb +43 -77
  136. data/vendor/listen/spec/listen/adapters/polling_spec.rb +8 -8
  137. data/vendor/listen/spec/listen/directory_record_spec.rb +81 -56
  138. data/vendor/listen/spec/listen/listener_spec.rb +128 -39
  139. data/vendor/listen/spec/listen_spec.rb +15 -21
  140. data/vendor/listen/spec/spec_helper.rb +4 -0
  141. data/vendor/listen/spec/support/adapter_helper.rb +52 -15
  142. data/vendor/listen/spec/support/directory_record_helper.rb +7 -5
  143. data/vendor/listen/spec/support/listeners_helper.rb +30 -7
  144. metadata +25 -22
  145. data/ext/mkrf_conf.rb +0 -27
  146. data/lib/sass/importers/deprecated_path.rb +0 -51
  147. data/lib/sass/script/value/deprecated_false.rb +0 -55
  148. data/vendor/listen/lib/listen/dependency_manager.rb +0 -126
  149. data/vendor/listen/lib/listen/multi_listener.rb +0 -143
  150. data/vendor/listen/spec/listen/dependency_manager_spec.rb +0 -107
  151. data/vendor/listen/spec/listen/multi_listener_spec.rb +0 -174
@@ -3,12 +3,12 @@
3
3
  require File.dirname(__FILE__) + '/../test_helper'
4
4
  require File.dirname(__FILE__) + '/test_helper'
5
5
 
6
- class SourcemapTest < Test::Unit::TestCase
6
+ class SourcemapTest < MiniTest::Test
7
7
  def test_to_json_requires_args
8
8
  _, sourcemap = render_with_sourcemap('')
9
- assert_raise(ArgumentError) {sourcemap.to_json({})}
10
- assert_raise(ArgumentError) {sourcemap.to_json({:css_path => 'foo'})}
11
- assert_raise(ArgumentError) {sourcemap.to_json({:sourcemap_path => 'foo'})}
9
+ assert_raises(ArgumentError) {sourcemap.to_json({})}
10
+ assert_raises(ArgumentError) {sourcemap.to_json({:css_path => 'foo'})}
11
+ assert_raises(ArgumentError) {sourcemap.to_json({:sourcemap_path => 'foo'})}
12
12
  end
13
13
 
14
14
  def test_simple_mapping_scss
@@ -60,6 +60,32 @@ CSS
60
60
  JSON
61
61
  end
62
62
 
63
+ def test_simple_mapping_with_file_uris
64
+ uri = Sass::Util.file_uri_from_path(Sass::Util.absolute_path(filename_for_test(:scss)))
65
+ assert_parses_with_sourcemap <<SCSS, <<CSS, <<JSON, :sourcemap => :file
66
+ a {
67
+ foo: bar;
68
+ /* SOME COMMENT */
69
+ font-size: 12px;
70
+ }
71
+ SCSS
72
+ a {
73
+ foo: bar;
74
+ /* SOME COMMENT */
75
+ font-size: 12px; }
76
+
77
+ /*# sourceMappingURL=test.css.map */
78
+ CSS
79
+ {
80
+ "version": 3,
81
+ "mappings": "AAAA,CAAE;EACA,GAAG,EAAE,GAAG;;EAER,SAAS,EAAE,IAAI",
82
+ "sources": ["#{uri}"],
83
+ "names": [],
84
+ "file": "test.css"
85
+ }
86
+ JSON
87
+ end
88
+
63
89
  def test_mapping_with_directory_scss
64
90
  options = {:filename => "scss/style.scss", :output => "css/style.css"}
65
91
  assert_parses_with_sourcemap <<SCSS, <<CSS, <<JSON, options
@@ -156,15 +182,15 @@ JSON
156
182
  end
157
183
 
158
184
  def test_different_charset_than_encoding_scss
159
- assert_parses_with_sourcemap(<<SCSS.force_encoding("IBM866"), <<CSS.force_encoding("IBM866"), <<JSON)
185
+ assert_parses_with_sourcemap(<<SCSS.force_encoding("IBM866"), <<CSS, <<JSON)
160
186
  @charset "IBM866";
161
187
  f\x86\x86 {
162
188
  \x86: b;
163
189
  }
164
190
  SCSS
165
- @charset "IBM866";
166
- f\x86\x86 {
167
- \x86: b; }
191
+ @charset "UTF-8";
192
+ fЖЖ {
193
+ Ж: b; }
168
194
 
169
195
  /*# sourceMappingURL=test.css.map */
170
196
  CSS
@@ -179,14 +205,14 @@ JSON
179
205
  end
180
206
 
181
207
  def test_different_charset_than_encoding_sass
182
- assert_parses_with_sourcemap(<<SASS.force_encoding("IBM866"), <<CSS.force_encoding("IBM866"), <<JSON, :syntax => :sass)
208
+ assert_parses_with_sourcemap(<<SASS.force_encoding("IBM866"), <<CSS, <<JSON, :syntax => :sass)
183
209
  @charset "IBM866"
184
210
  f\x86\x86
185
211
  \x86: b
186
212
  SASS
187
- @charset "IBM866";
188
- f\x86\x86 {
189
- \x86: b; }
213
+ @charset "UTF-8";
214
+ fЖЖ {
215
+ Ж: b; }
190
216
 
191
217
  /*# sourceMappingURL=test.css.map */
192
218
  CSS
@@ -443,8 +469,8 @@ CSS
443
469
  {{7}}border-width{{/7}}: {{8}}3px{{/8}}
444
470
  SASS
445
471
  {{1}}.error, .seriousError{{/1}} {
446
- {{2}}border{{/2}}: {{3}}1px red{{/3}};
447
- {{4}}background-color{{/4}}: {{5}}#ffdddd{{/5}}; }
472
+ {{2}}border{{/2}}: {{3}}1px #f00{{/3}};
473
+ {{4}}background-color{{/4}}: {{5}}#fdd{{/5}}; }
448
474
 
449
475
  {{6}}.seriousError{{/6}} {
450
476
  {{7}}border-width{{/7}}: {{8}}3px{{/8}}; }
@@ -632,9 +658,9 @@ SCSS
632
658
  {{22}}border-style{{/22}}: {{23}}dashed{{/23}}; }
633
659
 
634
660
  {{24}}.shadows{{/24}} {
635
- {{25}}-moz-box-shadow{{/25}}: {{26}}0px 4px 5px #666666, 2px 6px 10px #999999{{/26}};
636
- {{27}}-webkit-box-shadow{{/27}}: {{28}}0px 4px 5px #666666, 2px 6px 10px #999999{{/28}};
637
- {{29}}box-shadow{{/29}}: {{30}}0px 4px 5px #666666, 2px 6px 10px #999999{{/30}}; }
661
+ {{25}}-moz-box-shadow{{/25}}: {{26}}0px 4px 5px #666, 2px 6px 10px #999{{/26}};
662
+ {{27}}-webkit-box-shadow{{/27}}: {{28}}0px 4px 5px #666, 2px 6px 10px #999{{/28}};
663
+ {{29}}box-shadow{{/29}}: {{30}}0px 4px 5px #666, 2px 6px 10px #999{{/30}}; }
638
664
 
639
665
  /*# sourceMappingURL=test.css.map */
640
666
  CSS
@@ -675,7 +701,7 @@ SASS
675
701
  {{1}}.page-title{{/1}} {
676
702
  {{2}}font-size{{/2}}: {{3}}20px{{/3}};
677
703
  {{4}}font-weight{{/4}}: {{5}}bold{{/5}};
678
- {{6}}color{{/6}}: {{7}}red{{/7}};
704
+ {{6}}color{{/6}}: {{7}}#ff0000{{/7}};
679
705
  {{8}}padding{{/8}}: {{9}}4px{{/9}}; }
680
706
 
681
707
  {{10}}p{{/10}} {
@@ -689,9 +715,9 @@ SASS
689
715
  {{22}}border-style{{/22}}: {{23}}dashed{{/23}}; }
690
716
 
691
717
  {{24}}.shadows{{/24}} {
692
- {{25}}-moz-box-shadow{{/25}}: {{26}}0px 4px 5px #666666, 2px 6px 10px #999999{{/26}};
693
- {{27}}-webkit-box-shadow{{/27}}: {{28}}0px 4px 5px #666666, 2px 6px 10px #999999{{/28}};
694
- {{29}}box-shadow{{/29}}: {{30}}0px 4px 5px #666666, 2px 6px 10px #999999{{/30}}; }
718
+ {{25}}-moz-box-shadow{{/25}}: {{26}}0px 4px 5px #666, 2px 6px 10px #999{{/26}};
719
+ {{27}}-webkit-box-shadow{{/27}}: {{28}}0px 4px 5px #666, 2px 6px 10px #999{{/28}};
720
+ {{29}}box-shadow{{/29}}: {{30}}0px 4px 5px #666, 2px 6px 10px #999{{/30}}; }
695
721
 
696
722
  /*# sourceMappingURL=test.css.map */
697
723
  CSS
@@ -752,6 +778,63 @@ SASS
752
778
  CSS
753
779
  end
754
780
 
781
+ def test_multiline_script_scss
782
+ assert_parses_with_mapping <<SCSS, <<CSS, :syntax => :scss
783
+ $var: {{3}}foo +
784
+ bar{{/3}}; {{1}}x {{/1}}{ {{2}}y{{/2}}: $var }
785
+ SCSS
786
+ {{1}}x{{/1}} {
787
+ {{2}}y{{/2}}: {{3}}foobar{{/3}}; }
788
+
789
+ /*# sourceMappingURL=test.css.map */
790
+ CSS
791
+ end
792
+
793
+ def test_multiline_interpolation_source_range
794
+ engine = Sass::Engine.new(<<-SCSS, :cache => false, :syntax => :scss)
795
+ p {
796
+ filter: progid:DXImageTransform(
797
+ '\#{123}');
798
+ }
799
+ SCSS
800
+
801
+ interpolated = engine.to_tree.children.
802
+ first.children.
803
+ first.value.children[1]
804
+ assert_equal interpolated.to_sass, "\#{123}"
805
+ range = interpolated.source_range
806
+ assert_equal 3, range.start_pos.line
807
+ assert_equal 12, range.start_pos.offset
808
+ assert_equal 3, range.end_pos.line
809
+ assert_equal 18, range.end_pos.offset
810
+ end
811
+
812
+ def test_sources_array_is_uri_escaped
813
+ map = Sass::Source::Map.new
814
+ importer = Sass::Importers::Filesystem.new('.')
815
+ map.add(
816
+ Sass::Source::Range.new(
817
+ Sass::Source::Position.new(0, 0),
818
+ Sass::Source::Position.new(0, 10),
819
+ 'source file.scss',
820
+ importer),
821
+ Sass::Source::Range.new(
822
+ Sass::Source::Position.new(0, 0),
823
+ Sass::Source::Position.new(0, 10),
824
+ nil, nil))
825
+
826
+ json = map.to_json(:css_path => 'output file.css', :sourcemap_path => 'output file.css.map')
827
+ assert_equal json, <<JSON.rstrip
828
+ {
829
+ "version": 3,
830
+ "mappings": "DADD,UAAU",
831
+ "sources": ["source%20file.scss"],
832
+ "names": [],
833
+ "file": "output%20file.css"
834
+ }
835
+ JSON
836
+ end
837
+
755
838
  private
756
839
 
757
840
  ANNOTATION_REGEX = /\{\{(\/?)([^}]+)\}\}/
@@ -810,11 +893,18 @@ CSS
810
893
 
811
894
  def assert_positions_equal(expected, actual, lines, message = nil)
812
895
  prefix = message ? message + ": " : ""
896
+ expected_location = lines[expected.line - 1] + "\n" + ("-" * (expected.offset - 1)) + "^"
897
+ actual_location = lines[actual.line - 1] + "\n" + ("-" * (actual.offset - 1)) + "^"
813
898
  assert_equal(expected.line, actual.line, prefix +
814
- "Expected #{expected.inspect} but was #{actual.inspect}")
899
+ "Expected #{expected.inspect}\n" +
900
+ expected_location + "\n\n" +
901
+ "But was #{actual.inspect}\n" +
902
+ actual_location)
815
903
  assert_equal(expected.offset, actual.offset, prefix +
816
- "Expected #{expected.inspect} but was #{actual.inspect}\n" +
817
- lines[actual.line - 1] + "\n" + ("-" * (actual.offset - 1)) + "^")
904
+ "Expected #{expected.inspect}\n" +
905
+ expected_location + "\n\n" +
906
+ "But was #{actual.inspect}\n" +
907
+ actual_location)
818
908
  end
819
909
 
820
910
  def assert_ranges_equal(expected, actual, lines, prefix)
@@ -843,7 +933,7 @@ MESSAGE
843
933
  rendered, sourcemap = render_with_sourcemap(source, options)
844
934
  css_path = options[:output] || "test.css"
845
935
  sourcemap_path = Sass::Util.sourcemap_name(css_path)
846
- rendered_json = sourcemap.to_json(:css_path => css_path, :sourcemap_path => sourcemap_path)
936
+ rendered_json = sourcemap.to_json(:css_path => css_path, :sourcemap_path => sourcemap_path, :type => options[:sourcemap])
847
937
 
848
938
  assert_equal css.rstrip, rendered.rstrip
849
939
  assert_equal sourcemap_json.rstrip, rendered_json
@@ -0,0 +1,191 @@
1
+ #!/usr/bin/env ruby
2
+ require File.dirname(__FILE__) + '/../test_helper'
3
+
4
+ class SuperselectorTest < MiniTest::Test
5
+ def test_superselector_reflexivity
6
+ assert_superselector 'h1', 'h1'
7
+ assert_superselector '.foo', '.foo'
8
+ assert_superselector '#foo > .bar, baz', '#foo > .bar, baz'
9
+ end
10
+
11
+ def test_smaller_compound_superselector
12
+ assert_strict_superselector '.foo', '.foo.bar'
13
+ assert_strict_superselector '.bar', '.foo.bar'
14
+ assert_strict_superselector 'a', 'a#b'
15
+ assert_strict_superselector '#b', 'a#b'
16
+ end
17
+
18
+ def test_smaller_complex_superselector
19
+ assert_strict_superselector '.bar', '.foo .bar'
20
+ assert_strict_superselector '.bar', '.foo > .bar'
21
+ assert_strict_superselector '.bar', '.foo + .bar'
22
+ assert_strict_superselector '.bar', '.foo ~ .bar'
23
+ end
24
+
25
+ def test_selector_list_subset_superselector
26
+ assert_strict_superselector '.foo, .bar', '.foo'
27
+ assert_strict_superselector '.foo, .bar, .baz', '.foo, .baz'
28
+ assert_strict_superselector '.foo, .baz, .qux', '.foo.bar, .baz.bang'
29
+ end
30
+
31
+ def test_leading_combinator_superselector
32
+ refute_superselector '+ .foo', '.foo'
33
+ refute_superselector '+ .foo', '.bar + .foo'
34
+ end
35
+
36
+ def test_trailing_combinator_superselector
37
+ refute_superselector '.foo +', '.foo'
38
+ refute_superselector '.foo +', '.foo + .bar'
39
+ end
40
+
41
+ def test_matching_combinator_superselector
42
+ assert_strict_superselector '.foo + .bar', '.foo + .bar.baz'
43
+ assert_strict_superselector '.foo + .bar', '.foo.baz + .bar'
44
+ assert_strict_superselector '.foo > .bar', '.foo > .bar.baz'
45
+ assert_strict_superselector '.foo > .bar', '.foo.baz > .bar'
46
+ assert_strict_superselector '.foo ~ .bar', '.foo ~ .bar.baz'
47
+ assert_strict_superselector '.foo ~ .bar', '.foo.baz ~ .bar'
48
+ end
49
+
50
+ def test_following_sibling_is_superselector_of_next_sibling
51
+ assert_strict_superselector '.foo ~ .bar', '.foo + .bar.baz'
52
+ assert_strict_superselector '.foo ~ .bar', '.foo.baz + .bar'
53
+ end
54
+
55
+ def test_descendant_is_superselector_of_child
56
+ assert_strict_superselector '.foo .bar', '.foo > .bar.baz'
57
+ assert_strict_superselector '.foo .bar', '.foo.baz > .bar'
58
+ end
59
+
60
+ def test_matches_is_superselector_of_constituent_selectors
61
+ %w[matches -moz-any].each do |name|
62
+ assert_strict_superselector ":#{name}(.foo, .bar)", '.foo.baz'
63
+ assert_strict_superselector ":#{name}(.foo, .bar)", '.bar.baz'
64
+ assert_strict_superselector ":#{name}(.foo .bar, .baz)", '.x .foo .bar'
65
+ end
66
+ end
67
+
68
+ def test_matches_is_superselector_of_subset_matches
69
+ assert_strict_superselector ':matches(.foo, .bar, .baz)', '#x:matches(.foo.bip, .baz.bang)'
70
+ assert_strict_superselector ':-moz-any(.foo, .bar, .baz)', '#x:-moz-any(.foo.bip, .baz.bang)'
71
+ end
72
+
73
+ def test_matches_is_not_superselector_of_any
74
+ refute_superselector ':matches(.foo, .bar)', ':-moz-any(.foo, .bar)'
75
+ refute_superselector ':-moz-any(.foo, .bar)', ':matches(.foo, .bar)'
76
+ end
77
+
78
+ def test_matches_can_be_subselector
79
+ %w[matches -moz-any].each do |name|
80
+ assert_superselector '.foo', ":#{name}(.foo.bar)"
81
+ assert_superselector '.foo.bar', ":#{name}(.foo.bar.baz)"
82
+ assert_superselector '.foo', ":#{name}(.foo.bar, .foo.baz)"
83
+ end
84
+ end
85
+
86
+ def test_any_is_not_superselector_of_different_prefix
87
+ refute_superselector ':-moz-any(.foo, .bar)', ':-s-any(.foo, .bar)'
88
+ end
89
+
90
+ def test_not_is_superselector_of_less_complex_not
91
+ assert_strict_superselector ':not(.foo.bar)', ':not(.foo)'
92
+ assert_strict_superselector ':not(.foo .bar)', ':not(.bar)'
93
+ end
94
+
95
+ def test_not_is_superselector_of_superset
96
+ assert_strict_superselector ':not(.foo.bip, .baz.bang)', ':not(.foo, .bar, .baz)'
97
+ assert_strict_superselector ':not(.foo.bip, .baz.bang)', ':not(.foo):not(.bar):not(.baz)'
98
+ end
99
+
100
+ def test_not_is_superselector_of_unique_selectors
101
+ assert_strict_superselector ':not(h1.foo)', 'a'
102
+ assert_strict_superselector ':not(.baz #foo)', '#bar'
103
+ end
104
+
105
+ def test_not_is_not_superselector_of_non_unique_selectors
106
+ refute_superselector ':not(.foo)', '.bar'
107
+ refute_superselector ':not(:hover)', ':visited'
108
+ end
109
+
110
+ def test_current_is_superselector_with_identical_innards
111
+ assert_superselector ':current(.foo)', ':current(.foo)'
112
+ end
113
+
114
+ def test_current_is_superselector_with_subselector_innards
115
+ refute_superselector ':current(.foo)', ':current(.foo.bar)'
116
+ refute_superselector ':current(.foo.bar)', ':current(.foo)'
117
+ end
118
+
119
+ def test_nth_match_is_superselector_of_subset_nth_match
120
+ assert_strict_superselector(
121
+ ':nth-child(2n of .foo, .bar, .baz)', '#x:nth-child(2n of .foo.bip, .baz.bang)')
122
+ assert_strict_superselector(
123
+ ':nth-last-child(2n of .foo, .bar, .baz)', '#x:nth-last-child(2n of .foo.bip, .baz.bang)')
124
+ end
125
+
126
+ def test_nth_match_is_not_superselector_of_nth_match_with_different_arg
127
+ refute_superselector(
128
+ ':nth-child(2n of .foo, .bar, .baz)', '#x:nth-child(2n + 1 of .foo.bip, .baz.bang)')
129
+ refute_superselector(
130
+ ':nth-last-child(2n of .foo, .bar, .baz)', '#x:nth-last-child(2n + 1 of .foo.bip, .baz.bang)')
131
+ end
132
+
133
+ def test_nth_match_is_not_superselector_of_nth_last_match
134
+ refute_superselector ':nth-child(2n of .foo, .bar)', ':nth-last-child(2n of .foo, .bar)'
135
+ refute_superselector ':nth-last-child(2n of .foo, .bar)', ':nth-child(2n of .foo, .bar)'
136
+ end
137
+
138
+ def test_nth_match_can_be_subselector
139
+ %w[nth-child nth-last-child].each do |name|
140
+ assert_superselector '.foo', ":#{name}(2n of .foo.bar)"
141
+ assert_superselector '.foo.bar', ":#{name}(2n of .foo.bar.baz)"
142
+ assert_superselector '.foo', ":#{name}(2n of .foo.bar, .foo.baz)"
143
+ end
144
+ end
145
+
146
+ def has_is_superselector_of_subset_host
147
+ assert_strict_superselector ':has(.foo, .bar, .baz)', ':has(.foo.bip, .baz.bang)'
148
+ end
149
+
150
+ def has_isnt_superselector_of_contained_selector
151
+ assert_strict_superselector ':has(.foo, .bar, .baz)', '.foo'
152
+ end
153
+
154
+ def host_is_superselector_of_subset_host
155
+ assert_strict_superselector ':host(.foo, .bar, .baz)', ':host(.foo.bip, .baz.bang)'
156
+ end
157
+
158
+ def host_isnt_superselector_of_contained_selector
159
+ assert_strict_superselector ':host(.foo, .bar, .baz)', '.foo'
160
+ end
161
+
162
+ def host_context_is_superselector_of_subset_host
163
+ assert_strict_superselector(
164
+ ':host-context(.foo, .bar, .baz)', ':host-context(.foo.bip, .baz.bang)')
165
+ end
166
+
167
+ def host_context_isnt_superselector_of_contained_selector
168
+ assert_strict_superselector ':host-context(.foo, .bar, .baz)', '.foo'
169
+ end
170
+
171
+ private
172
+
173
+ def assert_superselector(superselector, subselector)
174
+ assert(parse_selector(superselector).superselector?(parse_selector(subselector)),
175
+ "Expected #{superselector} to be a superselector of #{subselector}.")
176
+ end
177
+
178
+ def refute_superselector(superselector, subselector)
179
+ assert(!parse_selector(superselector).superselector?(parse_selector(subselector)),
180
+ "Expected #{superselector} not to be a superselector of #{subselector}.")
181
+ end
182
+
183
+ def assert_strict_superselector(superselector, subselector)
184
+ assert_superselector(superselector, subselector)
185
+ refute_superselector(subselector, superselector)
186
+ end
187
+
188
+ def parse_selector(selector)
189
+ Sass::SCSS::CssParser.new(selector, filename_for_test, nil).parse_selector
190
+ end
191
+ end
@@ -3,7 +3,8 @@ $preconst: hello;
3
3
  @mixin premixin {pre-mixin: here}
4
4
 
5
5
  @import "importee.sass", "scss_importee", "basic.sass", "basic.css", "../results/complex.css";
6
- @import "partial.sass";
6
+ @import "part\
7
+ ial.sass";
7
8
 
8
9
  nonimported {
9
10
  myconst: $preconst;
@@ -1,7 +1,7 @@
1
1
  test_dir = File.dirname(__FILE__)
2
2
  $:.unshift test_dir unless $:.include?(test_dir)
3
3
 
4
- class Test::Unit::TestCase
4
+ class MiniTest::Test
5
5
  def absolutize(file)
6
6
  File.expand_path("#{File.dirname(__FILE__)}/#{file}")
7
7
  end
@@ -3,7 +3,7 @@
3
3
  require File.dirname(__FILE__) + '/../../test_helper'
4
4
 
5
5
  unless Sass::Util.ruby1_8?
6
- class MultibyteStringScannerTest < Test::Unit::TestCase
6
+ class MultibyteStringScannerTest < MiniTest::Test
7
7
  def setup
8
8
  @scanner = Sass::Util::MultibyteStringScanner.new("cölorfül")
9
9
  end
@@ -2,7 +2,7 @@
2
2
  require File.dirname(__FILE__) + '/../../test_helper'
3
3
  require 'sass/util/normalized_map'
4
4
 
5
- class NormalizedMapTest < Test::Unit::TestCase
5
+ class NormalizedMapTest < MiniTest::Test
6
6
  extend PublicApiLinter
7
7
 
8
8
  lint_api Hash, Sass::Util::NormalizedMap
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env ruby
2
2
  require File.dirname(__FILE__) + '/../../test_helper'
3
3
 
4
- class SubsetMapTest < Test::Unit::TestCase
4
+ class SubsetMapTest < MiniTest::Test
5
5
  def setup
6
6
  @ssm = Sass::Util::SubsetMap.new
7
7
  @ssm[Set[1, 2]] = "Foo"
@@ -44,7 +44,7 @@ class SubsetMapTest < Test::Unit::TestCase
44
44
  end
45
45
 
46
46
  def test_empty_key_set
47
- assert_raise(ArgumentError) {@ssm[Set[]] = "Fail"}
47
+ assert_raises(ArgumentError) {@ssm[Set[]] = "Fail"}
48
48
  end
49
49
 
50
50
  def test_empty_key_get
@@ -3,7 +3,7 @@ require File.dirname(__FILE__) + '/../test_helper'
3
3
  require 'pathname'
4
4
  require 'tmpdir'
5
5
 
6
- class UtilTest < Test::Unit::TestCase
6
+ class UtilTest < MiniTest::Test
7
7
  include Sass::Util
8
8
 
9
9
  def test_scope
@@ -79,6 +79,15 @@ class UtilTest < Test::Unit::TestCase
79
79
  merge_adjacent_strings([str, " ", str, " ", str, :bang, str, " ", str, 12]))
80
80
  end
81
81
 
82
+ def test_replace_subseq
83
+ assert_equal([1, 2, :a, :b, 5],
84
+ replace_subseq([1, 2, 3, 4, 5], [3, 4], [:a, :b]))
85
+ assert_equal([1, 2, 3, 4, 5],
86
+ replace_subseq([1, 2, 3, 4, 5], [3, 4, 6], [:a, :b]))
87
+ assert_equal([1, 2, 3, 4, 5],
88
+ replace_subseq([1, 2, 3, 4, 5], [4, 5, 6], [:a, :b]))
89
+ end
90
+
82
91
  def test_intersperse
83
92
  assert_equal(["foo", " ", "bar", " ", "baz"],
84
93
  intersperse(%w[foo bar baz], " "))
@@ -419,6 +428,27 @@ WARNING
419
428
  end
420
429
  end
421
430
 
431
+ def test_atomic_write_permissions
432
+ atomic_filename = File.join(Dir.tmpdir, "test_atomic_perms.atomic")
433
+ normal_filename = File.join(Dir.tmpdir, "test_atomic_perms.normal")
434
+ atomic_create_and_write_file(atomic_filename) {|f| f.write("whatever\n") }
435
+ open(normal_filename, "wb") {|f| f.write("whatever\n") }
436
+ assert_equal File.stat(normal_filename).mode.to_s(8), File.stat(atomic_filename).mode.to_s(8)
437
+ ensure
438
+ File.unlink(atomic_filename) rescue nil
439
+ File.unlink(normal_filename) rescue nil
440
+ end
441
+
442
+ def test_atomic_writes_respect_umask
443
+ atomic_filename = File.join(Dir.tmpdir, "test_atomic_perms.atomic")
444
+ atomic_create_and_write_file(atomic_filename) do |f|
445
+ f.write("whatever\n")
446
+ end
447
+ assert_equal 0, File.stat(atomic_filename).mode & File.umask
448
+ ensure
449
+ File.unlink(atomic_filename)
450
+ end
451
+
422
452
  class FakeError < RuntimeError; end
423
453
 
424
454
  def test_atomic_writes_handles_exceptions
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env ruby
2
2
  require File.dirname(__FILE__) + '/../test_helper'
3
3
 
4
- class ValueHelpersTest < Test::Unit::TestCase
4
+ class ValueHelpersTest < MiniTest::Test
5
5
  include Sass::Script
6
6
  include Sass::Script::Value::Helpers
7
7
 
@@ -51,10 +51,8 @@ class ValueHelpersTest < Test::Unit::TestCase
51
51
  assert_equal 0.5, color_with_alpha.alpha
52
52
  end
53
53
 
54
- def test_hex_color_alpha_enforces_0_to_1
55
- assert_raises ArgumentError do
56
- hex_color("FF007F", 50)
57
- end
54
+ def test_hex_color_alpha_clamps_0_to_1
55
+ assert_equal 1, hex_color("FF007F", 50).alpha
58
56
  end
59
57
 
60
58
  def test_hsl_color_without_alpha
@@ -132,14 +130,14 @@ class ValueHelpersTest < Test::Unit::TestCase
132
130
  l = list(number(1, "px"), hex_color("#f71"), :space)
133
131
  l.options = {}
134
132
  assert_kind_of Sass::Script::Value::List, l
135
- assert_equal "1px #ff7711", l.to_sass
133
+ assert_equal "1px #f71", l.to_sass
136
134
  end
137
135
 
138
136
  def test_comma_list
139
137
  l = list(number(1, "px"), hex_color("#f71"), :comma)
140
138
  l.options = {}
141
139
  assert_kind_of Sass::Script::Value::List, l
142
- assert_equal "1px, #ff7711", l.to_sass
140
+ assert_equal "1px, #f71", l.to_sass
143
141
  end
144
142
 
145
143
  def test_missing_list_type
data/test/test_helper.rb CHANGED
@@ -1,6 +1,6 @@
1
1
  lib_dir = File.dirname(__FILE__) + '/../lib'
2
2
 
3
- require 'test/unit'
3
+ require 'minitest/autorun'
4
4
  require 'fileutils'
5
5
  $:.unshift lib_dir unless $:.include?(lib_dir)
6
6
  require 'sass'
@@ -22,7 +22,7 @@ module Sass::Script::Functions
22
22
  end
23
23
  end
24
24
 
25
- class Test::Unit::TestCase
25
+ class MiniTest::Test
26
26
  def munge_filename(opts = {})
27
27
  opts[:filename] ||= filename_for_test(opts[:syntax] || :sass)
28
28
  opts[:sourcemap_filename] ||= sourcemap_filename_for_test