sass 3.3.0 → 3.4.0

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 (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