sass 3.7.4 → 4.0.0.alpha.1

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 (257) hide show
  1. checksums.yaml +13 -5
  2. data/.yardopts +1 -1
  3. data/CODE_OF_CONDUCT.md +1 -1
  4. data/CONTRIBUTING.md +1 -146
  5. data/MIT-LICENSE +1 -1
  6. data/README.md +25 -39
  7. data/Rakefile +274 -0
  8. data/VERSION +1 -1
  9. data/VERSION_DATE +1 -1
  10. data/lib/sass.rb +3 -3
  11. data/lib/sass/cache_stores/filesystem.rb +2 -2
  12. data/lib/sass/cache_stores/memory.rb +5 -4
  13. data/lib/sass/callbacks.rb +2 -2
  14. data/lib/sass/css.rb +12 -12
  15. data/lib/sass/engine.rb +44 -62
  16. data/lib/sass/environment.rb +7 -35
  17. data/lib/sass/error.rb +14 -14
  18. data/lib/sass/exec/base.rb +14 -3
  19. data/lib/sass/exec/sass_convert.rb +6 -20
  20. data/lib/sass/exec/sass_scss.rb +29 -5
  21. data/lib/sass/features.rb +2 -3
  22. data/lib/sass/importers/filesystem.rb +6 -11
  23. data/lib/sass/logger.rb +3 -8
  24. data/lib/sass/logger/base.rb +2 -19
  25. data/lib/sass/plugin.rb +2 -3
  26. data/lib/sass/plugin/compiler.rb +67 -48
  27. data/lib/sass/plugin/configuration.rb +3 -3
  28. data/lib/sass/plugin/merb.rb +1 -1
  29. data/lib/sass/plugin/rack.rb +3 -3
  30. data/lib/sass/plugin/staleness_checker.rb +3 -3
  31. data/lib/sass/railtie.rb +1 -1
  32. data/lib/sass/script.rb +3 -3
  33. data/lib/sass/script/css_parser.rb +15 -5
  34. data/lib/sass/script/functions.rb +121 -337
  35. data/lib/sass/script/lexer.rb +36 -102
  36. data/lib/sass/script/parser.rb +153 -529
  37. data/lib/sass/script/tree/funcall.rb +34 -42
  38. data/lib/sass/script/tree/interpolation.rb +26 -171
  39. data/lib/sass/script/tree/list_literal.rb +8 -23
  40. data/lib/sass/script/tree/map_literal.rb +2 -2
  41. data/lib/sass/script/tree/node.rb +3 -3
  42. data/lib/sass/script/tree/operation.rb +16 -43
  43. data/lib/sass/script/tree/string_interpolation.rb +43 -64
  44. data/lib/sass/script/tree/variable.rb +1 -1
  45. data/lib/sass/script/value.rb +0 -2
  46. data/lib/sass/script/value/arg_list.rb +1 -1
  47. data/lib/sass/script/value/base.rb +9 -27
  48. data/lib/sass/script/value/color.rb +18 -26
  49. data/lib/sass/script/value/helpers.rb +18 -44
  50. data/lib/sass/script/value/list.rb +14 -35
  51. data/lib/sass/script/value/map.rb +2 -2
  52. data/lib/sass/script/value/number.rb +16 -26
  53. data/lib/sass/script/value/string.rb +1 -30
  54. data/lib/sass/scss.rb +2 -0
  55. data/lib/sass/scss/css_parser.rb +3 -7
  56. data/lib/sass/scss/parser.rb +78 -196
  57. data/lib/sass/scss/rx.rb +14 -7
  58. data/lib/sass/scss/script_lexer.rb +15 -0
  59. data/lib/sass/scss/script_parser.rb +25 -0
  60. data/lib/sass/scss/static_parser.rb +55 -38
  61. data/lib/sass/selector.rb +10 -7
  62. data/lib/sass/selector/abstract_sequence.rb +12 -15
  63. data/lib/sass/selector/comma_sequence.rb +6 -24
  64. data/lib/sass/selector/pseudo.rb +6 -19
  65. data/lib/sass/selector/sequence.rb +16 -14
  66. data/lib/sass/selector/simple.rb +7 -9
  67. data/lib/sass/selector/simple_sequence.rb +12 -16
  68. data/lib/sass/shared.rb +1 -1
  69. data/lib/sass/source/map.rb +9 -7
  70. data/lib/sass/source/position.rb +4 -4
  71. data/lib/sass/stack.rb +3 -23
  72. data/lib/sass/tree/charset_node.rb +1 -1
  73. data/lib/sass/tree/comment_node.rb +1 -1
  74. data/lib/sass/tree/function_node.rb +3 -2
  75. data/lib/sass/tree/node.rb +3 -5
  76. data/lib/sass/tree/prop_node.rb +58 -49
  77. data/lib/sass/tree/rule_node.rb +8 -15
  78. data/lib/sass/tree/visitors/check_nesting.rb +23 -19
  79. data/lib/sass/tree/visitors/convert.rb +13 -15
  80. data/lib/sass/tree/visitors/cssize.rb +15 -4
  81. data/lib/sass/tree/visitors/deep_copy.rb +2 -2
  82. data/lib/sass/tree/visitors/extend.rb +14 -10
  83. data/lib/sass/tree/visitors/perform.rb +18 -29
  84. data/lib/sass/tree/visitors/set_options.rb +2 -2
  85. data/lib/sass/tree/visitors/to_css.rb +47 -77
  86. data/lib/sass/util.rb +311 -98
  87. data/lib/sass/util/cross_platform_random.rb +19 -0
  88. data/lib/sass/util/multibyte_string_scanner.rb +133 -127
  89. data/lib/sass/util/normalized_map.rb +8 -1
  90. data/lib/sass/util/ordered_hash.rb +192 -0
  91. data/lib/sass/version.rb +6 -2
  92. data/test/sass/cache_test.rb +131 -0
  93. data/test/sass/callbacks_test.rb +61 -0
  94. data/test/sass/compiler_test.rb +236 -0
  95. data/test/sass/conversion_test.rb +2171 -0
  96. data/test/sass/css2sass_test.rb +526 -0
  97. data/test/sass/data/hsl-rgb.txt +319 -0
  98. data/test/sass/encoding_test.rb +219 -0
  99. data/test/sass/engine_test.rb +3400 -0
  100. data/test/sass/exec_test.rb +86 -0
  101. data/test/sass/extend_test.rb +1719 -0
  102. data/test/sass/fixtures/test_staleness_check_across_importers.css +1 -0
  103. data/test/sass/fixtures/test_staleness_check_across_importers.scss +1 -0
  104. data/test/sass/functions_test.rb +1984 -0
  105. data/test/sass/importer_test.rb +421 -0
  106. data/test/sass/logger_test.rb +58 -0
  107. data/test/sass/mock_importer.rb +49 -0
  108. data/test/sass/more_results/more1.css +9 -0
  109. data/test/sass/more_results/more1_with_line_comments.css +26 -0
  110. data/test/sass/more_results/more_import.css +29 -0
  111. data/test/sass/more_templates/_more_partial.sass +2 -0
  112. data/test/sass/more_templates/more1.sass +23 -0
  113. data/test/sass/more_templates/more_import.sass +11 -0
  114. data/test/sass/plugin_test.rb +556 -0
  115. data/test/sass/results/alt.css +4 -0
  116. data/test/sass/results/basic.css +9 -0
  117. data/test/sass/results/cached_import_option.css +3 -0
  118. data/test/sass/results/compact.css +5 -0
  119. data/test/sass/results/complex.css +86 -0
  120. data/test/sass/results/compressed.css +1 -0
  121. data/test/sass/results/expanded.css +19 -0
  122. data/test/sass/results/filename_fn.css +3 -0
  123. data/test/sass/results/if.css +3 -0
  124. data/test/sass/results/import.css +31 -0
  125. data/test/sass/results/import_charset.css +5 -0
  126. data/test/sass/results/import_charset_1_8.css +5 -0
  127. data/test/sass/results/import_charset_ibm866.css +5 -0
  128. data/test/sass/results/import_content.css +1 -0
  129. data/test/sass/results/line_numbers.css +49 -0
  130. data/test/sass/results/mixins.css +95 -0
  131. data/test/sass/results/multiline.css +24 -0
  132. data/test/sass/results/nested.css +22 -0
  133. data/test/sass/results/options.css +1 -0
  134. data/test/sass/results/parent_ref.css +13 -0
  135. data/test/sass/results/script.css +16 -0
  136. data/test/sass/results/scss_import.css +31 -0
  137. data/test/sass/results/scss_importee.css +2 -0
  138. data/test/sass/results/subdir/nested_subdir/nested_subdir.css +1 -0
  139. data/test/sass/results/subdir/subdir.css +3 -0
  140. data/test/sass/results/units.css +11 -0
  141. data/test/sass/results/warn.css +0 -0
  142. data/test/sass/results/warn_imported.css +0 -0
  143. data/test/sass/script_conversion_test.rb +306 -0
  144. data/test/sass/script_test.rb +1206 -0
  145. data/test/sass/scss/css_test.rb +1281 -0
  146. data/test/sass/scss/rx_test.rb +160 -0
  147. data/test/sass/scss/scss_test.rb +4147 -0
  148. data/test/sass/scss/test_helper.rb +37 -0
  149. data/test/sass/source_map_test.rb +1055 -0
  150. data/test/sass/superselector_test.rb +210 -0
  151. data/test/sass/templates/_cached_import_option_partial.scss +1 -0
  152. data/test/sass/templates/_double_import_loop2.sass +1 -0
  153. data/test/sass/templates/_filename_fn_import.scss +11 -0
  154. data/test/sass/templates/_imported_charset_ibm866.sass +4 -0
  155. data/test/sass/templates/_imported_charset_utf8.sass +4 -0
  156. data/test/sass/templates/_imported_content.sass +3 -0
  157. data/test/sass/templates/_partial.sass +2 -0
  158. data/test/sass/templates/_same_name_different_partiality.scss +1 -0
  159. data/test/sass/templates/alt.sass +16 -0
  160. data/test/sass/templates/basic.sass +23 -0
  161. data/test/sass/templates/bork1.sass +2 -0
  162. data/test/sass/templates/bork2.sass +2 -0
  163. data/test/sass/templates/bork3.sass +2 -0
  164. data/test/sass/templates/bork4.sass +2 -0
  165. data/test/sass/templates/bork5.sass +3 -0
  166. data/test/sass/templates/cached_import_option.scss +3 -0
  167. data/test/sass/templates/compact.sass +17 -0
  168. data/test/sass/templates/complex.sass +305 -0
  169. data/test/sass/templates/compressed.sass +15 -0
  170. data/test/sass/templates/double_import_loop1.sass +1 -0
  171. data/test/sass/templates/expanded.sass +17 -0
  172. data/test/sass/templates/filename_fn.scss +18 -0
  173. data/test/sass/templates/if.sass +11 -0
  174. data/test/sass/templates/import.sass +12 -0
  175. data/test/sass/templates/import_charset.sass +9 -0
  176. data/test/sass/templates/import_charset_1_8.sass +6 -0
  177. data/test/sass/templates/import_charset_ibm866.sass +11 -0
  178. data/test/sass/templates/import_content.sass +4 -0
  179. data/test/sass/templates/importee.less +2 -0
  180. data/test/sass/templates/importee.sass +19 -0
  181. data/test/sass/templates/line_numbers.sass +13 -0
  182. data/test/sass/templates/mixin_bork.sass +5 -0
  183. data/test/sass/templates/mixins.sass +76 -0
  184. data/test/sass/templates/multiline.sass +20 -0
  185. data/test/sass/templates/nested.sass +25 -0
  186. data/test/sass/templates/nested_bork1.sass +2 -0
  187. data/test/sass/templates/nested_bork2.sass +2 -0
  188. data/test/sass/templates/nested_bork3.sass +2 -0
  189. data/test/sass/templates/nested_bork4.sass +2 -0
  190. data/test/sass/templates/nested_import.sass +2 -0
  191. data/test/sass/templates/nested_mixin_bork.sass +6 -0
  192. data/test/sass/templates/options.sass +2 -0
  193. data/test/sass/templates/parent_ref.sass +25 -0
  194. data/test/sass/templates/same_name_different_ext.sass +2 -0
  195. data/test/sass/templates/same_name_different_ext.scss +1 -0
  196. data/test/sass/templates/same_name_different_partiality.scss +1 -0
  197. data/test/sass/templates/script.sass +101 -0
  198. data/test/sass/templates/scss_import.scss +12 -0
  199. data/test/sass/templates/scss_importee.scss +1 -0
  200. data/test/sass/templates/single_import_loop.sass +1 -0
  201. data/test/sass/templates/subdir/import_up1.scss +1 -0
  202. data/test/sass/templates/subdir/import_up2.scss +1 -0
  203. data/test/sass/templates/subdir/nested_subdir/_nested_partial.sass +2 -0
  204. data/test/sass/templates/subdir/nested_subdir/nested_subdir.sass +3 -0
  205. data/test/sass/templates/subdir/subdir.sass +6 -0
  206. data/test/sass/templates/units.sass +11 -0
  207. data/test/sass/templates/warn.sass +3 -0
  208. data/test/sass/templates/warn_imported.sass +4 -0
  209. data/test/sass/test_helper.rb +8 -0
  210. data/test/sass/util/multibyte_string_scanner_test.rb +147 -0
  211. data/test/sass/util/normalized_map_test.rb +51 -0
  212. data/test/sass/util/subset_map_test.rb +91 -0
  213. data/test/sass/util_test.rb +438 -0
  214. data/test/sass/value_helpers_test.rb +179 -0
  215. data/test/test_helper.rb +110 -0
  216. data/vendor/listen/CHANGELOG.md +1 -0
  217. data/vendor/listen/CONTRIBUTING.md +38 -0
  218. data/vendor/listen/Gemfile +20 -0
  219. data/vendor/listen/Guardfile +8 -0
  220. data/vendor/listen/LICENSE +20 -0
  221. data/vendor/listen/README.md +349 -0
  222. data/vendor/listen/Rakefile +5 -0
  223. data/vendor/listen/Vagrantfile +96 -0
  224. data/vendor/listen/lib/listen.rb +54 -0
  225. data/vendor/listen/lib/listen/adapter.rb +327 -0
  226. data/vendor/listen/lib/listen/adapters/bsd.rb +75 -0
  227. data/vendor/listen/lib/listen/adapters/darwin.rb +48 -0
  228. data/vendor/listen/lib/listen/adapters/linux.rb +81 -0
  229. data/vendor/listen/lib/listen/adapters/polling.rb +58 -0
  230. data/vendor/listen/lib/listen/adapters/windows.rb +91 -0
  231. data/vendor/listen/lib/listen/directory_record.rb +406 -0
  232. data/vendor/listen/lib/listen/listener.rb +323 -0
  233. data/vendor/listen/lib/listen/turnstile.rb +32 -0
  234. data/vendor/listen/lib/listen/version.rb +3 -0
  235. data/vendor/listen/listen.gemspec +28 -0
  236. data/vendor/listen/spec/listen/adapter_spec.rb +149 -0
  237. data/vendor/listen/spec/listen/adapters/bsd_spec.rb +36 -0
  238. data/vendor/listen/spec/listen/adapters/darwin_spec.rb +37 -0
  239. data/vendor/listen/spec/listen/adapters/linux_spec.rb +47 -0
  240. data/vendor/listen/spec/listen/adapters/polling_spec.rb +68 -0
  241. data/vendor/listen/spec/listen/adapters/windows_spec.rb +30 -0
  242. data/vendor/listen/spec/listen/directory_record_spec.rb +1250 -0
  243. data/vendor/listen/spec/listen/listener_spec.rb +258 -0
  244. data/vendor/listen/spec/listen/turnstile_spec.rb +56 -0
  245. data/vendor/listen/spec/listen_spec.rb +67 -0
  246. data/vendor/listen/spec/spec_helper.rb +25 -0
  247. data/vendor/listen/spec/support/adapter_helper.rb +666 -0
  248. data/vendor/listen/spec/support/directory_record_helper.rb +57 -0
  249. data/vendor/listen/spec/support/fixtures_helper.rb +29 -0
  250. data/vendor/listen/spec/support/listeners_helper.rb +179 -0
  251. data/vendor/listen/spec/support/platform_helper.rb +15 -0
  252. metadata +217 -76
  253. data/extra/sass-spec-ref.sh +0 -40
  254. data/lib/sass/deprecation.rb +0 -55
  255. data/lib/sass/logger/delayed.rb +0 -50
  256. data/lib/sass/script/value/callable.rb +0 -25
  257. data/lib/sass/script/value/function.rb +0 -19
@@ -0,0 +1,179 @@
1
+ #!/usr/bin/env ruby
2
+ require File.dirname(__FILE__) + '/../test_helper'
3
+
4
+ class ValueHelpersTest < MiniTest::Test
5
+ include Sass::Script
6
+ include Sass::Script::Value::Helpers
7
+
8
+ def test_bool
9
+ assert_same Value::Bool::TRUE, bool(true)
10
+ assert_same Value::Bool::FALSE, bool(false)
11
+ assert_same Value::Bool::FALSE, bool(nil)
12
+ assert_same Value::Bool::TRUE, bool(Object.new)
13
+ end
14
+
15
+ def test_hex_color_with_three_digits
16
+ color = hex_color("F07")
17
+ assert_equal 255, color.red
18
+ assert_equal 0, color.green
19
+ assert_equal 119, color.blue
20
+ assert_equal 1, color.alpha
21
+ end
22
+
23
+ def test_hex_color_without_hash
24
+ color_without_hash = hex_color("FF007F")
25
+ assert_equal 255, color_without_hash.red
26
+ assert_equal 0, color_without_hash.green
27
+ assert_equal 127, color_without_hash.blue
28
+ assert_equal 1, color_without_hash.alpha
29
+ end
30
+
31
+ def test_hex_color_with_hash
32
+ color_with_hash = hex_color("#FF007F")
33
+ assert_equal 255, color_with_hash.red
34
+ assert_equal 0, color_with_hash.green
35
+ assert_equal 127, color_with_hash.blue
36
+ assert_equal 1, color_with_hash.alpha
37
+ end
38
+
39
+ def test_malformed_hex_color
40
+ assert_raises ArgumentError do
41
+ hex_color("green")
42
+ end
43
+ assert_raises ArgumentError do
44
+ hex_color("#abcd")
45
+ end
46
+ end
47
+
48
+
49
+ def test_hex_color_with_alpha
50
+ color_with_alpha = hex_color("FF007F", 0.5)
51
+ assert_equal 0.5, color_with_alpha.alpha
52
+ end
53
+
54
+ def test_hex_color_alpha_clamps_0_to_1
55
+ assert_equal 1, hex_color("FF007F", 50).alpha
56
+ end
57
+
58
+ def test_hsl_color_without_alpha
59
+ no_alpha = hsl_color(1, 0.5, 1)
60
+ assert_equal 1, no_alpha.hue
61
+ assert_equal 0.5, no_alpha.saturation
62
+ assert_equal 1, no_alpha.lightness
63
+ assert_equal 1, no_alpha.alpha
64
+ end
65
+
66
+ def test_hsl_color_with_alpha
67
+ has_alpha = hsl_color(1, 0.5, 1, 0.5)
68
+ assert_equal 1, has_alpha.hue
69
+ assert_equal 0.5, has_alpha.saturation
70
+ assert_equal 1, has_alpha.lightness
71
+ assert_equal 0.5, has_alpha.alpha
72
+ end
73
+
74
+ def test_rgb_color_without_alpha
75
+ no_alpha = rgb_color(255, 0, 0)
76
+ assert_equal 255, no_alpha.red
77
+ assert_equal 0, no_alpha.green
78
+ assert_equal 0, no_alpha.blue
79
+ assert_equal 1, no_alpha.alpha
80
+ end
81
+
82
+ def test_rgb_color_with_alpha
83
+ has_alpha = rgb_color(255, 255, 255, 0.5)
84
+ assert_equal 255, has_alpha.red
85
+ assert_equal 255, has_alpha.green
86
+ assert_equal 255, has_alpha.blue
87
+ assert_equal 0.5, has_alpha.alpha
88
+ end
89
+
90
+ def test_number
91
+ n = number(1)
92
+ assert_equal 1, n.value
93
+ assert_equal "1", n.to_sass
94
+ end
95
+
96
+ def test_number_with_single_unit
97
+ n = number(1, "px")
98
+ assert_equal 1, n.value
99
+ assert_equal "1px", n.to_sass
100
+ end
101
+
102
+ def test_number_with_singal_numerator_and_denominator
103
+ ratio = number(1, "px/em")
104
+ assert_equal "1px/em", ratio.to_sass
105
+ end
106
+
107
+ def test_number_with_many_numerator_and_denominator_units
108
+ complex = number(1, "px*in/em*%")
109
+ assert_equal "1in*px/%*em", complex.to_sass
110
+ end
111
+
112
+ def test_number_with_many_numerator_and_denominator_units_with_spaces
113
+ complex = number(1, "px * in / em * %")
114
+ assert_equal "1in*px/%*em", complex.to_sass
115
+ end
116
+
117
+ def test_number_with_malformed_units
118
+ assert_raises ArgumentError do
119
+ number(1, "px/em/%")
120
+ end
121
+ assert_raises ArgumentError do
122
+ number(1, "/")
123
+ end
124
+ assert_raises ArgumentError do
125
+ number(1, "px/")
126
+ end
127
+ end
128
+
129
+ def test_space_list
130
+ l = list(number(1, "px"), hex_color("#f71"), :space)
131
+ l.options = {}
132
+ assert_kind_of Sass::Script::Value::List, l
133
+ assert_equal "1px #f71", l.to_sass
134
+ end
135
+
136
+ def test_comma_list
137
+ l = list(number(1, "px"), hex_color("#f71"), :comma)
138
+ l.options = {}
139
+ assert_kind_of Sass::Script::Value::List, l
140
+ assert_equal "1px, #f71", l.to_sass
141
+ end
142
+
143
+ def test_missing_list_type
144
+ assert_raises ArgumentError do
145
+ list(number(1, "px"), hex_color("#f71"))
146
+ end
147
+ end
148
+
149
+ def test_null
150
+ assert_kind_of Sass::Script::Value::Null, null
151
+ end
152
+
153
+ def test_quoted_string
154
+ s = quoted_string("sassy string")
155
+ s.options = {}
156
+ assert_kind_of Sass::Script::Value::String, s
157
+ assert_equal "sassy string", s.value
158
+ assert_equal :string, s.type
159
+ assert_equal '"sassy string"', s.to_sass
160
+ end
161
+
162
+ def test_identifier
163
+ s = identifier("a-sass-ident")
164
+ s.options = {}
165
+ assert_kind_of Sass::Script::Value::String, s
166
+ assert_equal "a-sass-ident", s.value
167
+ assert_equal :identifier, s.type
168
+ assert_equal "a-sass-ident", s.to_sass
169
+ end
170
+
171
+ def test_unquoted_string
172
+ s = unquoted_string("a-sass-ident")
173
+ s.options = {}
174
+ assert_kind_of Sass::Script::Value::String, s
175
+ assert_equal "a-sass-ident", s.value
176
+ assert_equal :identifier, s.type
177
+ assert_equal "a-sass-ident", s.to_sass
178
+ end
179
+ end
@@ -0,0 +1,110 @@
1
+ lib_dir = File.dirname(__FILE__) + '/../lib'
2
+
3
+ require 'minitest/autorun'
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
+
11
+ Sass.tests_running = true
12
+
13
+ if defined?(Encoding)
14
+ $-w, w = false, $-w
15
+ Encoding.default_external = 'UTF-8'
16
+ $-w = w
17
+ end
18
+
19
+ module Sass::Script::Functions
20
+ def option(name)
21
+ Sass::Script::Value::String.new(@options[name.value.to_sym].to_s)
22
+ end
23
+ end
24
+
25
+ class MiniTest::Test
26
+ def munge_filename(opts = {})
27
+ opts[:filename] ||= filename_for_test(opts[:syntax] || :sass)
28
+ opts[:sourcemap_filename] ||= sourcemap_filename_for_test
29
+ opts
30
+ end
31
+
32
+ def test_name
33
+ caller.
34
+ map {|c| Sass::Util.caller_info(c)[2]}.
35
+ compact.
36
+ map {|c| c.sub(/^(block|rescue) in /, '')}.
37
+ find {|c| c =~ /^test_/}
38
+ end
39
+
40
+ def filename_for_test(syntax = :sass)
41
+ "#{test_name}_inline.#{syntax}"
42
+ end
43
+
44
+ def sourcemap_filename_for_test(syntax = :sass)
45
+ "#{test_name}_inline.css.map"
46
+ end
47
+
48
+ def clean_up_sassc
49
+ path = File.dirname(__FILE__) + "/../.sass-cache"
50
+ Sass::Util.retry_on_windows {FileUtils.rm_r(path) if File.exist?(path)}
51
+ end
52
+
53
+ def assert_warning(message)
54
+ the_real_stderr, $stderr = $stderr, StringIO.new
55
+ result = yield
56
+
57
+ if message.is_a?(Regexp)
58
+ assert_match message, $stderr.string.strip
59
+ else
60
+ assert_equal message.strip, $stderr.string.strip
61
+ end
62
+ result
63
+ ensure
64
+ $stderr = the_real_stderr
65
+ end
66
+
67
+ def assert_no_warning
68
+ the_real_stderr, $stderr = $stderr, StringIO.new
69
+ result = yield
70
+ assert_equal '', $stderr.string
71
+ result
72
+ ensure
73
+ $stderr = the_real_stderr
74
+ end
75
+
76
+ def silence_warnings(&block)
77
+ Sass::Util.silence_warnings(&block)
78
+ end
79
+
80
+ def assert_raise_message(klass, message)
81
+ yield
82
+ rescue Exception => e
83
+ assert_instance_of(klass, e)
84
+ assert_equal(message, e.message)
85
+ else
86
+ flunk "Expected exception #{klass}, none raised"
87
+ end
88
+
89
+ def assert_raise_line(line)
90
+ yield
91
+ rescue Sass::SyntaxError => e
92
+ assert_equal(line, e.sass_line)
93
+ else
94
+ flunk "Expected exception on line #{line}, none raised"
95
+ end
96
+ end
97
+
98
+ module PublicApiLinter
99
+ def lint_api(api_class, duck_type_class)
100
+ define_method :test_lint_instance do
101
+ assert lint_instance.is_a?(duck_type_class)
102
+ end
103
+ api_class.instance_methods.each do |meth|
104
+ define_method :"test_has_#{meth}" do
105
+ assert lint_instance.respond_to?(meth),
106
+ "#{duck_type_class.name} does not implement #{meth}"
107
+ end
108
+ end
109
+ end
110
+ end
@@ -0,0 +1 @@
1
+ # Moved to [Github releases](https://github.com/guard/listen/releases) page.
@@ -0,0 +1,38 @@
1
+ Contribute to Listen
2
+ ===================
3
+
4
+ File an issue
5
+ -------------
6
+
7
+ You can report bugs and feature requests to [GitHub Issues](https://github.com/guard/listen/issues).
8
+
9
+ **Please don't ask question in the issue tracker**, instead ask them in our
10
+ [Google group](http://groups.google.com/group/guard-dev) or on `#guard` (irc.freenode.net).
11
+
12
+ Try to figure out where the issue belongs to: Is it an issue with Listen itself or with Guard?
13
+
14
+ When you file a bug, please try to follow these simple rules if applicable:
15
+
16
+ * Make sure you run Listen with `bundle exec` first.
17
+ * Add your `Guardfile` (if used) and `Gemfile` to the issue.
18
+ * Make sure that the issue is reproducible with your description.
19
+
20
+ **It's most likely that your bug gets resolved faster if you provide as much information as possible!**
21
+
22
+ Development
23
+ -----------
24
+
25
+ * Documentation hosted at [RubyDoc](http://rubydoc.info/github/guard/listen/master/frames).
26
+ * Source hosted at [GitHub](https://github.com/guard/listen).
27
+
28
+ Pull requests are very welcome! Please try to follow these simple rules if applicable:
29
+
30
+ * Please create a topic branch for every separate change you make.
31
+ * Make sure your patches are well tested. All specs run with `rake spec` must pass.
32
+ * Update the [Yard](http://yardoc.org/) documentation.
33
+ * Update the [README](https://github.com/guard/listen/blob/master/README.md).
34
+ * Update the [CHANGELOG](https://github.com/guard/listen/blob/master/CHANGELOG.md) for noteworthy changes.
35
+ * Please **do not change** the version number.
36
+
37
+ For questions please join us in our [Google group](http://groups.google.com/group/guard-dev) or on
38
+ `#guard` (irc.freenode.net).
@@ -0,0 +1,20 @@
1
+ source 'https://rubygems.org'
2
+
3
+ gemspec
4
+
5
+ gem 'rake'
6
+
7
+ require 'rbconfig'
8
+ gem 'wdm', '>= 0.1.0' if RbConfig::CONFIG['target_os'] =~ /mswin|mingw/i
9
+
10
+ group :development do
11
+ gem 'guard-rspec'
12
+ gem 'yard'
13
+ gem 'redcarpet'
14
+ gem 'pimpmychangelog'
15
+ end
16
+
17
+ group :test do
18
+ gem 'rspec'
19
+ gem 'coveralls', :require => false
20
+ end
@@ -0,0 +1,8 @@
1
+ guard :rspec, :all_on_start => false, :all_after_pass => false do
2
+ watch(%r{^spec/.+_spec\.rb$})
3
+ watch(%r{^lib/(.+)\.rb$}) { |m| "spec/#{m[1]}_spec.rb" }
4
+ watch('spec/support/adapter_helper.rb') { "spec/listen/adapters" }
5
+ watch('spec/support/listener_helper.rb') { "spec/listen/listener_spec.rb" }
6
+ watch('spec/support/fixtures_helper.rb') { "spec" }
7
+ watch('spec/spec_helper.rb') { "spec" }
8
+ end
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2013 Thibaud Guillaume-Gentil
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,349 @@
1
+ # Listen [![Gem Version](https://badge.fury.io/rb/listen.png)](http://badge.fury.io/rb/listen) [![Build Status](https://secure.travis-ci.org/guard/listen.png?branch=master)](http://travis-ci.org/guard/listen) [![Dependency Status](https://gemnasium.com/guard/listen.png)](https://gemnasium.com/guard/listen) [![Code Climate](https://codeclimate.com/github/guard/listen.png)](https://codeclimate.com/github/guard/listen) [![Coverage Status](https://coveralls.io/repos/guard/listen/badge.png?branch=master)](https://coveralls.io/r/guard/listen)
2
+
3
+ The Listen gem listens to file modifications and notifies you about the changes.
4
+
5
+ ## Features
6
+
7
+ * Works everywhere!
8
+ * Supports watching multiple directories from a single listener.
9
+ * OS-specific adapters for Mac OS X 10.6+, Linux, *BSD and Windows.
10
+ * Automatic fallback to polling if OS-specific adapter doesn't work.
11
+ * Detects file modification, addition and removal.
12
+ * File content checksum comparison for modifications made under the same second.
13
+ * Allows supplying regexp-patterns to ignore and filter paths for better results.
14
+ * Tested on all Ruby environments via [Travis CI](https://travis-ci.org/guard/listen).
15
+
16
+ ## Pending features
17
+
18
+ Still not implemented, pull requests are welcome.
19
+
20
+ * Symlinks support. [#25](https://github.com/guard/listen/issues/25)
21
+ * Signal handling. [#105](https://github.com/guard/listen/issues/105)
22
+ * Non-recursive directory scanning. [#111](https://github.com/guard/listen/issues/111)
23
+
24
+ ## Install
25
+
26
+ ### Using Bundler
27
+
28
+ The simplest way to install Listen is to use Bundler.
29
+
30
+ Add Listen to your Gemfile:
31
+
32
+ ```ruby
33
+ group :development do
34
+ gem 'listen'
35
+ end
36
+ ```
37
+
38
+ and install it by running Bundler:
39
+
40
+ ```bash
41
+ $ bundle
42
+ ```
43
+
44
+ ### Install the gem with RubyGems
45
+
46
+ ```bash
47
+ $ gem install listen
48
+ ```
49
+
50
+ ### On Windows
51
+
52
+ If your are on Windows and using Ruby MRI >= 1.9.2 you can try to use the [`wdm`](https://github.com/Maher4Ever/wdm) instead of polling.
53
+ Please add the following to your Gemfile:
54
+
55
+ ```ruby
56
+ require 'rbconfig'
57
+ gem 'wdm', '>= 0.1.0' if RbConfig::CONFIG['target_os'] =~ /mswin|mingw/i
58
+ ```
59
+
60
+ ## Usage
61
+
62
+ There are **two ways** to use Listen:
63
+
64
+ 1. Block API: Call `Listen.to`/`Listen.to!` with either a single directory or multiple directories, then define the `change` callback in a block.
65
+ 2. "Object" API: Create a `listener` object and use it in a chainable way.
66
+
67
+ ### Block API
68
+
69
+ ``` ruby
70
+ # Listen to a single directory.
71
+ Listen.to('dir/path/to/listen', :filter => /\.rb$/, :ignore => %r{ignored/path/}) do |modified, added, removed|
72
+ # ...
73
+ end
74
+
75
+ # Listen to multiple directories.
76
+ Listen.to('dir/to/awesome_app', 'dir/to/other_app', :filter => /\.rb$/, :latency => 0.1) do |modified, added, removed|
77
+ # ...
78
+ end
79
+ ```
80
+
81
+ ### "Object" API
82
+
83
+ ``` ruby
84
+ listener = Listen.to('dir/path/to/listen')
85
+ listener = listener.ignore(%r{^ignored/path/})
86
+ listener = listener.filter(/\.rb$/)
87
+ listener = listener.latency(0.5)
88
+ listener = listener.force_polling(true)
89
+ listener = listener.polling_fallback_message(false)
90
+ listener = listener.force_adapter(Listen::Adapters::Linux)
91
+ listener = listener.change(&callback)
92
+ listener.start
93
+ ```
94
+
95
+ **Note**: All the "Object" API methods except `start`/`start!` return the listener
96
+ and are thus chainable:
97
+
98
+ ``` ruby
99
+ Listen.to('dir/path/to/listen')
100
+ .ignore(%r{^ignored/path/})
101
+ .filter(/\.rb$/)
102
+ .latency(0.5)
103
+ .force_polling(true)
104
+ .polling_fallback_message('custom message')
105
+ .change(&callback)
106
+ .start
107
+ ```
108
+
109
+ ### Pause/Unpause
110
+
111
+ Listener can also easily be paused/unpaused:
112
+
113
+ ``` ruby
114
+ listener = Listen.to('dir/path/to/listen')
115
+ listener.start # non-blocking mode
116
+ listener.pause # stop listening to changes
117
+ listener.paused? # => true
118
+ listener.unpause # start listening to changes again
119
+ listener.stop # stop completely the listener
120
+ ```
121
+
122
+ ## Changes callback
123
+
124
+ Changes to the listened-to directories gets reported back to the user in a callback.
125
+ The registered callback gets invoked, when there are changes, with **three** parameters:
126
+ `modified_paths`, `added_paths` and `removed_paths` in that particular order.
127
+
128
+ You can register a callback in two ways. The first way is by passing a block when calling
129
+ the `Listen.to`/`Listen.to!` method or when initializing a listener object:
130
+
131
+ ```ruby
132
+ Listen.to('path/to/app') do |modified, added, removed|
133
+ # This block will be called when there are changes.
134
+ end
135
+
136
+ # or ...
137
+
138
+ listener = Listen::Listener.new('path/to/app') do |modified, added, removed|
139
+ # This block will be called when there are changes.
140
+ end
141
+
142
+ ```
143
+
144
+ The second way to register a callback is by calling the `#change` method on a
145
+ listener passing it a block:
146
+
147
+ ```ruby
148
+ # Create a callback
149
+ callback = Proc.new do |modified, added, removed|
150
+ # This proc will be called when there are changes.
151
+ end
152
+
153
+ listener = Listen.to('dir')
154
+ listener.change(&callback) # convert the callback to a block and register it
155
+
156
+ listener.start
157
+ ```
158
+
159
+ ### Paths in callbacks
160
+
161
+ Listeners invoke callbacks passing them absolute paths by default:
162
+
163
+ ```ruby
164
+ # Assume someone changes the 'style.css' file in '/home/user/app/css' after creating
165
+ # the listener.
166
+ Listen.to('/home/user/app/css') do |modified, added, removed|
167
+ modified.inspect # => ['/home/user/app/css/style.css']
168
+ end
169
+ ```
170
+
171
+ #### Relative paths in callbacks
172
+
173
+ When creating a listener for a **single** path (more specifically a `Listen::Listener` instance),
174
+ you can pass `:relative_paths => true` as an option to get relative paths in
175
+ your callback:
176
+
177
+ ```ruby
178
+ # Assume someone changes the 'style.css' file in '/home/user/app/css' after creating
179
+ # the listener.
180
+ Listen.to('/home/user/app/css', :relative_paths => true) do |modified, added, removed|
181
+ modified.inspect # => ['style.css']
182
+ end
183
+ ```
184
+
185
+ Passing the `:relative_paths => true` option won't work when listening to multiple
186
+ directories:
187
+
188
+ ```ruby
189
+ # Assume someone changes the 'style.css' file in '/home/user/app/css' after creating
190
+ # the listener.
191
+ Listen.to('/home/user/app/css', '/home/user/app/js', :relative_paths => true) do |modified, added, removed|
192
+ modified.inspect # => ['/home/user/app/css/style.css']
193
+ end
194
+ ```
195
+
196
+ ## Options
197
+
198
+ All the following options can be set through the `Listen.to`/`Listen.to!` params
199
+ or via ["Object" API](#object-api) methods:
200
+
201
+ ```ruby
202
+ :ignore => %r{app/CMake/}, /\.pid$/ # Ignore a list of paths (root directory or sub-dir)
203
+ # default: See DEFAULT_IGNORED_DIRECTORIES and DEFAULT_IGNORED_EXTENSIONS in Listen::DirectoryRecord
204
+
205
+ :filter => /\.rb$/, /\.coffee$/ # Filter files to listen to via a regexps list.
206
+ # default: none
207
+
208
+ :latency => 0.5 # Set the delay (**in seconds**) between checking for changes
209
+ # default: 0.25 sec (1.0 sec for polling)
210
+
211
+ :force_adapter => Listen::Adapters::Linux # Force the use of a particular adapter class
212
+ # default: none
213
+
214
+ :force_polling => true # Force the use of the polling adapter
215
+ # default: none
216
+
217
+ :polling_fallback_message => 'custom message' # Set a custom polling fallback message (or disable it with false)
218
+ # default: "Listen will be polling for changes. Learn more at https://github.com/guard/listen#polling-fallback."
219
+
220
+ :relative_paths => true # Enable the use of relative paths in the callback.
221
+ # default: false
222
+ ```
223
+
224
+ ### Note on the patterns for ignoring and filtering paths
225
+
226
+ Just like the unix convention of beginning absolute paths with the
227
+ directory-separator (forward slash `/` in unix) and with no prefix for relative paths,
228
+ Listen doesn't prefix relative paths (to the watched directory) with a directory-separator.
229
+
230
+ Therefore make sure _NOT_ to prefix your regexp-patterns for filtering or ignoring paths
231
+ with a directory-separator, otherwise they won't work as expected.
232
+
233
+ As an example: to ignore the `build` directory in a C-project, use `%r{build/}`
234
+ and not `%r{/build/}`.
235
+
236
+ Use `#filter!` and `#ignore!` methods to overwrites default patterns.
237
+
238
+ ## Blocking listening to changes
239
+
240
+ Calling `Listen.to` with a block doesn't block the current thread. If you want
241
+ to block the current thread instead until the listener is stopped (which needs
242
+ to be done from another thread), you can use `Listen.to!`.
243
+
244
+ Similarly, if you're using the "Object" API, you can use `#start!` instead of `#start` to block the
245
+ current thread until the listener is stopped.
246
+
247
+ Here is an example of using a listener in the blocking mode:
248
+
249
+ ```ruby
250
+ Listen.to!('dir/path/to/listen') # block execution
251
+
252
+ # Code here will not run until the listener is stopped
253
+
254
+ ```
255
+
256
+ Here is an example of using a listener started with the "Object" API in blocking mode:
257
+
258
+ ```ruby
259
+ listener = Listen.to('dir/path/to/listen')
260
+ listener.start! # block execution
261
+
262
+ # Code here will not run until the listener is stopped
263
+
264
+ ```
265
+
266
+ **Note**: Using the `Listen.to!` helper-method with or without a callback-block
267
+ will always start the listener right away and block execution of the current thread.
268
+
269
+ ## Listen adapters
270
+
271
+ The Listen gem has a set of adapters to notify it when there are changes.
272
+ There are 4 OS-specific adapters to support Mac, Linux, *BSD and Windows.
273
+ These adapters are fast as they use some system-calls to implement the notifying function.
274
+
275
+ There is also a polling adapter which is a cross-platform adapter and it will
276
+ work on any system. This adapter is unfortunately slower than the rest of the adapters.
277
+
278
+ The Listen gem will choose the best and working adapter for your machine automatically. If you
279
+ want to force the use of the polling adapter, either use the `:force_polling` option
280
+ while initializing the listener or call the `#force_polling` method on your listener
281
+ before starting it.
282
+
283
+ It is also possible to force the use of a particular adapter, by using the `:force_adapter`
284
+ option. This option skips the usual adapter choosing mechanism and uses the given
285
+ adapter class instead. The adapter choosing mechanism requires write permission
286
+ to your watched directories and will needlessly load code, which isn't always desirable.
287
+
288
+ ## Polling fallback
289
+
290
+ When a OS-specific adapter doesn't work the Listen gem automatically falls back to the polling adapter.
291
+ Here are some things you could try to avoid the polling fallback:
292
+
293
+ * [Update your Dropbox client](http://www.dropbox.com/downloading) (if used).
294
+ * Increase latency. (Please [open an issue](https://github.com/guard/listen/issues/new)
295
+ if you think that default is too low.)
296
+ * Move or rename the listened folder.
297
+ * Update/reboot your OS.
298
+
299
+ If your application keeps using the polling-adapter and you can't figure out why, feel free to [open an issue](https://github.com/guard/listen/issues/new) (and be sure to [give all the details](https://github.com/guard/listen/blob/master/CONTRIBUTING.md)).
300
+
301
+ ## Development [![Dependency Status](https://gemnasium.com/guard/listen.png?branch=master)](https://gemnasium.com/guard/listen)
302
+
303
+ * Documentation hosted at [RubyDoc](http://rubydoc.info/github/guard/listen/master/frames).
304
+ * Source hosted at [GitHub](https://github.com/guard/listen).
305
+
306
+ Pull requests are very welcome! Please try to follow these simple rules if applicable:
307
+
308
+ * Please create a topic branch for every separate change you make.
309
+ * Make sure your patches are well tested. All specs must pass on [Travis CI](https://travis-ci.org/guard/listen).
310
+ * Update the [Yard](http://yardoc.org/) documentation.
311
+ * Update the [README](https://github.com/guard/listen/blob/master/README.md).
312
+ * Update the [CHANGELOG](https://github.com/guard/listen/blob/master/CHANGELOG.md) for noteworthy changes (don't forget to run `bundle exec pimpmychangelog` and watch the magic happen)!
313
+ * Please **do not change** the version number.
314
+
315
+ For questions please join us in our [Google group](http://groups.google.com/group/guard-dev) or on
316
+ `#guard` (irc.freenode.net).
317
+
318
+ ## Acknowledgments
319
+
320
+ * [Michael Kessler (netzpirat)][] for having written the [initial specs](https://github.com/guard/listen/commit/1e457b13b1bb8a25d2240428ce5ed488bafbed1f).
321
+ * [Travis Tilley (ttilley)][] for this awesome work on [fssm][] & [rb-fsevent][].
322
+ * [Nathan Weizenbaum (nex3)][] for [rb-inotify][], a thorough inotify wrapper.
323
+ * [Mathieu Arnold (mat813)][] for [rb-kqueue][], a simple kqueue wrapper.
324
+ * [stereobooster][] for [rb-fchange][], windows support wouldn't exist without him.
325
+ * [Yehuda Katz (wycats)][] for [vigilo][], that has been a great source of inspiration.
326
+
327
+ ## Authors
328
+
329
+ * [Thibaud Guillaume-Gentil][] ([@thibaudgg](http://twitter.com/thibaudgg))
330
+ * [Maher Sallam][] ([@mahersalam](http://twitter.com/mahersalam))
331
+
332
+ ## Contributors
333
+
334
+ [https://github.com/guard/listen/contributors](https://github.com/guard/listen/contributors)
335
+
336
+ [Thibaud Guillaume-Gentil]: https://github.com/thibaudgg
337
+ [Maher Sallam]: https://github.com/Maher4Ever
338
+ [Michael Kessler (netzpirat)]: https://github.com/netzpirat
339
+ [Travis Tilley (ttilley)]: https://github.com/ttilley
340
+ [fssm]: https://github.com/ttilley/fssm
341
+ [rb-fsevent]: https://github.com/thibaudgg/rb-fsevent
342
+ [Mathieu Arnold (mat813)]: https://github.com/mat813
343
+ [Nathan Weizenbaum (nex3)]: https://github.com/nex3
344
+ [rb-inotify]: https://github.com/nex3/rb-inotify
345
+ [stereobooster]: https://github.com/stereobooster
346
+ [rb-fchange]: https://github.com/stereobooster/rb-fchange
347
+ [rb-kqueue]: https://github.com/mat813/rb-kqueue
348
+ [Yehuda Katz (wycats)]: https://github.com/wycats
349
+ [vigilo]: https://github.com/wycats/vigilo