sass 3.3.0 → 3.4.25

Sign up to get free protection for your applications and to get access to all the features.
Files changed (208) hide show
  1. checksums.yaml +4 -4
  2. data/.yardopts +3 -1
  3. data/CODE_OF_CONDUCT.md +10 -0
  4. data/CONTRIBUTING.md +148 -0
  5. data/MIT-LICENSE +1 -1
  6. data/README.md +76 -62
  7. data/Rakefile +104 -24
  8. data/VERSION +1 -1
  9. data/VERSION_DATE +1 -1
  10. data/VERSION_NAME +1 -1
  11. data/bin/sass +1 -1
  12. data/bin/scss +1 -1
  13. data/extra/sass-spec-ref.sh +32 -0
  14. data/extra/update_watch.rb +1 -1
  15. data/lib/sass/cache_stores/filesystem.rb +9 -5
  16. data/lib/sass/cache_stores/memory.rb +4 -5
  17. data/lib/sass/callbacks.rb +2 -2
  18. data/lib/sass/css.rb +12 -13
  19. data/lib/sass/deprecation.rb +55 -0
  20. data/lib/sass/engine.rb +106 -70
  21. data/lib/sass/environment.rb +39 -19
  22. data/lib/sass/error.rb +17 -20
  23. data/lib/sass/exec/base.rb +199 -0
  24. data/lib/sass/exec/sass_convert.rb +283 -0
  25. data/lib/sass/exec/sass_scss.rb +440 -0
  26. data/lib/sass/exec.rb +5 -771
  27. data/lib/sass/features.rb +9 -2
  28. data/lib/sass/importers/base.rb +8 -3
  29. data/lib/sass/importers/filesystem.rb +30 -38
  30. data/lib/sass/logger/base.rb +8 -2
  31. data/lib/sass/logger/delayed.rb +50 -0
  32. data/lib/sass/logger.rb +8 -3
  33. data/lib/sass/media.rb +1 -4
  34. data/lib/sass/plugin/compiler.rb +224 -90
  35. data/lib/sass/plugin/configuration.rb +38 -22
  36. data/lib/sass/plugin/merb.rb +2 -2
  37. data/lib/sass/plugin/rack.rb +3 -3
  38. data/lib/sass/plugin/rails.rb +1 -1
  39. data/lib/sass/plugin/staleness_checker.rb +4 -4
  40. data/lib/sass/plugin.rb +6 -5
  41. data/lib/sass/script/css_lexer.rb +1 -1
  42. data/lib/sass/script/css_parser.rb +2 -3
  43. data/lib/sass/script/css_variable_warning.rb +52 -0
  44. data/lib/sass/script/functions.rb +739 -318
  45. data/lib/sass/script/lexer.rb +134 -54
  46. data/lib/sass/script/parser.rb +252 -56
  47. data/lib/sass/script/tree/funcall.rb +13 -6
  48. data/lib/sass/script/tree/interpolation.rb +127 -4
  49. data/lib/sass/script/tree/list_literal.rb +31 -4
  50. data/lib/sass/script/tree/literal.rb +4 -0
  51. data/lib/sass/script/tree/node.rb +21 -3
  52. data/lib/sass/script/tree/operation.rb +54 -1
  53. data/lib/sass/script/tree/selector.rb +26 -0
  54. data/lib/sass/script/tree/string_interpolation.rb +59 -38
  55. data/lib/sass/script/tree/variable.rb +1 -1
  56. data/lib/sass/script/tree.rb +1 -0
  57. data/lib/sass/script/value/base.rb +17 -14
  58. data/lib/sass/script/value/bool.rb +0 -5
  59. data/lib/sass/script/value/color.rb +78 -42
  60. data/lib/sass/script/value/helpers.rb +119 -2
  61. data/lib/sass/script/value/list.rb +0 -15
  62. data/lib/sass/script/value/map.rb +1 -1
  63. data/lib/sass/script/value/null.rb +0 -5
  64. data/lib/sass/script/value/number.rb +112 -31
  65. data/lib/sass/script/value/string.rb +102 -13
  66. data/lib/sass/script/value.rb +0 -1
  67. data/lib/sass/script.rb +3 -3
  68. data/lib/sass/scss/css_parser.rb +24 -4
  69. data/lib/sass/scss/parser.rb +290 -383
  70. data/lib/sass/scss/rx.rb +17 -9
  71. data/lib/sass/scss/static_parser.rb +306 -4
  72. data/lib/sass/scss.rb +0 -2
  73. data/lib/sass/selector/abstract_sequence.rb +35 -18
  74. data/lib/sass/selector/comma_sequence.rb +114 -19
  75. data/lib/sass/selector/pseudo.rb +266 -0
  76. data/lib/sass/selector/sequence.rb +146 -40
  77. data/lib/sass/selector/simple.rb +22 -33
  78. data/lib/sass/selector/simple_sequence.rb +122 -39
  79. data/lib/sass/selector.rb +57 -197
  80. data/lib/sass/shared.rb +2 -2
  81. data/lib/sass/source/map.rb +31 -14
  82. data/lib/sass/source/position.rb +4 -4
  83. data/lib/sass/stack.rb +2 -8
  84. data/lib/sass/supports.rb +10 -13
  85. data/lib/sass/tree/at_root_node.rb +1 -0
  86. data/lib/sass/tree/charset_node.rb +1 -1
  87. data/lib/sass/tree/comment_node.rb +1 -1
  88. data/lib/sass/tree/css_import_node.rb +9 -1
  89. data/lib/sass/tree/directive_node.rb +8 -2
  90. data/lib/sass/tree/error_node.rb +18 -0
  91. data/lib/sass/tree/extend_node.rb +1 -1
  92. data/lib/sass/tree/function_node.rb +9 -0
  93. data/lib/sass/tree/import_node.rb +6 -5
  94. data/lib/sass/tree/keyframe_rule_node.rb +15 -0
  95. data/lib/sass/tree/node.rb +5 -3
  96. data/lib/sass/tree/prop_node.rb +6 -7
  97. data/lib/sass/tree/rule_node.rb +26 -11
  98. data/lib/sass/tree/visitors/check_nesting.rb +56 -32
  99. data/lib/sass/tree/visitors/convert.rb +59 -44
  100. data/lib/sass/tree/visitors/cssize.rb +34 -30
  101. data/lib/sass/tree/visitors/deep_copy.rb +6 -1
  102. data/lib/sass/tree/visitors/extend.rb +15 -13
  103. data/lib/sass/tree/visitors/perform.rb +87 -50
  104. data/lib/sass/tree/visitors/set_options.rb +15 -1
  105. data/lib/sass/tree/visitors/to_css.rb +72 -43
  106. data/lib/sass/util/multibyte_string_scanner.rb +0 -2
  107. data/lib/sass/util/normalized_map.rb +0 -1
  108. data/lib/sass/util/subset_map.rb +2 -3
  109. data/lib/sass/util.rb +334 -154
  110. data/lib/sass/version.rb +7 -7
  111. data/lib/sass.rb +10 -8
  112. data/test/sass/cache_test.rb +62 -20
  113. data/test/sass/callbacks_test.rb +1 -1
  114. data/test/sass/compiler_test.rb +24 -11
  115. data/test/sass/conversion_test.rb +241 -50
  116. data/test/sass/css2sass_test.rb +73 -5
  117. data/test/sass/css_variable_test.rb +132 -0
  118. data/test/sass/encoding_test.rb +219 -0
  119. data/test/sass/engine_test.rb +343 -260
  120. data/test/sass/exec_test.rb +12 -2
  121. data/test/sass/extend_test.rb +333 -44
  122. data/test/sass/functions_test.rb +353 -260
  123. data/test/sass/importer_test.rb +40 -21
  124. data/test/sass/logger_test.rb +1 -1
  125. data/test/sass/more_results/more_import.css +1 -1
  126. data/test/sass/more_templates/more1.sass +10 -10
  127. data/test/sass/more_templates/more_import.sass +2 -2
  128. data/test/sass/plugin_test.rb +24 -21
  129. data/test/sass/results/compact.css +1 -1
  130. data/test/sass/results/complex.css +4 -4
  131. data/test/sass/results/expanded.css +1 -1
  132. data/test/sass/results/import.css +1 -1
  133. data/test/sass/results/import_charset_ibm866.css +2 -2
  134. data/test/sass/results/mixins.css +17 -17
  135. data/test/sass/results/nested.css +1 -1
  136. data/test/sass/results/parent_ref.css +2 -2
  137. data/test/sass/results/script.css +5 -5
  138. data/test/sass/results/scss_import.css +1 -1
  139. data/test/sass/script_conversion_test.rb +71 -39
  140. data/test/sass/script_test.rb +714 -123
  141. data/test/sass/scss/css_test.rb +213 -30
  142. data/test/sass/scss/rx_test.rb +8 -4
  143. data/test/sass/scss/scss_test.rb +766 -22
  144. data/test/sass/source_map_test.rb +263 -95
  145. data/test/sass/superselector_test.rb +210 -0
  146. data/test/sass/templates/_partial.sass +1 -1
  147. data/test/sass/templates/basic.sass +10 -10
  148. data/test/sass/templates/bork1.sass +1 -1
  149. data/test/sass/templates/bork5.sass +1 -1
  150. data/test/sass/templates/compact.sass +10 -10
  151. data/test/sass/templates/complex.sass +187 -187
  152. data/test/sass/templates/compressed.sass +10 -10
  153. data/test/sass/templates/expanded.sass +10 -10
  154. data/test/sass/templates/import.sass +2 -2
  155. data/test/sass/templates/importee.sass +3 -3
  156. data/test/sass/templates/mixins.sass +22 -22
  157. data/test/sass/templates/multiline.sass +4 -4
  158. data/test/sass/templates/nested.sass +13 -13
  159. data/test/sass/templates/parent_ref.sass +12 -12
  160. data/test/sass/templates/script.sass +70 -70
  161. data/test/sass/templates/scss_import.scss +2 -1
  162. data/test/sass/templates/subdir/nested_subdir/_nested_partial.sass +1 -1
  163. data/test/sass/templates/subdir/nested_subdir/nested_subdir.sass +2 -2
  164. data/test/sass/templates/subdir/subdir.sass +3 -3
  165. data/test/sass/templates/units.sass +10 -10
  166. data/test/sass/test_helper.rb +1 -1
  167. data/test/sass/util/multibyte_string_scanner_test.rb +11 -3
  168. data/test/sass/util/normalized_map_test.rb +1 -1
  169. data/test/sass/util/subset_map_test.rb +2 -2
  170. data/test/sass/util_test.rb +46 -45
  171. data/test/sass/value_helpers_test.rb +5 -7
  172. data/test/sass-spec.yml +3 -0
  173. data/test/test_helper.rb +7 -6
  174. data/vendor/listen/CHANGELOG.md +1 -228
  175. data/vendor/listen/Gemfile +5 -15
  176. data/vendor/listen/README.md +111 -77
  177. data/vendor/listen/Rakefile +0 -42
  178. data/vendor/listen/lib/listen/adapter.rb +195 -82
  179. data/vendor/listen/lib/listen/adapters/bsd.rb +27 -64
  180. data/vendor/listen/lib/listen/adapters/darwin.rb +21 -58
  181. data/vendor/listen/lib/listen/adapters/linux.rb +23 -55
  182. data/vendor/listen/lib/listen/adapters/polling.rb +25 -34
  183. data/vendor/listen/lib/listen/adapters/windows.rb +50 -46
  184. data/vendor/listen/lib/listen/directory_record.rb +96 -61
  185. data/vendor/listen/lib/listen/listener.rb +135 -37
  186. data/vendor/listen/lib/listen/turnstile.rb +9 -5
  187. data/vendor/listen/lib/listen/version.rb +1 -1
  188. data/vendor/listen/lib/listen.rb +33 -19
  189. data/vendor/listen/listen.gemspec +6 -0
  190. data/vendor/listen/spec/listen/adapter_spec.rb +43 -77
  191. data/vendor/listen/spec/listen/adapters/polling_spec.rb +8 -8
  192. data/vendor/listen/spec/listen/directory_record_spec.rb +81 -56
  193. data/vendor/listen/spec/listen/listener_spec.rb +128 -39
  194. data/vendor/listen/spec/listen_spec.rb +15 -21
  195. data/vendor/listen/spec/spec_helper.rb +4 -0
  196. data/vendor/listen/spec/support/adapter_helper.rb +52 -15
  197. data/vendor/listen/spec/support/directory_record_helper.rb +7 -5
  198. data/vendor/listen/spec/support/listeners_helper.rb +30 -7
  199. metadata +310 -300
  200. data/CONTRIBUTING +0 -3
  201. data/ext/mkrf_conf.rb +0 -27
  202. data/lib/sass/script/value/deprecated_false.rb +0 -55
  203. data/lib/sass/scss/script_lexer.rb +0 -15
  204. data/lib/sass/scss/script_parser.rb +0 -25
  205. data/vendor/listen/lib/listen/dependency_manager.rb +0 -126
  206. data/vendor/listen/lib/listen/multi_listener.rb +0 -143
  207. data/vendor/listen/spec/listen/dependency_manager_spec.rb +0 -107
  208. data/vendor/listen/spec/listen/multi_listener_spec.rb +0 -174
@@ -1,5 +1,5 @@
1
1
  #!/usr/bin/env ruby
2
- require 'test/unit'
2
+ require 'minitest/autorun'
3
3
  require File.dirname(__FILE__) + '/../test_helper'
4
4
  require File.dirname(__FILE__) + '/test_helper'
5
5
  require 'sass/script'
@@ -19,6 +19,12 @@ module Sass::Script::Functions
19
19
  Sass::Script::Value::String.new("only-kw-args(" + kwargs.keys.map {|a| a.to_s}.sort.join(", ") + ")")
20
20
  end
21
21
  declare :only_kw_args, [], :var_kwargs => true
22
+
23
+ def deprecated_arg_fn(arg1, arg2, arg3 = nil)
24
+ Sass::Script::Value::List.new([arg1, arg2, arg3 || Sass::Script::Value::Null.new], :space)
25
+ end
26
+ declare :deprecated_arg_fn, [:arg1, :arg2, :arg3], :deprecated => [:arg_1, :arg_2, :arg3]
27
+ declare :deprecated_arg_fn, [:arg1, :arg2], :deprecated => [:arg_1, :arg_2]
22
28
  end
23
29
 
24
30
  module Sass::Script::Functions::UserFunctions
@@ -45,7 +51,7 @@ module Sass::Script::Functions
45
51
  include Sass::Script::Functions::UserFunctions
46
52
  end
47
53
 
48
- class SassFunctionTest < Test::Unit::TestCase
54
+ class SassFunctionTest < MiniTest::Test
49
55
  # Tests taken from:
50
56
  # http://www.w3.org/Style/CSS/Test/CSS3/Color/20070927/html4/t040204-hsl-h-rotating-b.htm
51
57
  # http://www.w3.org/Style/CSS/Test/CSS3/Color/20070927/html4/t040204-hsl-values-b.htm
@@ -84,9 +90,9 @@ class SassFunctionTest < Test::Unit::TestCase
84
90
  assert_equal "#33cccc", evaluate("hsl($hue: 180, $saturation: 60%, $lightness: 50%)")
85
91
  end
86
92
 
87
- def test_hsl_checks_bounds
88
- assert_error_message("Saturation -114 must be between 0% and 100% for `hsl'", "hsl(10, -114, 12)");
89
- assert_error_message("Lightness 256% must be between 0% and 100% for `hsl'", "hsl(10, 10, 256%)");
93
+ def test_hsl_clamps_bounds
94
+ assert_equal("#1f1f1f", evaluate("hsl(10, -114, 12)"))
95
+ assert_equal("white", evaluate("hsl(10, 10, 256%)"))
90
96
  end
91
97
 
92
98
  def test_hsl_checks_types
@@ -102,11 +108,11 @@ class SassFunctionTest < Test::Unit::TestCase
102
108
  assert_equal "rgba(51, 204, 204, 0.4)", evaluate("hsla($hue: 180, $saturation: 60%, $lightness: 50%, $alpha: 0.4)")
103
109
  end
104
110
 
105
- def test_hsla_checks_bounds
106
- assert_error_message("Saturation -114 must be between 0% and 100% for `hsla'", "hsla(10, -114, 12, 1)");
107
- assert_error_message("Lightness 256% must be between 0% and 100% for `hsla'", "hsla(10, 10, 256%, 0)");
108
- assert_error_message("Alpha channel -0.1 must be between 0 and 1 for `hsla'", "hsla(10, 10, 10, -0.1)");
109
- assert_error_message("Alpha channel 1.1 must be between 0 and 1 for `hsla'", "hsla(10, 10, 10, 1.1)");
111
+ def test_hsla_clamps_bounds
112
+ assert_equal("#1f1f1f", evaluate("hsla(10, -114, 12, 1)"))
113
+ assert_equal("rgba(255, 255, 255, 0)", evaluate("hsla(10, 10, 256%, 0)"))
114
+ assert_equal("rgba(28, 24, 23, 0)", evaluate("hsla(10, 10, 10, -0.1)"))
115
+ assert_equal("#1c1817", evaluate("hsla(10, 10, 10, 1.1)"))
110
116
  end
111
117
 
112
118
  def test_hsla_checks_types
@@ -116,6 +122,20 @@ class SassFunctionTest < Test::Unit::TestCase
116
122
  assert_error_message("$alpha: \"foo\" is not a number for `hsla'", "hsla(10, 10, 10, \"foo\")");
117
123
  end
118
124
 
125
+ def test_hsla_percent_warning
126
+ assert_warning(<<WARNING) {evaluate("hsla(180, 60%, 50%, 40%)")}
127
+ DEPRECATION WARNING: Passing a percentage as the alpha value to hsla() will be
128
+ interpreted differently in future versions of Sass. For now, use 40 instead.
129
+ WARNING
130
+ end
131
+
132
+ def test_hsla_unit_warning
133
+ assert_warning(<<WARNING) {evaluate("hsla(180, 60%, 50%, 40em)")}
134
+ DEPRECATION WARNING: Passing a number with units as the alpha value to hsla() is
135
+ deprecated and will be an error in future versions of Sass. Use 40 instead.
136
+ WARNING
137
+ end
138
+
119
139
  def test_percentage
120
140
  assert_equal("50%", evaluate("percentage(.5)"))
121
141
  assert_equal("100%", evaluate("percentage(1)"))
@@ -123,12 +143,6 @@ class SassFunctionTest < Test::Unit::TestCase
123
143
  assert_equal("50%", evaluate("percentage($number: 0.5)"))
124
144
  end
125
145
 
126
- def test_percentage_deprecated_arg_name
127
- assert_warning(<<WARNING) {assert_equal("50%", evaluate("percentage($value: 0.5)"))}
128
- DEPRECATION WARNING: The `$value' argument for `percentage()' has been renamed to `$number'.
129
- WARNING
130
- end
131
-
132
146
  def test_percentage_checks_types
133
147
  assert_error_message("$number: 25px is not a unitless number for `percentage'", "percentage(25px)")
134
148
  assert_error_message("$number: #cccccc is not a unitless number for `percentage'", "percentage(#ccc)")
@@ -140,12 +154,7 @@ WARNING
140
154
  assert_equal("5px", evaluate("round(4.8px)"))
141
155
  assert_equal("5px", evaluate("round(5.49px)"))
142
156
  assert_equal("5px", evaluate("round($number: 5.49px)"))
143
- end
144
-
145
- def test_round_deprecated_arg_name
146
- assert_warning(<<WARNING) {assert_equal("5px", evaluate("round($value: 5.49px)"))}
147
- DEPRECATION WARNING: The `$value' argument for `round()' has been renamed to `$number'.
148
- WARNING
157
+ assert_equal("-6", evaluate("round(-5.5)"))
149
158
  end
150
159
 
151
160
  def test_round_checks_types
@@ -158,12 +167,6 @@ WARNING
158
167
  assert_equal("4px", evaluate("floor($number: 4.8px)"))
159
168
  end
160
169
 
161
- def test_floor_deprecated_arg_name
162
- assert_warning(<<WARNING) {assert_equal("4px", evaluate("floor($value: 4.8px)"))}
163
- DEPRECATION WARNING: The `$value' argument for `floor()' has been renamed to `$number'.
164
- WARNING
165
- end
166
-
167
170
  def test_floor_checks_types
168
171
  assert_error_message("$value: \"foo\" is not a number for `floor'", "floor(\"foo\")")
169
172
  end
@@ -174,12 +177,6 @@ WARNING
174
177
  assert_equal("5px", evaluate("ceil($number: 4.8px)"))
175
178
  end
176
179
 
177
- def test_ceil_deprecated_arg_name
178
- assert_warning(<<WARNING) {assert_equal("5px", evaluate("ceil($value: 4.8px)"))}
179
- DEPRECATION WARNING: The `$value' argument for `ceil()' has been renamed to `$number'.
180
- WARNING
181
- end
182
-
183
180
  def test_ceil_checks_types
184
181
  assert_error_message("$value: \"a\" is not a number for `ceil'", "ceil(\"a\")")
185
182
  end
@@ -192,12 +189,6 @@ WARNING
192
189
  assert_equal("5px", evaluate("abs($number: 5px)"))
193
190
  end
194
191
 
195
- def test_abs_deprecated_arg_name
196
- assert_warning(<<WARNING) {assert_equal("5px", evaluate("abs($value: 5px)"))}
197
- DEPRECATION WARNING: The `$value' argument for `abs()' has been renamed to `$number'.
198
- WARNING
199
- end
200
-
201
192
  def test_abs_checks_types
202
193
  assert_error_message("$value: #aaaaaa is not a number for `abs'", "abs(#aaa)")
203
194
  end
@@ -207,6 +198,7 @@ WARNING
207
198
  assert_equal("1", evaluate("min(3px, 2px, 1)"))
208
199
  assert_equal("4em", evaluate("min(4em)"))
209
200
  assert_equal("10cm", evaluate("min(10cm, 6in)"))
201
+ assert_equal("1q", evaluate("min(1cm, 1q)"))
210
202
 
211
203
  assert_error_message("#aaaaaa is not a number for `min'", "min(#aaa)")
212
204
  assert_error_message("Incompatible units: 'px' and 'em'.", "min(3em, 4em, 1px)")
@@ -217,6 +209,7 @@ WARNING
217
209
  assert_equal("3", evaluate("max(3, 2px, 1px)"))
218
210
  assert_equal("4em", evaluate("max(4em)"))
219
211
  assert_equal("6in", evaluate("max(10cm, 6in)"))
212
+ assert_equal("11mm", evaluate("max(11mm, 10q)"))
220
213
 
221
214
  assert_error_message("#aaaaaa is not a number for `max'", "max(#aaa)")
222
215
  assert_error_message("Incompatible units: 'px' and 'em'.", "max(3em, 4em, 1px)")
@@ -230,32 +223,24 @@ WARNING
230
223
  end
231
224
 
232
225
  def test_rgb_percent
233
- assert_equal("#123456", evaluate("rgb(7.1%, 20.4%, 34%)"))
226
+ assert_equal("#123457", evaluate("rgb(7.1%, 20.4%, 34%)"))
234
227
  assert_equal("#beaded", evaluate("rgb(74.7%, 173, 93%)"))
235
228
  assert_equal("#beaded", evaluate("rgb(190, 68%, 237)"))
236
- assert_equal("springgreen", evaluate("rgb(0%, 100%, 50%)"))
229
+ assert_equal("#00ff80", evaluate("rgb(0%, 100%, 50%)"))
237
230
  end
238
231
 
239
- def test_rgb_tests_bounds
240
- assert_error_message("$red: Color value 256 must be between 0 and 255 for `rgb'",
241
- "rgb(256, 1, 1)")
242
- assert_error_message("$green: Color value 256 must be between 0 and 255 for `rgb'",
243
- "rgb(1, 256, 1)")
244
- assert_error_message("$blue: Color value 256 must be between 0 and 255 for `rgb'",
245
- "rgb(1, 1, 256)")
246
- assert_error_message("$green: Color value 256 must be between 0 and 255 for `rgb'",
247
- "rgb(1, 256, 257)")
248
- assert_error_message("$red: Color value -1 must be between 0 and 255 for `rgb'",
249
- "rgb(-1, 1, 1)")
232
+ def test_rgb_clamps_bounds
233
+ assert_equal("#ff0101", evaluate("rgb(256, 1, 1)"))
234
+ assert_equal("#01ff01", evaluate("rgb(1, 256, 1)"))
235
+ assert_equal("#0101ff", evaluate("rgb(1, 1, 256)"))
236
+ assert_equal("#01ffff", evaluate("rgb(1, 256, 257)"))
237
+ assert_equal("#000101", evaluate("rgb(-1, 1, 1)"))
250
238
  end
251
239
 
252
- def test_rgb_test_percent_bounds
253
- assert_error_message("$red: Color value 100.1% must be between 0% and 100% for `rgb'",
254
- "rgb(100.1%, 0, 0)")
255
- assert_error_message("$green: Color value -0.1% must be between 0% and 100% for `rgb'",
256
- "rgb(0, -0.1%, 0)")
257
- assert_error_message("$blue: Color value 101% must be between 0% and 100% for `rgb'",
258
- "rgb(0, 0, 101%)")
240
+ def test_rgb_clamps_percent_bounds
241
+ assert_equal("red", evaluate("rgb(100.1%, 0, 0)"))
242
+ assert_equal("black", evaluate("rgb(0, -0.1%, 0)"))
243
+ assert_equal("blue", evaluate("rgb(0, 0, 101%)"))
259
244
  end
260
245
 
261
246
  def test_rgb_tests_types
@@ -271,21 +256,14 @@ WARNING
271
256
  assert_equal("rgba(0, 255, 127, 0)", evaluate("rgba($red: 0, $green: 255, $blue: 127, $alpha: 0)"))
272
257
  end
273
258
 
274
- def test_rgba_tests_bounds
275
- assert_error_message("$red: Color value 256 must be between 0 and 255 for `rgba'",
276
- "rgba(256, 1, 1, 0.3)")
277
- assert_error_message("$green: Color value 256 must be between 0 and 255 for `rgba'",
278
- "rgba(1, 256, 1, 0.3)")
279
- assert_error_message("$blue: Color value 256 must be between 0 and 255 for `rgba'",
280
- "rgba(1, 1, 256, 0.3)")
281
- assert_error_message("$green: Color value 256 must be between 0 and 255 for `rgba'",
282
- "rgba(1, 256, 257, 0.3)")
283
- assert_error_message("$red: Color value -1 must be between 0 and 255 for `rgba'",
284
- "rgba(-1, 1, 1, 0.3)")
285
- assert_error_message("Alpha channel -0.2 must be between 0 and 1 for `rgba'",
286
- "rgba(1, 1, 1, -0.2)")
287
- assert_error_message("Alpha channel 1.2 must be between 0 and 1 for `rgba'",
288
- "rgba(1, 1, 1, 1.2)")
259
+ def test_rgba_clamps_bounds
260
+ assert_equal("rgba(255, 1, 1, 0.3)", evaluate("rgba(256, 1, 1, 0.3)"))
261
+ assert_equal("rgba(1, 255, 1, 0.3)", evaluate("rgba(1, 256, 1, 0.3)"))
262
+ assert_equal("rgba(1, 1, 255, 0.3)", evaluate("rgba(1, 1, 256, 0.3)"))
263
+ assert_equal("rgba(1, 255, 255, 0.3)", evaluate("rgba(1, 256, 257, 0.3)"))
264
+ assert_equal("rgba(0, 1, 1, 0.3)", evaluate("rgba(-1, 1, 1, 0.3)"))
265
+ assert_equal("rgba(1, 1, 1, 0)", evaluate("rgba(1, 1, 1, -0.2)"))
266
+ assert_equal("#010101", evaluate("rgba(1, 1, 1, 1.2)"))
289
267
  end
290
268
 
291
269
  def test_rgba_tests_types
@@ -313,6 +291,20 @@ WARNING
313
291
  assert_error_message("wrong number of arguments (5 for 4) for `rgba'", "rgba(1, 2, 3, 0.4, 5)");
314
292
  end
315
293
 
294
+ def test_rgba_percent_warning
295
+ assert_warning(<<WARNING) {evaluate("rgba(1, 2, 3, 40%)")}
296
+ DEPRECATION WARNING: Passing a percentage as the alpha value to rgba() will be
297
+ interpreted differently in future versions of Sass. For now, use 40 instead.
298
+ WARNING
299
+ end
300
+
301
+ def test_rgba_unit_warning
302
+ assert_warning(<<WARNING) {evaluate("rgba(1, 2, 3, 40em)")}
303
+ DEPRECATION WARNING: Passing a number with units as the alpha value to rgba() is
304
+ deprecated and will be an error in future versions of Sass. Use 40 instead.
305
+ WARNING
306
+ end
307
+
316
308
  def test_red
317
309
  assert_equal("18", evaluate("red(#123456)"))
318
310
  assert_equal("18", evaluate("red($color: #123456)"))
@@ -824,11 +816,11 @@ WARNING
824
816
  end
825
817
 
826
818
  def test_mix
827
- assert_equal("#7f007f", evaluate("mix(#f00, #00f)"))
828
- assert_equal("#7f7f7f", evaluate("mix(#f00, #0ff)"))
829
- assert_equal("#7f9055", evaluate("mix(#f70, #0aa)"))
830
- assert_equal("#3f00bf", evaluate("mix(#f00, #00f, 25%)"))
831
- assert_equal("rgba(63, 0, 191, 0.75)", evaluate("mix(rgba(255, 0, 0, 0.5), #00f)"))
819
+ assert_equal("purple", evaluate("mix(#f00, #00f)"))
820
+ assert_equal("gray", evaluate("mix(#f00, #0ff)"))
821
+ assert_equal("#809155", evaluate("mix(#f70, #0aa)"))
822
+ assert_equal("#4000bf", evaluate("mix(#f00, #00f, 25%)"))
823
+ assert_equal("rgba(64, 0, 191, 0.75)", evaluate("mix(rgba(255, 0, 0, 0.5), #00f)"))
832
824
  assert_equal("red", evaluate("mix(#f00, #00f, 100%)"))
833
825
  assert_equal("blue", evaluate("mix(#f00, #00f, 0%)"))
834
826
  assert_equal("rgba(255, 0, 0, 0.5)", evaluate("mix(#f00, transparentize(#00f, 1))"))
@@ -840,32 +832,6 @@ WARNING
840
832
  assert_equal("rgba(255, 0, 0, 0)", evaluate("mix($color1: transparentize(#f00, 1), $color2: #00f, $weight: 100%)"))
841
833
  end
842
834
 
843
- def test_mix_deprecated_arg_name
844
- assert_warning <<WARNING do
845
- DEPRECATION WARNING: The `$color-1' argument for `mix()' has been renamed to `$color1'.
846
- DEPRECATION WARNING: The `$color-2' argument for `mix()' has been renamed to `$color2'.
847
- WARNING
848
- assert_equal("rgba(255, 0, 0, 0)",
849
- evaluate("mix($color-1: transparentize(#f00, 1), $color-2: #00f, $weight: 100%)"))
850
- end
851
-
852
- assert_warning <<WARNING do
853
- DEPRECATION WARNING: The `$color-1' argument for `mix()' has been renamed to `$color1'.
854
- DEPRECATION WARNING: The `$color-2' argument for `mix()' has been renamed to `$color2'.
855
- WARNING
856
- assert_equal("rgba(0, 0, 255, 0.5)",
857
- evaluate("mix($color-1: transparentize(#f00, 1), $color-2: #00f)"))
858
- end
859
-
860
- assert_warning <<WARNING do
861
- DEPRECATION WARNING: The `$color_1' argument for `mix()' has been renamed to `$color1'.
862
- DEPRECATION WARNING: The `$color_2' argument for `mix()' has been renamed to `$color2'.
863
- WARNING
864
- assert_equal("rgba(0, 0, 255, 0.5)",
865
- evaluate("mix($color_1: transparentize(#f00, 1), $color_2: #00f)"))
866
- end
867
- end
868
-
869
835
  def test_mix_tests_types
870
836
  assert_error_message("$color1: \"foo\" is not a color for `mix'", "mix(\"foo\", #f00, 10%)")
871
837
  assert_error_message("$color2: \"foo\" is not a color for `mix'", "mix(#f00, \"foo\", 10%)")
@@ -922,6 +888,12 @@ WARNING
922
888
  assert_equal('foo', evaluate('unquote("foo")'))
923
889
  assert_equal('foo', evaluate('unquote(foo)'))
924
890
  assert_equal('foo', evaluate('unquote($string: foo)'))
891
+ assert_warning <<MESSAGE do
892
+ DEPRECATION WARNING: Passing blue, a non-string value, to unquote()
893
+ will be an error in future versions of Sass.
894
+ MESSAGE
895
+ assert_equal('blue', evaluate('unquote(blue)'))
896
+ end
925
897
  end
926
898
 
927
899
  def test_quote
@@ -995,6 +967,7 @@ WARNING
995
967
  assert_equal('ab', evaluate('str-slice(abcd,1,2)')) # for completeness
996
968
  assert_equal('abcd', evaluate('str-slice(abcd,1,4)')) # at the end points
997
969
  assert_equal('abcd', evaluate('str-slice(abcd,0,4)')) # when start is before the start of the string
970
+ assert_equal('', evaluate('str-slice(abcd,1,0)')) # when end is before the start of the string
998
971
  assert_equal('abcd', evaluate('str-slice(abcd,1,100)')) # when end is past the end of the string
999
972
  assert_equal('', evaluate('str-slice(abcd,2,1)')) # when end is before start
1000
973
  assert_equal('"bc"', evaluate('str-slice("abcd",2,3)')) # when used with a quoted string
@@ -1084,22 +1057,6 @@ MSG
1084
1057
  assert_equal(%Q{false}, evaluate("comparable($number1: 100px, $number2: 3em)"))
1085
1058
  end
1086
1059
 
1087
- def test_comparable_deprecated_arg_name
1088
- assert_warning <<WARNING do
1089
- DEPRECATION WARNING: The `$number-1' argument for `comparable()' has been renamed to `$number1'.
1090
- DEPRECATION WARNING: The `$number-2' argument for `comparable()' has been renamed to `$number2'.
1091
- WARNING
1092
- assert_equal("false", evaluate("comparable($number-1: 100px, $number-2: 3em)"))
1093
- end
1094
-
1095
- assert_warning <<WARNING do
1096
- DEPRECATION WARNING: The `$number_1' argument for `comparable()' has been renamed to `$number1'.
1097
- DEPRECATION WARNING: The `$number_2' argument for `comparable()' has been renamed to `$number2'.
1098
- WARNING
1099
- assert_equal("false", evaluate("comparable($number_1: 100px, $number_2: 3em)"))
1100
- end
1101
- end
1102
-
1103
1060
  def test_comparable_checks_types
1104
1061
  assert_error_message("$number1: #ff0000 is not a number for `comparable'", "comparable(#f00, 1px)")
1105
1062
  assert_error_message("$number2: #ff0000 is not a number for `comparable'", "comparable(1px, #f00)")
@@ -1257,76 +1214,17 @@ WARNING
1257
1214
  end
1258
1215
 
1259
1216
  def test_index
1217
+ null = Sass::Script::Value::Null.new
1260
1218
  assert_equal("1", evaluate("index(1px solid blue, 1px)"))
1261
1219
  assert_equal("2", evaluate("index(1px solid blue, solid)"))
1262
1220
  assert_equal("3", evaluate("index(1px solid blue, #00f)"))
1263
1221
  assert_equal("1", evaluate("index(1px, 1px)"))
1264
- assert_equal("false", evaluate("index(1px solid blue, 1em)"))
1265
- assert_equal("false", evaluate("index(1px solid blue, notfound)"))
1266
- assert_equal("false", evaluate("index(1px, #00f)"))
1222
+ assert_equal(null, perform("index(1px solid blue, 1em)"))
1223
+ assert_equal(null, perform("index(1px solid blue, notfound)"))
1224
+ assert_equal(null, perform("index(1px, #00f)"))
1267
1225
 
1268
1226
  assert_equal("1", evaluate("index((foo: bar, bar: baz), (foo bar))"))
1269
- assert_equal("false", evaluate("index((foo: bar, bar: baz), (foo: bar))"))
1270
- end
1271
-
1272
- def test_index_deprecation_warning
1273
- assert_warning(<<WARNING) do
1274
- DEPRECATION WARNING: The return value of index() will change from "false" to
1275
- "null" in future versions of Sass. For compatibility, avoid using "== false" on
1276
- the return value. For example, instead of "@if index(...) == false", just write
1277
- "@if index(...)".
1278
- WARNING
1279
- assert_equal("true", evaluate("index(1, 2 3 4) == false"))
1280
- end
1281
-
1282
- assert_warning(<<WARNING) do
1283
- DEPRECATION WARNING: The return value of index() will change from "false" to
1284
- "null" in future versions of Sass. For compatibility, avoid using "!= null" on
1285
- the return value.
1286
- WARNING
1287
- assert_equal("true", evaluate("index(1, 2 3 4) != null"))
1288
- end
1289
-
1290
- assert_warning(<<WARNING) do
1291
- DEPRECATION WARNING: The return value of index() will change from "false" to
1292
- "null" in future versions of Sass. For compatibility, avoid using "== false" on
1293
- the return value. For example, instead of "@if index(...) == false", just write
1294
- "@if index(...)".
1295
- WARNING
1296
- assert_equal("true", evaluate("false == index(1, 2 3 4)"))
1297
- end
1298
-
1299
- assert_warning(<<WARNING) do
1300
- DEPRECATION WARNING: The return value of index() will change from "false" to
1301
- "null" in future versions of Sass. For compatibility, avoid using "!= null" on
1302
- the return value.
1303
- WARNING
1304
- assert_equal("true", evaluate("null != index(1, 2 3 4)"))
1305
- end
1306
- end
1307
-
1308
- def test_index_deprecation_warning_is_only_emitted_once_per_call
1309
- assert_warning(<<WARNING) do
1310
- DEPRECATION WARNING: The return value of index() will change from "false" to
1311
- "null" in future versions of Sass. For compatibility, avoid using "== false" on
1312
- the return value. For example, instead of "@if index(...) == false", just write
1313
- "@if index(...)".
1314
- on line 3 of test_index_deprecation_warning_is_only_emitted_once_per_call_inline.scss
1315
- DEPRECATION WARNING: The return value of index() will change from "false" to
1316
- "null" in future versions of Sass. For compatibility, avoid using "== false" on
1317
- the return value. For example, instead of "@if index(...) == false", just write
1318
- "@if index(...)".
1319
- on line 6 of test_index_deprecation_warning_is_only_emitted_once_per_call_inline.scss
1320
- WARNING
1321
- render(<<SCSS)
1322
- @for $i from 1 to 10 {
1323
- $var1: index(1, 2 3 4);
1324
- $var2: $var1 == false;
1325
- $var3: $var1 != null;
1326
- }
1327
- $var4: index(1, 2 3 4) == false;
1328
- SCSS
1329
- end
1227
+ assert_equal(null, perform("index((foo: bar, bar: baz), (foo: bar))"))
1330
1228
  end
1331
1229
 
1332
1230
  def test_list_separator
@@ -1446,7 +1344,7 @@ SCSS
1446
1344
  50.times do
1447
1345
  last_id, current_id = current_id, evaluate("unique-id()")
1448
1346
  assert_match(/u[a-z0-9]{8}/, current_id)
1449
- assert_not_equal last_id, current_id
1347
+ refute_equal last_id, current_id
1450
1348
  end
1451
1349
  end
1452
1350
 
@@ -1457,16 +1355,6 @@ SCSS
1457
1355
  assert_equal "null", perform("map-get((), foo)").to_sass
1458
1356
  end
1459
1357
 
1460
- def test_map_get_deprecation_warning
1461
- assert_warning(<<WARNING) do
1462
- DEPRECATION WARNING: Passing lists of pairs to map-get is deprecated and will
1463
- be removed in future versions of Sass. Use Sass maps instead. For details, see
1464
- http://sass-lang.com/docs/yardoc/file.SASS_REFERENCE.html#maps.
1465
- WARNING
1466
- assert_equal "1", evaluate("map-get((foo 1) (bar 2), foo)")
1467
- end
1468
- end
1469
-
1470
1358
  def test_map_get_checks_type
1471
1359
  assert_error_message("$map: 12 is not a map for `map-get'", "map-get(12, bar)")
1472
1360
  end
@@ -1480,26 +1368,6 @@ WARNING
1480
1368
  perform("map-merge((foo: 1, bar: 2), ())").to_sass)
1481
1369
  end
1482
1370
 
1483
- def test_map_merge_deprecation_warning
1484
- assert_warning(<<WARNING) do
1485
- DEPRECATION WARNING: Passing lists of pairs to map-merge is deprecated and will
1486
- be removed in future versions of Sass. Use Sass maps instead. For details, see
1487
- http://sass-lang.com/docs/yardoc/file.SASS_REFERENCE.html#maps.
1488
- WARNING
1489
- assert_equal("(foo: 1, bar: 2, baz: 3)",
1490
- perform("map-merge((foo 1, bar 2), (baz: 3))").to_sass)
1491
- end
1492
-
1493
- assert_warning(<<WARNING) do
1494
- DEPRECATION WARNING: Passing lists of pairs to map-merge is deprecated and will
1495
- be removed in future versions of Sass. Use Sass maps instead. For details, see
1496
- http://sass-lang.com/docs/yardoc/file.SASS_REFERENCE.html#maps.
1497
- WARNING
1498
- assert_equal("(baz: 3, foo: 1, bar: 2)",
1499
- perform("map-merge((baz: 3), (foo 1, bar 2))").to_sass)
1500
- end
1501
- end
1502
-
1503
1371
  def test_map_merge_checks_type
1504
1372
  assert_error_message("$map1: 12 is not a map for `map-merge'", "map-merge(12, (foo: 1))")
1505
1373
  assert_error_message("$map2: 12 is not a map for `map-merge'", "map-merge((foo: 1), 12)")
@@ -1508,18 +1376,12 @@ WARNING
1508
1376
  def test_map_remove
1509
1377
  assert_equal("(foo: 1, baz: 3)",
1510
1378
  perform("map-remove((foo: 1, bar: 2, baz: 3), bar)").to_sass)
1379
+ assert_equal("(foo: 1, baz: 3)",
1380
+ perform("map-remove($map: (foo: 1, bar: 2, baz: 3), $key: bar)").to_sass)
1381
+ assert_equal("()",
1382
+ perform("map-remove((foo: 1, bar: 2, baz: 3), foo, bar, baz)").to_sass)
1511
1383
  assert_equal("()", perform("map-remove((), foo)").to_sass)
1512
- end
1513
-
1514
- def test_map_remove_deprecation_warning
1515
- assert_warning(<<WARNING) do
1516
- DEPRECATION WARNING: Passing lists of pairs to map-remove is deprecated and will
1517
- be removed in future versions of Sass. Use Sass maps instead. For details, see
1518
- http://sass-lang.com/docs/yardoc/file.SASS_REFERENCE.html#maps.
1519
- WARNING
1520
- assert_equal("(foo: 1, baz: 3)",
1521
- perform("map-remove((foo 1, bar 2, baz 3), bar)").to_sass)
1522
- end
1384
+ assert_equal("()", perform("map-remove((), foo, bar)").to_sass)
1523
1385
  end
1524
1386
 
1525
1387
  def test_map_remove_checks_type
@@ -1532,17 +1394,6 @@ WARNING
1532
1394
  assert_equal("()", perform("map-keys(())").to_sass)
1533
1395
  end
1534
1396
 
1535
- def test_map_keys_deprecation_warning
1536
- assert_warning(<<WARNING) do
1537
- DEPRECATION WARNING: Passing lists of pairs to map-keys is deprecated and will
1538
- be removed in future versions of Sass. Use Sass maps instead. For details, see
1539
- http://sass-lang.com/docs/yardoc/file.SASS_REFERENCE.html#maps.
1540
- WARNING
1541
- assert_equal("foo, bar",
1542
- perform("map-keys((foo 1, bar 2))").to_sass)
1543
- end
1544
- end
1545
-
1546
1397
  def test_map_keys_checks_type
1547
1398
  assert_error_message("$map: 12 is not a map for `map-keys'", "map-keys(12)")
1548
1399
  end
@@ -1554,16 +1405,6 @@ WARNING
1554
1405
  assert_equal("()", perform("map-values(())").to_sass)
1555
1406
  end
1556
1407
 
1557
- def test_map_values_deprecation_warning
1558
- assert_warning(<<WARNING) do
1559
- DEPRECATION WARNING: Passing lists of pairs to map-values is deprecated and will
1560
- be removed in future versions of Sass. Use Sass maps instead. For details, see
1561
- http://sass-lang.com/docs/yardoc/file.SASS_REFERENCE.html#maps.
1562
- WARNING
1563
- assert_equal("1, 2", perform("map-values((foo 1, bar 2))").to_sass)
1564
- end
1565
- end
1566
-
1567
1408
  def test_map_values_checks_type
1568
1409
  assert_error_message("$map: 12 is not a map for `map-values'", "map-values(12)")
1569
1410
  end
@@ -1574,16 +1415,6 @@ WARNING
1574
1415
  assert_equal "false", evaluate("map-has-key((), foo)")
1575
1416
  end
1576
1417
 
1577
- def test_map_has_key_deprecation_warning
1578
- assert_warning(<<WARNING) do
1579
- DEPRECATION WARNING: Passing lists of pairs to map-has-key is deprecated and will
1580
- be removed in future versions of Sass. Use Sass maps instead. For details, see
1581
- http://sass-lang.com/docs/yardoc/file.SASS_REFERENCE.html#maps.
1582
- WARNING
1583
- assert_equal("true", evaluate("map-has-key((foo 1, bar 1), foo)"))
1584
- end
1585
- end
1586
-
1587
1418
  def test_map_has_key_checks_type
1588
1419
  assert_error_message("$map: 12 is not a map for `map-has-key'", "map-has-key(12, foo)")
1589
1420
  end
@@ -1799,6 +1630,9 @@ SCSS
1799
1630
  assert_equal "null", evaluate("inspect(null)")
1800
1631
  assert_equal "1px null 3px", evaluate("inspect(1px null 3px)")
1801
1632
  assert_equal "(a: 1, b: 2)", evaluate("inspect((a: 1, b: 2))")
1633
+ assert_equal "(a: 1, b: (c: 2))", evaluate("inspect((a: 1, b: (c: 2)))")
1634
+ assert_equal "(a: 1, b: (2, 3))", evaluate("inspect((a: 1, b: (2, 3)))")
1635
+ assert_equal "(a: 1, b: 2 3)", evaluate("inspect((a: 1, b: 2 3))")
1802
1636
  end
1803
1637
 
1804
1638
  def test_random
@@ -1833,12 +1667,271 @@ SCSS
1833
1667
  assert_error_message("Expected $limit to be an integer but got 1.5 for `random'", "random(1.5)")
1834
1668
  end
1835
1669
 
1670
+ # Regression test for #1638.
1671
+ def test_random_with_float_integer_limit
1672
+ result = perform("random(1.0)")
1673
+ assert_kind_of Sass::Script::Number, result
1674
+ assert result.value >= 0, "Random number was below 0"
1675
+ assert result.value <= 1, "Random number was above 1"
1676
+ end
1677
+
1836
1678
  # This could *possibly* fail, but exceedingly unlikely
1837
1679
  def test_random_is_semi_unique
1838
1680
  if Sass::Script::Functions.instance_variable_defined?("@random_number_generator")
1839
1681
  Sass::Script::Functions.send(:remove_instance_variable, "@random_number_generator")
1840
1682
  end
1841
- assert_not_equal evaluate("random()"), evaluate("random()")
1683
+ refute_equal evaluate("random()"), evaluate("random()")
1684
+ end
1685
+
1686
+ def test_deprecated_arg_names
1687
+ assert_warning <<WARNING do
1688
+ DEPRECATION WARNING: The `$arg-1' argument for `deprecated-arg-fn()' has been renamed to `$arg1'.
1689
+ DEPRECATION WARNING: The `$arg-2' argument for `deprecated-arg-fn()' has been renamed to `$arg2'.
1690
+ WARNING
1691
+ assert_equal("1 2 3",
1692
+ evaluate("deprecated-arg-fn($arg-1: 1, $arg-2: 2, $arg3: 3)"))
1693
+ end
1694
+
1695
+ assert_warning <<WARNING do
1696
+ DEPRECATION WARNING: The `$arg-1' argument for `deprecated-arg-fn()' has been renamed to `$arg1'.
1697
+ DEPRECATION WARNING: The `$arg-2' argument for `deprecated-arg-fn()' has been renamed to `$arg2'.
1698
+ WARNING
1699
+ assert_equal("1 2",
1700
+ evaluate("deprecated-arg-fn($arg-1: 1, $arg-2: 2)"))
1701
+ end
1702
+
1703
+ assert_warning <<WARNING do
1704
+ DEPRECATION WARNING: The `$arg_1' argument for `deprecated-arg-fn()' has been renamed to `$arg1'.
1705
+ DEPRECATION WARNING: The `$arg_2' argument for `deprecated-arg-fn()' has been renamed to `$arg2'.
1706
+ WARNING
1707
+ assert_equal("1 2",
1708
+ evaluate("deprecated-arg-fn($arg_1: 1, $arg_2: 2)"))
1709
+ end
1710
+ end
1711
+
1712
+ def test_non_deprecated_arg_names
1713
+ assert_equal("1 2 3", evaluate("deprecated-arg-fn($arg1: 1, $arg2: 2, $arg3: 3)"))
1714
+ assert_equal("1 2", evaluate("deprecated-arg-fn($arg1: 1, $arg2: 2)"))
1715
+ end
1716
+
1717
+ ## Selector Functions
1718
+
1719
+ def test_selector_argument_parsing
1720
+ assert_equal("true", evaluate("selector-parse('.foo') == (join(('.foo',), (), space),)"))
1721
+ assert_equal("true", evaluate("selector-parse('.foo .bar') == ('.foo' '.bar',)"))
1722
+ assert_equal("true",
1723
+ evaluate("selector-parse('.foo .bar, .baz .bang') == ('.foo' '.bar', '.baz' '.bang')"))
1724
+
1725
+ assert_equal(".foo %bar", evaluate("selector-parse('.foo %bar')"))
1726
+
1727
+ assert_equal("true",
1728
+ evaluate("selector-parse(('.foo', '.bar')) == selector-parse('.foo, .bar')"))
1729
+ assert_equal("true",
1730
+ evaluate("selector-parse('.foo' '.bar') == selector-parse('.foo .bar')"))
1731
+
1732
+ assert_equal("true", evaluate("selector-parse(('.foo' '.bar', '.baz' '.bang')) == " +
1733
+ "selector-parse('.foo .bar, .baz .bang')"))
1734
+ assert_equal("true", evaluate("selector-parse(('.foo .bar', '.baz .bang')) == " +
1735
+ "selector-parse('.foo .bar, .baz .bang')"))
1736
+
1737
+ # This may throw an error in the future.
1738
+ assert_equal("true", evaluate("selector-parse(('.foo, .bar' '.baz, .bang')) == " +
1739
+ "selector-parse('.foo, .bar .baz, .bang')"))
1740
+ end
1741
+
1742
+ def test_selector_argument_validation
1743
+ assert_error_message("$selector: 12 is not a valid selector: it must be a string,\n" +
1744
+ "a list of strings, or a list of lists of strings for `selector-parse'", "selector-parse(12)")
1745
+ assert_error_message("$selector: (((\".foo\" \".bar\"), \".baz\") (\".bang\", \".qux\")) is not a valid selector: it must be a string,\n" +
1746
+ "a list of strings, or a list of lists of strings for `selector-parse'",
1747
+ "selector-parse(('.foo' '.bar', '.baz') ('.bang', '.qux'))")
1748
+ assert_error_message("$selector: \".#\" is not a valid selector: Invalid CSS after \".\": " +
1749
+ "expected class name, was \"#\" for `selector-parse'", "selector-parse('.#')")
1750
+ assert_error_message("$selector: \"&.foo\" is not a valid selector: Invalid CSS after \"\": " +
1751
+ "expected selector, was \"&.foo\" for `selector-parse'", "selector-parse('&.foo')")
1752
+ end
1753
+
1754
+ def test_selector_nest
1755
+ assert_equal(".foo", evaluate("selector-nest('.foo')"))
1756
+ assert_equal(".foo .bar", evaluate("selector-nest('.foo', '.bar')"))
1757
+ assert_equal(".foo .bar .baz", evaluate("selector-nest('.foo', '.bar', '.baz')"))
1758
+ assert_equal(".a .foo .b .bar", evaluate("selector-nest('.a .foo', '.b .bar')"))
1759
+ assert_equal(".foo.bar", evaluate("selector-nest('.foo', '&.bar')"))
1760
+ assert_equal(".baz .foo.bar", evaluate("selector-nest('.foo', '&.bar', '.baz &')"))
1761
+ end
1762
+
1763
+ def test_selector_nest_checks_types
1764
+ assert_error_message("$selectors: 12 is not a valid selector: it must be a string,\n" +
1765
+ "a list of strings, or a list of lists of strings for `selector-nest'",
1766
+ "selector-nest(12)")
1767
+ assert_error_message("$selectors: 12 is not a valid selector: it must be a string,\n" +
1768
+ "a list of strings, or a list of lists of strings for `selector-nest'",
1769
+ "selector-nest('.foo', 12)")
1770
+ end
1771
+
1772
+ def test_selector_nest_argument_validation
1773
+ assert_error_message("$selectors: At least one selector must be passed for `selector-nest'",
1774
+ "selector-nest()")
1775
+ end
1776
+
1777
+ def test_selector_append
1778
+ assert_equal(".foo.bar", evaluate("selector-append('.foo', '.bar')"))
1779
+ assert_equal(".a .foo.b .bar", evaluate("selector-append('.a .foo', '.b .bar')"))
1780
+ assert_equal(".foo-suffix", evaluate("selector-append('.foo', '-suffix')"))
1781
+ assert_equal(".foo.bar, .foo-suffix", evaluate("selector-append('.foo', '.bar, -suffix')"))
1782
+ assert_equal(".foo--suffix", evaluate("selector-append('.foo', '--suffix')"))
1783
+ assert_equal(".foo.bar, .foo--suffix", evaluate("selector-append('.foo', '.bar, --suffix')"))
1784
+ end
1785
+
1786
+ def test_selector_append_checks_types
1787
+ assert_error_message("$selectors: 12 is not a valid selector: it must be a string,\n" +
1788
+ "a list of strings, or a list of lists of strings for `selector-append'",
1789
+ "selector-append(12)")
1790
+ assert_error_message("$selectors: 12 is not a valid selector: it must be a string,\n" +
1791
+ "a list of strings, or a list of lists of strings for `selector-append'",
1792
+ "selector-append('.foo', 12)")
1793
+ end
1794
+
1795
+ def test_selector_append_errors
1796
+ assert_error_message("$selectors: At least one selector must be passed for `selector-append'",
1797
+ "selector-append()")
1798
+ assert_error_message("Can't append \"> .bar\" to \".foo\" for `selector-append'",
1799
+ "selector-append('.foo', '> .bar')")
1800
+ assert_error_message("Can't append \"*.bar\" to \".foo\" for `selector-append'",
1801
+ "selector-append('.foo', '*.bar')")
1802
+ assert_error_message("Can't append \"ns|suffix\" to \".foo\" for `selector-append'",
1803
+ "selector-append('.foo', 'ns|suffix')")
1804
+ end
1805
+
1806
+ def test_selector_extend
1807
+ assert_equal(".foo .x, .foo .a .bar, .a .foo .bar",
1808
+ evaluate("selector-extend('.foo .x', '.x', '.a .bar')"))
1809
+ assert_equal(".foo .x, .foo .bang, .x.bar, .bar.bang",
1810
+ evaluate("selector-extend('.foo .x, .x.bar', '.x', '.bang')"))
1811
+ assert_equal(".y .x, .foo .x, .y .foo, .foo .foo",
1812
+ evaluate("selector-extend('.y .x', '.x, .y', '.foo')"))
1813
+ assert_equal(".foo .x, .foo .bar, .foo .bang",
1814
+ evaluate("selector-extend('.foo .x', '.x', '.bar, .bang')"))
1815
+ assert_equal(".foo.x, .foo",
1816
+ evaluate("selector-extend('.foo.x', '.x', '.foo')"))
1817
+ end
1818
+
1819
+ def test_selector_extend_checks_types
1820
+ assert_error_message("$selector: 12 is not a valid selector: it must be a string,\n" +
1821
+ "a list of strings, or a list of lists of strings for `selector-extend'",
1822
+ "selector-extend(12, '.foo', '.bar')")
1823
+ assert_error_message("$extendee: 12 is not a valid selector: it must be a string,\n" +
1824
+ "a list of strings, or a list of lists of strings for `selector-extend'",
1825
+ "selector-extend('.foo', 12, '.bar')")
1826
+ assert_error_message("$extender: 12 is not a valid selector: it must be a string,\n" +
1827
+ "a list of strings, or a list of lists of strings for `selector-extend'",
1828
+ "selector-extend('.foo', '.bar', 12)")
1829
+ end
1830
+
1831
+ def test_selector_extend_errors
1832
+ assert_error_message("Can't extend .bar .baz: can't extend nested selectors for " +
1833
+ "`selector-extend'", "selector-extend('.foo', '.bar .baz', '.bang')")
1834
+ assert_error_message("Can't extend >: invalid selector for `selector-extend'",
1835
+ "selector-extend('.foo', '>', '.bang')")
1836
+ assert_error_message(".bang > can't extend: invalid selector for `selector-extend'",
1837
+ "selector-extend('.foo', '.bar', '.bang >')")
1838
+ end
1839
+
1840
+ def test_selector_replace
1841
+ assert_equal(".bar", evaluate("selector-replace('.foo', '.foo', '.bar')"))
1842
+ assert_equal(".foo.baz", evaluate("selector-replace('.foo.bar', '.bar', '.baz')"))
1843
+ assert_equal(".a .foo.baz", evaluate("selector-replace('.foo.bar', '.bar', '.a .baz')"))
1844
+
1845
+ # These shouldn't warn since we still support componud targets for selector
1846
+ # functions.
1847
+ assert_no_warning {assert_equal(".foo.bar", evaluate("selector-replace('.foo.bar', '.baz.bar', '.qux')"))}
1848
+ assert_no_warning {assert_equal(".bar.qux", evaluate("selector-replace('.foo.bar.baz', '.foo.baz', '.qux')"))}
1849
+
1850
+ assert_equal(":not(.bar)", evaluate("selector-replace(':not(.foo)', '.foo', '.bar')"))
1851
+ assert_equal(".bar", evaluate("selector-replace(':not(.foo)', ':not(.foo)', '.bar')"))
1852
+ end
1853
+
1854
+ def test_selector_replace_checks_types
1855
+ assert_error_message("$selector: 12 is not a valid selector: it must be a string,\n" +
1856
+ "a list of strings, or a list of lists of strings for `selector-replace'",
1857
+ "selector-replace(12, '.foo', '.bar')")
1858
+ assert_error_message("$original: 12 is not a valid selector: it must be a string,\n" +
1859
+ "a list of strings, or a list of lists of strings for `selector-replace'",
1860
+ "selector-replace('.foo', 12, '.bar')")
1861
+ assert_error_message("$replacement: 12 is not a valid selector: it must be a string,\n" +
1862
+ "a list of strings, or a list of lists of strings for `selector-replace'",
1863
+ "selector-replace('.foo', '.bar', 12)")
1864
+ end
1865
+
1866
+ def test_selector_replace_errors
1867
+ assert_error_message("Can't extend .bar .baz: can't extend nested selectors for " +
1868
+ "`selector-replace'", "selector-replace('.foo', '.bar .baz', '.bang')")
1869
+ assert_error_message("Can't extend >: invalid selector for `selector-replace'",
1870
+ "selector-replace('.foo', '>', '.bang')")
1871
+ assert_error_message(".bang > can't extend: invalid selector for `selector-replace'",
1872
+ "selector-replace('.foo', '.bar', '.bang >')")
1873
+ end
1874
+
1875
+ def test_selector_unify
1876
+ assert_equal(".foo", evaluate("selector-unify('.foo', '.foo')"))
1877
+ assert_equal(".foo.bar", evaluate("selector-unify('.foo', '.bar')"))
1878
+ assert_equal(".foo.bar.baz", evaluate("selector-unify('.foo.bar', '.bar.baz')"))
1879
+ assert_equal(".a .b .foo.bar, .b .a .foo.bar", evaluate("selector-unify('.a .foo', '.b .bar')"))
1880
+ assert_equal(".a .foo.bar", evaluate("selector-unify('.a .foo', '.a .bar')"))
1881
+ assert_equal("", evaluate("selector-unify('p', 'a')"))
1882
+ assert_equal("", evaluate("selector-unify('.foo >', '.bar')"))
1883
+ assert_equal("", evaluate("selector-unify('.foo', '.bar >')"))
1884
+ assert_equal(".foo.baz, .foo.bang, .bar.baz, .bar.bang",
1885
+ evaluate("selector-unify('.foo, .bar', '.baz, .bang')"))
1886
+ end
1887
+
1888
+ def test_selector_unify_checks_types
1889
+ assert_error_message("$selector1: 12 is not a valid selector: it must be a string,\n" +
1890
+ "a list of strings, or a list of lists of strings for `selector-unify'",
1891
+ "selector-unify(12, '.foo')")
1892
+ assert_error_message("$selector2: 12 is not a valid selector: it must be a string,\n" +
1893
+ "a list of strings, or a list of lists of strings for `selector-unify'",
1894
+ "selector-unify('.foo', 12)")
1895
+ end
1896
+
1897
+ def test_simple_selectors
1898
+ assert_equal('(.foo,)', evaluate("inspect(simple-selectors('.foo'))"))
1899
+ assert_equal('.foo, .bar', evaluate("inspect(simple-selectors('.foo.bar'))"))
1900
+ assert_equal('.foo, .bar, :pseudo("flip, flap")',
1901
+ evaluate("inspect(simple-selectors('.foo.bar:pseudo(\"flip, flap\")'))"))
1902
+ end
1903
+
1904
+ def test_simple_selectors_checks_types
1905
+ assert_error_message("$selector: 12 is not a string for `simple-selectors'",
1906
+ "simple-selectors(12)")
1907
+ end
1908
+
1909
+ def test_simple_selectors_errors
1910
+ assert_error_message("$selector: \".foo .bar\" is not a compound selector for `simple-selectors'",
1911
+ "simple-selectors('.foo .bar')")
1912
+ assert_error_message("$selector: \".foo,.bar\" is not a compound selector for `simple-selectors'",
1913
+ "simple-selectors('.foo,.bar')")
1914
+ assert_error_message("$selector: \".#\" is not a valid selector: Invalid CSS after \".\": " +
1915
+ "expected class name, was \"#\" for `simple-selectors'", "simple-selectors('.#')")
1916
+ end
1917
+
1918
+ def test_is_superselector
1919
+ assert_equal("true", evaluate("is-superselector('.foo', '.foo.bar')"))
1920
+ assert_equal("false", evaluate("is-superselector('.foo.bar', '.foo')"))
1921
+ assert_equal("true", evaluate("is-superselector('.foo', '.foo')"))
1922
+ assert_equal("true", evaluate("is-superselector('.bar', '.foo .bar')"))
1923
+ assert_equal("false", evaluate("is-superselector('.foo .bar', '.bar')"))
1924
+ assert_equal("true", evaluate("is-superselector('.foo .bar', '.foo > .bar')"))
1925
+ assert_equal("false", evaluate("is-superselector('.foo > .bar', '.foo .bar')"))
1926
+ end
1927
+
1928
+ def test_is_superselector_checks_types
1929
+ assert_error_message("$super: 12 is not a valid selector: it must be a string,\n" +
1930
+ "a list of strings, or a list of lists of strings for `is-superselector'",
1931
+ "is-superselector(12, '.foo')")
1932
+ assert_error_message("$sub: 12 is not a valid selector: it must be a string,\n" +
1933
+ "a list of strings, or a list of lists of strings for `is-superselector'",
1934
+ "is-superselector('.foo', 12)")
1842
1935
  end
1843
1936
 
1844
1937
  ## Regression Tests