sass-embedded 0.2.4 → 0.5.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.
- checksums.yaml +4 -4
- data/.github/workflows/build.yml +1 -1
- data/.rubocop.yml +11 -0
- data/README.md +1 -3
- data/Rakefile +9 -4
- data/ext/extconf.rb +15 -2
- data/lib/sass.rb +49 -27
- data/lib/sass/embedded.rb +186 -194
- data/lib/sass/error.rb +4 -9
- data/lib/sass/info.rb +30 -0
- data/lib/sass/observer.rb +38 -0
- data/lib/sass/render.rb +242 -0
- data/lib/sass/transport.rb +55 -80
- data/lib/sass/util.rb +24 -3
- data/lib/sass/version.rb +1 -1
- data/sass-embedded.gemspec +3 -1
- data/test/concurrency_test.rb +34 -0
- data/test/functions_test.rb +153 -157
- data/test/{custom_importer_test.rb → importer_test.rb} +24 -31
- data/test/include_paths_test.rb +81 -0
- data/test/indented_syntax_test.rb +61 -0
- data/test/input_test.rb +56 -0
- data/test/output_test.rb +136 -0
- data/test/render_error_test.rb +44 -0
- data/test/render_test.rb +19 -0
- data/test/source_maps_test.rb +178 -0
- data/test/test_helper.rb +1 -0
- metadata +53 -13
- data/test/compiler_test.rb +0 -276
- data/test/error_test.rb +0 -31
- data/test/output_style_test.rb +0 -93
- data/test/sass_test.rb +0 -22
data/lib/sass/util.rb
CHANGED
@@ -1,19 +1,40 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
require 'pathname'
|
4
|
+
|
3
5
|
module Sass
|
6
|
+
# The utilitiy module.
|
4
7
|
module Util
|
5
8
|
module_function
|
6
9
|
|
10
|
+
FILE_PROTOCOL = 'file://'
|
11
|
+
|
7
12
|
def file_uri(path)
|
8
13
|
absolute_path = File.absolute_path(path)
|
9
14
|
|
10
|
-
unless absolute_path.start_with?
|
15
|
+
unless absolute_path.start_with? File::SEPARATOR
|
11
16
|
components = absolute_path.split File::SEPARATOR
|
12
|
-
components[0] = components[0].
|
17
|
+
components[0] = components[0][0].downcase
|
13
18
|
absolute_path = components.join File::SEPARATOR
|
14
19
|
end
|
15
20
|
|
16
|
-
"
|
21
|
+
"#{FILE_PROTOCOL}#{absolute_path}"
|
22
|
+
end
|
23
|
+
|
24
|
+
def path(file_uri)
|
25
|
+
absolute_path = file_uri[FILE_PROTOCOL.length..]
|
26
|
+
|
27
|
+
unless absolute_path.start_with? File::SEPARATOR
|
28
|
+
components = absolute_path.split File::SEPARATOR
|
29
|
+
components[0] = "#{components[0].upcase}:"
|
30
|
+
absolute_path = components.join File::SEPARATOR
|
31
|
+
end
|
32
|
+
|
33
|
+
absolute_path
|
34
|
+
end
|
35
|
+
|
36
|
+
def relative(from, to)
|
37
|
+
Pathname.new(File.absolute_path(to)).relative_path_from(Pathname.new(File.absolute_path(from))).to_s
|
17
38
|
end
|
18
39
|
|
19
40
|
def now
|
data/lib/sass/version.rb
CHANGED
data/sass-embedded.gemspec
CHANGED
@@ -19,7 +19,7 @@ Gem::Specification.new do |spec|
|
|
19
19
|
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
20
20
|
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
21
21
|
|
22
|
-
spec.required_ruby_version = '>= 2.
|
22
|
+
spec.required_ruby_version = '>= 2.6.0'
|
23
23
|
|
24
24
|
spec.require_paths = ['lib']
|
25
25
|
|
@@ -33,4 +33,6 @@ Gem::Specification.new do |spec|
|
|
33
33
|
spec.add_development_dependency 'rake'
|
34
34
|
spec.add_development_dependency 'rake-compiler'
|
35
35
|
spec.add_development_dependency 'rubocop'
|
36
|
+
spec.add_development_dependency 'rubocop-minitest'
|
37
|
+
spec.add_development_dependency 'rubocop-rake'
|
36
38
|
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative 'test_helper'
|
4
|
+
|
5
|
+
module Sass
|
6
|
+
class ConcurrencyTest < MiniTest::Test
|
7
|
+
include TempFileTest
|
8
|
+
|
9
|
+
def setup
|
10
|
+
@embedded = Embedded.new
|
11
|
+
end
|
12
|
+
|
13
|
+
def teardown
|
14
|
+
@embedded.close
|
15
|
+
end
|
16
|
+
|
17
|
+
def render(data)
|
18
|
+
@embedded.render(data: data)[:css]
|
19
|
+
end
|
20
|
+
|
21
|
+
def test_concurrency
|
22
|
+
10.times do
|
23
|
+
threads = []
|
24
|
+
10.times do |i|
|
25
|
+
threads << Thread.new(i) do |id|
|
26
|
+
output = @embedded.render(data: "div { width: #{id} }")[:css]
|
27
|
+
assert_match(/#{id}/, output)
|
28
|
+
end
|
29
|
+
end
|
30
|
+
threads.each(&:join)
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
data/test/functions_test.rb
CHANGED
@@ -12,159 +12,161 @@ module Sass
|
|
12
12
|
@embedded.close
|
13
13
|
end
|
14
14
|
|
15
|
+
# rubocop:disable Layout/LineLength
|
16
|
+
|
15
17
|
def render(sass)
|
16
|
-
@embedded.render(
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
path
|
29
|
-
},
|
30
|
-
'no_return_path($path)': lambda { |_path|
|
31
|
-
Sass::EmbeddedProtocol::Value.new(
|
32
|
-
singleton: Sass::EmbeddedProtocol::SingletonValue::NULL
|
33
|
-
)
|
18
|
+
@embedded.render(data: sass,
|
19
|
+
functions: {
|
20
|
+
'javascript_path($path)': lambda { |path|
|
21
|
+
path.string.text = "/js/#{path.string.text}"
|
22
|
+
path
|
23
|
+
},
|
24
|
+
'stylesheet_path($path)': lambda { |path|
|
25
|
+
path.string.text = "/css/#{path.string.text}"
|
26
|
+
path
|
27
|
+
},
|
28
|
+
'sass_return_path($path)': lambda { |path|
|
29
|
+
path
|
34
30
|
},
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
31
|
+
'no_return_path($path)': lambda { |_path|
|
32
|
+
EmbeddedProtocol::Value.new(
|
33
|
+
singleton: EmbeddedProtocol::SingletonValue::NULL
|
34
|
+
)
|
35
|
+
},
|
36
|
+
'optional_arguments($path, $optional: null)': lambda { |path, optional|
|
37
|
+
EmbeddedProtocol::Value.new(
|
38
|
+
string: EmbeddedProtocol::Value::String.new(
|
39
|
+
text: "#{path.string.text}/#{optional.singleton == :NULL ? 'bar' : optional.string.text}",
|
40
|
+
quoted: true
|
41
41
|
)
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
'nice_color_argument($color)': lambda { |color|
|
48
|
-
color
|
42
|
+
)
|
43
|
+
},
|
44
|
+
'function_that_raises_errors()': lambda {
|
45
|
+
raise StandardError,
|
46
|
+
'Intentional wrong thing happened somewhere inside the custom function'
|
49
47
|
},
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
48
|
+
'nice_color_argument($color)': lambda { |color|
|
49
|
+
color
|
50
|
+
},
|
51
|
+
'returns_a_color()': lambda {
|
52
|
+
EmbeddedProtocol::Value.new(
|
53
|
+
rgb_color: EmbeddedProtocol::Value::RgbColor.new(
|
54
|
+
red: 0,
|
55
|
+
green: 0,
|
56
|
+
blue: 0,
|
57
|
+
alpha: 1
|
58
58
|
)
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
59
|
+
)
|
60
|
+
},
|
61
|
+
'returns_a_number()': lambda {
|
62
|
+
EmbeddedProtocol::Value.new(
|
63
|
+
number: EmbeddedProtocol::Value::Number.new(
|
64
|
+
value: -312,
|
65
|
+
numerators: ['rem']
|
66
66
|
)
|
67
|
-
},
|
68
|
-
'returns_a_bool()': lambda {
|
69
|
-
Sass::EmbeddedProtocol::Value.new(
|
70
|
-
singleton: Sass::EmbeddedProtocol::SingletonValue::TRUE
|
71
67
|
)
|
72
68
|
},
|
73
|
-
|
74
|
-
|
69
|
+
'returns_a_bool()': lambda {
|
70
|
+
EmbeddedProtocol::Value.new(
|
71
|
+
singleton: EmbeddedProtocol::SingletonValue::TRUE
|
72
|
+
)
|
73
|
+
},
|
74
|
+
'inspect_bool($argument)': lambda { |argument|
|
75
|
+
unless argument&.singleton == :TRUE || argument.singleton == :FALSE
|
76
|
+
raise StandardError,
|
77
|
+
'passed value is not a EmbeddedProtocol::SingletonValue::TRUE or EmbeddedProtocol::SingletonValue::FALSE'
|
78
|
+
end
|
79
|
+
|
80
|
+
argument
|
81
|
+
},
|
82
|
+
'inspect_number($argument)': lambda { |argument|
|
83
|
+
unless argument&.number.is_a? EmbeddedProtocol::Value::Number
|
75
84
|
raise StandardError,
|
76
|
-
'passed value is not a
|
85
|
+
'passed value is not a EmbeddedProtocol::Value::Number'
|
77
86
|
end
|
78
87
|
|
79
88
|
argument
|
80
89
|
},
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
90
|
+
'inspect_map($argument)': lambda { |argument|
|
91
|
+
unless argument&.map.is_a? EmbeddedProtocol::Value::Map
|
92
|
+
raise StandardError,
|
93
|
+
'passed value is not a EmbeddedProtocol::Value::Map'
|
94
|
+
end
|
86
95
|
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
argument
|
96
|
-
},
|
97
|
-
'inspect_list($argument)': lambda { |argument|
|
98
|
-
unless argument&.list.is_a? Sass::EmbeddedProtocol::Value::List
|
99
|
-
raise StandardError,
|
100
|
-
'passed value is not a Sass::EmbeddedProtocol::Value::List'
|
101
|
-
end
|
96
|
+
argument
|
97
|
+
},
|
98
|
+
'inspect_list($argument)': lambda { |argument|
|
99
|
+
unless argument&.list.is_a? EmbeddedProtocol::Value::List
|
100
|
+
raise StandardError,
|
101
|
+
'passed value is not a EmbeddedProtocol::Value::List'
|
102
|
+
end
|
102
103
|
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
)
|
104
|
+
argument
|
105
|
+
},
|
106
|
+
'returns_sass_value()': lambda {
|
107
|
+
EmbeddedProtocol::Value.new(
|
108
|
+
rgb_color: EmbeddedProtocol::Value::RgbColor.new(
|
109
|
+
red: 0,
|
110
|
+
green: 0,
|
111
|
+
blue: 0,
|
112
|
+
alpha: 1
|
113
113
|
)
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
)
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
114
|
+
)
|
115
|
+
},
|
116
|
+
'returns_sass_map()': lambda {
|
117
|
+
EmbeddedProtocol::Value.new(
|
118
|
+
map: EmbeddedProtocol::Value::Map.new(
|
119
|
+
entries: [
|
120
|
+
EmbeddedProtocol::Value::Map::Entry.new(
|
121
|
+
key: EmbeddedProtocol::Value.new(
|
122
|
+
string: EmbeddedProtocol::Value::String.new(
|
123
|
+
text: 'color',
|
124
|
+
quoted: true
|
125
|
+
)
|
126
|
+
),
|
127
|
+
value: EmbeddedProtocol::Value.new(
|
128
|
+
rgb_color: EmbeddedProtocol::Value::RgbColor.new(
|
129
|
+
red: 0,
|
130
|
+
green: 0,
|
131
|
+
blue: 0,
|
132
|
+
alpha: 1
|
133
133
|
)
|
134
134
|
)
|
135
|
-
|
136
|
-
|
135
|
+
)
|
136
|
+
]
|
137
137
|
)
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
)
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
),
|
155
|
-
Sass::EmbeddedProtocol::Value.new(
|
156
|
-
number: Sass::EmbeddedProtocol::Value::Number.new(
|
157
|
-
value: 30
|
158
|
-
)
|
138
|
+
)
|
139
|
+
},
|
140
|
+
'returns_sass_list()': lambda {
|
141
|
+
EmbeddedProtocol::Value.new(
|
142
|
+
list: EmbeddedProtocol::Value::List.new(
|
143
|
+
separator: EmbeddedProtocol::ListSeparator::COMMA,
|
144
|
+
has_brackets: true,
|
145
|
+
contents: [
|
146
|
+
EmbeddedProtocol::Value.new(
|
147
|
+
number: EmbeddedProtocol::Value::Number.new(
|
148
|
+
value: 10
|
149
|
+
)
|
150
|
+
),
|
151
|
+
EmbeddedProtocol::Value.new(
|
152
|
+
number: EmbeddedProtocol::Value::Number.new(
|
153
|
+
value: 20
|
159
154
|
)
|
160
|
-
|
161
|
-
|
155
|
+
),
|
156
|
+
EmbeddedProtocol::Value.new(
|
157
|
+
number: EmbeddedProtocol::Value::Number.new(
|
158
|
+
value: 30
|
159
|
+
)
|
160
|
+
)
|
161
|
+
]
|
162
162
|
)
|
163
|
-
|
164
|
-
|
163
|
+
)
|
164
|
+
}
|
165
165
|
})[:css]
|
166
166
|
end
|
167
167
|
|
168
|
+
# rubocop:enable Layout/LineLength
|
169
|
+
|
168
170
|
def test_functions_may_return_sass_string_type
|
169
171
|
assert_sass <<-SCSS, <<-CSS
|
170
172
|
div { url: url(sass_return_path("foo.svg")); }
|
@@ -270,7 +272,7 @@ module Sass
|
|
270
272
|
end
|
271
273
|
|
272
274
|
def test_function_with_error
|
273
|
-
assert_raises(
|
275
|
+
assert_raises(RenderError) do
|
274
276
|
render('div {url: function_that_raises_errors();}')
|
275
277
|
end
|
276
278
|
end
|
@@ -322,17 +324,15 @@ module Sass
|
|
322
324
|
threads = []
|
323
325
|
10.times do |i|
|
324
326
|
threads << Thread.new(i) do |id|
|
325
|
-
output = @embedded.render({
|
326
|
-
|
327
|
-
|
328
|
-
|
329
|
-
|
330
|
-
|
331
|
-
|
332
|
-
quoted: true
|
333
|
-
)
|
327
|
+
output = @embedded.render(data: 'div { url: test-function() }',
|
328
|
+
functions: {
|
329
|
+
'test_function()': lambda {
|
330
|
+
EmbeddedProtocol::Value.new(
|
331
|
+
string: EmbeddedProtocol::Value::String.new(
|
332
|
+
text: "{test_key1: 'test_value', test_key2: #{id}}",
|
333
|
+
quoted: true
|
334
334
|
)
|
335
|
-
|
335
|
+
)
|
336
336
|
}
|
337
337
|
})[:css]
|
338
338
|
assert_match(/test_key1/, output)
|
@@ -346,17 +346,15 @@ module Sass
|
|
346
346
|
end
|
347
347
|
|
348
348
|
def test_pass_custom_functions_as_a_parameter
|
349
|
-
output = @embedded.render({
|
350
|
-
|
351
|
-
|
352
|
-
|
353
|
-
|
354
|
-
|
355
|
-
|
356
|
-
quoted: true
|
357
|
-
)
|
349
|
+
output = @embedded.render(data: 'div { url: test-function(); }',
|
350
|
+
functions: {
|
351
|
+
'test_function()': lambda {
|
352
|
+
EmbeddedProtocol::Value.new(
|
353
|
+
string: EmbeddedProtocol::Value::String.new(
|
354
|
+
text: 'custom_function',
|
355
|
+
quoted: true
|
358
356
|
)
|
359
|
-
|
357
|
+
)
|
360
358
|
}
|
361
359
|
})[:css]
|
362
360
|
|
@@ -364,13 +362,11 @@ module Sass
|
|
364
362
|
end
|
365
363
|
|
366
364
|
def test_pass_incompatible_type_to_custom_functions
|
367
|
-
assert_raises(
|
368
|
-
@embedded.render({
|
369
|
-
|
370
|
-
|
371
|
-
|
372
|
-
Class.new
|
373
|
-
}
|
365
|
+
assert_raises(RenderError) do
|
366
|
+
@embedded.render(data: 'div { url: test-function(); }',
|
367
|
+
functions: {
|
368
|
+
'test_function()': lambda {
|
369
|
+
Class.new
|
374
370
|
}
|
375
371
|
})[:css]
|
376
372
|
end
|