sass 3.3.0 → 3.4.25

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 (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