sassc4 2.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (216) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +18 -0
  3. data/.gitmodules +3 -0
  4. data/.travis.yml +16 -0
  5. data/CHANGELOG.md +97 -0
  6. data/CODE_OF_CONDUCT.md +10 -0
  7. data/Gemfile +2 -0
  8. data/LICENSE.txt +22 -0
  9. data/README.md +80 -0
  10. data/Rakefile +51 -0
  11. data/ext/depend +4 -0
  12. data/ext/extconf.rb +92 -0
  13. data/ext/libsass/VERSION +1 -0
  14. data/ext/libsass/contrib/plugin.cpp +60 -0
  15. data/ext/libsass/include/sass/base.h +97 -0
  16. data/ext/libsass/include/sass/context.h +174 -0
  17. data/ext/libsass/include/sass/functions.h +139 -0
  18. data/ext/libsass/include/sass/values.h +145 -0
  19. data/ext/libsass/include/sass/version.h +12 -0
  20. data/ext/libsass/include/sass.h +15 -0
  21. data/ext/libsass/include/sass2scss.h +120 -0
  22. data/ext/libsass/src/MurmurHash2.hpp +91 -0
  23. data/ext/libsass/src/ast.cpp +953 -0
  24. data/ext/libsass/src/ast.hpp +1064 -0
  25. data/ext/libsass/src/ast2c.cpp +80 -0
  26. data/ext/libsass/src/ast2c.hpp +39 -0
  27. data/ext/libsass/src/ast_def_macros.hpp +140 -0
  28. data/ext/libsass/src/ast_fwd_decl.cpp +31 -0
  29. data/ext/libsass/src/ast_fwd_decl.hpp +274 -0
  30. data/ext/libsass/src/ast_helpers.hpp +316 -0
  31. data/ext/libsass/src/ast_sel_cmp.cpp +396 -0
  32. data/ext/libsass/src/ast_sel_super.cpp +539 -0
  33. data/ext/libsass/src/ast_sel_unify.cpp +275 -0
  34. data/ext/libsass/src/ast_sel_weave.cpp +616 -0
  35. data/ext/libsass/src/ast_selectors.cpp +1070 -0
  36. data/ext/libsass/src/ast_selectors.hpp +523 -0
  37. data/ext/libsass/src/ast_supports.cpp +114 -0
  38. data/ext/libsass/src/ast_supports.hpp +121 -0
  39. data/ext/libsass/src/ast_values.cpp +1154 -0
  40. data/ext/libsass/src/ast_values.hpp +498 -0
  41. data/ext/libsass/src/b64/cencode.h +32 -0
  42. data/ext/libsass/src/b64/encode.h +79 -0
  43. data/ext/libsass/src/backtrace.cpp +50 -0
  44. data/ext/libsass/src/backtrace.hpp +29 -0
  45. data/ext/libsass/src/base64vlq.cpp +47 -0
  46. data/ext/libsass/src/base64vlq.hpp +30 -0
  47. data/ext/libsass/src/bind.cpp +312 -0
  48. data/ext/libsass/src/bind.hpp +15 -0
  49. data/ext/libsass/src/c2ast.cpp +64 -0
  50. data/ext/libsass/src/c2ast.hpp +14 -0
  51. data/ext/libsass/src/c99func.c +54 -0
  52. data/ext/libsass/src/cencode.c +106 -0
  53. data/ext/libsass/src/check_nesting.cpp +393 -0
  54. data/ext/libsass/src/check_nesting.hpp +70 -0
  55. data/ext/libsass/src/color_maps.cpp +652 -0
  56. data/ext/libsass/src/color_maps.hpp +323 -0
  57. data/ext/libsass/src/color_spaces.cpp +241 -0
  58. data/ext/libsass/src/color_spaces.hpp +227 -0
  59. data/ext/libsass/src/constants.cpp +199 -0
  60. data/ext/libsass/src/constants.hpp +200 -0
  61. data/ext/libsass/src/context.cpp +870 -0
  62. data/ext/libsass/src/context.hpp +140 -0
  63. data/ext/libsass/src/cssize.cpp +521 -0
  64. data/ext/libsass/src/cssize.hpp +71 -0
  65. data/ext/libsass/src/dart_helpers.hpp +199 -0
  66. data/ext/libsass/src/debug.hpp +43 -0
  67. data/ext/libsass/src/debugger.hpp +964 -0
  68. data/ext/libsass/src/emitter.cpp +297 -0
  69. data/ext/libsass/src/emitter.hpp +101 -0
  70. data/ext/libsass/src/environment.cpp +260 -0
  71. data/ext/libsass/src/environment.hpp +124 -0
  72. data/ext/libsass/src/error_handling.cpp +239 -0
  73. data/ext/libsass/src/error_handling.hpp +248 -0
  74. data/ext/libsass/src/eval.cpp +1543 -0
  75. data/ext/libsass/src/eval.hpp +110 -0
  76. data/ext/libsass/src/eval_selectors.cpp +75 -0
  77. data/ext/libsass/src/expand.cpp +875 -0
  78. data/ext/libsass/src/expand.hpp +98 -0
  79. data/ext/libsass/src/extender.cpp +1226 -0
  80. data/ext/libsass/src/extender.hpp +399 -0
  81. data/ext/libsass/src/extension.cpp +43 -0
  82. data/ext/libsass/src/extension.hpp +89 -0
  83. data/ext/libsass/src/file.cpp +531 -0
  84. data/ext/libsass/src/file.hpp +124 -0
  85. data/ext/libsass/src/fn_colors.cpp +836 -0
  86. data/ext/libsass/src/fn_colors.hpp +99 -0
  87. data/ext/libsass/src/fn_lists.cpp +285 -0
  88. data/ext/libsass/src/fn_lists.hpp +34 -0
  89. data/ext/libsass/src/fn_maps.cpp +94 -0
  90. data/ext/libsass/src/fn_maps.hpp +30 -0
  91. data/ext/libsass/src/fn_miscs.cpp +248 -0
  92. data/ext/libsass/src/fn_miscs.hpp +40 -0
  93. data/ext/libsass/src/fn_numbers.cpp +246 -0
  94. data/ext/libsass/src/fn_numbers.hpp +45 -0
  95. data/ext/libsass/src/fn_selectors.cpp +205 -0
  96. data/ext/libsass/src/fn_selectors.hpp +35 -0
  97. data/ext/libsass/src/fn_strings.cpp +268 -0
  98. data/ext/libsass/src/fn_strings.hpp +34 -0
  99. data/ext/libsass/src/fn_utils.cpp +159 -0
  100. data/ext/libsass/src/fn_utils.hpp +62 -0
  101. data/ext/libsass/src/inspect.cpp +1126 -0
  102. data/ext/libsass/src/inspect.hpp +101 -0
  103. data/ext/libsass/src/json.cpp +1436 -0
  104. data/ext/libsass/src/json.hpp +117 -0
  105. data/ext/libsass/src/kwd_arg_macros.hpp +28 -0
  106. data/ext/libsass/src/lexer.cpp +122 -0
  107. data/ext/libsass/src/lexer.hpp +304 -0
  108. data/ext/libsass/src/listize.cpp +70 -0
  109. data/ext/libsass/src/listize.hpp +37 -0
  110. data/ext/libsass/src/mapping.hpp +19 -0
  111. data/ext/libsass/src/memory/allocator.cpp +48 -0
  112. data/ext/libsass/src/memory/allocator.hpp +138 -0
  113. data/ext/libsass/src/memory/config.hpp +20 -0
  114. data/ext/libsass/src/memory/memory_pool.hpp +186 -0
  115. data/ext/libsass/src/memory/shared_ptr.cpp +33 -0
  116. data/ext/libsass/src/memory/shared_ptr.hpp +332 -0
  117. data/ext/libsass/src/memory.hpp +12 -0
  118. data/ext/libsass/src/operation.hpp +223 -0
  119. data/ext/libsass/src/operators.cpp +267 -0
  120. data/ext/libsass/src/operators.hpp +30 -0
  121. data/ext/libsass/src/ordered_map.hpp +112 -0
  122. data/ext/libsass/src/output.cpp +320 -0
  123. data/ext/libsass/src/output.hpp +47 -0
  124. data/ext/libsass/src/parser.cpp +3059 -0
  125. data/ext/libsass/src/parser.hpp +395 -0
  126. data/ext/libsass/src/parser_selectors.cpp +189 -0
  127. data/ext/libsass/src/permutate.hpp +164 -0
  128. data/ext/libsass/src/plugins.cpp +188 -0
  129. data/ext/libsass/src/plugins.hpp +57 -0
  130. data/ext/libsass/src/position.cpp +163 -0
  131. data/ext/libsass/src/position.hpp +147 -0
  132. data/ext/libsass/src/prelexer.cpp +1780 -0
  133. data/ext/libsass/src/prelexer.hpp +484 -0
  134. data/ext/libsass/src/remove_placeholders.cpp +86 -0
  135. data/ext/libsass/src/remove_placeholders.hpp +37 -0
  136. data/ext/libsass/src/sass.cpp +156 -0
  137. data/ext/libsass/src/sass.hpp +147 -0
  138. data/ext/libsass/src/sass2scss.cpp +895 -0
  139. data/ext/libsass/src/sass_context.cpp +742 -0
  140. data/ext/libsass/src/sass_context.hpp +129 -0
  141. data/ext/libsass/src/sass_functions.cpp +210 -0
  142. data/ext/libsass/src/sass_functions.hpp +50 -0
  143. data/ext/libsass/src/sass_values.cpp +362 -0
  144. data/ext/libsass/src/sass_values.hpp +82 -0
  145. data/ext/libsass/src/settings.hpp +19 -0
  146. data/ext/libsass/src/source.cpp +69 -0
  147. data/ext/libsass/src/source.hpp +95 -0
  148. data/ext/libsass/src/source_data.hpp +32 -0
  149. data/ext/libsass/src/source_map.cpp +202 -0
  150. data/ext/libsass/src/source_map.hpp +65 -0
  151. data/ext/libsass/src/stylesheet.cpp +22 -0
  152. data/ext/libsass/src/stylesheet.hpp +57 -0
  153. data/ext/libsass/src/to_value.cpp +114 -0
  154. data/ext/libsass/src/to_value.hpp +46 -0
  155. data/ext/libsass/src/units.cpp +507 -0
  156. data/ext/libsass/src/units.hpp +110 -0
  157. data/ext/libsass/src/utf8/checked.h +336 -0
  158. data/ext/libsass/src/utf8/core.h +332 -0
  159. data/ext/libsass/src/utf8/unchecked.h +235 -0
  160. data/ext/libsass/src/utf8.h +34 -0
  161. data/ext/libsass/src/utf8_string.cpp +104 -0
  162. data/ext/libsass/src/utf8_string.hpp +38 -0
  163. data/ext/libsass/src/util.cpp +723 -0
  164. data/ext/libsass/src/util.hpp +105 -0
  165. data/ext/libsass/src/util_string.cpp +125 -0
  166. data/ext/libsass/src/util_string.hpp +73 -0
  167. data/ext/libsass/src/values.cpp +140 -0
  168. data/ext/libsass/src/values.hpp +12 -0
  169. data/lib/sassc/dependency.rb +17 -0
  170. data/lib/sassc/engine.rb +141 -0
  171. data/lib/sassc/error.rb +37 -0
  172. data/lib/sassc/functions_handler.rb +73 -0
  173. data/lib/sassc/import_handler.rb +50 -0
  174. data/lib/sassc/importer.rb +31 -0
  175. data/lib/sassc/native/native_context_api.rb +147 -0
  176. data/lib/sassc/native/native_functions_api.rb +159 -0
  177. data/lib/sassc/native/sass2scss_api.rb +10 -0
  178. data/lib/sassc/native/sass_input_style.rb +13 -0
  179. data/lib/sassc/native/sass_output_style.rb +12 -0
  180. data/lib/sassc/native/sass_value.rb +97 -0
  181. data/lib/sassc/native/string_list.rb +10 -0
  182. data/lib/sassc/native.rb +64 -0
  183. data/lib/sassc/sass_2_scss.rb +9 -0
  184. data/lib/sassc/script/functions.rb +8 -0
  185. data/lib/sassc/script/value/bool.rb +32 -0
  186. data/lib/sassc/script/value/color.rb +95 -0
  187. data/lib/sassc/script/value/list.rb +136 -0
  188. data/lib/sassc/script/value/map.rb +69 -0
  189. data/lib/sassc/script/value/number.rb +389 -0
  190. data/lib/sassc/script/value/string.rb +96 -0
  191. data/lib/sassc/script/value.rb +137 -0
  192. data/lib/sassc/script/value_conversion/base.rb +13 -0
  193. data/lib/sassc/script/value_conversion/bool.rb +13 -0
  194. data/lib/sassc/script/value_conversion/color.rb +18 -0
  195. data/lib/sassc/script/value_conversion/list.rb +25 -0
  196. data/lib/sassc/script/value_conversion/map.rb +21 -0
  197. data/lib/sassc/script/value_conversion/number.rb +13 -0
  198. data/lib/sassc/script/value_conversion/string.rb +17 -0
  199. data/lib/sassc/script/value_conversion.rb +69 -0
  200. data/lib/sassc/script.rb +17 -0
  201. data/lib/sassc/util/normalized_map.rb +117 -0
  202. data/lib/sassc/util.rb +231 -0
  203. data/lib/sassc/version.rb +5 -0
  204. data/lib/sassc.rb +57 -0
  205. data/sassc.gemspec +69 -0
  206. data/test/css_color_level4_test.rb +168 -0
  207. data/test/custom_importer_test.rb +127 -0
  208. data/test/engine_test.rb +314 -0
  209. data/test/error_test.rb +29 -0
  210. data/test/fixtures/paths.scss +10 -0
  211. data/test/functions_test.rb +340 -0
  212. data/test/native_test.rb +213 -0
  213. data/test/output_style_test.rb +107 -0
  214. data/test/sass_2_scss_test.rb +14 -0
  215. data/test/test_helper.rb +45 -0
  216. metadata +396 -0
@@ -0,0 +1,340 @@
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_match /\[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
+ def test_concurrency
189
+ 10.times do
190
+ threads = []
191
+ 10.times do |i|
192
+ threads << Thread.new(i) do |id|
193
+ out = Engine.new("div { url: inspect_options(); }", {test_key1: 'test_value', test_key2: id}).render
194
+ assert_match /test_key1/, out
195
+ assert_match /test_key2/, out
196
+ assert_match /test_value/, out
197
+ assert_match /#{id}/, out
198
+ end
199
+ end
200
+ threads.each(&:join)
201
+ end
202
+ end
203
+
204
+ def test_pass_custom_functions_as_a_parameter
205
+ out = Engine.new("div { url: test-function(); }", {functions: ExternalFunctions}).render
206
+ assert_match /custom_function/, out
207
+ end
208
+
209
+ def test_pass_incompatible_type_to_custom_functions
210
+ assert_raises(TypeError) do
211
+ Engine.new("div { url: test-function(); }", {functions: Class.new}).render
212
+ end
213
+ end
214
+
215
+ private
216
+
217
+ def assert_sass(sass, expected_css)
218
+ engine = Engine.new(sass)
219
+ assert_equal expected_css.strip.gsub!(/\s+/, " "), # poor man's String#squish
220
+ engine.render.strip.gsub!(/\s+/, " ")
221
+ end
222
+
223
+ def stderr_output
224
+ $stderr.string.gsub("\u0000\n", '').chomp
225
+ end
226
+
227
+ module Script::Functions
228
+
229
+ def javascript_path(path)
230
+ SassC::Script::Value::String.new("/js/#{path.value}", :string)
231
+ end
232
+
233
+ def stylesheet_path(path)
234
+ SassC::Script::Value::String.new("/css/#{path.value}", :identifier)
235
+ end
236
+
237
+ def no_return_path(path)
238
+ nil
239
+ end
240
+
241
+ def sass_return_path(path)
242
+ SassC::Script::Value::String.new("#{path.value}", :string)
243
+ end
244
+
245
+ def optional_arguments(path, optional = nil)
246
+ optional ||= SassC::Script::Value::String.new("bar")
247
+ SassC::Script::Value::String.new("#{path.value}/#{optional.value}", :string)
248
+ end
249
+
250
+ def function_that_raises_errors
251
+ raise StandardError, "Intentional wrong thing happened somewhere inside the custom function"
252
+ end
253
+
254
+ def function_with_unsupported_tag(value)
255
+ end
256
+
257
+ def nice_color_argument(color)
258
+ return SassC::Script::Value::String.new(color.to_s, :identifier)
259
+ end
260
+
261
+ def returns_a_color
262
+ return SassC::Script::Value::Color.new(red: 0, green: 0, blue: 0)
263
+ end
264
+
265
+ def returns_a_number
266
+ return SassC::Script::Value::Number.new(-312,'rem')
267
+ end
268
+
269
+ def returns_a_bool
270
+ return SassC::Script::Value::Bool.new(true)
271
+ end
272
+
273
+ def inspect_bool ( argument )
274
+ raise StandardError.new "passed value is not a Sass::Script::Value::Bool" unless argument.is_a? SassC::Script::Value::Bool
275
+ return argument
276
+ end
277
+
278
+ def inspect_number ( argument )
279
+ raise StandardError.new "passed value is not a Sass::Script::Value::Number" unless argument.is_a? SassC::Script::Value::Number
280
+ return argument
281
+ end
282
+
283
+ def inspect_map ( argument )
284
+ argument.to_h.each_pair do |key, value|
285
+ raise StandardError.new "key #{key.inspect} is not a string" unless key.is_a? SassC::Script::Value::String
286
+
287
+ valueClass = case key.value
288
+ when 'string'
289
+ SassC::Script::Value::String
290
+ when 'number'
291
+ SassC::Script::Value::Number
292
+ when 'color'
293
+ SassC::Script::Value::Color
294
+ when 'map'
295
+ SassC::Script::Value::Map
296
+ end
297
+
298
+ raise StandardError.new "unknown key #{key.inspect}" unless valueClass
299
+ raise StandardError.new "value for #{key.inspect} is not a #{valueClass}" unless value.is_a? valueClass
300
+ end
301
+ return argument
302
+ end
303
+
304
+ def inspect_list(argument)
305
+ raise StandardError.new "passed value is not a Sass::Script::Value::List" unless argument.is_a? SassC::Script::Value::List
306
+ return argument
307
+ end
308
+
309
+ def inspect_options
310
+ SassC::Script::Value::String.new(self.options.inspect, :string)
311
+ end
312
+
313
+ def returns_sass_value
314
+ return SassC::Script::Value::Color.new(red: 0, green: 0, blue: 0)
315
+ end
316
+
317
+ def returns_sass_map
318
+ key = SassC::Script::Value::String.new("color", "string")
319
+ value = SassC::Script::Value::Color.new(red: 0, green: 0, blue: 0)
320
+ values = {}
321
+ values[key] = value
322
+ map = SassC::Script::Value::Map.new values
323
+ return map
324
+ end
325
+
326
+ def returns_sass_list
327
+ numbers = [10, 20, 30].map { |n| SassC::Script::Value::Number.new(n, '') }
328
+ SassC::Script::Value::List.new(numbers, separator: :space)
329
+ end
330
+
331
+ end
332
+
333
+ module ExternalFunctions
334
+ def test_function
335
+ SassC::Script::Value::String.new("custom_function", :string)
336
+ end
337
+ end
338
+
339
+ end
340
+ end
@@ -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 "4.0.1", 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;"
189
+ data = FFI::MemoryPointer.from_string(str)
190
+ data.autorelease = false
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