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.
- checksums.yaml +4 -4
- data/CODE_OF_CONDUCT.md +1 -1
- data/CONTRIBUTING.md +3 -3
- data/README.md +17 -9
- data/VERSION +1 -1
- data/VERSION_DATE +1 -1
- data/extra/sass-spec-ref.sh +9 -1
- data/lib/sass/engine.rb +1 -9
- data/lib/sass/exec/base.rb +0 -2
- data/lib/sass/exec/sass_scss.rb +1 -5
- data/lib/sass/importers/filesystem.rb +4 -2
- data/lib/sass/logger/base.rb +11 -0
- data/lib/sass/script/css_parser.rb +4 -1
- data/lib/sass/script/functions.rb +76 -41
- data/lib/sass/script/lexer.rb +62 -19
- data/lib/sass/script/parser.rb +260 -93
- data/lib/sass/script/tree/funcall.rb +0 -4
- data/lib/sass/script/tree/interpolation.rb +0 -3
- data/lib/sass/script/tree/operation.rb +1 -1
- data/lib/sass/script/value/color.rb +3 -2
- data/lib/sass/script/value/helpers.rb +8 -2
- data/lib/sass/script/value/number.rb +2 -1
- data/lib/sass/scss/css_parser.rb +6 -1
- data/lib/sass/scss/parser.rb +48 -18
- data/lib/sass/scss/rx.rb +1 -1
- data/lib/sass/scss/static_parser.rb +15 -18
- data/lib/sass/selector/comma_sequence.rb +2 -1
- data/lib/sass/selector/pseudo.rb +1 -1
- data/lib/sass/selector/sequence.rb +0 -4
- data/lib/sass/source/map.rb +0 -4
- data/lib/sass/tree/rule_node.rb +3 -6
- data/lib/sass/tree/visitors/perform.rb +2 -6
- data/lib/sass/tree/visitors/to_css.rb +4 -11
- data/lib/sass/util.rb +60 -20
- data/lib/sass/version.rb +0 -2
- metadata +38 -162
- data/Rakefile +0 -338
- data/lib/test.css +0 -4
- data/lib/test.css.map +0 -7
- data/test/sass-spec.yml +0 -3
- data/test/sass/cache_test.rb +0 -130
- data/test/sass/callbacks_test.rb +0 -60
- data/test/sass/compiler_test.rb +0 -225
- data/test/sass/conversion_test.rb +0 -2138
- data/test/sass/css2sass_test.rb +0 -523
- data/test/sass/css_variable_test.rb +0 -237
- data/test/sass/data/hsl-rgb.txt +0 -319
- data/test/sass/encoding_test.rb +0 -188
- data/test/sass/engine_test.rb +0 -3499
- data/test/sass/exec_test.rb +0 -95
- data/test/sass/extend_test.rb +0 -1678
- data/test/sass/fixtures/test_staleness_check_across_importers.css +0 -1
- data/test/sass/fixtures/test_staleness_check_across_importers.scss +0 -1
- data/test/sass/functions_test.rb +0 -2021
- data/test/sass/importer_test.rb +0 -420
- data/test/sass/logger_test.rb +0 -57
- data/test/sass/mock_importer.rb +0 -49
- data/test/sass/more_results/more1.css +0 -9
- data/test/sass/more_results/more1_with_line_comments.css +0 -26
- data/test/sass/more_results/more_import.css +0 -29
- data/test/sass/more_templates/_more_partial.sass +0 -2
- data/test/sass/more_templates/more1.sass +0 -23
- data/test/sass/more_templates/more_import.sass +0 -11
- data/test/sass/plugin_test.rb +0 -552
- data/test/sass/results/alt.css +0 -4
- data/test/sass/results/basic.css +0 -9
- data/test/sass/results/cached_import_option.css +0 -3
- data/test/sass/results/compact.css +0 -5
- data/test/sass/results/complex.css +0 -86
- data/test/sass/results/compressed.css +0 -1
- data/test/sass/results/expanded.css +0 -19
- data/test/sass/results/filename_fn.css +0 -3
- data/test/sass/results/if.css +0 -3
- data/test/sass/results/import.css +0 -31
- data/test/sass/results/import_charset.css +0 -5
- data/test/sass/results/import_charset_ibm866.css +0 -5
- data/test/sass/results/import_content.css +0 -1
- data/test/sass/results/line_numbers.css +0 -49
- data/test/sass/results/mixins.css +0 -95
- data/test/sass/results/multiline.css +0 -24
- data/test/sass/results/nested.css +0 -22
- data/test/sass/results/options.css +0 -1
- data/test/sass/results/parent_ref.css +0 -13
- data/test/sass/results/script.css +0 -16
- data/test/sass/results/scss_import.css +0 -31
- data/test/sass/results/scss_importee.css +0 -2
- data/test/sass/results/subdir/nested_subdir/nested_subdir.css +0 -1
- data/test/sass/results/subdir/subdir.css +0 -3
- data/test/sass/results/units.css +0 -11
- data/test/sass/results/warn.css +0 -0
- data/test/sass/results/warn_imported.css +0 -0
- data/test/sass/script_conversion_test.rb +0 -365
- data/test/sass/script_test.rb +0 -1429
- data/test/sass/scss/css_test.rb +0 -1266
- data/test/sass/scss/rx_test.rb +0 -159
- data/test/sass/scss/scss_test.rb +0 -4238
- data/test/sass/scss/test_helper.rb +0 -37
- data/test/sass/source_map_test.rb +0 -1052
- data/test/sass/superselector_test.rb +0 -209
- data/test/sass/templates/_cached_import_option_partial.scss +0 -1
- data/test/sass/templates/_double_import_loop2.sass +0 -1
- data/test/sass/templates/_filename_fn_import.scss +0 -11
- data/test/sass/templates/_imported_charset_ibm866.sass +0 -4
- data/test/sass/templates/_imported_charset_utf8.sass +0 -4
- data/test/sass/templates/_imported_content.sass +0 -3
- data/test/sass/templates/_partial.sass +0 -2
- data/test/sass/templates/_same_name_different_partiality.scss +0 -1
- data/test/sass/templates/alt.sass +0 -16
- data/test/sass/templates/basic.sass +0 -23
- data/test/sass/templates/bork1.sass +0 -2
- data/test/sass/templates/bork2.sass +0 -2
- data/test/sass/templates/bork3.sass +0 -2
- data/test/sass/templates/bork4.sass +0 -2
- data/test/sass/templates/bork5.sass +0 -3
- data/test/sass/templates/cached_import_option.scss +0 -3
- data/test/sass/templates/compact.sass +0 -17
- data/test/sass/templates/complex.sass +0 -305
- data/test/sass/templates/compressed.sass +0 -15
- data/test/sass/templates/double_import_loop1.sass +0 -1
- data/test/sass/templates/expanded.sass +0 -17
- data/test/sass/templates/filename_fn.scss +0 -18
- data/test/sass/templates/if.sass +0 -11
- data/test/sass/templates/import.sass +0 -12
- data/test/sass/templates/import_charset.sass +0 -9
- data/test/sass/templates/import_charset_ibm866.sass +0 -11
- data/test/sass/templates/import_content.sass +0 -4
- data/test/sass/templates/importee.less +0 -2
- data/test/sass/templates/importee.sass +0 -19
- data/test/sass/templates/line_numbers.sass +0 -13
- data/test/sass/templates/mixin_bork.sass +0 -5
- data/test/sass/templates/mixins.sass +0 -76
- data/test/sass/templates/multiline.sass +0 -20
- data/test/sass/templates/nested.sass +0 -25
- data/test/sass/templates/nested_bork1.sass +0 -2
- data/test/sass/templates/nested_bork2.sass +0 -2
- data/test/sass/templates/nested_bork3.sass +0 -2
- data/test/sass/templates/nested_bork4.sass +0 -2
- data/test/sass/templates/nested_import.sass +0 -2
- data/test/sass/templates/nested_mixin_bork.sass +0 -6
- data/test/sass/templates/options.sass +0 -2
- data/test/sass/templates/parent_ref.sass +0 -25
- data/test/sass/templates/same_name_different_ext.sass +0 -2
- data/test/sass/templates/same_name_different_ext.scss +0 -1
- data/test/sass/templates/same_name_different_partiality.scss +0 -1
- data/test/sass/templates/script.sass +0 -101
- data/test/sass/templates/scss_import.scss +0 -12
- data/test/sass/templates/scss_importee.scss +0 -1
- data/test/sass/templates/single_import_loop.sass +0 -1
- data/test/sass/templates/subdir/import_up1.scss +0 -1
- data/test/sass/templates/subdir/import_up2.scss +0 -1
- data/test/sass/templates/subdir/nested_subdir/_nested_partial.sass +0 -2
- data/test/sass/templates/subdir/nested_subdir/nested_subdir.sass +0 -3
- data/test/sass/templates/subdir/subdir.sass +0 -6
- data/test/sass/templates/units.sass +0 -11
- data/test/sass/templates/warn.sass +0 -3
- data/test/sass/templates/warn_imported.sass +0 -4
- data/test/sass/test_helper.rb +0 -8
- data/test/sass/util/multibyte_string_scanner_test.rb +0 -152
- data/test/sass/util/normalized_map_test.rb +0 -50
- data/test/sass/util/subset_map_test.rb +0 -90
- data/test/sass/util_test.rb +0 -403
- data/test/sass/value_helpers_test.rb +0 -178
- 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,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
|
data/test/sass/test_helper.rb
DELETED
|
@@ -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
|
data/test/sass/util_test.rb
DELETED
|
@@ -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
|