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
@@ -8,7 +8,7 @@ module Sass
8
8
  # if it was installed from Git.
9
9
  module Version
10
10
  # Returns a hash representing the version of Sass.
11
- # The `:major`, `:minor`, and `:teeny` keys have their respective numbers as Integers.
11
+ # The `:major`, `:minor`, and `:teeny` keys have their respective numbers as Fixnums.
12
12
  # The `:name` key has the name of the version.
13
13
  # The `:string` key contains a human-readable string representation of the version.
14
14
  # The `:number` key is the major, minor, and teeny keys separated by periods.
@@ -41,7 +41,9 @@ module Sass
41
41
  # :prerelease_number => 1
42
42
  # }
43
43
  #
44
- # @return [{Symbol => String/Integer}] The version hash
44
+ # @return [{Symbol => String/Fixnum}] The version hash
45
+ # @comment
46
+ # rubocop:disable ClassVars
45
47
  def version
46
48
  return @@version if defined?(@@version)
47
49
 
@@ -75,8 +77,10 @@ module Sass
75
77
  end
76
78
  end
77
79
 
80
+ @@version[:string] << " (#{name})"
78
81
  @@version
79
82
  end
83
+ # rubocop:enable ClassVars
80
84
 
81
85
  private
82
86
 
@@ -0,0 +1,131 @@
1
+ #!/usr/bin/env ruby
2
+ require File.dirname(__FILE__) + '/../test_helper'
3
+ require File.dirname(__FILE__) + '/test_helper'
4
+ require 'sass/engine'
5
+
6
+ class CacheTest < MiniTest::Test
7
+ @@cache_dir = "tmp/file_cache"
8
+
9
+ def setup
10
+ FileUtils.mkdir_p @@cache_dir
11
+ end
12
+
13
+ def teardown
14
+ FileUtils.rm_rf @@cache_dir
15
+ clean_up_sassc
16
+ end
17
+
18
+ def test_file_cache_writes_a_file
19
+ file_store = Sass::CacheStores::Filesystem.new(@@cache_dir)
20
+ file_store.store("asdf/foo.scssc", "fakesha1", root_node)
21
+ assert File.exist?("#{@@cache_dir}/asdf/foo.scssc")
22
+ end
23
+
24
+ def test_file_cache_reads_a_file
25
+ file_store = Sass::CacheStores::Filesystem.new(@@cache_dir)
26
+ assert !File.exist?("#{@@cache_dir}/asdf/foo.scssc")
27
+ file_store.store("asdf/foo.scssc", "fakesha1", root_node)
28
+ assert File.exist?("#{@@cache_dir}/asdf/foo.scssc")
29
+ assert_kind_of Sass::Tree::RootNode, file_store.retrieve("asdf/foo.scssc", "fakesha1")
30
+ end
31
+
32
+ def test_file_cache_miss_returns_nil
33
+ file_store = Sass::CacheStores::Filesystem.new(@@cache_dir)
34
+ assert !File.exist?("#{@@cache_dir}/asdf/foo.scssc")
35
+ assert_nil file_store.retrieve("asdf/foo.scssc", "fakesha1")
36
+ end
37
+
38
+ def test_sha_change_invalidates_cache_and_cleans_up
39
+ file_store = Sass::CacheStores::Filesystem.new(@@cache_dir)
40
+ assert !File.exist?("#{@@cache_dir}/asdf/foo.scssc")
41
+ file_store.store("asdf/foo.scssc", "fakesha1", root_node)
42
+ assert File.exist?("#{@@cache_dir}/asdf/foo.scssc")
43
+ assert_nil file_store.retrieve("asdf/foo.scssc", "differentsha1")
44
+ assert !File.exist?("#{@@cache_dir}/asdf/foo.scssc")
45
+ end
46
+
47
+ def test_version_change_invalidates_cache_and_cleans_up
48
+ file_store = Sass::CacheStores::Filesystem.new(@@cache_dir)
49
+ assert !File.exist?("#{@@cache_dir}/asdf/foo.scssc")
50
+ file_store.store("asdf/foo.scssc", "fakesha1", root_node)
51
+ assert File.exist?("#{@@cache_dir}/asdf/foo.scssc")
52
+ real_version = Sass::VERSION
53
+ begin
54
+ Sass::VERSION.replace("a different version")
55
+ assert_nil file_store.retrieve("asdf/foo.scssc", "fakesha1")
56
+ assert !File.exist?("#{@@cache_dir}/asdf/foo.scssc")
57
+ ensure
58
+ Sass::VERSION.replace(real_version)
59
+ end
60
+ end
61
+
62
+ def test_arbitrary_objects_can_go_into_cache
63
+ cache = Sass::CacheStores::Memory.new
64
+ an_object = {:foo => :bar}
65
+ cache.store("an_object", "", an_object)
66
+ assert_equal an_object, cache.retrieve("an_object", "")
67
+ end
68
+
69
+ def test_cache_node_with_unmarshalable_option
70
+ engine_with_unmarshalable_options("foo {a: b + c}").to_tree
71
+ end
72
+
73
+ # Regression tests
74
+
75
+ def test_cache_mixin_def_splat_sass_node_with_unmarshalable_option
76
+ engine_with_unmarshalable_options(<<SASS, :syntax => :sass).to_tree
77
+ =color($args...)
78
+ color: red
79
+ SASS
80
+ end
81
+
82
+ def test_cache_mixin_def_splat_scss_node_with_unmarshalable_option
83
+ engine_with_unmarshalable_options(<<SCSS, :syntax => :scss).to_tree
84
+ @mixin color($args...) {
85
+ color: red;
86
+ }
87
+ SCSS
88
+ end
89
+
90
+ def test_cache_function_splat_sass_node_with_unmarshalable_option
91
+ engine_with_unmarshalable_options(<<SASS, :syntax => :sass).to_tree
92
+ @function color($args...)
93
+ @return red
94
+ SASS
95
+ end
96
+
97
+ def test_cache_function_splat_scss_node_with_unmarshalable_option
98
+ engine_with_unmarshalable_options(<<SCSS, :syntax => :scss).to_tree
99
+ @function color($args...) {
100
+ @return red;
101
+ }
102
+ SCSS
103
+ end
104
+
105
+ def test_cache_include_splat_sass_node_with_unmarshalable_option
106
+ engine_with_unmarshalable_options(<<SASS, :syntax => :sass).to_tree
107
+ @include color($args..., $kwargs...)
108
+ SASS
109
+ end
110
+
111
+ def test_cache_include_splat_scss_node_with_unmarshalable_option
112
+ engine_with_unmarshalable_options(<<SCSS, :syntax => :scss).to_tree
113
+ @include color($args..., $kwargs...);
114
+ SCSS
115
+ end
116
+
117
+ private
118
+ def root_node
119
+ Sass::Engine.new(<<-SCSS, :syntax => :scss).to_tree
120
+ @mixin color($c) { color: $c}
121
+ div { @include color(red); }
122
+ SCSS
123
+ end
124
+
125
+ def engine_with_unmarshalable_options(src, options={})
126
+ Sass::Engine.new(src, {
127
+ :syntax => :scss, :object => Class.new.new, :filename => 'file.scss',
128
+ :importer => Sass::Importers::Filesystem.new(absolutize('templates'))
129
+ }.merge(options))
130
+ end
131
+ end
@@ -0,0 +1,61 @@
1
+ #!/usr/bin/env ruby
2
+ require File.dirname(__FILE__) + '/../test_helper'
3
+ require 'sass/callbacks'
4
+
5
+ class CallerBack
6
+ extend Sass::Callbacks
7
+ define_callback :foo
8
+ define_callback :bar
9
+
10
+ def do_foo
11
+ run_foo
12
+ end
13
+
14
+ def do_bar
15
+ run_bar 12
16
+ end
17
+ end
18
+
19
+ module ClassLevelCallerBack
20
+ extend Sass::Callbacks
21
+ define_callback :foo
22
+ extend self
23
+
24
+ def do_foo
25
+ run_foo
26
+ end
27
+ end
28
+
29
+ class SassCallbacksTest < MiniTest::Test
30
+ def test_simple_callback
31
+ cb = CallerBack.new
32
+ there = false
33
+ cb.on_foo {there = true}
34
+ cb.do_foo
35
+ assert there, "Expected callback to be called."
36
+ end
37
+
38
+ def test_multiple_callbacks
39
+ cb = CallerBack.new
40
+ str = ""
41
+ cb.on_foo {str += "first"}
42
+ cb.on_foo {str += " second"}
43
+ cb.do_foo
44
+ assert_equal "first second", str
45
+ end
46
+
47
+ def test_callback_with_arg
48
+ cb = CallerBack.new
49
+ val = nil
50
+ cb.on_bar {|a| val = a}
51
+ cb.do_bar
52
+ assert_equal 12, val
53
+ end
54
+
55
+ def test_class_level_callback
56
+ there = false
57
+ ClassLevelCallerBack.on_foo {there = true}
58
+ ClassLevelCallerBack.do_foo
59
+ assert there, "Expected callback to be called."
60
+ end
61
+ end
@@ -0,0 +1,236 @@
1
+ #!/usr/bin/env ruby
2
+ require 'minitest/autorun'
3
+ require File.dirname(__FILE__) + '/../test_helper'
4
+ require 'sass/plugin'
5
+ require 'sass/plugin/compiler'
6
+
7
+ class CompilerTest < MiniTest::Test
8
+ class FakeListener
9
+ attr_accessor :options
10
+ attr_accessor :directories
11
+ attr_reader :start_called
12
+ attr_reader :thread
13
+
14
+ def initialize(*args, &on_filesystem_event)
15
+ self.options = args.last.is_a?(Hash) ? args.pop : {}
16
+ self.directories = args
17
+ @on_filesystem_event = on_filesystem_event
18
+ @start_called = false
19
+ reset_events!
20
+ end
21
+
22
+ def fire_events!(*args)
23
+ @on_filesystem_event.call(@modified, @added, @removed)
24
+ reset_events!
25
+ end
26
+
27
+ def changed(filename)
28
+ @modified << File.expand_path(filename)
29
+ end
30
+
31
+ def added(filename)
32
+ @added << File.expand_path(filename)
33
+ end
34
+
35
+ def removed(filename)
36
+ @removed << File.expand_path(filename)
37
+ end
38
+
39
+ def on_start!(&run_during_start)
40
+ @run_during_start = run_during_start
41
+ end
42
+
43
+ # used for Listen < 2.0
44
+ def start!
45
+ @run_during_start.call(self) if @run_during_start
46
+ end
47
+
48
+ # used for Listen >= 2.0
49
+ def start
50
+ parent = Thread.current
51
+ @thread = Thread.new do
52
+ @run_during_start.call(self) if @run_during_start
53
+ parent.raise Interrupt
54
+ end
55
+ end
56
+
57
+ def stop
58
+ end
59
+
60
+ def reset_events!
61
+ @modified = []
62
+ @added = []
63
+ @removed = []
64
+ end
65
+ end
66
+
67
+ module MockWatcher
68
+ attr_accessor :run_during_start
69
+ attr_accessor :update_stylesheets_times
70
+ attr_accessor :update_stylesheets_called_with
71
+ attr_accessor :deleted_css_files
72
+
73
+ def fake_listener
74
+ @fake_listener
75
+ end
76
+
77
+ def update_stylesheets(individual_files)
78
+ @update_stylesheets_times ||= 0
79
+ @update_stylesheets_times += 1
80
+ (@update_stylesheets_called_with ||= []) << individual_files
81
+ end
82
+
83
+ def try_delete_css(css_filename)
84
+ (@deleted_css_files ||= []) << css_filename
85
+ end
86
+
87
+ private
88
+ def create_listener(*args, &on_filesystem_event)
89
+ if Sass::Util.listen_geq_2?
90
+ options = args.pop if args.last.is_a?(Hash)
91
+ args.map do |dir|
92
+ @fake_listener = FakeListener.new(*args, &on_filesystem_event)
93
+ @fake_listener.on_start!(&run_during_start)
94
+ @fake_listener
95
+ end
96
+ else
97
+ @fake_listener = FakeListener.new(*args, &on_filesystem_event)
98
+ @fake_listener.on_start!(&run_during_start)
99
+ @fake_listener
100
+ end
101
+ end
102
+ end
103
+
104
+ def test_initialize
105
+ watcher
106
+ end
107
+
108
+ def test_watch_starts_the_listener
109
+ start_called = false
110
+ c = watcher do |listener|
111
+ start_called = true
112
+ end
113
+ c.watch
114
+ assert start_called, "start! was not called"
115
+ end
116
+
117
+ def test_sass_callbacks_fire_from_listener_events
118
+ c = watcher do |listener|
119
+ listener.changed "changed.scss"
120
+ listener.added "added.scss"
121
+ listener.removed "removed.scss"
122
+ listener.fire_events!
123
+ end
124
+
125
+ modified_fired = false
126
+ c.on_template_modified do |sass_file|
127
+ modified_fired = true
128
+ assert_equal "changed.scss", sass_file
129
+ end
130
+
131
+ added_fired = false
132
+ c.on_template_created do |sass_file|
133
+ added_fired = true
134
+ assert_equal "added.scss", sass_file
135
+ end
136
+
137
+ removed_fired = false
138
+ c.on_template_deleted do |sass_file|
139
+ removed_fired = true
140
+ assert_equal "removed.scss", sass_file
141
+ end
142
+
143
+ c.watch
144
+
145
+ assert_equal 2, c.update_stylesheets_times
146
+ assert modified_fired
147
+ assert added_fired
148
+ assert removed_fired
149
+ end
150
+
151
+ def test_removing_a_sass_file_removes_corresponding_css_file
152
+ c = watcher do |listener|
153
+ listener.removed "remove_me.scss"
154
+ listener.fire_events!
155
+ end
156
+
157
+ c.watch
158
+
159
+ assert_equal "./remove_me.css", c.deleted_css_files.first
160
+ end
161
+
162
+ def test_an_importer_can_watch_an_image
163
+ image_importer = Sass::Importers::Filesystem.new(".")
164
+ class << image_importer
165
+ def watched_file?(filename)
166
+ filename =~ /\.png$/
167
+ end
168
+ end
169
+ c = watcher(:load_paths => [image_importer]) do |listener|
170
+ listener.changed "image.png"
171
+ listener.fire_events!
172
+ end
173
+
174
+ modified_fired = false
175
+ c.on_template_modified do |f|
176
+ modified_fired = true
177
+ assert_equal "image.png", f
178
+ end
179
+
180
+ c.watch
181
+
182
+ assert_equal 2, c.update_stylesheets_times
183
+ assert modified_fired
184
+ end
185
+
186
+ def test_watching_specific_files_and_one_is_deleted
187
+ directories = nil
188
+ c = watcher do |listener|
189
+ directories = listener.directories
190
+ listener.removed File.expand_path("./foo.scss")
191
+ listener.fire_events!
192
+ end
193
+ c.watch([[File.expand_path("./foo.scss"), File.expand_path("./foo.css"), nil]])
194
+ assert directories.include?(File.expand_path(".")), directories.inspect
195
+ assert_equal File.expand_path("./foo.css"), c.deleted_css_files.first, "the corresponding css file was not deleted"
196
+ assert_equal [], c.update_stylesheets_called_with[1], "the sass file should not have been compiled"
197
+ end
198
+
199
+ def test_watched_directories_are_dedupped
200
+ directories = nil
201
+ c = watcher(:load_paths => [".", "./foo", "."]) do |listener|
202
+ directories = listener.directories
203
+ end
204
+ c.watch
205
+ assert_equal [File.expand_path(".")], directories
206
+ end
207
+
208
+ def test_a_changed_css_in_a_watched_directory_does_not_force_a_compile
209
+ c = watcher do |listener|
210
+ listener.changed "foo.css"
211
+ listener.fire_events!
212
+ end
213
+
214
+ c.on_template_modified do |f|
215
+ assert false, "Should not have been called"
216
+ end
217
+
218
+ c.watch
219
+
220
+ assert_equal 1, c.update_stylesheets_times
221
+ end
222
+
223
+ private
224
+
225
+ def default_options
226
+ {:template_location => [[".","."]]}
227
+ end
228
+
229
+ def watcher(options = {}, &run_during_start)
230
+ options = default_options.merge(options)
231
+ watcher = Sass::Plugin::Compiler.new(options)
232
+ watcher.extend(MockWatcher)
233
+ watcher.run_during_start = run_during_start
234
+ watcher
235
+ end
236
+ end