sass 3.5.2 → 3.7.4

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 (163) hide show
  1. checksums.yaml +4 -4
  2. data/CODE_OF_CONDUCT.md +1 -1
  3. data/CONTRIBUTING.md +3 -3
  4. data/README.md +17 -9
  5. data/VERSION +1 -1
  6. data/VERSION_DATE +1 -1
  7. data/extra/sass-spec-ref.sh +9 -1
  8. data/lib/sass/engine.rb +1 -9
  9. data/lib/sass/exec/base.rb +0 -2
  10. data/lib/sass/exec/sass_scss.rb +1 -5
  11. data/lib/sass/importers/filesystem.rb +4 -2
  12. data/lib/sass/logger/base.rb +11 -0
  13. data/lib/sass/script/css_parser.rb +4 -1
  14. data/lib/sass/script/functions.rb +76 -41
  15. data/lib/sass/script/lexer.rb +62 -19
  16. data/lib/sass/script/parser.rb +260 -93
  17. data/lib/sass/script/tree/funcall.rb +0 -4
  18. data/lib/sass/script/tree/interpolation.rb +0 -3
  19. data/lib/sass/script/tree/operation.rb +1 -1
  20. data/lib/sass/script/value/color.rb +3 -2
  21. data/lib/sass/script/value/helpers.rb +8 -2
  22. data/lib/sass/script/value/number.rb +2 -1
  23. data/lib/sass/scss/css_parser.rb +6 -1
  24. data/lib/sass/scss/parser.rb +48 -18
  25. data/lib/sass/scss/rx.rb +1 -1
  26. data/lib/sass/scss/static_parser.rb +15 -18
  27. data/lib/sass/selector/comma_sequence.rb +2 -1
  28. data/lib/sass/selector/pseudo.rb +1 -1
  29. data/lib/sass/selector/sequence.rb +0 -4
  30. data/lib/sass/source/map.rb +0 -4
  31. data/lib/sass/tree/rule_node.rb +3 -6
  32. data/lib/sass/tree/visitors/perform.rb +2 -6
  33. data/lib/sass/tree/visitors/to_css.rb +4 -11
  34. data/lib/sass/util.rb +60 -20
  35. data/lib/sass/version.rb +0 -2
  36. metadata +38 -162
  37. data/Rakefile +0 -338
  38. data/lib/test.css +0 -4
  39. data/lib/test.css.map +0 -7
  40. data/test/sass-spec.yml +0 -3
  41. data/test/sass/cache_test.rb +0 -130
  42. data/test/sass/callbacks_test.rb +0 -60
  43. data/test/sass/compiler_test.rb +0 -225
  44. data/test/sass/conversion_test.rb +0 -2138
  45. data/test/sass/css2sass_test.rb +0 -523
  46. data/test/sass/css_variable_test.rb +0 -237
  47. data/test/sass/data/hsl-rgb.txt +0 -319
  48. data/test/sass/encoding_test.rb +0 -188
  49. data/test/sass/engine_test.rb +0 -3499
  50. data/test/sass/exec_test.rb +0 -95
  51. data/test/sass/extend_test.rb +0 -1678
  52. data/test/sass/fixtures/test_staleness_check_across_importers.css +0 -1
  53. data/test/sass/fixtures/test_staleness_check_across_importers.scss +0 -1
  54. data/test/sass/functions_test.rb +0 -2021
  55. data/test/sass/importer_test.rb +0 -420
  56. data/test/sass/logger_test.rb +0 -57
  57. data/test/sass/mock_importer.rb +0 -49
  58. data/test/sass/more_results/more1.css +0 -9
  59. data/test/sass/more_results/more1_with_line_comments.css +0 -26
  60. data/test/sass/more_results/more_import.css +0 -29
  61. data/test/sass/more_templates/_more_partial.sass +0 -2
  62. data/test/sass/more_templates/more1.sass +0 -23
  63. data/test/sass/more_templates/more_import.sass +0 -11
  64. data/test/sass/plugin_test.rb +0 -552
  65. data/test/sass/results/alt.css +0 -4
  66. data/test/sass/results/basic.css +0 -9
  67. data/test/sass/results/cached_import_option.css +0 -3
  68. data/test/sass/results/compact.css +0 -5
  69. data/test/sass/results/complex.css +0 -86
  70. data/test/sass/results/compressed.css +0 -1
  71. data/test/sass/results/expanded.css +0 -19
  72. data/test/sass/results/filename_fn.css +0 -3
  73. data/test/sass/results/if.css +0 -3
  74. data/test/sass/results/import.css +0 -31
  75. data/test/sass/results/import_charset.css +0 -5
  76. data/test/sass/results/import_charset_ibm866.css +0 -5
  77. data/test/sass/results/import_content.css +0 -1
  78. data/test/sass/results/line_numbers.css +0 -49
  79. data/test/sass/results/mixins.css +0 -95
  80. data/test/sass/results/multiline.css +0 -24
  81. data/test/sass/results/nested.css +0 -22
  82. data/test/sass/results/options.css +0 -1
  83. data/test/sass/results/parent_ref.css +0 -13
  84. data/test/sass/results/script.css +0 -16
  85. data/test/sass/results/scss_import.css +0 -31
  86. data/test/sass/results/scss_importee.css +0 -2
  87. data/test/sass/results/subdir/nested_subdir/nested_subdir.css +0 -1
  88. data/test/sass/results/subdir/subdir.css +0 -3
  89. data/test/sass/results/units.css +0 -11
  90. data/test/sass/results/warn.css +0 -0
  91. data/test/sass/results/warn_imported.css +0 -0
  92. data/test/sass/script_conversion_test.rb +0 -365
  93. data/test/sass/script_test.rb +0 -1429
  94. data/test/sass/scss/css_test.rb +0 -1266
  95. data/test/sass/scss/rx_test.rb +0 -159
  96. data/test/sass/scss/scss_test.rb +0 -4238
  97. data/test/sass/scss/test_helper.rb +0 -37
  98. data/test/sass/source_map_test.rb +0 -1052
  99. data/test/sass/superselector_test.rb +0 -209
  100. data/test/sass/templates/_cached_import_option_partial.scss +0 -1
  101. data/test/sass/templates/_double_import_loop2.sass +0 -1
  102. data/test/sass/templates/_filename_fn_import.scss +0 -11
  103. data/test/sass/templates/_imported_charset_ibm866.sass +0 -4
  104. data/test/sass/templates/_imported_charset_utf8.sass +0 -4
  105. data/test/sass/templates/_imported_content.sass +0 -3
  106. data/test/sass/templates/_partial.sass +0 -2
  107. data/test/sass/templates/_same_name_different_partiality.scss +0 -1
  108. data/test/sass/templates/alt.sass +0 -16
  109. data/test/sass/templates/basic.sass +0 -23
  110. data/test/sass/templates/bork1.sass +0 -2
  111. data/test/sass/templates/bork2.sass +0 -2
  112. data/test/sass/templates/bork3.sass +0 -2
  113. data/test/sass/templates/bork4.sass +0 -2
  114. data/test/sass/templates/bork5.sass +0 -3
  115. data/test/sass/templates/cached_import_option.scss +0 -3
  116. data/test/sass/templates/compact.sass +0 -17
  117. data/test/sass/templates/complex.sass +0 -305
  118. data/test/sass/templates/compressed.sass +0 -15
  119. data/test/sass/templates/double_import_loop1.sass +0 -1
  120. data/test/sass/templates/expanded.sass +0 -17
  121. data/test/sass/templates/filename_fn.scss +0 -18
  122. data/test/sass/templates/if.sass +0 -11
  123. data/test/sass/templates/import.sass +0 -12
  124. data/test/sass/templates/import_charset.sass +0 -9
  125. data/test/sass/templates/import_charset_ibm866.sass +0 -11
  126. data/test/sass/templates/import_content.sass +0 -4
  127. data/test/sass/templates/importee.less +0 -2
  128. data/test/sass/templates/importee.sass +0 -19
  129. data/test/sass/templates/line_numbers.sass +0 -13
  130. data/test/sass/templates/mixin_bork.sass +0 -5
  131. data/test/sass/templates/mixins.sass +0 -76
  132. data/test/sass/templates/multiline.sass +0 -20
  133. data/test/sass/templates/nested.sass +0 -25
  134. data/test/sass/templates/nested_bork1.sass +0 -2
  135. data/test/sass/templates/nested_bork2.sass +0 -2
  136. data/test/sass/templates/nested_bork3.sass +0 -2
  137. data/test/sass/templates/nested_bork4.sass +0 -2
  138. data/test/sass/templates/nested_import.sass +0 -2
  139. data/test/sass/templates/nested_mixin_bork.sass +0 -6
  140. data/test/sass/templates/options.sass +0 -2
  141. data/test/sass/templates/parent_ref.sass +0 -25
  142. data/test/sass/templates/same_name_different_ext.sass +0 -2
  143. data/test/sass/templates/same_name_different_ext.scss +0 -1
  144. data/test/sass/templates/same_name_different_partiality.scss +0 -1
  145. data/test/sass/templates/script.sass +0 -101
  146. data/test/sass/templates/scss_import.scss +0 -12
  147. data/test/sass/templates/scss_importee.scss +0 -1
  148. data/test/sass/templates/single_import_loop.sass +0 -1
  149. data/test/sass/templates/subdir/import_up1.scss +0 -1
  150. data/test/sass/templates/subdir/import_up2.scss +0 -1
  151. data/test/sass/templates/subdir/nested_subdir/_nested_partial.sass +0 -2
  152. data/test/sass/templates/subdir/nested_subdir/nested_subdir.sass +0 -3
  153. data/test/sass/templates/subdir/subdir.sass +0 -6
  154. data/test/sass/templates/units.sass +0 -11
  155. data/test/sass/templates/warn.sass +0 -3
  156. data/test/sass/templates/warn_imported.sass +0 -4
  157. data/test/sass/test_helper.rb +0 -8
  158. data/test/sass/util/multibyte_string_scanner_test.rb +0 -152
  159. data/test/sass/util/normalized_map_test.rb +0 -50
  160. data/test/sass/util/subset_map_test.rb +0 -90
  161. data/test/sass/util_test.rb +0 -403
  162. data/test/sass/value_helpers_test.rb +0 -178
  163. data/test/test_helper.rb +0 -149
@@ -1,12 +0,0 @@
1
- $preconst: hello;
2
-
3
- @mixin premixin {pre-mixin: here}
4
-
5
- @import "importee.sass", "scss_importee", "basic.sass", "basic.css", "../results/complex.css";
6
- @import "part\
7
- ial.sass";
8
-
9
- nonimported {
10
- myconst: $preconst;
11
- otherconst: $postconst;
12
- @include postmixin; }
@@ -1 +0,0 @@
1
- scss {imported: yes}
@@ -1 +0,0 @@
1
- @import "single_import_loop"
@@ -1 +0,0 @@
1
- @import "../subdir/import_up2.scss";
@@ -1 +0,0 @@
1
- @import "../subdir/import_up3.scss";
@@ -1,2 +0,0 @@
1
- #nested
2
- relative: true
@@ -1,6 +0,0 @@
1
- @import nested_subdir/nested_partial.sass
2
-
3
- #subdir
4
- font:
5
- size: 20px
6
- weight: bold
@@ -1,11 +0,0 @@
1
- b
2
- foo: 0.5 * 10px
3
- bar: 10zzz * 12px / 5zzz
4
- baz: percentage(12.0px / 18px)
5
- many-units: 10.0zzz / 3yyy * 12px / 5zzz * 3yyy / 3px * 4em
6
- mm: 5mm + 1cm
7
- pc: 1pc + 12pt
8
- pt: 72pt - 2in
9
- inches: 1in + 2.54cm
10
- more-inches: 1in + ((72pt * 2in) + (36pt * 1in)) / 2.54cm
11
- mixed: (1 + (1em * 6px / 3in)) * 4in / 2em
@@ -1,3 +0,0 @@
1
- @warn "In the main file"
2
- @import warn_imported.sass
3
- +emits-a-warning
@@ -1,4 +0,0 @@
1
- @warn "Imported"
2
-
3
- =emits-a-warning
4
- @warn "In an imported mixin"
@@ -1,8 +0,0 @@
1
- test_dir = File.dirname(__FILE__)
2
- $:.unshift test_dir unless $:.include?(test_dir)
3
-
4
- class MiniTest::Test
5
- def absolutize(file)
6
- File.expand_path("#{File.dirname(__FILE__)}/#{file}")
7
- end
8
- end
@@ -1,152 +0,0 @@
1
- # -*- coding: utf-8 -*-
2
- require File.dirname(__FILE__) + '/../../test_helper'
3
-
4
- class MultibyteStringScannerTest < MiniTest::Test
5
- def setup
6
- @scanner = Sass::Util::MultibyteStringScanner.new("cölorfül")
7
- end
8
-
9
- def test_initial
10
- assert_scanner_state 0, 0, nil, nil
11
- end
12
-
13
- def test_check
14
- assert_equal 'cö', @scanner.check(/../)
15
- assert_scanner_state 0, 0, 2, 3
16
- assert_equal 0, @scanner.pos
17
- assert_equal 0, @scanner.pos
18
- assert_equal 2, @scanner.matched_size
19
- assert_equal 3, @scanner.byte_matched_size
20
- end
21
-
22
- def test_check_until
23
- assert_equal 'cölorfü', @scanner.check_until(/f./)
24
- assert_scanner_state 0, 0, 2, 3
25
- end
26
-
27
- def test_getch
28
- assert_equal 'c', @scanner.getch
29
- assert_equal 'ö', @scanner.getch
30
- assert_scanner_state 2, 3, 1, 2
31
- end
32
-
33
- def test_match?
34
- assert_equal 2, @scanner.match?(/../)
35
- assert_scanner_state 0, 0, 2, 3
36
- end
37
-
38
- def test_peek
39
- assert_equal 'cö', @scanner.peek(2)
40
- assert_scanner_state 0, 0, nil, nil
41
- end
42
-
43
- def test_rest_size
44
- assert_equal 'cö', @scanner.scan(/../)
45
- assert_equal 6, @scanner.rest_size
46
- end
47
-
48
- def test_scan
49
- assert_equal 'cö', @scanner.scan(/../)
50
- assert_scanner_state 2, 3, 2, 3
51
- end
52
-
53
- def test_scan_until
54
- assert_equal 'cölorfü', @scanner.scan_until(/f./)
55
- assert_scanner_state 7, 9, 2, 3
56
- end
57
-
58
- def test_skip
59
- assert_equal 2, @scanner.skip(/../)
60
- assert_scanner_state 2, 3, 2, 3
61
- end
62
-
63
- def test_skip_until
64
- assert_equal 7, @scanner.skip_until(/f./)
65
- assert_scanner_state 7, 9, 2, 3
66
- end
67
-
68
- def test_set_pos
69
- @scanner.pos = 7
70
- assert_scanner_state 7, 9, nil, nil
71
- @scanner.pos = 6
72
- assert_scanner_state 6, 7, nil, nil
73
- @scanner.pos = 1
74
- assert_scanner_state 1, 1, nil, nil
75
- end
76
-
77
- def test_reset
78
- @scanner.scan(/../)
79
- @scanner.reset
80
- assert_scanner_state 0, 0, nil, nil
81
- end
82
-
83
- def test_scan_full
84
- assert_equal 'cö', @scanner.scan_full(/../, true, true)
85
- assert_scanner_state 2, 3, 2, 3
86
-
87
- @scanner.reset
88
- assert_equal 'cö', @scanner.scan_full(/../, false, true)
89
- assert_scanner_state 0, 0, 2, 3
90
-
91
- @scanner.reset
92
- assert_nil @scanner.scan_full(/../, true, false)
93
- assert_scanner_state 2, 3, 2, 3
94
-
95
- @scanner.reset
96
- assert_nil @scanner.scan_full(/../, false, false)
97
- assert_scanner_state 0, 0, 2, 3
98
- end
99
-
100
- def test_search_full
101
- assert_equal 'cölorfü', @scanner.search_full(/f./, true, true)
102
- assert_scanner_state 7, 9, 2, 3
103
-
104
- @scanner.reset
105
- assert_equal 'cölorfü', @scanner.search_full(/f./, false, true)
106
- assert_scanner_state 0, 0, 2, 3
107
-
108
- @scanner.reset
109
- assert_nil @scanner.search_full(/f./, true, false)
110
- assert_scanner_state 7, 9, 2, 3
111
-
112
- @scanner.reset
113
- assert_nil @scanner.search_full(/f./, false, false)
114
- assert_scanner_state 0, 0, 2, 3
115
- end
116
-
117
- def test_set_string
118
- @scanner.scan(/../)
119
- @scanner.string = 'föóbâr'
120
- assert_scanner_state 0, 0, nil, nil
121
- end
122
-
123
- def test_terminate
124
- @scanner.scan(/../)
125
- @scanner.terminate
126
- assert_scanner_state 8, 10, nil, nil
127
- end
128
-
129
- def test_unscan
130
- @scanner.scan(/../)
131
- @scanner.scan_until(/f./)
132
- @scanner.unscan
133
- assert_scanner_state 2, 3, nil, nil
134
- end
135
-
136
- private
137
-
138
- def assert_scanner_state(pos, byte_pos, matched_size, byte_matched_size)
139
- assert_equal pos, @scanner.pos, 'pos'
140
- assert_equal byte_pos, @scanner.byte_pos, 'byte_pos'
141
- if matched_size.nil?
142
- assert_nil @scanner.matched_size, 'matched_size'
143
- else
144
- assert_equal matched_size, @scanner.matched_size, 'matched_size'
145
- end
146
- if byte_matched_size.nil?
147
- assert_nil @scanner.byte_matched_size, 'byte_matched_size'
148
- else
149
- assert_equal byte_matched_size, @scanner.byte_matched_size, 'byte_matched_size'
150
- end
151
- end
152
- end
@@ -1,50 +0,0 @@
1
- require File.dirname(__FILE__) + '/../../test_helper'
2
- require 'sass/util/normalized_map'
3
-
4
- class NormalizedMapTest < MiniTest::Test
5
- extend PublicApiLinter
6
-
7
- lint_api Hash, Sass::Util::NormalizedMap
8
-
9
- def lint_instance
10
- Sass::Util::NormalizedMap.new
11
- end
12
-
13
- def test_normalized_map_errors_unless_explicitly_implemented
14
- assert Sass.tests_running
15
- assert_raise_message(ArgumentError, "The method invert must be implemented explicitly") do
16
- Sass::Util::NormalizedMap.new.invert
17
- end
18
- end
19
-
20
- def test_normalized_map_does_not_error_when_released
21
- Sass.tests_running = false
22
- assert_equal({}, Sass::Util::NormalizedMap.new.invert)
23
- ensure
24
- Sass.tests_running = true
25
- end
26
-
27
- def test_basic_lifecycle
28
- m = Sass::Util::NormalizedMap.new
29
- m["a-b"] = 1
30
- assert_equal ["a_b"], m.keys
31
- assert_equal 1, m["a_b"]
32
- assert_equal 1, m["a-b"]
33
- assert m.has_key?("a_b")
34
- assert m.has_key?("a-b")
35
- assert_equal({"a-b" => 1}, m.as_stored)
36
- assert_equal 1, m.delete("a-b")
37
- assert !m.has_key?("a-b")
38
- m["a_b"] = 2
39
- assert_equal({"a_b" => 2}, m.as_stored)
40
- end
41
-
42
- def test_dup
43
- m = Sass::Util::NormalizedMap.new
44
- m["a-b"] = 1
45
- m2 = m.dup
46
- m.delete("a-b")
47
- assert !m.has_key?("a-b")
48
- assert m2.has_key?("a-b")
49
- end
50
- end
@@ -1,90 +0,0 @@
1
- require File.dirname(__FILE__) + '/../../test_helper'
2
-
3
- class SubsetMapTest < MiniTest::Test
4
- def setup
5
- @ssm = Sass::Util::SubsetMap.new
6
- @ssm[Set[1, 2]] = "Foo"
7
- @ssm[Set["fizz", "fazz"]] = "Bar"
8
-
9
- @ssm[Set[:foo, :bar]] = "Baz"
10
- @ssm[Set[:foo, :bar, :baz]] = "Bang"
11
-
12
- @ssm[Set[:bip, :bop, :blip]] = "Qux"
13
- @ssm[Set[:bip, :bop]] = "Thram"
14
- end
15
-
16
- def test_equal_keys
17
- assert_equal [["Foo", Set[1, 2]]], @ssm.get(Set[1, 2])
18
- assert_equal [["Bar", Set["fizz", "fazz"]]], @ssm.get(Set["fizz", "fazz"])
19
- end
20
-
21
- def test_subset_keys
22
- assert_equal [["Foo", Set[1, 2]]], @ssm.get(Set[1, 2, "fuzz"])
23
- assert_equal [["Bar", Set["fizz", "fazz"]]], @ssm.get(Set["fizz", "fazz", 3])
24
- end
25
-
26
- def test_superset_keys
27
- assert_equal [], @ssm.get(Set[1])
28
- assert_equal [], @ssm.get(Set[2])
29
- assert_equal [], @ssm.get(Set["fizz"])
30
- assert_equal [], @ssm.get(Set["fazz"])
31
- end
32
-
33
- def test_disjoint_keys
34
- assert_equal [], @ssm.get(Set[3, 4])
35
- assert_equal [], @ssm.get(Set["fuzz", "frizz"])
36
- assert_equal [], @ssm.get(Set["gran", 15])
37
- end
38
-
39
- def test_semi_disjoint_keys
40
- assert_equal [], @ssm.get(Set[2, 3])
41
- assert_equal [], @ssm.get(Set["fizz", "fuzz"])
42
- assert_equal [], @ssm.get(Set[1, "fazz"])
43
- end
44
-
45
- def test_empty_key_set
46
- assert_raises(ArgumentError) {@ssm[Set[]] = "Fail"}
47
- end
48
-
49
- def test_empty_key_get
50
- assert_equal [], @ssm.get(Set[])
51
- end
52
-
53
- def test_multiple_subsets
54
- assert_equal [["Foo", Set[1, 2]], ["Bar", Set["fizz", "fazz"]]], @ssm.get(Set[1, 2, "fizz", "fazz"])
55
- assert_equal [["Foo", Set[1, 2]], ["Bar", Set["fizz", "fazz"]]], @ssm.get(Set[1, 2, 3, "fizz", "fazz", "fuzz"])
56
-
57
- assert_equal [["Baz", Set[:foo, :bar]]], @ssm.get(Set[:foo, :bar])
58
- assert_equal [["Baz", Set[:foo, :bar]], ["Bang", Set[:foo, :bar, :baz]]], @ssm.get(Set[:foo, :bar, :baz])
59
- end
60
-
61
- def test_bracket_bracket
62
- assert_equal ["Foo"], @ssm[Set[1, 2, "fuzz"]]
63
- assert_equal ["Baz", "Bang"], @ssm[Set[:foo, :bar, :baz]]
64
- end
65
-
66
- def test_order_preserved
67
- @ssm[Set[10, 11, 12]] = 1
68
- @ssm[Set[10, 11]] = 2
69
- @ssm[Set[11]] = 3
70
- @ssm[Set[11, 12]] = 4
71
- @ssm[Set[9, 10, 11, 12, 13]] = 5
72
- @ssm[Set[10, 13]] = 6
73
-
74
- assert_equal(
75
- [[1, Set[10, 11, 12]], [2, Set[10, 11]], [3, Set[11]], [4, Set[11, 12]],
76
- [5, Set[9, 10, 11, 12, 13]], [6, Set[10, 13]]],
77
- @ssm.get(Set[9, 10, 11, 12, 13]))
78
- end
79
-
80
- def test_multiple_equal_values
81
- @ssm[Set[11, 12]] = 1
82
- @ssm[Set[12, 13]] = 2
83
- @ssm[Set[13, 14]] = 1
84
- @ssm[Set[14, 15]] = 1
85
-
86
- assert_equal(
87
- [[1, Set[11, 12]], [2, Set[12, 13]], [1, Set[13, 14]], [1, Set[14, 15]]],
88
- @ssm.get(Set[11, 12, 13, 14, 15]))
89
- end
90
- end
@@ -1,403 +0,0 @@
1
- require File.dirname(__FILE__) + '/../test_helper'
2
- require 'pathname'
3
- require 'tmpdir'
4
-
5
- class UtilTest < MiniTest::Test
6
- include Sass::Util
7
-
8
- def test_scope
9
- assert(File.exist?(scope("Rakefile")))
10
- end
11
-
12
- def test_map_keys
13
- assert_equal({
14
- "foo" => 1,
15
- "bar" => 2,
16
- "baz" => 3
17
- }, map_keys({:foo => 1, :bar => 2, :baz => 3}) {|k| k.to_s})
18
- end
19
-
20
- def test_map_vals
21
- assert_equal({
22
- :foo => "1",
23
- :bar => "2",
24
- :baz => "3"
25
- }, map_vals({:foo => 1, :bar => 2, :baz => 3}) {|k| k.to_s})
26
- end
27
-
28
- def test_map_hash
29
- assert_equal({
30
- "foo" => "1",
31
- "bar" => "2",
32
- "baz" => "3"
33
- }, map_hash({:foo => 1, :bar => 2, :baz => 3}) {|k, v| [k.to_s, v.to_s]})
34
- end
35
-
36
- def test_map_hash_with_normalized_map
37
- map = NormalizedMap.new("foo-bar" => 1, "baz_bang" => 2)
38
- result = map_hash(map) {|k, v| [k, v.to_s]}
39
- assert_equal("1", result["foo-bar"])
40
- assert_equal("1", result["foo_bar"])
41
- assert_equal("2", result["baz-bang"])
42
- assert_equal("2", result["baz_bang"])
43
- end
44
-
45
- def test_powerset
46
- assert_equal([[].to_set].to_set,
47
- powerset([]))
48
- assert_equal([[].to_set, [1].to_set].to_set,
49
- powerset([1]))
50
- assert_equal([[].to_set, [1].to_set, [2].to_set, [1, 2].to_set].to_set,
51
- powerset([1, 2]))
52
- assert_equal([[].to_set, [1].to_set, [2].to_set, [3].to_set,
53
- [1, 2].to_set, [2, 3].to_set, [1, 3].to_set, [1, 2, 3].to_set].to_set,
54
- powerset([1, 2, 3]))
55
- end
56
-
57
- def test_restrict
58
- assert_equal(0.5, restrict(0.5, 0..1))
59
- assert_equal(1, restrict(2, 0..1))
60
- assert_equal(1.3, restrict(2, 0..1.3))
61
- assert_equal(0, restrict(-1, 0..1))
62
- end
63
-
64
- def test_merge_adjacent_strings
65
- assert_equal(["foo bar baz", :bang, "biz bop", 12],
66
- merge_adjacent_strings(["foo ", "bar ", "baz", :bang, "biz", " bop", 12]))
67
- str = "foo"
68
- assert_equal(["foo foo foo", :bang, "foo foo", 12],
69
- merge_adjacent_strings([str, " ", str, " ", str, :bang, str, " ", str, 12]))
70
- end
71
-
72
- def test_replace_subseq
73
- assert_equal([1, 2, :a, :b, 5],
74
- replace_subseq([1, 2, 3, 4, 5], [3, 4], [:a, :b]))
75
- assert_equal([1, 2, 3, 4, 5],
76
- replace_subseq([1, 2, 3, 4, 5], [3, 4, 6], [:a, :b]))
77
- assert_equal([1, 2, 3, 4, 5],
78
- replace_subseq([1, 2, 3, 4, 5], [4, 5, 6], [:a, :b]))
79
- end
80
-
81
- def test_intersperse
82
- assert_equal(["foo", " ", "bar", " ", "baz"],
83
- intersperse(%w[foo bar baz], " "))
84
- assert_equal([], intersperse([], " "))
85
- end
86
-
87
- def test_substitute
88
- assert_equal(["foo", "bar", "baz", 3, 4],
89
- substitute([1, 2, 3, 4], [1, 2], ["foo", "bar", "baz"]))
90
- assert_equal([1, "foo", "bar", "baz", 4],
91
- substitute([1, 2, 3, 4], [2, 3], ["foo", "bar", "baz"]))
92
- assert_equal([1, 2, "foo", "bar", "baz"],
93
- substitute([1, 2, 3, 4], [3, 4], ["foo", "bar", "baz"]))
94
-
95
- assert_equal([1, "foo", "bar", "baz", 2, 3, 4],
96
- substitute([1, 2, 2, 2, 3, 4], [2, 2], ["foo", "bar", "baz"]))
97
- end
98
-
99
- def test_strip_string_array
100
- assert_equal(["foo ", " bar ", " baz"],
101
- strip_string_array([" foo ", " bar ", " baz "]))
102
- assert_equal([:foo, " bar ", " baz"],
103
- strip_string_array([:foo, " bar ", " baz "]))
104
- assert_equal(["foo ", " bar ", :baz],
105
- strip_string_array([" foo ", " bar ", :baz]))
106
- end
107
-
108
- def test_paths
109
- assert_equal([[1, 3, 5], [2, 3, 5], [1, 4, 5], [2, 4, 5]],
110
- paths([[1, 2], [3, 4], [5]]))
111
- assert_equal([[]], paths([]))
112
- assert_equal([[1, 2, 3]], paths([[1], [2], [3]]))
113
- end
114
-
115
- def test_lcs
116
- assert_equal([1, 2, 3], lcs([1, 2, 3], [1, 2, 3]))
117
- assert_equal([], lcs([], [1, 2, 3]))
118
- assert_equal([], lcs([1, 2, 3], []))
119
- assert_equal([1, 2, 3], lcs([5, 1, 4, 2, 3, 17], [0, 0, 1, 2, 6, 3]))
120
-
121
- assert_equal([1], lcs([1, 2, 3, 4], [4, 3, 2, 1]))
122
- assert_equal([1, 2], lcs([1, 2, 3, 4], [3, 4, 1, 2]))
123
- end
124
-
125
- def test_lcs_with_block
126
- assert_equal(["1", "2", "3"],
127
- lcs([1, 4, 2, 5, 3], [1, 2, 3]) {|a, b| a == b && a.to_s})
128
- assert_equal([-4, 2, 8],
129
- lcs([-5, 3, 2, 8], [-4, 1, 8]) {|a, b| (a - b).abs <= 1 && [a, b].max})
130
- end
131
-
132
- def test_subsequence
133
- assert(subsequence?([1, 2, 3], [1, 2, 3]))
134
- assert(subsequence?([1, 2, 3], [1, :a, 2, :b, 3]))
135
- assert(subsequence?([1, 2, 3], [:a, 1, :b, :c, 2, :d, 3, :e, :f]))
136
-
137
- assert(!subsequence?([1, 2, 3], [1, 2]))
138
- assert(!subsequence?([1, 2, 3], [1, 3, 2]))
139
- assert(!subsequence?([1, 2, 3], [3, 2, 1]))
140
- end
141
-
142
- def test_silence_warnings
143
- old_stderr, $stderr = $stderr, StringIO.new
144
- warn "Out"
145
- assert_equal("Out\n", $stderr.string)
146
- silence_warnings {warn "In"}
147
- assert_equal("Out\n", $stderr.string)
148
- ensure
149
- $stderr = old_stderr
150
- end
151
-
152
- def test_sass_warn
153
- assert_warning("Foo!") {sass_warn "Foo!"}
154
- end
155
-
156
- def test_silence_sass_warnings
157
- old_stderr, $stderr = $stderr, StringIO.new
158
- silence_sass_warnings {warn "Out"}
159
- assert_equal("Out\n", $stderr.string)
160
- silence_sass_warnings {sass_warn "In"}
161
- assert_equal("Out\n", $stderr.string)
162
- ensure
163
- $stderr = old_stderr
164
- end
165
-
166
- def test_extract
167
- arr = [1, 2, 3, 4, 5]
168
- assert_equal([1, 3, 5], extract!(arr) {|e| e % 2 == 1})
169
- assert_equal([2, 4], arr)
170
- end
171
-
172
- def test_flatten_vertically
173
- assert_equal([1, 2, 3], flatten_vertically([1, 2, 3]))
174
- assert_equal([1, 3, 5, 2, 4, 6], flatten_vertically([[1, 2], [3, 4], [5, 6]]))
175
- assert_equal([1, 2, 4, 3, 5, 6], flatten_vertically([1, [2, 3], [4, 5, 6]]))
176
- assert_equal([1, 4, 6, 2, 5, 3], flatten_vertically([[1, 2, 3], [4, 5], 6]))
177
- end
178
-
179
- def test_extract_and_inject_values
180
- test = lambda {|arr| assert_equal(arr, with_extracted_values(arr) {|str| str})}
181
-
182
- test[['foo bar']]
183
- test[['foo {12} bar']]
184
- test[['foo {{12} bar']]
185
- test[['foo {{1', 12, '2} bar']]
186
- test[['foo 1', 2, '{3', 4, 5, 6, '{7}', 8]]
187
- test[['foo 1', [2, 3, 4], ' bar']]
188
- test[['foo ', 1, "\n bar\n", [2, 3, 4], "\n baz"]]
189
- end
190
-
191
- def nested_caller_info_fn
192
- caller_info
193
- end
194
-
195
- def double_nested_caller_info_fn
196
- nested_caller_info_fn
197
- end
198
-
199
- def test_caller_info
200
- assert_equal(["/tmp/foo.rb", 12, "fizzle"], caller_info("/tmp/foo.rb:12: in `fizzle'"))
201
- assert_equal(["/tmp/foo.rb", 12, nil], caller_info("/tmp/foo.rb:12"))
202
- assert_equal(["C:/tmp/foo.rb", 12, nil], caller_info("C:/tmp/foo.rb:12"))
203
- assert_equal(["(sass)", 12, "blah"], caller_info("(sass):12: in `blah'"))
204
- assert_equal(["", 12, "boop"], caller_info(":12: in `boop'"))
205
- assert_equal(["/tmp/foo.rb", -12, "fizzle"], caller_info("/tmp/foo.rb:-12: in `fizzle'"))
206
- assert_equal(["/tmp/foo.rb", 12, "fizzle"], caller_info("/tmp/foo.rb:12: in `fizzle {}'"))
207
- assert_equal(["C:/tmp/foo.rb", 12, "fizzle"], caller_info("C:/tmp/foo.rb:12: in `fizzle {}'"))
208
-
209
- info = nested_caller_info_fn
210
- assert_equal(__FILE__, info[0])
211
- assert_equal("test_caller_info", info[2])
212
-
213
- info = proc {nested_caller_info_fn}.call
214
- assert_equal(__FILE__, info[0])
215
- assert_match(/^(block in )?test_caller_info$/, info[2])
216
-
217
- info = double_nested_caller_info_fn
218
- assert_equal(__FILE__, info[0])
219
- assert_equal("double_nested_caller_info_fn", info[2])
220
-
221
- info = proc {double_nested_caller_info_fn}.call
222
- assert_equal(__FILE__, info[0])
223
- assert_equal("double_nested_caller_info_fn", info[2])
224
- end
225
-
226
- def test_version_gt
227
- assert_version_gt("2.0.0", "1.0.0")
228
- assert_version_gt("1.1.0", "1.0.0")
229
- assert_version_gt("1.0.1", "1.0.0")
230
- assert_version_gt("1.0.0", "1.0.0.rc")
231
- assert_version_gt("1.0.0.1", "1.0.0.rc")
232
- assert_version_gt("1.0.0.rc", "0.9.9")
233
- assert_version_gt("1.0.0.beta", "1.0.0.alpha")
234
-
235
- assert_version_eq("1.0.0", "1.0.0")
236
- assert_version_eq("1.0.0", "1.0.0.0")
237
- end
238
-
239
- def assert_version_gt(v1, v2)
240
- #assert(version_gt(v1, v2), "Expected #{v1} > #{v2}")
241
- assert(!version_gt(v2, v1), "Expected #{v2} < #{v1}")
242
- end
243
-
244
- def assert_version_eq(v1, v2)
245
- assert(!version_gt(v1, v2), "Expected #{v1} = #{v2}")
246
- assert(!version_gt(v2, v1), "Expected #{v2} = #{v1}")
247
- end
248
-
249
- class FooBar
250
- def foo
251
- Sass::Util.abstract(self)
252
- end
253
- def old_method
254
- Sass::Util.deprecated(self)
255
- end
256
- def old_method_with_custom_message
257
- Sass::Util.deprecated(self, "Call FooBar#new_method instead.")
258
- end
259
- def self.another_old_method
260
- Sass::Util.deprecated(self)
261
- end
262
- end
263
-
264
- def test_abstract
265
- assert_raise_message(NotImplementedError,
266
- "UtilTest::FooBar must implement #foo") {FooBar.new.foo}
267
- end
268
-
269
- def test_deprecated
270
- assert_warning("DEPRECATION WARNING: UtilTest::FooBar#old_method will be removed in a future version of Sass.") { FooBar.new.old_method }
271
- assert_warning(<<WARNING) { FooBar.new.old_method_with_custom_message }
272
- DEPRECATION WARNING: UtilTest::FooBar#old_method_with_custom_message will be removed in a future version of Sass.
273
- Call FooBar#new_method instead.
274
- WARNING
275
- assert_warning("DEPRECATION WARNING: UtilTest::FooBar.another_old_method will be removed in a future version of Sass.") { FooBar.another_old_method }
276
- end
277
-
278
- def test_json_escape_string
279
- assert_json_string "", ""
280
- alphanum = (("0".."9").to_a).concat(("a".."z").to_a).concat(("A".."Z").to_a).join
281
- assert_json_string alphanum, alphanum
282
- assert_json_string "'\"\\'", "'\\\"\\\\'"
283
- assert_json_string "\b\f\n\r\t", "\\b\\f\\n\\r\\t"
284
- end
285
-
286
- def assert_json_string(source, target)
287
- assert_equal target, json_escape_string(source)
288
- end
289
-
290
- def test_json_value_of
291
- assert_json_value 0, "0"
292
- assert_json_value(-42, "-42")
293
- assert_json_value 42, "42"
294
- assert_json_value true, "true"
295
- assert_json_value false, "false"
296
- assert_json_value "", "\"\""
297
- assert_json_value "\"\"", "\"\\\"\\\"\""
298
- assert_json_value "Multi\nLine\rString", "\"Multi\\nLine\\rString\""
299
- assert_json_value [1, "some\nstr,ing", false, nil], "[1,\"some\\nstr,ing\",false,null]"
300
- end
301
-
302
- def assert_json_value(source, target)
303
- assert_equal target, json_value_of(source)
304
- end
305
-
306
- def test_vlq
307
- assert_equal "A", encode_vlq(0)
308
- assert_equal "e", encode_vlq(15)
309
- assert_equal "gB", encode_vlq(16)
310
- assert_equal "wH", encode_vlq(120)
311
- end
312
-
313
- def assert_vlq_encodes(int, vlq)
314
- vlq_from_decimal_array = decimal_array.map {|d| encode_vlq(d)}.join
315
- decimal_array_from_vlq = decode_vlq(vlq)
316
- assert_equal vlq, vlq_from_decimal_array
317
- assert_equal decimal_array, decimal_array_from_vlq
318
- end
319
-
320
- def test_round_respects_precision
321
- original_precision = Sass::Script::Value::Number.precision
322
- assert_equal 0, Sass::Util.round(0.4999999999)
323
- # 10 9s doesn't work because 0.49999999999 - 0.5 is very slightly greater
324
- # than -0.1e11 due to float nonsense.
325
- assert_equal 1, Sass::Util.round(0.499999999999)
326
- Sass::Script::Value::Number.precision = 6
327
- assert_equal 0, Sass::Util.round(0.499999)
328
- assert_equal 1, Sass::Util.round(0.49999999)
329
- ensure
330
- Sass::Script::Value::Number.precision = original_precision
331
- end
332
-
333
- def test_atomic_writes
334
- # when using normal writes, this test fails about 90% of the time.
335
- filename = File.join(Dir.tmpdir, "test_atomic")
336
- 5.times do
337
- writes_to_perform = %w(1 2 3 4 5 6 7 8 9).map {|i| "#{i}\n" * 100_000}
338
- threads = writes_to_perform.map do |to_write|
339
- Thread.new do
340
- # To see this test fail with a normal write,
341
- # change to the standard file open mechanism:
342
- # open(filename, "w") do |f|
343
- atomic_create_and_write_file(filename) do |f|
344
- f.write(to_write)
345
- end
346
- end
347
- end
348
- loop do
349
- contents = File.exist?(filename) ? File.read(filename) : nil
350
- next if contents.nil? || contents.size == 0
351
- unless writes_to_perform.include?(contents)
352
- if contents.size != writes_to_perform.first.size
353
- fail "Incomplete write detected: was #{contents.size} characters, " +
354
- "should have been #{writes_to_perform.first.size}"
355
- else
356
- fail "Corrupted read/write detected"
357
- end
358
- end
359
- break if threads.all? {|t| !t.alive?}
360
- end
361
- threads.each {|t| t.join}
362
- end
363
- ensure
364
- Sass::Util.retry_on_windows {File.delete filename if File.exist?(filename)}
365
- end
366
-
367
- def test_atomic_write_permissions
368
- atomic_filename = File.join(Dir.tmpdir, "test_atomic_perms.atomic")
369
- normal_filename = File.join(Dir.tmpdir, "test_atomic_perms.normal")
370
- atomic_create_and_write_file(atomic_filename) {|f| f.write("whatever\n") }
371
- open(normal_filename, "wb") {|f| f.write("whatever\n") }
372
- assert_equal File.stat(normal_filename).mode.to_s(8), File.stat(atomic_filename).mode.to_s(8)
373
- ensure
374
- File.unlink(atomic_filename) rescue nil
375
- File.unlink(normal_filename) rescue nil
376
- end
377
-
378
- def test_atomic_writes_respect_umask
379
- atomic_filename = File.join(Dir.tmpdir, "test_atomic_perms.atomic")
380
- atomic_create_and_write_file(atomic_filename) do |f|
381
- f.write("whatever\n")
382
- end
383
- assert_equal 0, File.stat(atomic_filename).mode & File.umask
384
- ensure
385
- File.unlink(atomic_filename)
386
- end
387
-
388
- class FakeError < RuntimeError; end
389
-
390
- def test_atomic_writes_handles_exceptions
391
- filename = File.join(Dir.tmpdir, "test_atomic_exception")
392
- FileUtils.rm_f(filename)
393
- tmp_filename = nil
394
- assert_raises FakeError do
395
- atomic_create_and_write_file(filename) do |f|
396
- tmp_filename = f.path
397
- raise FakeError.new "Borken"
398
- end
399
- end
400
- assert !File.exist?(filename)
401
- assert !File.exist?(tmp_filename)
402
- end
403
- end