haml 3.1.0.alpha.14 → 3.1.0.alpha.17

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of haml might be problematic. Click here for more details.

Files changed (222) hide show
  1. data/EDGE_GEM_VERSION +1 -1
  2. data/VERSION +1 -1
  3. data/lib/haml.rb +3 -2
  4. data/lib/haml/exec.rb +0 -226
  5. data/lib/sass.rb +8 -0
  6. data/lib/sass/plugin.rb +8 -0
  7. data/lib/sass/rails2_shim.rb +9 -0
  8. data/lib/sass/rails3_shim.rb +16 -0
  9. data/vendor/sass/CONTRIBUTING +3 -0
  10. data/vendor/sass/MIT-LICENSE +20 -0
  11. data/vendor/sass/README.md +201 -0
  12. data/vendor/sass/Rakefile +363 -0
  13. data/vendor/sass/TODO +39 -0
  14. data/vendor/sass/VERSION +1 -0
  15. data/vendor/sass/VERSION_NAME +1 -0
  16. data/vendor/sass/bin/css2sass +13 -0
  17. data/vendor/sass/bin/sass +8 -0
  18. data/vendor/sass/bin/sass-convert +7 -0
  19. data/vendor/sass/doc-src/FAQ.md +35 -0
  20. data/vendor/sass/doc-src/INDENTED_SYNTAX.md +210 -0
  21. data/vendor/sass/doc-src/SASS_CHANGELOG.md +1878 -0
  22. data/vendor/sass/doc-src/SASS_REFERENCE.md +1713 -0
  23. data/vendor/sass/doc-src/SCSS_FOR_SASS_USERS.md +155 -0
  24. data/vendor/sass/ext/extconf.rb +10 -0
  25. data/vendor/sass/extra/update_watch.rb +13 -0
  26. data/vendor/sass/init.rb +18 -0
  27. data/vendor/sass/lib/sass.rb +71 -0
  28. data/vendor/sass/lib/sass/cache_store.rb +208 -0
  29. data/vendor/sass/lib/sass/callbacks.rb +66 -0
  30. data/vendor/sass/lib/sass/css.rb +294 -0
  31. data/vendor/sass/lib/sass/engine.rb +792 -0
  32. data/vendor/sass/lib/sass/environment.rb +143 -0
  33. data/vendor/sass/lib/sass/error.rb +201 -0
  34. data/vendor/sass/lib/sass/exec.rb +619 -0
  35. data/vendor/sass/lib/sass/importers.rb +22 -0
  36. data/vendor/sass/lib/sass/importers/base.rb +138 -0
  37. data/vendor/sass/lib/sass/importers/filesystem.rb +121 -0
  38. data/vendor/sass/lib/sass/less.rb +363 -0
  39. data/vendor/sass/lib/sass/plugin.rb +126 -0
  40. data/vendor/sass/lib/sass/plugin/compiler.rb +346 -0
  41. data/vendor/sass/lib/sass/plugin/configuration.rb +123 -0
  42. data/vendor/sass/lib/sass/plugin/generic.rb +15 -0
  43. data/vendor/sass/lib/sass/plugin/merb.rb +48 -0
  44. data/vendor/sass/lib/sass/plugin/rack.rb +47 -0
  45. data/vendor/sass/lib/sass/plugin/rails.rb +41 -0
  46. data/vendor/sass/lib/sass/plugin/staleness_checker.rb +145 -0
  47. data/vendor/sass/lib/sass/railtie.rb +8 -0
  48. data/vendor/sass/lib/sass/repl.rb +58 -0
  49. data/vendor/sass/lib/sass/root.rb +7 -0
  50. data/vendor/sass/lib/sass/script.rb +63 -0
  51. data/vendor/sass/lib/sass/script/bool.rb +18 -0
  52. data/vendor/sass/lib/sass/script/color.rb +491 -0
  53. data/vendor/sass/lib/sass/script/css_lexer.rb +29 -0
  54. data/vendor/sass/lib/sass/script/css_parser.rb +31 -0
  55. data/vendor/sass/lib/sass/script/funcall.rb +76 -0
  56. data/vendor/sass/lib/sass/script/functions.rb +852 -0
  57. data/vendor/sass/lib/sass/script/interpolation.rb +70 -0
  58. data/vendor/sass/lib/sass/script/lexer.rb +337 -0
  59. data/vendor/sass/lib/sass/script/literal.rb +236 -0
  60. data/vendor/sass/lib/sass/script/node.rb +112 -0
  61. data/vendor/sass/lib/sass/script/number.rb +423 -0
  62. data/vendor/sass/lib/sass/script/operation.rb +90 -0
  63. data/vendor/sass/lib/sass/script/parser.rb +392 -0
  64. data/vendor/sass/lib/sass/script/string.rb +67 -0
  65. data/vendor/sass/lib/sass/script/string_interpolation.rb +93 -0
  66. data/vendor/sass/lib/sass/script/unary_operation.rb +57 -0
  67. data/vendor/sass/lib/sass/script/variable.rb +48 -0
  68. data/vendor/sass/lib/sass/scss.rb +17 -0
  69. data/vendor/sass/lib/sass/scss/css_parser.rb +51 -0
  70. data/vendor/sass/lib/sass/scss/parser.rb +838 -0
  71. data/vendor/sass/lib/sass/scss/rx.rb +126 -0
  72. data/vendor/sass/lib/sass/scss/sass_parser.rb +11 -0
  73. data/vendor/sass/lib/sass/scss/script_lexer.rb +15 -0
  74. data/vendor/sass/lib/sass/scss/script_parser.rb +25 -0
  75. data/vendor/sass/lib/sass/scss/static_parser.rb +40 -0
  76. data/vendor/sass/lib/sass/selector.rb +361 -0
  77. data/vendor/sass/lib/sass/selector/abstract_sequence.rb +62 -0
  78. data/vendor/sass/lib/sass/selector/comma_sequence.rb +82 -0
  79. data/vendor/sass/lib/sass/selector/sequence.rb +236 -0
  80. data/vendor/sass/lib/sass/selector/simple.rb +113 -0
  81. data/vendor/sass/lib/sass/selector/simple_sequence.rb +135 -0
  82. data/vendor/sass/lib/sass/shared.rb +78 -0
  83. data/vendor/sass/lib/sass/tree/comment_node.rb +128 -0
  84. data/vendor/sass/lib/sass/tree/debug_node.rb +36 -0
  85. data/vendor/sass/lib/sass/tree/directive_node.rb +75 -0
  86. data/vendor/sass/lib/sass/tree/extend_node.rb +65 -0
  87. data/vendor/sass/lib/sass/tree/for_node.rb +67 -0
  88. data/vendor/sass/lib/sass/tree/if_node.rb +81 -0
  89. data/vendor/sass/lib/sass/tree/import_node.rb +124 -0
  90. data/vendor/sass/lib/sass/tree/mixin_def_node.rb +60 -0
  91. data/vendor/sass/lib/sass/tree/mixin_node.rb +123 -0
  92. data/vendor/sass/lib/sass/tree/node.rb +490 -0
  93. data/vendor/sass/lib/sass/tree/prop_node.rb +220 -0
  94. data/vendor/sass/lib/sass/tree/root_node.rb +125 -0
  95. data/vendor/sass/lib/sass/tree/rule_node.rb +273 -0
  96. data/vendor/sass/lib/sass/tree/variable_node.rb +39 -0
  97. data/vendor/sass/lib/sass/tree/warn_node.rb +42 -0
  98. data/vendor/sass/lib/sass/tree/while_node.rb +48 -0
  99. data/vendor/sass/lib/sass/util.rb +700 -0
  100. data/vendor/sass/lib/sass/util/subset_map.rb +101 -0
  101. data/vendor/sass/lib/sass/version.rb +109 -0
  102. data/vendor/sass/rails/init.rb +1 -0
  103. data/vendor/sass/sass.gemspec +32 -0
  104. data/vendor/sass/test/sass/cache_test.rb +74 -0
  105. data/vendor/sass/test/sass/callbacks_test.rb +61 -0
  106. data/vendor/sass/test/sass/conversion_test.rb +1210 -0
  107. data/vendor/sass/test/sass/css2sass_test.rb +364 -0
  108. data/vendor/sass/test/sass/data/hsl-rgb.txt +319 -0
  109. data/vendor/sass/test/sass/engine_test.rb +2305 -0
  110. data/vendor/sass/test/sass/extend_test.rb +1348 -0
  111. data/vendor/sass/test/sass/functions_test.rb +565 -0
  112. data/vendor/sass/test/sass/importer_test.rb +104 -0
  113. data/vendor/sass/test/sass/less_conversion_test.rb +632 -0
  114. data/vendor/sass/test/sass/mock_importer.rb +49 -0
  115. data/vendor/sass/test/sass/more_results/more1.css +9 -0
  116. data/vendor/sass/test/sass/more_results/more1_with_line_comments.css +26 -0
  117. data/vendor/sass/test/sass/more_results/more_import.css +29 -0
  118. data/vendor/sass/test/sass/more_templates/_more_partial.sass +2 -0
  119. data/vendor/sass/test/sass/more_templates/more1.sass +23 -0
  120. data/vendor/sass/test/sass/more_templates/more_import.sass +11 -0
  121. data/vendor/sass/test/sass/plugin_test.rb +430 -0
  122. data/vendor/sass/test/sass/results/alt.css +4 -0
  123. data/vendor/sass/test/sass/results/basic.css +9 -0
  124. data/vendor/sass/test/sass/results/compact.css +5 -0
  125. data/vendor/sass/test/sass/results/complex.css +86 -0
  126. data/vendor/sass/test/sass/results/compressed.css +1 -0
  127. data/vendor/sass/test/sass/results/expanded.css +19 -0
  128. data/vendor/sass/test/sass/results/import.css +31 -0
  129. data/vendor/sass/test/sass/results/line_numbers.css +49 -0
  130. data/vendor/sass/test/sass/results/mixins.css +95 -0
  131. data/vendor/sass/test/sass/results/multiline.css +24 -0
  132. data/vendor/sass/test/sass/results/nested.css +22 -0
  133. data/vendor/sass/test/sass/results/options.css +1 -0
  134. data/vendor/sass/test/sass/results/parent_ref.css +13 -0
  135. data/vendor/sass/test/sass/results/script.css +16 -0
  136. data/vendor/sass/test/sass/results/scss_import.css +31 -0
  137. data/vendor/sass/test/sass/results/scss_importee.css +2 -0
  138. data/vendor/sass/test/sass/results/subdir/nested_subdir/nested_subdir.css +1 -0
  139. data/vendor/sass/test/sass/results/subdir/subdir.css +3 -0
  140. data/vendor/sass/test/sass/results/units.css +11 -0
  141. data/vendor/sass/test/sass/results/warn.css +0 -0
  142. data/vendor/sass/test/sass/results/warn_imported.css +0 -0
  143. data/vendor/sass/test/sass/script_conversion_test.rb +254 -0
  144. data/vendor/sass/test/sass/script_test.rb +470 -0
  145. data/vendor/sass/test/sass/scss/css_test.rb +897 -0
  146. data/vendor/sass/test/sass/scss/rx_test.rb +156 -0
  147. data/vendor/sass/test/sass/scss/scss_test.rb +1088 -0
  148. data/vendor/sass/test/sass/scss/test_helper.rb +37 -0
  149. data/vendor/sass/test/sass/templates/_partial.sass +2 -0
  150. data/vendor/sass/test/sass/templates/alt.sass +16 -0
  151. data/vendor/sass/test/sass/templates/basic.sass +23 -0
  152. data/vendor/sass/test/sass/templates/bork1.sass +2 -0
  153. data/vendor/sass/test/sass/templates/bork2.sass +2 -0
  154. data/vendor/sass/test/sass/templates/bork3.sass +2 -0
  155. data/vendor/sass/test/sass/templates/bork4.sass +2 -0
  156. data/vendor/sass/test/sass/templates/compact.sass +17 -0
  157. data/vendor/sass/test/sass/templates/complex.sass +305 -0
  158. data/vendor/sass/test/sass/templates/compressed.sass +15 -0
  159. data/vendor/sass/test/sass/templates/expanded.sass +17 -0
  160. data/vendor/sass/test/sass/templates/import.sass +12 -0
  161. data/vendor/sass/test/sass/templates/importee.less +2 -0
  162. data/vendor/sass/test/sass/templates/importee.sass +19 -0
  163. data/vendor/sass/test/sass/templates/line_numbers.sass +13 -0
  164. data/vendor/sass/test/sass/templates/mixin_bork.sass +5 -0
  165. data/vendor/sass/test/sass/templates/mixins.sass +76 -0
  166. data/vendor/sass/test/sass/templates/multiline.sass +20 -0
  167. data/vendor/sass/test/sass/templates/nested.sass +25 -0
  168. data/vendor/sass/test/sass/templates/nested_bork1.sass +2 -0
  169. data/vendor/sass/test/sass/templates/nested_bork2.sass +2 -0
  170. data/vendor/sass/test/sass/templates/nested_bork3.sass +2 -0
  171. data/vendor/sass/test/sass/templates/nested_bork4.sass +2 -0
  172. data/vendor/sass/test/sass/templates/nested_mixin_bork.sass +6 -0
  173. data/vendor/sass/test/sass/templates/options.sass +2 -0
  174. data/vendor/sass/test/sass/templates/parent_ref.sass +25 -0
  175. data/vendor/sass/test/sass/templates/script.sass +101 -0
  176. data/vendor/sass/test/sass/templates/scss_import.scss +11 -0
  177. data/vendor/sass/test/sass/templates/scss_importee.scss +1 -0
  178. data/vendor/sass/test/sass/templates/subdir/nested_subdir/_nested_partial.sass +2 -0
  179. data/vendor/sass/test/sass/templates/subdir/nested_subdir/nested_subdir.sass +3 -0
  180. data/vendor/sass/test/sass/templates/subdir/subdir.sass +6 -0
  181. data/vendor/sass/test/sass/templates/units.sass +11 -0
  182. data/vendor/sass/test/sass/templates/warn.sass +3 -0
  183. data/vendor/sass/test/sass/templates/warn_imported.sass +4 -0
  184. data/vendor/sass/test/sass/test_helper.rb +8 -0
  185. data/vendor/sass/test/sass/util/subset_map_test.rb +91 -0
  186. data/vendor/sass/test/sass/util_test.rb +275 -0
  187. data/vendor/sass/test/test_helper.rb +64 -0
  188. data/vendor/sass/vendor/fssm/LICENSE +20 -0
  189. data/vendor/sass/vendor/fssm/README.markdown +55 -0
  190. data/vendor/sass/vendor/fssm/Rakefile +59 -0
  191. data/vendor/sass/vendor/fssm/VERSION.yml +5 -0
  192. data/vendor/sass/vendor/fssm/example.rb +9 -0
  193. data/vendor/sass/vendor/fssm/fssm.gemspec +77 -0
  194. data/vendor/sass/vendor/fssm/lib/fssm.rb +33 -0
  195. data/vendor/sass/vendor/fssm/lib/fssm/backends/fsevents.rb +36 -0
  196. data/vendor/sass/vendor/fssm/lib/fssm/backends/inotify.rb +26 -0
  197. data/vendor/sass/vendor/fssm/lib/fssm/backends/polling.rb +25 -0
  198. data/vendor/sass/vendor/fssm/lib/fssm/backends/rubycocoa/fsevents.rb +131 -0
  199. data/vendor/sass/vendor/fssm/lib/fssm/monitor.rb +26 -0
  200. data/vendor/sass/vendor/fssm/lib/fssm/path.rb +91 -0
  201. data/vendor/sass/vendor/fssm/lib/fssm/pathname.rb +502 -0
  202. data/vendor/sass/vendor/fssm/lib/fssm/state/directory.rb +57 -0
  203. data/vendor/sass/vendor/fssm/lib/fssm/state/file.rb +24 -0
  204. data/vendor/sass/vendor/fssm/lib/fssm/support.rb +63 -0
  205. data/vendor/sass/vendor/fssm/lib/fssm/tree.rb +176 -0
  206. data/vendor/sass/vendor/fssm/profile/prof-cache.rb +40 -0
  207. data/vendor/sass/vendor/fssm/profile/prof-fssm-pathname.html +1231 -0
  208. data/vendor/sass/vendor/fssm/profile/prof-pathname.rb +68 -0
  209. data/vendor/sass/vendor/fssm/profile/prof-plain-pathname.html +988 -0
  210. data/vendor/sass/vendor/fssm/profile/prof.html +2379 -0
  211. data/vendor/sass/vendor/fssm/spec/path_spec.rb +75 -0
  212. data/vendor/sass/vendor/fssm/spec/root/duck/quack.txt +0 -0
  213. data/vendor/sass/vendor/fssm/spec/root/file.css +0 -0
  214. data/vendor/sass/vendor/fssm/spec/root/file.rb +0 -0
  215. data/vendor/sass/vendor/fssm/spec/root/file.yml +0 -0
  216. data/vendor/sass/vendor/fssm/spec/root/moo/cow.txt +0 -0
  217. data/vendor/sass/vendor/fssm/spec/spec_helper.rb +14 -0
  218. data/vendor/sass/yard/callbacks.rb +29 -0
  219. data/vendor/sass/yard/default/fulldoc/html/css/common.sass +26 -0
  220. data/vendor/sass/yard/default/layout/html/footer.erb +12 -0
  221. data/vendor/sass/yard/inherited_hash.rb +41 -0
  222. metadata +219 -2
@@ -0,0 +1,49 @@
1
+ class MockImporter < Sass::Importers::Base
2
+ def initialize(name = "mock")
3
+ @name = name
4
+ @imports = Hash.new({})
5
+ end
6
+
7
+ def find_relative(uri, base, options)
8
+ nil
9
+ end
10
+
11
+ def find(uri, options)
12
+ contents = @imports[uri][:contents]
13
+ return unless contents
14
+ options[:syntax] = @imports[uri][:syntax]
15
+ options[:filename] = uri
16
+ options[:importer] = self
17
+ @imports[uri][:engine] = Sass::Engine.new(contents, options)
18
+ end
19
+
20
+ def mtime(uri, options)
21
+ @imports[uri][:mtime]
22
+ end
23
+
24
+ def key(uri, options)
25
+ ["mock", uri]
26
+ end
27
+
28
+ def to_s
29
+ @name
30
+ end
31
+
32
+ # Methods for testing
33
+
34
+ def add_import(uri, contents, syntax = :scss, mtime = Time.now - 10)
35
+ @imports[uri] = {
36
+ :contents => contents,
37
+ :mtime => mtime,
38
+ :syntax => syntax
39
+ }
40
+ end
41
+
42
+ def touch(uri)
43
+ @imports[uri][:mtime] = Time.now
44
+ end
45
+
46
+ def engine(uri)
47
+ @imports[uri][:engine]
48
+ end
49
+ end
@@ -0,0 +1,9 @@
1
+ body { font: Arial; background: blue; }
2
+
3
+ #page { width: 700px; height: 100; }
4
+ #page #header { height: 300px; }
5
+ #page #header h1 { font-size: 50px; color: blue; }
6
+
7
+ #content.user.show #container.top #column.left { width: 100px; }
8
+ #content.user.show #container.top #column.right { width: 600px; }
9
+ #content.user.show #container.bottom { background: brown; }
@@ -0,0 +1,26 @@
1
+ /* line 3, ../more_templates/more1.sass */
2
+ body {
3
+ font: Arial;
4
+ background: blue; }
5
+
6
+ /* line 7, ../more_templates/more1.sass */
7
+ #page {
8
+ width: 700px;
9
+ height: 100; }
10
+ /* line 10, ../more_templates/more1.sass */
11
+ #page #header {
12
+ height: 300px; }
13
+ /* line 12, ../more_templates/more1.sass */
14
+ #page #header h1 {
15
+ font-size: 50px;
16
+ color: blue; }
17
+
18
+ /* line 18, ../more_templates/more1.sass */
19
+ #content.user.show #container.top #column.left {
20
+ width: 100px; }
21
+ /* line 20, ../more_templates/more1.sass */
22
+ #content.user.show #container.top #column.right {
23
+ width: 600px; }
24
+ /* line 22, ../more_templates/more1.sass */
25
+ #content.user.show #container.bottom {
26
+ background: brown; }
@@ -0,0 +1,29 @@
1
+ imported { otherconst: hello; myconst: goodbye; pre-mixin: here; }
2
+
3
+ body { font: Arial; background: blue; }
4
+
5
+ #page { width: 700px; height: 100; }
6
+ #page #header { height: 300px; }
7
+ #page #header h1 { font-size: 50px; color: blue; }
8
+
9
+ #content.user.show #container.top #column.left { width: 100px; }
10
+ #content.user.show #container.top #column.right { width: 600px; }
11
+ #content.user.show #container.bottom { background: brown; }
12
+
13
+ midrule { inthe: middle; }
14
+
15
+ body { font: Arial; background: blue; }
16
+
17
+ #page { width: 700px; height: 100; }
18
+ #page #header { height: 300px; }
19
+ #page #header h1 { font-size: 50px; color: blue; }
20
+
21
+ #content.user.show #container.top #column.left { width: 100px; }
22
+ #content.user.show #container.top #column.right { width: 600px; }
23
+ #content.user.show #container.bottom { background: brown; }
24
+
25
+ @import url(basic.css);
26
+ @import url(../results/complex.css);
27
+ #foo { background-color: #bbaaff; }
28
+
29
+ nonimported { myconst: hello; otherconst: goodbye; post-mixin: here; }
@@ -0,0 +1,2 @@
1
+ #foo
2
+ :background-color #baf
@@ -0,0 +1,23 @@
1
+
2
+
3
+ body
4
+ :font Arial
5
+ :background blue
6
+
7
+ #page
8
+ :width 700px
9
+ :height 100
10
+ #header
11
+ :height 300px
12
+ h1
13
+ :font-size 50px
14
+ :color blue
15
+
16
+ #content.user.show
17
+ #container.top
18
+ #column.left
19
+ :width 100px
20
+ #column.right
21
+ :width 600px
22
+ #container.bottom
23
+ :background brown
@@ -0,0 +1,11 @@
1
+ $preconst: hello
2
+
3
+ =premixin
4
+ pre-mixin: here
5
+
6
+ @import importee, basic, basic.css, ../results/complex.css, more_partial
7
+
8
+ nonimported
9
+ :myconst $preconst
10
+ :otherconst $postconst
11
+ +postmixin
@@ -0,0 +1,430 @@
1
+ #!/usr/bin/env ruby
2
+ require File.dirname(__FILE__) + '/../test_helper'
3
+ require File.dirname(__FILE__) + '/test_helper'
4
+ require 'sass/plugin'
5
+ require 'fileutils'
6
+
7
+ class SassPluginTest < Test::Unit::TestCase
8
+ @@templates = %w{
9
+ complex script parent_ref import scss_import alt
10
+ subdir/subdir subdir/nested_subdir/nested_subdir
11
+ options
12
+ }
13
+
14
+ @@cache_store = Sass::InMemoryCacheStore.new
15
+
16
+ def setup
17
+ FileUtils.mkdir_p tempfile_loc
18
+ FileUtils.mkdir_p tempfile_loc(nil,"more_")
19
+ set_plugin_opts
20
+ update_all_stylesheets!
21
+ reset_mtimes
22
+ end
23
+
24
+ def teardown
25
+ clean_up_sassc
26
+ Sass::Plugin.reset!
27
+ FileUtils.rm_r tempfile_loc
28
+ FileUtils.rm_r tempfile_loc(nil,"more_")
29
+ end
30
+
31
+ @@templates.each do |name|
32
+ define_method("test_template_renders_correctly (#{name})") do
33
+ assert_renders_correctly(name)
34
+ end
35
+ end
36
+
37
+ def test_no_update
38
+ File.delete(tempfile_loc('basic'))
39
+ assert_needs_update 'basic'
40
+ update_all_stylesheets!
41
+ assert_stylesheet_updated 'basic'
42
+ end
43
+
44
+ def test_update_needed_when_modified
45
+ touch 'basic'
46
+ assert_needs_update 'basic'
47
+ update_all_stylesheets!
48
+ assert_stylesheet_updated 'basic'
49
+ end
50
+
51
+ def test_update_needed_when_dependency_modified
52
+ touch 'basic'
53
+ assert_needs_update 'import'
54
+ update_all_stylesheets!
55
+ assert_stylesheet_updated 'basic'
56
+ assert_stylesheet_updated 'import'
57
+ end
58
+
59
+ def test_update_needed_when_scss_dependency_modified
60
+ touch 'scss_importee'
61
+ assert_needs_update 'import'
62
+ update_all_stylesheets!
63
+ assert_stylesheet_updated 'scss_importee'
64
+ assert_stylesheet_updated 'import'
65
+ end
66
+
67
+ def test_scss_update_needed_when_dependency_modified
68
+ touch 'basic'
69
+ assert_needs_update 'scss_import'
70
+ update_all_stylesheets!
71
+ assert_stylesheet_updated 'basic'
72
+ assert_stylesheet_updated 'scss_import'
73
+ end
74
+
75
+ def test_full_exception_handling
76
+ File.delete(tempfile_loc('bork1'))
77
+ update_all_stylesheets!
78
+ File.open(tempfile_loc('bork1')) do |file|
79
+ assert_equal(<<CSS.strip, file.read.split("\n")[0...6].join("\n"))
80
+ /*
81
+ Syntax error: Undefined variable: "$bork".
82
+ on line 2 of #{template_loc('bork1')}
83
+
84
+ 1: bork
85
+ 2: :bork $bork
86
+ CSS
87
+ end
88
+ File.delete(tempfile_loc('bork1'))
89
+ end
90
+
91
+ def test_nonfull_exception_handling
92
+ old_full_exception = Sass::Plugin.options[:full_exception]
93
+ Sass::Plugin.options[:full_exception] = false
94
+
95
+ File.delete(tempfile_loc('bork1'))
96
+ assert_raise(Sass::SyntaxError) {update_all_stylesheets!}
97
+ ensure
98
+ Sass::Plugin.options[:full_exception] = old_full_exception
99
+ end
100
+
101
+ def test_two_template_directories
102
+ set_plugin_opts :template_location => {
103
+ template_loc => tempfile_loc,
104
+ template_loc(nil,'more_') => tempfile_loc(nil,'more_')
105
+ }
106
+ update_all_stylesheets!
107
+ ['more1', 'more_import'].each { |name| assert_renders_correctly(name, :prefix => 'more_') }
108
+ end
109
+
110
+ def test_two_template_directories_with_line_annotations
111
+ set_plugin_opts :line_comments => true,
112
+ :style => :nested,
113
+ :template_location => {
114
+ template_loc => tempfile_loc,
115
+ template_loc(nil,'more_') => tempfile_loc(nil,'more_')
116
+ }
117
+ update_all_stylesheets!
118
+ assert_renders_correctly('more1_with_line_comments', 'more1', :prefix => 'more_')
119
+ end
120
+
121
+ def test_doesnt_render_partials
122
+ assert !File.exists?(tempfile_loc('_partial'))
123
+ end
124
+
125
+ def test_template_location_array
126
+ assert_equal [[template_loc, tempfile_loc]], Sass::Plugin.template_location_array
127
+ end
128
+
129
+ def test_add_template_location
130
+ Sass::Plugin.add_template_location(template_loc(nil, "more_"), tempfile_loc(nil, "more_"))
131
+ assert_equal(
132
+ [[template_loc, tempfile_loc], [template_loc(nil, "more_"), tempfile_loc(nil, "more_")]],
133
+ Sass::Plugin.template_location_array)
134
+
135
+ touch 'more1', 'more_'
136
+ touch 'basic'
137
+ assert_needs_update "more1", "more_"
138
+ assert_needs_update "basic"
139
+ update_all_stylesheets!
140
+ assert_doesnt_need_update "more1", "more_"
141
+ assert_doesnt_need_update "basic"
142
+ end
143
+
144
+ def test_remove_template_location
145
+ Sass::Plugin.add_template_location(template_loc(nil, "more_"), tempfile_loc(nil, "more_"))
146
+ Sass::Plugin.remove_template_location(template_loc, tempfile_loc)
147
+ assert_equal(
148
+ [[template_loc(nil, "more_"), tempfile_loc(nil, "more_")]],
149
+ Sass::Plugin.template_location_array)
150
+
151
+ touch 'more1', 'more_'
152
+ touch 'basic'
153
+ assert_needs_update "more1", "more_"
154
+ assert_needs_update "basic"
155
+ update_all_stylesheets!
156
+ assert_doesnt_need_update "more1", "more_"
157
+ assert_needs_update "basic"
158
+ end
159
+
160
+ # Callbacks
161
+
162
+ def test_updating_stylesheets_callback
163
+ # Should run even when there's nothing to update
164
+ assert_callback :updating_stylesheets, []
165
+ end
166
+
167
+ def test_updating_stylesheets_callback_with_individual_files
168
+ files = [[template_loc("basic"), tempfile_loc("basic")]]
169
+ assert_callback(:updating_stylesheets, files) {Sass::Util.silence_sass_warnings{Sass::Plugin.update_stylesheets(files)}}
170
+ end
171
+
172
+ def test_updating_stylesheets_callback_with_never_update
173
+ Sass::Plugin.options[:never_update] = true
174
+ assert_no_callback :updating_stylesheets
175
+ end
176
+
177
+ def test_updating_stylesheet_callback_for_updated_template
178
+ Sass::Plugin.options[:always_update] = false
179
+ touch 'basic'
180
+ assert_no_callback :updating_stylesheet, template_loc("complex"), tempfile_loc("complex") do
181
+ assert_callbacks(
182
+ [:updating_stylesheet, template_loc("basic"), tempfile_loc("basic")],
183
+ [:updating_stylesheet, template_loc("import"), tempfile_loc("import")])
184
+ end
185
+ end
186
+
187
+ def test_updating_stylesheet_callback_for_fresh_template
188
+ Sass::Plugin.options[:always_update] = false
189
+ assert_no_callback :updating_stylesheet
190
+ end
191
+
192
+ def test_updating_stylesheet_callback_for_error_template
193
+ Sass::Plugin.options[:always_update] = false
194
+ touch 'bork1'
195
+ assert_no_callback :updating_stylesheet
196
+ end
197
+
198
+ def test_not_updating_stylesheet_callback_for_fresh_template
199
+ Sass::Plugin.options[:always_update] = false
200
+ assert_callback :not_updating_stylesheet, template_loc("basic"), tempfile_loc("basic")
201
+ end
202
+
203
+ def test_not_updating_stylesheet_callback_for_updated_template
204
+ Sass::Plugin.options[:always_update] = false
205
+ assert_callback :not_updating_stylesheet, template_loc("complex"), tempfile_loc("complex") do
206
+ assert_no_callbacks(
207
+ [:updating_stylesheet, template_loc("basic"), tempfile_loc("basic")],
208
+ [:updating_stylesheet, template_loc("import"), tempfile_loc("import")])
209
+ end
210
+ end
211
+
212
+ def test_not_updating_stylesheet_callback_with_never_update
213
+ Sass::Plugin.options[:never_update] = true
214
+ assert_no_callback :not_updating_stylesheet
215
+ end
216
+
217
+ def test_not_updating_stylesheet_callback_for_partial
218
+ Sass::Plugin.options[:always_update] = false
219
+ assert_no_callback :not_updating_stylesheet, template_loc("_partial"), tempfile_loc("_partial")
220
+ end
221
+
222
+ def test_not_updating_stylesheet_callback_for_error
223
+ Sass::Plugin.options[:always_update] = false
224
+ touch 'bork1'
225
+ assert_no_callback :not_updating_stylesheet, template_loc("bork1"), tempfile_loc("bork1")
226
+ end
227
+
228
+ def test_compilation_error_callback
229
+ Sass::Plugin.options[:always_update] = false
230
+ touch 'bork1'
231
+ assert_callback(:compilation_error,
232
+ lambda {|e| e.message == 'Undefined variable: "$bork".'},
233
+ template_loc("bork1"), tempfile_loc("bork1"))
234
+ end
235
+
236
+ def test_compilation_error_callback_for_file_access
237
+ Sass::Plugin.options[:always_update] = false
238
+ assert_callback(:compilation_error,
239
+ lambda {|e| e.is_a?(Errno::ENOENT)},
240
+ template_loc("nonexistent"), tempfile_loc("nonexistent")) do
241
+ Sass::Plugin.update_stylesheets([[template_loc("nonexistent"), tempfile_loc("nonexistent")]])
242
+ end
243
+ end
244
+
245
+ def test_creating_directory_callback
246
+ Sass::Plugin.options[:always_update] = false
247
+ dir = File.join(tempfile_loc, "subdir", "nested_subdir")
248
+ FileUtils.rm_r dir
249
+ assert_callback :creating_directory, dir
250
+ end
251
+
252
+ ## Regression
253
+
254
+ def test_cached_dependencies_update
255
+ FileUtils.mv(template_loc("basic"), template_loc("basic", "more_"))
256
+ set_plugin_opts :load_paths => [template_loc(nil, "more_")]
257
+
258
+ touch 'basic', 'more_'
259
+ assert_needs_update "import"
260
+ update_all_stylesheets!
261
+ assert_renders_correctly("import")
262
+ ensure
263
+ FileUtils.mv(template_loc("basic", "more_"), template_loc("basic"))
264
+ end
265
+
266
+ def test_cached_relative_import
267
+ old_always_update = Sass::Plugin.options[:always_update]
268
+ Sass::Plugin.options[:always_update] = true
269
+ update_all_stylesheets!
270
+ assert_renders_correctly('subdir/subdir')
271
+ ensure
272
+ Sass::Plugin.options[:always_update] = old_always_update
273
+ end
274
+
275
+ private
276
+
277
+ def assert_renders_correctly(*arguments)
278
+ options = arguments.last.is_a?(Hash) ? arguments.pop : {}
279
+ prefix = options[:prefix]
280
+ result_name = arguments.shift
281
+ tempfile_name = arguments.shift || result_name
282
+ expected_lines = File.read(result_loc(result_name, prefix)).split("\n")
283
+ actual_lines = File.read(tempfile_loc(tempfile_name, prefix)).split("\n")
284
+
285
+ if actual_lines.first == "/*" && expected_lines.first != "/*"
286
+ assert(false, actual_lines[0..actual_lines.enum_with_index.find {|l, i| l == "*/"}.last].join("\n"))
287
+ end
288
+
289
+ expected_lines.zip(actual_lines).each_with_index do |pair, line|
290
+ message = "template: #{result_name}\nline: #{line + 1}"
291
+ assert_equal(pair.first, pair.last, message)
292
+ end
293
+ if expected_lines.size < actual_lines.size
294
+ assert(false, "#{actual_lines.size - expected_lines.size} Trailing lines found in #{tempfile_name}.css: #{actual_lines[expected_lines.size..-1].join('\n')}")
295
+ end
296
+ end
297
+
298
+ def assert_stylesheet_updated(name)
299
+ assert_doesnt_need_update name
300
+
301
+ # Make sure it isn't an exception
302
+ expected_lines = File.read(result_loc(name)).split("\n")
303
+ actual_lines = File.read(tempfile_loc(name)).split("\n")
304
+ if actual_lines.first == "/*" && expected_lines.first != "/*"
305
+ assert(false, actual_lines[0..actual_lines.enum_with_index.find {|l, i| l == "*/"}.last].join("\n"))
306
+ end
307
+ end
308
+
309
+ def assert_callback(name, *expected_args)
310
+ run = false
311
+ Sass::Plugin.send("on_#{name}") do |*args|
312
+ run ||= expected_args.zip(args).all? do |ea, a|
313
+ ea.respond_to?(:call) ? ea.call(a) : ea == a
314
+ end
315
+ end
316
+
317
+ if block_given?
318
+ yield
319
+ else
320
+ update_all_stylesheets!
321
+ end
322
+
323
+ assert run, "Expected #{name} callback to be run with arguments:\n #{expected_args.inspect}"
324
+ end
325
+
326
+ def assert_no_callback(name, *unexpected_args)
327
+ Sass::Plugin.send("on_#{name}") do |*a|
328
+ next unless unexpected_args.empty? || a == unexpected_args
329
+
330
+ msg = "Expected #{name} callback not to be run"
331
+ if !unexpected_args.empty?
332
+ msg << " with arguments #{unexpected_args.inspect}"
333
+ elsif !a.empty?
334
+ msg << ",\n was run with arguments #{a.inspect}"
335
+ end
336
+
337
+ flunk msg
338
+ end
339
+
340
+ if block_given?
341
+ yield
342
+ else
343
+ update_all_stylesheets!
344
+ end
345
+ end
346
+
347
+ def assert_callbacks(*args)
348
+ return update_all_stylesheets! if args.empty?
349
+ assert_callback(*args.pop) {assert_callbacks(*args)}
350
+ end
351
+
352
+ def assert_no_callbacks(*args)
353
+ return update_all_stylesheets! if args.empty?
354
+ assert_no_callback(*args.pop) {assert_no_callbacks(*args)}
355
+ end
356
+
357
+ def update_all_stylesheets!
358
+ Sass::Util.silence_sass_warnings do
359
+ Sass::Plugin.update_stylesheets
360
+ end
361
+ end
362
+
363
+ def assert_needs_update(*args)
364
+ assert(Sass::Plugin::StalenessChecker.stylesheet_needs_update?(tempfile_loc(*args), template_loc(*args)),
365
+ "Expected #{template_loc(*args)} to need an update.")
366
+ end
367
+
368
+ def assert_doesnt_need_update(*args)
369
+ assert(!Sass::Plugin::StalenessChecker.stylesheet_needs_update?(tempfile_loc(*args), template_loc(*args)),
370
+ "Expected #{template_loc(*args)} not to need an update.")
371
+ end
372
+
373
+ def touch(*args)
374
+ FileUtils.touch(template_loc(*args))
375
+ end
376
+
377
+ def reset_mtimes
378
+ Sass::Plugin::StalenessChecker.dependencies_cache = {}
379
+ atime = Time.now
380
+ mtime = Time.now - 5
381
+ Dir["{#{template_loc},#{tempfile_loc}}/**/*.{css,sass,scss}"].each {|f| File.utime(atime, mtime, f)}
382
+ end
383
+
384
+ def template_loc(name = nil, prefix = nil)
385
+ if name
386
+ scss = absolutize "#{prefix}templates/#{name}.scss"
387
+ File.exists?(scss) ? scss : absolutize("#{prefix}templates/#{name}.sass")
388
+ else
389
+ absolutize "#{prefix}templates"
390
+ end
391
+ end
392
+
393
+ def tempfile_loc(name = nil, prefix = nil)
394
+ if name
395
+ absolutize "#{prefix}tmp/#{name}.css"
396
+ else
397
+ absolutize "#{prefix}tmp"
398
+ end
399
+ end
400
+
401
+ def result_loc(name = nil, prefix = nil)
402
+ if name
403
+ absolutize "#{prefix}results/#{name}.css"
404
+ else
405
+ absolutize "#{prefix}results"
406
+ end
407
+ end
408
+
409
+ def set_plugin_opts(overrides = {})
410
+ Sass::Plugin.options.merge!(
411
+ :template_location => template_loc,
412
+ :css_location => tempfile_loc,
413
+ :style => :compact,
414
+ :always_update => true,
415
+ :never_update => false,
416
+ :full_exception => true,
417
+ :cache_store => @@cache_store
418
+ )
419
+ Sass::Plugin.options.merge!(overrides)
420
+ end
421
+ end
422
+
423
+ class Sass::Engine
424
+ alias_method :old_render, :render
425
+
426
+ def render
427
+ raise "bork bork bork!" if @template[0] == "{bork now!}"
428
+ old_render
429
+ end
430
+ end