sassc 2.1.0.pre1-x86-mingw32
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 +7 -0
- data/.gitignore +17 -0
- data/.gitmodules +3 -0
- data/.travis.yml +11 -0
- data/CHANGELOG.md +66 -0
- data/CODE_OF_CONDUCT.md +10 -0
- data/Gemfile +2 -0
- data/LICENSE.txt +22 -0
- data/README.md +68 -0
- data/Rakefile +30 -0
- data/lib/sassc/2.3/libsass.so +0 -0
- data/lib/sassc/2.4/libsass.so +0 -0
- data/lib/sassc/2.5/libsass.so +0 -0
- data/lib/sassc/2.6/libsass.so +0 -0
- data/lib/sassc/dependency.rb +17 -0
- data/lib/sassc/engine.rb +139 -0
- data/lib/sassc/error.rb +37 -0
- data/lib/sassc/functions_handler.rb +75 -0
- data/lib/sassc/import_handler.rb +50 -0
- data/lib/sassc/importer.rb +31 -0
- data/lib/sassc/native/lib_c.rb +21 -0
- data/lib/sassc/native/native_context_api.rb +147 -0
- data/lib/sassc/native/native_functions_api.rb +164 -0
- data/lib/sassc/native/sass2scss_api.rb +10 -0
- data/lib/sassc/native/sass_input_style.rb +13 -0
- data/lib/sassc/native/sass_output_style.rb +12 -0
- data/lib/sassc/native/sass_value.rb +97 -0
- data/lib/sassc/native/string_list.rb +10 -0
- data/lib/sassc/native.rb +70 -0
- data/lib/sassc/sass_2_scss.rb +9 -0
- data/lib/sassc/script/functions.rb +8 -0
- data/lib/sassc/script/value/bool.rb +32 -0
- data/lib/sassc/script/value/color.rb +95 -0
- data/lib/sassc/script/value/list.rb +136 -0
- data/lib/sassc/script/value/map.rb +69 -0
- data/lib/sassc/script/value/number.rb +389 -0
- data/lib/sassc/script/value/string.rb +96 -0
- data/lib/sassc/script/value.rb +137 -0
- data/lib/sassc/script/value_conversion/base.rb +13 -0
- data/lib/sassc/script/value_conversion/bool.rb +13 -0
- data/lib/sassc/script/value_conversion/color.rb +18 -0
- data/lib/sassc/script/value_conversion/list.rb +25 -0
- data/lib/sassc/script/value_conversion/map.rb +21 -0
- data/lib/sassc/script/value_conversion/number.rb +13 -0
- data/lib/sassc/script/value_conversion/string.rb +17 -0
- data/lib/sassc/script/value_conversion.rb +69 -0
- data/lib/sassc/script.rb +19 -0
- data/lib/sassc/util/normalized_map.rb +117 -0
- data/lib/sassc/util.rb +231 -0
- data/lib/sassc/version.rb +5 -0
- data/lib/sassc.rb +57 -0
- data/sassc.gemspec +57 -0
- data/test/custom_importer_test.rb +127 -0
- data/test/engine_test.rb +314 -0
- data/test/error_test.rb +29 -0
- data/test/fixtures/paths.scss +10 -0
- data/test/functions_test.rb +303 -0
- data/test/native_test.rb +213 -0
- data/test/output_style_test.rb +107 -0
- data/test/sass_2_scss_test.rb +14 -0
- data/test/test_helper.rb +45 -0
- metadata +242 -0
@@ -0,0 +1,303 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative "test_helper"
|
4
|
+
require "stringio"
|
5
|
+
|
6
|
+
module SassC
|
7
|
+
class FunctionsTest < MiniTest::Test
|
8
|
+
include FixtureHelper
|
9
|
+
|
10
|
+
def setup
|
11
|
+
@real_stderr, $stderr = $stderr, StringIO.new
|
12
|
+
end
|
13
|
+
|
14
|
+
def teardown
|
15
|
+
$stderr = @real_stderr
|
16
|
+
end
|
17
|
+
|
18
|
+
def test_functions_may_return_sass_string_type
|
19
|
+
assert_sass <<-SCSS, <<-CSS
|
20
|
+
div { url: url(sass_return_path("foo.svg")); }
|
21
|
+
SCSS
|
22
|
+
div { url: url("foo.svg"); }
|
23
|
+
CSS
|
24
|
+
end
|
25
|
+
|
26
|
+
def test_functions_work_with_varying_quotes_and_string_types
|
27
|
+
assert_sass <<-SCSS, <<-CSS
|
28
|
+
div {
|
29
|
+
url: url(asset-path("foo.svg"));
|
30
|
+
url: url(image-path("foo.png"));
|
31
|
+
url: url(video-path("foo.mov"));
|
32
|
+
url: url(audio-path("foo.mp3"));
|
33
|
+
url: url(font-path("foo.woff"));
|
34
|
+
url: url(javascript-path('foo.js'));
|
35
|
+
url: url(javascript-path("foo.js"));
|
36
|
+
url: url(stylesheet-path("foo.css"));
|
37
|
+
}
|
38
|
+
SCSS
|
39
|
+
div {
|
40
|
+
url: url(asset-path("foo.svg"));
|
41
|
+
url: url(image-path("foo.png"));
|
42
|
+
url: url(video-path("foo.mov"));
|
43
|
+
url: url(audio-path("foo.mp3"));
|
44
|
+
url: url(font-path("foo.woff"));
|
45
|
+
url: url("/js/foo.js");
|
46
|
+
url: url("/js/foo.js");
|
47
|
+
url: url(/css/foo.css);
|
48
|
+
}
|
49
|
+
CSS
|
50
|
+
end
|
51
|
+
|
52
|
+
def test_function_with_no_return_value
|
53
|
+
assert_sass <<-SCSS, <<-CSS
|
54
|
+
div {url: url(no-return-path('foo.svg'));}
|
55
|
+
SCSS
|
56
|
+
div { url: url(); }
|
57
|
+
CSS
|
58
|
+
end
|
59
|
+
|
60
|
+
def test_function_that_returns_a_color
|
61
|
+
assert_sass <<-SCSS, <<-CSS
|
62
|
+
div { background: returns-a-color(); }
|
63
|
+
SCSS
|
64
|
+
div { background: black; }
|
65
|
+
CSS
|
66
|
+
end
|
67
|
+
|
68
|
+
def test_function_that_returns_a_number
|
69
|
+
assert_sass <<-SCSS, <<-CSS
|
70
|
+
div { width: returns-a-number(); }
|
71
|
+
SCSS
|
72
|
+
div { width: -312rem; }
|
73
|
+
CSS
|
74
|
+
end
|
75
|
+
|
76
|
+
def test_function_that_takes_a_number
|
77
|
+
assert_sass <<-SCSS, <<-CSS
|
78
|
+
div { display: inspect-number(42.1px); }
|
79
|
+
SCSS
|
80
|
+
div { display: 42.1px; }
|
81
|
+
CSS
|
82
|
+
end
|
83
|
+
|
84
|
+
def test_function_that_returns_a_bool
|
85
|
+
assert_sass <<-SCSS, <<-CSS
|
86
|
+
div { width: returns-a-bool(); }
|
87
|
+
SCSS
|
88
|
+
div { width: true; }
|
89
|
+
CSS
|
90
|
+
end
|
91
|
+
|
92
|
+
def test_function_that_takes_a_bool
|
93
|
+
assert_sass <<-SCSS, <<-CSS
|
94
|
+
div { display: inspect-bool(true)}
|
95
|
+
SCSS
|
96
|
+
div { display: true; }
|
97
|
+
CSS
|
98
|
+
end
|
99
|
+
|
100
|
+
def test_function_with_optional_arguments
|
101
|
+
assert_sass <<-SCSS, <<-EXPECTED_CSS
|
102
|
+
div {
|
103
|
+
url: optional_arguments('first');
|
104
|
+
url: optional_arguments('second', 'qux');
|
105
|
+
}
|
106
|
+
SCSS
|
107
|
+
div {
|
108
|
+
url: "first/bar";
|
109
|
+
url: "second/qux";
|
110
|
+
}
|
111
|
+
EXPECTED_CSS
|
112
|
+
end
|
113
|
+
|
114
|
+
def test_functions_may_accept_sass_color_type
|
115
|
+
assert_sass <<-SCSS, <<-EXPECTED_CSS
|
116
|
+
div { color: nice_color_argument(red); }
|
117
|
+
SCSS
|
118
|
+
div { color: rgb(255, 0, 0); }
|
119
|
+
EXPECTED_CSS
|
120
|
+
end
|
121
|
+
|
122
|
+
def test_function_with_unsupported_tag
|
123
|
+
skip('What are other unsupported tags?')
|
124
|
+
engine = Engine.new("div {url: function_with_unsupported_tag(());}")
|
125
|
+
|
126
|
+
exception = assert_raises(SassC::SyntaxError) do
|
127
|
+
engine.render
|
128
|
+
end
|
129
|
+
|
130
|
+
assert_match /Sass argument of type sass_list unsupported/, exception.message
|
131
|
+
assert_equal "[SassC::FunctionsHandler] Sass argument of type sass_list unsupported", stderr_output
|
132
|
+
end
|
133
|
+
|
134
|
+
def test_function_with_error
|
135
|
+
engine = Engine.new("div {url: function_that_raises_errors();}")
|
136
|
+
|
137
|
+
exception = assert_raises(SassC::SyntaxError) do
|
138
|
+
engine.render
|
139
|
+
end
|
140
|
+
|
141
|
+
assert_match /Error: error in C function function_that_raises_errors/, exception.message
|
142
|
+
assert_match /Intentional wrong thing happened somewhere inside the custom function/, exception.message
|
143
|
+
assert_equal "[SassC::FunctionsHandler] Intentional wrong thing happened somewhere inside the custom function", stderr_output
|
144
|
+
end
|
145
|
+
|
146
|
+
def test_function_that_returns_a_sass_value
|
147
|
+
assert_sass <<-SCSS, <<-CSS
|
148
|
+
div { background: returns-sass-value(); }
|
149
|
+
SCSS
|
150
|
+
div { background: black; }
|
151
|
+
CSS
|
152
|
+
end
|
153
|
+
|
154
|
+
def test_function_that_returns_a_sass_map
|
155
|
+
assert_sass <<-SCSS, <<-CSS
|
156
|
+
$my-map: returns-sass-map();
|
157
|
+
div { background: map-get( $my-map, color ); }
|
158
|
+
SCSS
|
159
|
+
div { background: black; }
|
160
|
+
CSS
|
161
|
+
end
|
162
|
+
|
163
|
+
def test_function_that_takes_a_sass_map
|
164
|
+
assert_sass <<-SCSS, <<-CSS
|
165
|
+
div { background-color: map-get( inspect-map(( color: black, number: 1.23px, string: "abc", map: ( x: 'y' ))), color ); }
|
166
|
+
SCSS
|
167
|
+
div { background-color: black; }
|
168
|
+
CSS
|
169
|
+
end
|
170
|
+
|
171
|
+
def test_function_that_returns_a_sass_list
|
172
|
+
assert_sass <<-SCSS, <<-CSS
|
173
|
+
$my-list: returns-sass-list();
|
174
|
+
div { width: nth( $my-list, 2 ); }
|
175
|
+
SCSS
|
176
|
+
div { width: 20; }
|
177
|
+
CSS
|
178
|
+
end
|
179
|
+
|
180
|
+
def test_function_that_takes_a_sass_list
|
181
|
+
assert_sass <<-SCSS, <<-CSS
|
182
|
+
div { width: nth(inspect-list((10 20 30)), 2); }
|
183
|
+
SCSS
|
184
|
+
div { width: 20; }
|
185
|
+
CSS
|
186
|
+
end
|
187
|
+
|
188
|
+
private
|
189
|
+
|
190
|
+
def assert_sass(sass, expected_css)
|
191
|
+
engine = Engine.new(sass)
|
192
|
+
assert_equal expected_css.strip.gsub!(/\s+/, " "), # poor man's String#squish
|
193
|
+
engine.render.strip.gsub!(/\s+/, " ")
|
194
|
+
end
|
195
|
+
|
196
|
+
def stderr_output
|
197
|
+
$stderr.string.gsub("\u0000\n", '').chomp
|
198
|
+
end
|
199
|
+
|
200
|
+
module Script::Functions
|
201
|
+
|
202
|
+
def javascript_path(path)
|
203
|
+
SassC::Script::Value::String.new("/js/#{path.value}", :string)
|
204
|
+
end
|
205
|
+
|
206
|
+
def stylesheet_path(path)
|
207
|
+
SassC::Script::Value::String.new("/css/#{path.value}", :identifier)
|
208
|
+
end
|
209
|
+
|
210
|
+
def no_return_path(path)
|
211
|
+
nil
|
212
|
+
end
|
213
|
+
|
214
|
+
def sass_return_path(path)
|
215
|
+
SassC::Script::Value::String.new("#{path.value}", :string)
|
216
|
+
end
|
217
|
+
|
218
|
+
def optional_arguments(path, optional = nil)
|
219
|
+
optional ||= SassC::Script::Value::String.new("bar")
|
220
|
+
SassC::Script::Value::String.new("#{path.value}/#{optional.value}", :string)
|
221
|
+
end
|
222
|
+
|
223
|
+
def function_that_raises_errors
|
224
|
+
raise StandardError, "Intentional wrong thing happened somewhere inside the custom function"
|
225
|
+
end
|
226
|
+
|
227
|
+
def function_with_unsupported_tag(value)
|
228
|
+
end
|
229
|
+
|
230
|
+
def nice_color_argument(color)
|
231
|
+
return SassC::Script::Value::String.new(color.to_s, :identifier)
|
232
|
+
end
|
233
|
+
|
234
|
+
def returns_a_color
|
235
|
+
return SassC::Script::Value::Color.new(red: 0, green: 0, blue: 0)
|
236
|
+
end
|
237
|
+
|
238
|
+
def returns_a_number
|
239
|
+
return SassC::Script::Value::Number.new(-312,'rem')
|
240
|
+
end
|
241
|
+
|
242
|
+
def returns_a_bool
|
243
|
+
return SassC::Script::Value::Bool.new(true)
|
244
|
+
end
|
245
|
+
|
246
|
+
def inspect_bool ( argument )
|
247
|
+
raise StandardError.new "passed value is not a Sass::Script::Value::Bool" unless argument.is_a? SassC::Script::Value::Bool
|
248
|
+
return argument
|
249
|
+
end
|
250
|
+
|
251
|
+
def inspect_number ( argument )
|
252
|
+
raise StandardError.new "passed value is not a Sass::Script::Value::Number" unless argument.is_a? SassC::Script::Value::Number
|
253
|
+
return argument
|
254
|
+
end
|
255
|
+
|
256
|
+
def inspect_map ( argument )
|
257
|
+
argument.to_h.each_pair do |key, value|
|
258
|
+
raise StandardError.new "key #{key.inspect} is not a string" unless key.is_a? SassC::Script::Value::String
|
259
|
+
|
260
|
+
valueClass = case key.value
|
261
|
+
when 'string'
|
262
|
+
SassC::Script::Value::String
|
263
|
+
when 'number'
|
264
|
+
SassC::Script::Value::Number
|
265
|
+
when 'color'
|
266
|
+
SassC::Script::Value::Color
|
267
|
+
when 'map'
|
268
|
+
SassC::Script::Value::Map
|
269
|
+
end
|
270
|
+
|
271
|
+
raise StandardError.new "unknown key #{key.inspect}" unless valueClass
|
272
|
+
raise StandardError.new "value for #{key.inspect} is not a #{valueClass}" unless value.is_a? valueClass
|
273
|
+
end
|
274
|
+
return argument
|
275
|
+
end
|
276
|
+
|
277
|
+
def inspect_list(argument)
|
278
|
+
raise StandardError.new "passed value is not a Sass::Script::Value::List" unless argument.is_a? SassC::Script::Value::List
|
279
|
+
return argument
|
280
|
+
end
|
281
|
+
|
282
|
+
def returns_sass_value
|
283
|
+
return SassC::Script::Value::Color.new(red: 0, green: 0, blue: 0)
|
284
|
+
end
|
285
|
+
|
286
|
+
def returns_sass_map
|
287
|
+
key = SassC::Script::Value::String.new("color", "string")
|
288
|
+
value = SassC::Script::Value::Color.new(red: 0, green: 0, blue: 0)
|
289
|
+
values = {}
|
290
|
+
values[key] = value
|
291
|
+
map = SassC::Script::Value::Map.new values
|
292
|
+
return map
|
293
|
+
end
|
294
|
+
|
295
|
+
def returns_sass_list
|
296
|
+
numbers = [10, 20, 30].map { |n| SassC::Script::Value::Number.new(n, '') }
|
297
|
+
SassC::Script::Value::List.new(numbers, separator: :space)
|
298
|
+
end
|
299
|
+
|
300
|
+
end
|
301
|
+
|
302
|
+
end
|
303
|
+
end
|
data/test/native_test.rb
ADDED
@@ -0,0 +1,213 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative "test_helper"
|
4
|
+
|
5
|
+
module SassC
|
6
|
+
module NativeTest
|
7
|
+
SAMPLE_SASS_STRING = "$size: 30px; .hi { width: $size; }"
|
8
|
+
SPECIAL_SASS_STRING = "$sißßßßßße: 30px; .hßß©i { width: $size; }"
|
9
|
+
SAMPLE_CSS_OUTPUT = ".hi {\n width: 30px; }\n"
|
10
|
+
BAD_SASS_STRING = "$size = 30px;"
|
11
|
+
|
12
|
+
class General < MiniTest::Test
|
13
|
+
def test_it_reports_the_libsass_version
|
14
|
+
assert_equal "3.6.0", Native.version
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
class DataContext < MiniTest::Test
|
19
|
+
def teardown
|
20
|
+
Native.delete_data_context(@data_context) if @data_context
|
21
|
+
end
|
22
|
+
|
23
|
+
def test_compile_status_is_zero_when_successful
|
24
|
+
@data_context = Native.make_data_context(SAMPLE_SASS_STRING)
|
25
|
+
context = Native.data_context_get_context(@data_context)
|
26
|
+
|
27
|
+
status = Native.compile_data_context(@data_context)
|
28
|
+
assert_equal 0, status
|
29
|
+
|
30
|
+
status = Native.context_get_error_status(context)
|
31
|
+
assert_equal 0, status
|
32
|
+
end
|
33
|
+
|
34
|
+
def test_compiled_css_is_correct
|
35
|
+
@data_context = Native.make_data_context(SAMPLE_SASS_STRING)
|
36
|
+
context = Native.data_context_get_context(@data_context)
|
37
|
+
Native.compile_data_context(@data_context)
|
38
|
+
|
39
|
+
css = Native.context_get_output_string(context)
|
40
|
+
assert_equal SAMPLE_CSS_OUTPUT, css
|
41
|
+
end
|
42
|
+
|
43
|
+
def test_compile_status_is_one_if_failed
|
44
|
+
@data_context = Native.make_data_context(BAD_SASS_STRING)
|
45
|
+
context = Native.data_context_get_context(@data_context)
|
46
|
+
|
47
|
+
status = Native.compile_data_context(@data_context)
|
48
|
+
refute_equal 0, status
|
49
|
+
|
50
|
+
status = Native.context_get_error_status(context)
|
51
|
+
refute_equal 0, status
|
52
|
+
end
|
53
|
+
|
54
|
+
def test_multibyte_characters_work
|
55
|
+
@data_context = Native.make_data_context(SPECIAL_SASS_STRING)
|
56
|
+
context = Native.data_context_get_context(@data_context)
|
57
|
+
|
58
|
+
status = Native.compile_data_context(@data_context)
|
59
|
+
refute_equal 0, status
|
60
|
+
end
|
61
|
+
|
62
|
+
def test_custom_function
|
63
|
+
data_context = Native.make_data_context("foo { margin: foo(); }")
|
64
|
+
context = Native.data_context_get_context(data_context)
|
65
|
+
options = Native.context_get_options(context)
|
66
|
+
|
67
|
+
random_thing = FFI::MemoryPointer.from_string("hi")
|
68
|
+
|
69
|
+
funct = FFI::Function.new(:pointer, [:pointer, :pointer]) do |s_args, cookie|
|
70
|
+
Native.make_number(43, "px")
|
71
|
+
end
|
72
|
+
|
73
|
+
callback = Native.make_function(
|
74
|
+
"foo()",
|
75
|
+
funct,
|
76
|
+
random_thing
|
77
|
+
)
|
78
|
+
|
79
|
+
list = Native.make_function_list(1)
|
80
|
+
Native::function_set_list_entry(list, 0, callback);
|
81
|
+
Native::option_set_c_functions(options, list)
|
82
|
+
|
83
|
+
assert_equal Native.option_get_c_functions(options), list
|
84
|
+
|
85
|
+
first_list_entry = Native.function_get_list_entry(list, 0)
|
86
|
+
assert_equal Native.function_get_function(first_list_entry),
|
87
|
+
funct
|
88
|
+
assert_equal Native.function_get_signature(first_list_entry),
|
89
|
+
"foo()"
|
90
|
+
assert_equal Native.function_get_cookie(first_list_entry),
|
91
|
+
random_thing
|
92
|
+
|
93
|
+
string = Native.make_string("hello")
|
94
|
+
assert_equal :sass_string, Native.value_get_tag(string)
|
95
|
+
assert_equal "hello", Native.string_get_value(string)
|
96
|
+
|
97
|
+
number = Native.make_number(123.4, "rem")
|
98
|
+
assert_equal 123.4, Native.number_get_value(number)
|
99
|
+
assert_equal "rem", Native.number_get_unit(number)
|
100
|
+
|
101
|
+
Native.compile_data_context(data_context)
|
102
|
+
|
103
|
+
css = Native.context_get_output_string(context)
|
104
|
+
assert_equal "foo {\n margin: 43px; }\n", css
|
105
|
+
end
|
106
|
+
end
|
107
|
+
|
108
|
+
class FileContext < MiniTest::Test
|
109
|
+
include TempFileTest
|
110
|
+
|
111
|
+
def teardown
|
112
|
+
Native.delete_file_context(@file_context) if @file_context
|
113
|
+
end
|
114
|
+
|
115
|
+
def test_compile_status_is_zero_when_successful
|
116
|
+
temp_file("style.scss", SAMPLE_SASS_STRING)
|
117
|
+
|
118
|
+
@file_context = Native.make_file_context("style.scss")
|
119
|
+
context = Native.file_context_get_context(@file_context)
|
120
|
+
|
121
|
+
status = Native.compile_file_context(@file_context)
|
122
|
+
assert_equal 0, status
|
123
|
+
|
124
|
+
status = Native.context_get_error_status(context)
|
125
|
+
assert_equal 0, status
|
126
|
+
end
|
127
|
+
|
128
|
+
def test_compiled_css_is_correct
|
129
|
+
temp_file("style.scss", SAMPLE_SASS_STRING)
|
130
|
+
|
131
|
+
@file_context = Native.make_file_context("style.scss")
|
132
|
+
context = Native.file_context_get_context(@file_context)
|
133
|
+
Native.compile_file_context(@file_context)
|
134
|
+
|
135
|
+
css = Native.context_get_output_string(context)
|
136
|
+
assert_equal SAMPLE_CSS_OUTPUT, css
|
137
|
+
end
|
138
|
+
|
139
|
+
def test_invalid_file_name
|
140
|
+
temp_file("style.scss", SAMPLE_SASS_STRING)
|
141
|
+
|
142
|
+
@file_context = Native.make_file_context("style.jajaja")
|
143
|
+
context = Native.file_context_get_context(@file_context)
|
144
|
+
status = Native.compile_file_context(@file_context)
|
145
|
+
|
146
|
+
refute_equal 0, status
|
147
|
+
|
148
|
+
error = Native.context_get_error_message(context)
|
149
|
+
|
150
|
+
assert_match "Error: File to read not found or unreadable: style.jajaja",
|
151
|
+
error
|
152
|
+
end
|
153
|
+
|
154
|
+
def test_file_import
|
155
|
+
temp_file("not_included.scss", "$size: 30px;")
|
156
|
+
temp_file("import_parent.scss", "$size: 30px;")
|
157
|
+
temp_file("import.scss", "@import 'import_parent'; $size: 30px;")
|
158
|
+
temp_file("styles.scss", "@import 'import.scss'; .hi { width: $size; }")
|
159
|
+
|
160
|
+
@file_context = Native.make_file_context("styles.scss")
|
161
|
+
context = Native.file_context_get_context(@file_context)
|
162
|
+
status = Native.compile_file_context(@file_context)
|
163
|
+
|
164
|
+
assert_equal 0, status
|
165
|
+
|
166
|
+
css = Native.context_get_output_string(context)
|
167
|
+
assert_equal SAMPLE_CSS_OUTPUT, css
|
168
|
+
|
169
|
+
included_files = Native.context_get_included_files(context)
|
170
|
+
included_files.sort!
|
171
|
+
|
172
|
+
assert_match /import.scss/, included_files[0]
|
173
|
+
assert_match /import_parent.scss/, included_files[1]
|
174
|
+
assert_match /styles.scss/, included_files[2]
|
175
|
+
end
|
176
|
+
|
177
|
+
def test_custom_importer
|
178
|
+
temp_file("not_included.scss", "$size: $var + 25;")
|
179
|
+
temp_file("styles.scss", "@import 'import.scss'; .hi { width: $size; }")
|
180
|
+
|
181
|
+
@file_context = Native.make_file_context("styles.scss")
|
182
|
+
context = Native.file_context_get_context(@file_context)
|
183
|
+
options = Native.context_get_options(context)
|
184
|
+
|
185
|
+
funct = FFI::Function.new(:pointer, [:pointer, :pointer, :pointer]) do |url, prev, cookie|
|
186
|
+
list = Native.make_import_list(2)
|
187
|
+
|
188
|
+
str = "$var: 5px;\0"
|
189
|
+
data = Native::LibC.malloc(str.size)
|
190
|
+
data.write_string(str)
|
191
|
+
|
192
|
+
entry0 = Native.make_import_entry("fake_includ.scss", data, nil)
|
193
|
+
entry1 = Native.make_import_entry("not_included.scss", nil, nil)
|
194
|
+
Native.import_set_list_entry(list, 0, entry0)
|
195
|
+
Native.import_set_list_entry(list, 1, entry1)
|
196
|
+
list
|
197
|
+
end
|
198
|
+
|
199
|
+
callback = Native.make_importer(funct, nil)
|
200
|
+
list = Native.make_function_list(1)
|
201
|
+
Native::function_set_list_entry(list, 0, callback)
|
202
|
+
|
203
|
+
Native.option_set_c_importers(options, list)
|
204
|
+
|
205
|
+
status = Native.compile_file_context(@file_context)
|
206
|
+
assert_equal 0, status
|
207
|
+
|
208
|
+
css = Native.context_get_output_string(context)
|
209
|
+
assert_equal SAMPLE_CSS_OUTPUT, css
|
210
|
+
end
|
211
|
+
end
|
212
|
+
end
|
213
|
+
end
|
@@ -0,0 +1,107 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative "test_helper"
|
4
|
+
|
5
|
+
module SassC
|
6
|
+
class OutputStyleTest < MiniTest::Test
|
7
|
+
def input_scss
|
8
|
+
input_scss = <<-CSS
|
9
|
+
$color: #fff;
|
10
|
+
|
11
|
+
#main {
|
12
|
+
color: $color;
|
13
|
+
background-color: #000;
|
14
|
+
p {
|
15
|
+
width: 10em;
|
16
|
+
}
|
17
|
+
}
|
18
|
+
|
19
|
+
.huge {
|
20
|
+
font-size: 10em;
|
21
|
+
font-weight: bold;
|
22
|
+
text-decoration: underline;
|
23
|
+
}
|
24
|
+
CSS
|
25
|
+
end
|
26
|
+
|
27
|
+
def expected_nested_output
|
28
|
+
<<-CSS
|
29
|
+
#main {
|
30
|
+
color: #fff;
|
31
|
+
background-color: #000; }
|
32
|
+
#main p {
|
33
|
+
width: 10em; }
|
34
|
+
|
35
|
+
.huge {
|
36
|
+
font-size: 10em;
|
37
|
+
font-weight: bold;
|
38
|
+
text-decoration: underline; }
|
39
|
+
CSS
|
40
|
+
end
|
41
|
+
|
42
|
+
def test_nested_output_is_default
|
43
|
+
engine = Engine.new(input_scss)
|
44
|
+
assert_equal expected_nested_output, engine.render
|
45
|
+
end
|
46
|
+
|
47
|
+
def test_output_style_accepts_strings
|
48
|
+
engine = Engine.new(input_scss, style: 'sass_style_nested')
|
49
|
+
assert_equal expected_nested_output, engine.render
|
50
|
+
end
|
51
|
+
|
52
|
+
def test_invalid_output_style
|
53
|
+
engine = Engine.new(input_scss, style: 'totally_wrong')
|
54
|
+
assert_raises(InvalidStyleError) { engine.render }
|
55
|
+
end
|
56
|
+
|
57
|
+
def test_nested_output
|
58
|
+
engine = Engine.new(input_scss, style: :sass_style_nested)
|
59
|
+
assert_equal expected_nested_output, engine.render
|
60
|
+
end
|
61
|
+
|
62
|
+
def test_expanded_output
|
63
|
+
engine = Engine.new(input_scss, style: :sass_style_expanded)
|
64
|
+
assert_equal <<-CSS, engine.render
|
65
|
+
#main {
|
66
|
+
color: #fff;
|
67
|
+
background-color: #000;
|
68
|
+
}
|
69
|
+
|
70
|
+
#main p {
|
71
|
+
width: 10em;
|
72
|
+
}
|
73
|
+
|
74
|
+
.huge {
|
75
|
+
font-size: 10em;
|
76
|
+
font-weight: bold;
|
77
|
+
text-decoration: underline;
|
78
|
+
}
|
79
|
+
CSS
|
80
|
+
end
|
81
|
+
|
82
|
+
def test_compact_output
|
83
|
+
engine = Engine.new(input_scss, style: :sass_style_compact)
|
84
|
+
assert_equal <<-CSS, engine.render
|
85
|
+
#main { color: #fff; background-color: #000; }
|
86
|
+
|
87
|
+
#main p { width: 10em; }
|
88
|
+
|
89
|
+
.huge { font-size: 10em; font-weight: bold; text-decoration: underline; }
|
90
|
+
CSS
|
91
|
+
end
|
92
|
+
|
93
|
+
def test_compressed_output
|
94
|
+
engine = Engine.new(input_scss, style: :sass_style_compressed)
|
95
|
+
assert_equal <<-CSS, engine.render
|
96
|
+
#main{color:#fff;background-color:#000}#main p{width:10em}.huge{font-size:10em;font-weight:bold;text-decoration:underline}
|
97
|
+
CSS
|
98
|
+
end
|
99
|
+
|
100
|
+
def test_short_output_style_names
|
101
|
+
engine = Engine.new(input_scss, style: :compressed)
|
102
|
+
assert_equal <<-CSS, engine.render
|
103
|
+
#main{color:#fff;background-color:#000}#main p{width:10em}.huge{font-size:10em;font-weight:bold;text-decoration:underline}
|
104
|
+
CSS
|
105
|
+
end
|
106
|
+
end
|
107
|
+
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative "test_helper"
|
4
|
+
|
5
|
+
module SassC
|
6
|
+
class Sass2ScssTest < MiniTest::Test
|
7
|
+
def test_compact_output
|
8
|
+
assert_equal ".blat { color: red; }", Sass2Scss.convert(<<SASS)
|
9
|
+
.blat
|
10
|
+
color: red
|
11
|
+
SASS
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
data/test/test_helper.rb
ADDED
@@ -0,0 +1,45 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "minitest/autorun"
|
4
|
+
require "minitest/pride"
|
5
|
+
require "minitest/around/unit"
|
6
|
+
require "test_construct"
|
7
|
+
require "pry"
|
8
|
+
|
9
|
+
require "sassc"
|
10
|
+
|
11
|
+
module FixtureHelper
|
12
|
+
FIXTURE_ROOT = File.expand_path(File.join(File.dirname(__FILE__), "fixtures"))
|
13
|
+
|
14
|
+
def fixture(path)
|
15
|
+
IO.read(fixture_path(path))
|
16
|
+
end
|
17
|
+
|
18
|
+
def fixture_path(path)
|
19
|
+
if path.match(FIXTURE_ROOT)
|
20
|
+
path
|
21
|
+
else
|
22
|
+
File.join(FIXTURE_ROOT, path)
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
module TempFileTest
|
28
|
+
include TestConstruct::Helpers
|
29
|
+
|
30
|
+
def around
|
31
|
+
within_construct do |construct|
|
32
|
+
@construct = construct
|
33
|
+
yield
|
34
|
+
end
|
35
|
+
@construct = nil
|
36
|
+
end
|
37
|
+
|
38
|
+
def temp_file(filename, contents)
|
39
|
+
@construct.file(filename, contents)
|
40
|
+
end
|
41
|
+
|
42
|
+
def temp_dir(directory)
|
43
|
+
@construct.directory(directory)
|
44
|
+
end
|
45
|
+
end
|