xass 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (242) hide show
  1. checksums.yaml +7 -0
  2. data/.yardopts +11 -0
  3. data/CONTRIBUTING +3 -0
  4. data/MIT-LICENSE +20 -0
  5. data/README.md +201 -0
  6. data/Rakefile +349 -0
  7. data/VERSION +1 -0
  8. data/VERSION_NAME +1 -0
  9. data/bin/push +13 -0
  10. data/bin/sass +13 -0
  11. data/bin/sass-convert +12 -0
  12. data/bin/scss +13 -0
  13. data/extra/update_watch.rb +13 -0
  14. data/init.rb +18 -0
  15. data/lib/sass/cache_stores/base.rb +88 -0
  16. data/lib/sass/cache_stores/chain.rb +33 -0
  17. data/lib/sass/cache_stores/filesystem.rb +64 -0
  18. data/lib/sass/cache_stores/memory.rb +47 -0
  19. data/lib/sass/cache_stores/null.rb +25 -0
  20. data/lib/sass/cache_stores.rb +15 -0
  21. data/lib/sass/callbacks.rb +66 -0
  22. data/lib/sass/css.rb +409 -0
  23. data/lib/sass/engine.rb +930 -0
  24. data/lib/sass/environment.rb +101 -0
  25. data/lib/sass/error.rb +201 -0
  26. data/lib/sass/exec.rb +707 -0
  27. data/lib/sass/importers/base.rb +139 -0
  28. data/lib/sass/importers/filesystem.rb +186 -0
  29. data/lib/sass/importers.rb +22 -0
  30. data/lib/sass/logger/base.rb +32 -0
  31. data/lib/sass/logger/log_level.rb +49 -0
  32. data/lib/sass/logger.rb +15 -0
  33. data/lib/sass/media.rb +213 -0
  34. data/lib/sass/plugin/compiler.rb +406 -0
  35. data/lib/sass/plugin/configuration.rb +123 -0
  36. data/lib/sass/plugin/generic.rb +15 -0
  37. data/lib/sass/plugin/merb.rb +48 -0
  38. data/lib/sass/plugin/rack.rb +60 -0
  39. data/lib/sass/plugin/rails.rb +47 -0
  40. data/lib/sass/plugin/staleness_checker.rb +199 -0
  41. data/lib/sass/plugin.rb +133 -0
  42. data/lib/sass/railtie.rb +10 -0
  43. data/lib/sass/repl.rb +57 -0
  44. data/lib/sass/root.rb +7 -0
  45. data/lib/sass/script/arg_list.rb +52 -0
  46. data/lib/sass/script/bool.rb +18 -0
  47. data/lib/sass/script/color.rb +606 -0
  48. data/lib/sass/script/css_lexer.rb +29 -0
  49. data/lib/sass/script/css_parser.rb +31 -0
  50. data/lib/sass/script/funcall.rb +245 -0
  51. data/lib/sass/script/functions.rb +1543 -0
  52. data/lib/sass/script/interpolation.rb +79 -0
  53. data/lib/sass/script/lexer.rb +345 -0
  54. data/lib/sass/script/list.rb +85 -0
  55. data/lib/sass/script/literal.rb +221 -0
  56. data/lib/sass/script/node.rb +99 -0
  57. data/lib/sass/script/null.rb +37 -0
  58. data/lib/sass/script/number.rb +453 -0
  59. data/lib/sass/script/operation.rb +110 -0
  60. data/lib/sass/script/parser.rb +502 -0
  61. data/lib/sass/script/string.rb +51 -0
  62. data/lib/sass/script/string_interpolation.rb +103 -0
  63. data/lib/sass/script/unary_operation.rb +69 -0
  64. data/lib/sass/script/variable.rb +58 -0
  65. data/lib/sass/script.rb +39 -0
  66. data/lib/sass/scss/css_parser.rb +36 -0
  67. data/lib/sass/scss/parser.rb +1180 -0
  68. data/lib/sass/scss/rx.rb +133 -0
  69. data/lib/sass/scss/script_lexer.rb +15 -0
  70. data/lib/sass/scss/script_parser.rb +25 -0
  71. data/lib/sass/scss/static_parser.rb +54 -0
  72. data/lib/sass/scss.rb +16 -0
  73. data/lib/sass/selector/abstract_sequence.rb +94 -0
  74. data/lib/sass/selector/comma_sequence.rb +92 -0
  75. data/lib/sass/selector/sequence.rb +507 -0
  76. data/lib/sass/selector/simple.rb +119 -0
  77. data/lib/sass/selector/simple_sequence.rb +215 -0
  78. data/lib/sass/selector.rb +452 -0
  79. data/lib/sass/shared.rb +76 -0
  80. data/lib/sass/supports.rb +229 -0
  81. data/lib/sass/tree/charset_node.rb +22 -0
  82. data/lib/sass/tree/comment_node.rb +82 -0
  83. data/lib/sass/tree/content_node.rb +9 -0
  84. data/lib/sass/tree/css_import_node.rb +60 -0
  85. data/lib/sass/tree/debug_node.rb +18 -0
  86. data/lib/sass/tree/directive_node.rb +42 -0
  87. data/lib/sass/tree/each_node.rb +24 -0
  88. data/lib/sass/tree/extend_node.rb +36 -0
  89. data/lib/sass/tree/for_node.rb +36 -0
  90. data/lib/sass/tree/function_node.rb +34 -0
  91. data/lib/sass/tree/if_node.rb +52 -0
  92. data/lib/sass/tree/import_node.rb +75 -0
  93. data/lib/sass/tree/media_node.rb +58 -0
  94. data/lib/sass/tree/mixin_def_node.rb +38 -0
  95. data/lib/sass/tree/mixin_node.rb +39 -0
  96. data/lib/sass/tree/node.rb +196 -0
  97. data/lib/sass/tree/prop_node.rb +152 -0
  98. data/lib/sass/tree/return_node.rb +18 -0
  99. data/lib/sass/tree/root_node.rb +78 -0
  100. data/lib/sass/tree/rule_node.rb +132 -0
  101. data/lib/sass/tree/supports_node.rb +51 -0
  102. data/lib/sass/tree/trace_node.rb +32 -0
  103. data/lib/sass/tree/variable_node.rb +30 -0
  104. data/lib/sass/tree/visitors/base.rb +75 -0
  105. data/lib/sass/tree/visitors/check_nesting.rb +147 -0
  106. data/lib/sass/tree/visitors/convert.rb +316 -0
  107. data/lib/sass/tree/visitors/cssize.rb +241 -0
  108. data/lib/sass/tree/visitors/deep_copy.rb +102 -0
  109. data/lib/sass/tree/visitors/extend.rb +68 -0
  110. data/lib/sass/tree/visitors/perform.rb +446 -0
  111. data/lib/sass/tree/visitors/set_options.rb +125 -0
  112. data/lib/sass/tree/visitors/to_css.rb +228 -0
  113. data/lib/sass/tree/warn_node.rb +18 -0
  114. data/lib/sass/tree/while_node.rb +18 -0
  115. data/lib/sass/util/multibyte_string_scanner.rb +155 -0
  116. data/lib/sass/util/subset_map.rb +109 -0
  117. data/lib/sass/util/test.rb +10 -0
  118. data/lib/sass/util.rb +948 -0
  119. data/lib/sass/version.rb +126 -0
  120. data/lib/sass.rb +95 -0
  121. data/rails/init.rb +1 -0
  122. data/test/Gemfile +3 -0
  123. data/test/Gemfile.lock +10 -0
  124. data/test/sass/cache_test.rb +89 -0
  125. data/test/sass/callbacks_test.rb +61 -0
  126. data/test/sass/conversion_test.rb +1760 -0
  127. data/test/sass/css2sass_test.rb +458 -0
  128. data/test/sass/data/hsl-rgb.txt +319 -0
  129. data/test/sass/engine_test.rb +3244 -0
  130. data/test/sass/exec_test.rb +86 -0
  131. data/test/sass/extend_test.rb +1482 -0
  132. data/test/sass/fixtures/test_staleness_check_across_importers.css +1 -0
  133. data/test/sass/fixtures/test_staleness_check_across_importers.scss +1 -0
  134. data/test/sass/functions_test.rb +1139 -0
  135. data/test/sass/importer_test.rb +192 -0
  136. data/test/sass/logger_test.rb +58 -0
  137. data/test/sass/mock_importer.rb +49 -0
  138. data/test/sass/more_results/more1.css +9 -0
  139. data/test/sass/more_results/more1_with_line_comments.css +26 -0
  140. data/test/sass/more_results/more_import.css +29 -0
  141. data/test/sass/more_templates/_more_partial.sass +2 -0
  142. data/test/sass/more_templates/more1.sass +23 -0
  143. data/test/sass/more_templates/more_import.sass +11 -0
  144. data/test/sass/plugin_test.rb +564 -0
  145. data/test/sass/results/alt.css +4 -0
  146. data/test/sass/results/basic.css +9 -0
  147. data/test/sass/results/cached_import_option.css +3 -0
  148. data/test/sass/results/compact.css +5 -0
  149. data/test/sass/results/complex.css +86 -0
  150. data/test/sass/results/compressed.css +1 -0
  151. data/test/sass/results/expanded.css +19 -0
  152. data/test/sass/results/filename_fn.css +3 -0
  153. data/test/sass/results/if.css +3 -0
  154. data/test/sass/results/import.css +31 -0
  155. data/test/sass/results/import_charset.css +5 -0
  156. data/test/sass/results/import_charset_1_8.css +5 -0
  157. data/test/sass/results/import_charset_ibm866.css +5 -0
  158. data/test/sass/results/import_content.css +1 -0
  159. data/test/sass/results/line_numbers.css +49 -0
  160. data/test/sass/results/mixins.css +95 -0
  161. data/test/sass/results/multiline.css +24 -0
  162. data/test/sass/results/nested.css +22 -0
  163. data/test/sass/results/options.css +1 -0
  164. data/test/sass/results/parent_ref.css +13 -0
  165. data/test/sass/results/script.css +16 -0
  166. data/test/sass/results/scss_import.css +31 -0
  167. data/test/sass/results/scss_importee.css +2 -0
  168. data/test/sass/results/subdir/nested_subdir/nested_subdir.css +1 -0
  169. data/test/sass/results/subdir/subdir.css +3 -0
  170. data/test/sass/results/units.css +11 -0
  171. data/test/sass/results/warn.css +0 -0
  172. data/test/sass/results/warn_imported.css +0 -0
  173. data/test/sass/script_conversion_test.rb +299 -0
  174. data/test/sass/script_test.rb +622 -0
  175. data/test/sass/scss/css_test.rb +1100 -0
  176. data/test/sass/scss/rx_test.rb +156 -0
  177. data/test/sass/scss/scss_test.rb +2106 -0
  178. data/test/sass/scss/test_helper.rb +37 -0
  179. data/test/sass/templates/_cached_import_option_partial.scss +1 -0
  180. data/test/sass/templates/_double_import_loop2.sass +1 -0
  181. data/test/sass/templates/_filename_fn_import.scss +11 -0
  182. data/test/sass/templates/_imported_charset_ibm866.sass +4 -0
  183. data/test/sass/templates/_imported_charset_utf8.sass +4 -0
  184. data/test/sass/templates/_imported_content.sass +3 -0
  185. data/test/sass/templates/_partial.sass +2 -0
  186. data/test/sass/templates/_same_name_different_partiality.scss +1 -0
  187. data/test/sass/templates/alt.sass +16 -0
  188. data/test/sass/templates/basic.sass +23 -0
  189. data/test/sass/templates/bork1.sass +2 -0
  190. data/test/sass/templates/bork2.sass +2 -0
  191. data/test/sass/templates/bork3.sass +2 -0
  192. data/test/sass/templates/bork4.sass +2 -0
  193. data/test/sass/templates/bork5.sass +3 -0
  194. data/test/sass/templates/cached_import_option.scss +3 -0
  195. data/test/sass/templates/compact.sass +17 -0
  196. data/test/sass/templates/complex.sass +305 -0
  197. data/test/sass/templates/compressed.sass +15 -0
  198. data/test/sass/templates/double_import_loop1.sass +1 -0
  199. data/test/sass/templates/expanded.sass +17 -0
  200. data/test/sass/templates/filename_fn.scss +18 -0
  201. data/test/sass/templates/if.sass +11 -0
  202. data/test/sass/templates/import.sass +12 -0
  203. data/test/sass/templates/import_charset.sass +9 -0
  204. data/test/sass/templates/import_charset_1_8.sass +6 -0
  205. data/test/sass/templates/import_charset_ibm866.sass +11 -0
  206. data/test/sass/templates/import_content.sass +4 -0
  207. data/test/sass/templates/importee.less +2 -0
  208. data/test/sass/templates/importee.sass +19 -0
  209. data/test/sass/templates/line_numbers.sass +13 -0
  210. data/test/sass/templates/mixin_bork.sass +5 -0
  211. data/test/sass/templates/mixins.sass +76 -0
  212. data/test/sass/templates/multiline.sass +20 -0
  213. data/test/sass/templates/nested.sass +25 -0
  214. data/test/sass/templates/nested_bork1.sass +2 -0
  215. data/test/sass/templates/nested_bork2.sass +2 -0
  216. data/test/sass/templates/nested_bork3.sass +2 -0
  217. data/test/sass/templates/nested_bork4.sass +2 -0
  218. data/test/sass/templates/nested_import.sass +2 -0
  219. data/test/sass/templates/nested_mixin_bork.sass +6 -0
  220. data/test/sass/templates/options.sass +2 -0
  221. data/test/sass/templates/parent_ref.sass +25 -0
  222. data/test/sass/templates/same_name_different_ext.sass +2 -0
  223. data/test/sass/templates/same_name_different_ext.scss +1 -0
  224. data/test/sass/templates/same_name_different_partiality.scss +1 -0
  225. data/test/sass/templates/script.sass +101 -0
  226. data/test/sass/templates/scss_import.scss +11 -0
  227. data/test/sass/templates/scss_importee.scss +1 -0
  228. data/test/sass/templates/single_import_loop.sass +1 -0
  229. data/test/sass/templates/subdir/import_up1.scss +1 -0
  230. data/test/sass/templates/subdir/import_up2.scss +1 -0
  231. data/test/sass/templates/subdir/nested_subdir/_nested_partial.sass +2 -0
  232. data/test/sass/templates/subdir/nested_subdir/nested_subdir.sass +3 -0
  233. data/test/sass/templates/subdir/subdir.sass +6 -0
  234. data/test/sass/templates/units.sass +11 -0
  235. data/test/sass/templates/warn.sass +3 -0
  236. data/test/sass/templates/warn_imported.sass +4 -0
  237. data/test/sass/test_helper.rb +8 -0
  238. data/test/sass/util/multibyte_string_scanner_test.rb +147 -0
  239. data/test/sass/util/subset_map_test.rb +91 -0
  240. data/test/sass/util_test.rb +382 -0
  241. data/test/test_helper.rb +80 -0
  242. metadata +354 -0
@@ -0,0 +1,382 @@
1
+ #!/usr/bin/env ruby
2
+ require File.dirname(__FILE__) + '/../test_helper'
3
+ require 'pathname'
4
+ require 'tmpdir'
5
+
6
+ class UtilTest < Test::Unit::TestCase
7
+ include Sass::Util
8
+
9
+ def test_scope
10
+ assert(File.exist?(scope("Rakefile")))
11
+ end
12
+
13
+ def test_to_hash
14
+ assert_equal({
15
+ :foo => 1,
16
+ :bar => 2,
17
+ :baz => 3
18
+ }, to_hash([[:foo, 1], [:bar, 2], [:baz, 3]]))
19
+ end
20
+
21
+ def test_map_keys
22
+ assert_equal({
23
+ "foo" => 1,
24
+ "bar" => 2,
25
+ "baz" => 3
26
+ }, map_keys({:foo => 1, :bar => 2, :baz => 3}) {|k| k.to_s})
27
+ end
28
+
29
+ def test_map_vals
30
+ assert_equal({
31
+ :foo => "1",
32
+ :bar => "2",
33
+ :baz => "3"
34
+ }, map_vals({:foo => 1, :bar => 2, :baz => 3}) {|k| k.to_s})
35
+ end
36
+
37
+ def test_map_hash
38
+ assert_equal({
39
+ "foo" => "1",
40
+ "bar" => "2",
41
+ "baz" => "3"
42
+ }, map_hash({:foo => 1, :bar => 2, :baz => 3}) {|k, v| [k.to_s, v.to_s]})
43
+ end
44
+
45
+ def test_powerset
46
+ return unless Set[Set[]] == Set[Set[]] # There's a bug in Ruby 1.8.6 that breaks nested set equality
47
+ assert_equal([[].to_set].to_set,
48
+ powerset([]))
49
+ assert_equal([[].to_set, [1].to_set].to_set,
50
+ powerset([1]))
51
+ assert_equal([[].to_set, [1].to_set, [2].to_set, [1, 2].to_set].to_set,
52
+ powerset([1, 2]))
53
+ assert_equal([[].to_set, [1].to_set, [2].to_set, [3].to_set,
54
+ [1, 2].to_set, [2, 3].to_set, [1, 3].to_set, [1, 2, 3].to_set].to_set,
55
+ powerset([1, 2, 3]))
56
+ end
57
+
58
+ def test_restrict
59
+ assert_equal(0.5, restrict(0.5, 0..1))
60
+ assert_equal(1, restrict(2, 0..1))
61
+ assert_equal(1.3, restrict(2, 0..1.3))
62
+ assert_equal(0, restrict(-1, 0..1))
63
+ end
64
+
65
+ def test_merge_adjacent_strings
66
+ assert_equal(["foo bar baz", :bang, "biz bop", 12],
67
+ merge_adjacent_strings(["foo ", "bar ", "baz", :bang, "biz", " bop", 12]))
68
+ str = "foo"
69
+ assert_equal(["foo foo foo", :bang, "foo foo", 12],
70
+ merge_adjacent_strings([str, " ", str, " ", str, :bang, str, " ", str, 12]))
71
+ end
72
+
73
+ def test_intersperse
74
+ assert_equal(["foo", " ", "bar", " ", "baz"],
75
+ intersperse(%w[foo bar baz], " "))
76
+ assert_equal([], intersperse([], " "))
77
+ end
78
+
79
+ def test_substitute
80
+ assert_equal(["foo", "bar", "baz", 3, 4],
81
+ substitute([1, 2, 3, 4], [1, 2], ["foo", "bar", "baz"]))
82
+ assert_equal([1, "foo", "bar", "baz", 4],
83
+ substitute([1, 2, 3, 4], [2, 3], ["foo", "bar", "baz"]))
84
+ assert_equal([1, 2, "foo", "bar", "baz"],
85
+ substitute([1, 2, 3, 4], [3, 4], ["foo", "bar", "baz"]))
86
+
87
+ assert_equal([1, "foo", "bar", "baz", 2, 3, 4],
88
+ substitute([1, 2, 2, 2, 3, 4], [2, 2], ["foo", "bar", "baz"]))
89
+ end
90
+
91
+ def test_strip_string_array
92
+ assert_equal(["foo ", " bar ", " baz"],
93
+ strip_string_array([" foo ", " bar ", " baz "]))
94
+ assert_equal([:foo, " bar ", " baz"],
95
+ strip_string_array([:foo, " bar ", " baz "]))
96
+ assert_equal(["foo ", " bar ", :baz],
97
+ strip_string_array([" foo ", " bar ", :baz]))
98
+ end
99
+
100
+ def test_paths
101
+ assert_equal([[1, 3, 5], [2, 3, 5], [1, 4, 5], [2, 4, 5]],
102
+ paths([[1, 2], [3, 4], [5]]))
103
+ assert_equal([[]], paths([]))
104
+ assert_equal([[1, 2, 3]], paths([[1], [2], [3]]))
105
+ end
106
+
107
+ def test_lcs
108
+ assert_equal([1, 2, 3], lcs([1, 2, 3], [1, 2, 3]))
109
+ assert_equal([], lcs([], [1, 2, 3]))
110
+ assert_equal([], lcs([1, 2, 3], []))
111
+ assert_equal([1, 2, 3], lcs([5, 1, 4, 2, 3, 17], [0, 0, 1, 2, 6, 3]))
112
+
113
+ assert_equal([1], lcs([1, 2, 3, 4], [4, 3, 2, 1]))
114
+ assert_equal([1, 2], lcs([1, 2, 3, 4], [3, 4, 1, 2]))
115
+ end
116
+
117
+ def test_lcs_with_block
118
+ assert_equal(["1", "2", "3"],
119
+ lcs([1, 4, 2, 5, 3], [1, 2, 3]) {|a, b| a == b && a.to_s})
120
+ assert_equal([-4, 2, 8],
121
+ lcs([-5, 3, 2, 8], [-4, 1, 8]) {|a, b| (a - b).abs <= 1 && [a, b].max})
122
+ end
123
+
124
+ def test_group_by_to_a
125
+ assert_equal([[1, [1, 3, 5, 7]], [0, [2, 4, 6, 8]]],
126
+ group_by_to_a(1..8) {|i| i % 2})
127
+ assert_equal([[1, [1, 4, 7, 10]], [2, [2, 5, 8, 11]], [0, [3, 6, 9, 12]]],
128
+ group_by_to_a(1..12) {|i| i % 3})
129
+ end
130
+
131
+ def test_subsequence
132
+ assert(subsequence?([1, 2, 3], [1, 2, 3]))
133
+ assert(subsequence?([1, 2, 3], [1, :a, 2, :b, 3]))
134
+ assert(subsequence?([1, 2, 3], [:a, 1, :b, :c, 2, :d, 3, :e, :f]))
135
+
136
+ assert(!subsequence?([1, 2, 3], [1, 2]))
137
+ assert(!subsequence?([1, 2, 3], [1, 3, 2]))
138
+ assert(!subsequence?([1, 2, 3], [3, 2, 1]))
139
+ end
140
+
141
+ def test_silence_warnings
142
+ old_stderr, $stderr = $stderr, StringIO.new
143
+ warn "Out"
144
+ assert_equal("Out\n", $stderr.string)
145
+ silence_warnings {warn "In"}
146
+ assert_equal("Out\n", $stderr.string)
147
+ ensure
148
+ $stderr = old_stderr
149
+ end
150
+
151
+ def test_sass_warn
152
+ assert_warning("Foo!") {sass_warn "Foo!"}
153
+ end
154
+
155
+ def test_silence_sass_warnings
156
+ old_stderr, $stderr = $stderr, StringIO.new
157
+ silence_sass_warnings {warn "Out"}
158
+ assert_equal("Out\n", $stderr.string)
159
+ silence_sass_warnings {sass_warn "In"}
160
+ assert_equal("Out\n", $stderr.string)
161
+ ensure
162
+ $stderr = old_stderr
163
+ end
164
+
165
+ def test_has
166
+ assert(has?(:instance_method, String, :chomp!))
167
+ assert(has?(:private_instance_method, Sass::Engine, :parse_interp))
168
+ end
169
+
170
+ def test_enum_with_index
171
+ assert_equal(%w[foo0 bar1 baz2],
172
+ enum_with_index(%w[foo bar baz]).map {|s, i| "#{s}#{i}"})
173
+ end
174
+
175
+ def test_enum_cons
176
+ assert_equal(%w[foobar barbaz],
177
+ enum_cons(%w[foo bar baz], 2).map {|s1, s2| "#{s1}#{s2}"})
178
+ end
179
+
180
+ def test_extract
181
+ arr = [1, 2, 3, 4, 5]
182
+ assert_equal([1, 3, 5], extract!(arr) {|e| e % 2 == 1})
183
+ assert_equal([2, 4], arr)
184
+ end
185
+
186
+ def test_ord
187
+ assert_equal(102, ord("f"))
188
+ assert_equal(98, ord("bar"))
189
+ end
190
+
191
+ def test_flatten
192
+ assert_equal([1, 2, 3], flatten([1, 2, 3], 0))
193
+ assert_equal([1, 2, 3], flatten([1, 2, 3], 1))
194
+ assert_equal([1, 2, 3], flatten([1, 2, 3], 2))
195
+
196
+ assert_equal([[1, 2], 3], flatten([[1, 2], 3], 0))
197
+ assert_equal([1, 2, 3], flatten([[1, 2], 3], 1))
198
+ assert_equal([1, 2, 3], flatten([[1, 2], 3], 2))
199
+
200
+ assert_equal([[[1], 2], [3], 4], flatten([[[1], 2], [3], 4], 0))
201
+ assert_equal([[1], 2, 3, 4], flatten([[[1], 2], [3], 4], 1))
202
+ assert_equal([1, 2, 3, 4], flatten([[[1], 2], [3], 4], 2))
203
+ end
204
+
205
+ def test_set_hash
206
+ assert(set_hash(Set[1, 2, 3]) == set_hash(Set[3, 2, 1]))
207
+ assert(set_hash(Set[1, 2, 3]) == set_hash(Set[1, 2, 3]))
208
+
209
+ s1 = Set[]
210
+ s1 << 1
211
+ s1 << 2
212
+ s1 << 3
213
+ s2 = Set[]
214
+ s2 << 3
215
+ s2 << 2
216
+ s2 << 1
217
+ assert(set_hash(s1) == set_hash(s2))
218
+ end
219
+
220
+ def test_set_eql
221
+ assert(set_eql?(Set[1, 2, 3], Set[3, 2, 1]))
222
+ assert(set_eql?(Set[1, 2, 3], Set[1, 2, 3]))
223
+
224
+ s1 = Set[]
225
+ s1 << 1
226
+ s1 << 2
227
+ s1 << 3
228
+ s2 = Set[]
229
+ s2 << 3
230
+ s2 << 2
231
+ s2 << 1
232
+ assert(set_eql?(s1, s2))
233
+ end
234
+
235
+ def test_extract_and_inject_values
236
+ test = lambda {|arr| assert_equal(arr, with_extracted_values(arr) {|str| str})}
237
+
238
+ test[['foo bar']]
239
+ test[['foo {12} bar']]
240
+ test[['foo {{12} bar']]
241
+ test[['foo {{1', 12, '2} bar']]
242
+ test[['foo 1', 2, '{3', 4, 5, 6, '{7}', 8]]
243
+ test[['foo 1', [2, 3, 4], ' bar']]
244
+ test[['foo ', 1, "\n bar\n", [2, 3, 4], "\n baz"]]
245
+ end
246
+
247
+ def nested_caller_info_fn
248
+ caller_info
249
+ end
250
+
251
+ def double_nested_caller_info_fn
252
+ nested_caller_info_fn
253
+ end
254
+
255
+ def test_caller_info
256
+ assert_equal(["/tmp/foo.rb", 12, "fizzle"], caller_info("/tmp/foo.rb:12: in `fizzle'"))
257
+ assert_equal(["/tmp/foo.rb", 12, nil], caller_info("/tmp/foo.rb:12"))
258
+ assert_equal(["(sass)", 12, "blah"], caller_info("(sass):12: in `blah'"))
259
+ assert_equal(["", 12, "boop"], caller_info(":12: in `boop'"))
260
+ assert_equal(["/tmp/foo.rb", -12, "fizzle"], caller_info("/tmp/foo.rb:-12: in `fizzle'"))
261
+ assert_equal(["/tmp/foo.rb", 12, "fizzle"], caller_info("/tmp/foo.rb:12: in `fizzle {}'"))
262
+
263
+ info = nested_caller_info_fn
264
+ assert_equal(__FILE__, info[0])
265
+ assert_equal("test_caller_info", info[2])
266
+
267
+ info = proc {nested_caller_info_fn}.call
268
+ assert_equal(__FILE__, info[0])
269
+ assert_match(/^(block in )?test_caller_info$/, info[2])
270
+
271
+ info = double_nested_caller_info_fn
272
+ assert_equal(__FILE__, info[0])
273
+ assert_equal("double_nested_caller_info_fn", info[2])
274
+
275
+ info = proc {double_nested_caller_info_fn}.call
276
+ assert_equal(__FILE__, info[0])
277
+ assert_equal("double_nested_caller_info_fn", info[2])
278
+ end
279
+
280
+ def test_version_gt
281
+ assert_version_gt("2.0.0", "1.0.0")
282
+ assert_version_gt("1.1.0", "1.0.0")
283
+ assert_version_gt("1.0.1", "1.0.0")
284
+ assert_version_gt("1.0.0", "1.0.0.rc")
285
+ assert_version_gt("1.0.0.1", "1.0.0.rc")
286
+ assert_version_gt("1.0.0.rc", "0.9.9")
287
+ assert_version_gt("1.0.0.beta", "1.0.0.alpha")
288
+
289
+ assert_version_eq("1.0.0", "1.0.0")
290
+ assert_version_eq("1.0.0", "1.0.0.0")
291
+ end
292
+
293
+ def assert_version_gt(v1, v2)
294
+ #assert(version_gt(v1, v2), "Expected #{v1} > #{v2}")
295
+ assert(!version_gt(v2, v1), "Expected #{v2} < #{v1}")
296
+ end
297
+
298
+ def assert_version_eq(v1, v2)
299
+ assert(!version_gt(v1, v2), "Expected #{v1} = #{v2}")
300
+ assert(!version_gt(v2, v1), "Expected #{v2} = #{v1}")
301
+ end
302
+
303
+ class FooBar
304
+ def foo
305
+ Sass::Util.abstract(self)
306
+ end
307
+ end
308
+
309
+ def test_abstract
310
+ assert_raise_message(NotImplementedError,
311
+ "UtilTest::FooBar must implement #foo") {FooBar.new.foo}
312
+ end
313
+
314
+ def test_atomic_writes
315
+ # when using normal writes, this test fails about 90% of the time.
316
+ filename = File.join(Dir.tmpdir, "test_atomic")
317
+ 5.times do
318
+ writes_to_perform = %w(1 2 3 4 5 6 7 8 9).map {|i| "#{i}\n" * 100_000}
319
+ threads = writes_to_perform.map do |to_write|
320
+ Thread.new do
321
+ # To see this test fail with a normal write,
322
+ # change to the standard file open mechanism:
323
+ # open(filename, "w") do |f|
324
+ atomic_create_and_write_file(filename) do |f|
325
+ f.write(to_write)
326
+ end
327
+ end
328
+ end
329
+ loop do
330
+ contents = File.exist?(filename) ? File.read(filename) : nil
331
+ next if contents.nil? || contents.size == 0
332
+ unless writes_to_perform.include?(contents)
333
+ if contents.size != writes_to_perform.first.size
334
+ fail "Incomplete write detected: was #{contents.size} characters, " +
335
+ "should have been #{writes_to_perform.first.size}"
336
+ else
337
+ fail "Corrupted read/write detected"
338
+ end
339
+ end
340
+ break if threads.all? {|t| !t.alive?}
341
+ end
342
+ threads.each {|t| t.join}
343
+ end
344
+ end
345
+
346
+ def test_atomic_write_permissions
347
+ atomic_filename = File.join(Dir.tmpdir, "test_atomic_perms.atomic")
348
+ normal_filename = File.join(Dir.tmpdir, "test_atomic_perms.normal")
349
+ atomic_create_and_write_file(atomic_filename) {|f| f.write("whatever\n") }
350
+ open(normal_filename, "wb") {|f| f.write("whatever\n") }
351
+ assert_equal File.stat(normal_filename).mode.to_s(8), File.stat(atomic_filename).mode.to_s(8)
352
+ ensure
353
+ File.unlink(atomic_filename) rescue nil
354
+ File.unlink(normal_filename) rescue nil
355
+ end
356
+
357
+ def test_atomic_writes_respect_umask
358
+ atomic_filename = File.join(Dir.tmpdir, "test_atomic_perms.atomic")
359
+ atomic_create_and_write_file(atomic_filename) do |f|
360
+ f.write("whatever\n")
361
+ end
362
+ assert_equal 0, File.stat(atomic_filename).mode & File.umask
363
+ ensure
364
+ File.unlink(atomic_filename)
365
+ end
366
+
367
+ class FakeError < RuntimeError; end
368
+
369
+ def test_atomic_writes_handles_exceptions
370
+ filename = File.join(Dir.tmpdir, "test_atomic_exception")
371
+ FileUtils.rm_f(filename)
372
+ tmp_filename = nil
373
+ assert_raises FakeError do
374
+ atomic_create_and_write_file(filename) do |f|
375
+ tmp_filename = f.path
376
+ raise FakeError.new "Borken"
377
+ end
378
+ end
379
+ assert !File.exist?(filename)
380
+ assert !File.exist?(tmp_filename)
381
+ end
382
+ end
@@ -0,0 +1,80 @@
1
+ lib_dir = File.dirname(__FILE__) + '/../lib'
2
+
3
+ require 'test/unit'
4
+ require 'fileutils'
5
+ $:.unshift lib_dir unless $:.include?(lib_dir)
6
+ require 'sass'
7
+ require 'mathn' if ENV['MATHN'] == 'true'
8
+
9
+ Sass::RAILS_LOADED = true unless defined?(Sass::RAILS_LOADED)
10
+ Encoding.default_external = 'UTF-8' if defined?(Encoding)
11
+
12
+ module Sass::Script::Functions
13
+ def option(name)
14
+ Sass::Script::String.new(@options[name.value.to_sym].to_s)
15
+ end
16
+ end
17
+
18
+ class Test::Unit::TestCase
19
+ def munge_filename(opts = {})
20
+ return if opts.has_key?(:filename)
21
+ opts[:filename] = filename_for_test(opts[:syntax] || :sass)
22
+ end
23
+
24
+ def filename_for_test(syntax = :sass)
25
+ test_name = caller.
26
+ map {|c| Sass::Util.caller_info(c)[2]}.
27
+ compact.
28
+ map {|c| c.sub(/^(block|rescue) in /, '')}.
29
+ find {|c| c =~ /^test_/}
30
+ "#{test_name}_inline.#{syntax}"
31
+ end
32
+
33
+ def clean_up_sassc
34
+ path = File.dirname(__FILE__) + "/../.sass-cache"
35
+ FileUtils.rm_r(path) if File.exist?(path)
36
+ end
37
+
38
+ def assert_warning(message)
39
+ the_real_stderr, $stderr = $stderr, StringIO.new
40
+ yield
41
+
42
+ if message.is_a?(Regexp)
43
+ assert_match message, $stderr.string.strip
44
+ else
45
+ assert_equal message.strip, $stderr.string.strip
46
+ end
47
+ ensure
48
+ $stderr = the_real_stderr
49
+ end
50
+
51
+ def assert_no_warning
52
+ the_real_stderr, $stderr = $stderr, StringIO.new
53
+ yield
54
+
55
+ assert_equal '', $stderr.string
56
+ ensure
57
+ $stderr = the_real_stderr
58
+ end
59
+
60
+ def silence_warnings(&block)
61
+ Sass::Util.silence_warnings(&block)
62
+ end
63
+
64
+ def assert_raise_message(klass, message)
65
+ yield
66
+ rescue Exception => e
67
+ assert_instance_of(klass, e)
68
+ assert_equal(message, e.message)
69
+ else
70
+ flunk "Expected exception #{klass}, none raised"
71
+ end
72
+
73
+ def assert_raise_line(line)
74
+ yield
75
+ rescue Sass::SyntaxError => e
76
+ assert_equal(line, e.sass_line)
77
+ else
78
+ flunk "Expected exception on line #{line}, none raised"
79
+ end
80
+ end