drnic-haml 2.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (190) hide show
  1. data/.yardopts +5 -0
  2. data/CONTRIBUTING +4 -0
  3. data/MIT-LICENSE +20 -0
  4. data/README.md +347 -0
  5. data/REVISION +1 -0
  6. data/Rakefile +371 -0
  7. data/VERSION +1 -0
  8. data/VERSION_NAME +1 -0
  9. data/bin/css2sass +7 -0
  10. data/bin/haml +9 -0
  11. data/bin/html2haml +7 -0
  12. data/bin/sass +8 -0
  13. data/extra/haml-mode.el +663 -0
  14. data/extra/sass-mode.el +205 -0
  15. data/extra/update_watch.rb +13 -0
  16. data/init.rb +8 -0
  17. data/lib/haml.rb +40 -0
  18. data/lib/haml/buffer.rb +307 -0
  19. data/lib/haml/engine.rb +301 -0
  20. data/lib/haml/error.rb +22 -0
  21. data/lib/haml/exec.rb +470 -0
  22. data/lib/haml/filters.rb +341 -0
  23. data/lib/haml/helpers.rb +560 -0
  24. data/lib/haml/helpers/action_view_extensions.rb +40 -0
  25. data/lib/haml/helpers/action_view_mods.rb +176 -0
  26. data/lib/haml/herb.rb +96 -0
  27. data/lib/haml/html.rb +308 -0
  28. data/lib/haml/precompiler.rb +997 -0
  29. data/lib/haml/shared.rb +78 -0
  30. data/lib/haml/template.rb +51 -0
  31. data/lib/haml/template/patch.rb +58 -0
  32. data/lib/haml/template/plugin.rb +71 -0
  33. data/lib/haml/util.rb +244 -0
  34. data/lib/haml/version.rb +64 -0
  35. data/lib/sass.rb +24 -0
  36. data/lib/sass/css.rb +423 -0
  37. data/lib/sass/engine.rb +491 -0
  38. data/lib/sass/environment.rb +79 -0
  39. data/lib/sass/error.rb +162 -0
  40. data/lib/sass/files.rb +133 -0
  41. data/lib/sass/plugin.rb +170 -0
  42. data/lib/sass/plugin/merb.rb +57 -0
  43. data/lib/sass/plugin/rails.rb +23 -0
  44. data/lib/sass/repl.rb +58 -0
  45. data/lib/sass/script.rb +55 -0
  46. data/lib/sass/script/bool.rb +17 -0
  47. data/lib/sass/script/color.rb +183 -0
  48. data/lib/sass/script/funcall.rb +50 -0
  49. data/lib/sass/script/functions.rb +199 -0
  50. data/lib/sass/script/lexer.rb +191 -0
  51. data/lib/sass/script/literal.rb +177 -0
  52. data/lib/sass/script/node.rb +14 -0
  53. data/lib/sass/script/number.rb +381 -0
  54. data/lib/sass/script/operation.rb +45 -0
  55. data/lib/sass/script/parser.rb +222 -0
  56. data/lib/sass/script/string.rb +12 -0
  57. data/lib/sass/script/unary_operation.rb +34 -0
  58. data/lib/sass/script/variable.rb +31 -0
  59. data/lib/sass/tree/comment_node.rb +84 -0
  60. data/lib/sass/tree/debug_node.rb +30 -0
  61. data/lib/sass/tree/directive_node.rb +70 -0
  62. data/lib/sass/tree/for_node.rb +48 -0
  63. data/lib/sass/tree/if_node.rb +54 -0
  64. data/lib/sass/tree/import_node.rb +69 -0
  65. data/lib/sass/tree/mixin_def_node.rb +29 -0
  66. data/lib/sass/tree/mixin_node.rb +48 -0
  67. data/lib/sass/tree/node.rb +252 -0
  68. data/lib/sass/tree/prop_node.rb +106 -0
  69. data/lib/sass/tree/root_node.rb +56 -0
  70. data/lib/sass/tree/rule_node.rb +220 -0
  71. data/lib/sass/tree/variable_node.rb +34 -0
  72. data/lib/sass/tree/while_node.rb +31 -0
  73. data/rails/init.rb +1 -0
  74. data/test/benchmark.rb +99 -0
  75. data/test/haml/engine_test.rb +1129 -0
  76. data/test/haml/helper_test.rb +282 -0
  77. data/test/haml/html2haml_test.rb +258 -0
  78. data/test/haml/markaby/standard.mab +52 -0
  79. data/test/haml/mocks/article.rb +6 -0
  80. data/test/haml/results/content_for_layout.xhtml +12 -0
  81. data/test/haml/results/eval_suppressed.xhtml +9 -0
  82. data/test/haml/results/filters.xhtml +62 -0
  83. data/test/haml/results/helpers.xhtml +93 -0
  84. data/test/haml/results/helpful.xhtml +10 -0
  85. data/test/haml/results/just_stuff.xhtml +68 -0
  86. data/test/haml/results/list.xhtml +12 -0
  87. data/test/haml/results/nuke_inner_whitespace.xhtml +40 -0
  88. data/test/haml/results/nuke_outer_whitespace.xhtml +148 -0
  89. data/test/haml/results/original_engine.xhtml +20 -0
  90. data/test/haml/results/partial_layout.xhtml +5 -0
  91. data/test/haml/results/partials.xhtml +21 -0
  92. data/test/haml/results/render_layout.xhtml +3 -0
  93. data/test/haml/results/silent_script.xhtml +74 -0
  94. data/test/haml/results/standard.xhtml +162 -0
  95. data/test/haml/results/tag_parsing.xhtml +23 -0
  96. data/test/haml/results/very_basic.xhtml +5 -0
  97. data/test/haml/results/whitespace_handling.xhtml +89 -0
  98. data/test/haml/rhtml/_av_partial_1.rhtml +12 -0
  99. data/test/haml/rhtml/_av_partial_2.rhtml +8 -0
  100. data/test/haml/rhtml/action_view.rhtml +62 -0
  101. data/test/haml/rhtml/standard.rhtml +54 -0
  102. data/test/haml/spec_test.rb +44 -0
  103. data/test/haml/template_test.rb +217 -0
  104. data/test/haml/templates/_av_partial_1.haml +9 -0
  105. data/test/haml/templates/_av_partial_1_ugly.haml +9 -0
  106. data/test/haml/templates/_av_partial_2.haml +5 -0
  107. data/test/haml/templates/_av_partial_2_ugly.haml +5 -0
  108. data/test/haml/templates/_layout.erb +3 -0
  109. data/test/haml/templates/_layout_for_partial.haml +3 -0
  110. data/test/haml/templates/_partial.haml +8 -0
  111. data/test/haml/templates/_text_area.haml +3 -0
  112. data/test/haml/templates/action_view.haml +47 -0
  113. data/test/haml/templates/action_view_ugly.haml +47 -0
  114. data/test/haml/templates/breakage.haml +8 -0
  115. data/test/haml/templates/content_for_layout.haml +8 -0
  116. data/test/haml/templates/eval_suppressed.haml +11 -0
  117. data/test/haml/templates/filters.haml +66 -0
  118. data/test/haml/templates/helpers.haml +95 -0
  119. data/test/haml/templates/helpful.haml +11 -0
  120. data/test/haml/templates/just_stuff.haml +83 -0
  121. data/test/haml/templates/list.haml +12 -0
  122. data/test/haml/templates/nuke_inner_whitespace.haml +32 -0
  123. data/test/haml/templates/nuke_outer_whitespace.haml +144 -0
  124. data/test/haml/templates/original_engine.haml +17 -0
  125. data/test/haml/templates/partial_layout.haml +3 -0
  126. data/test/haml/templates/partialize.haml +1 -0
  127. data/test/haml/templates/partials.haml +12 -0
  128. data/test/haml/templates/render_layout.haml +2 -0
  129. data/test/haml/templates/silent_script.haml +40 -0
  130. data/test/haml/templates/standard.haml +42 -0
  131. data/test/haml/templates/standard_ugly.haml +42 -0
  132. data/test/haml/templates/tag_parsing.haml +21 -0
  133. data/test/haml/templates/very_basic.haml +4 -0
  134. data/test/haml/templates/whitespace_handling.haml +87 -0
  135. data/test/haml/util_test.rb +92 -0
  136. data/test/linked_rails.rb +12 -0
  137. data/test/sass/css2sass_test.rb +294 -0
  138. data/test/sass/engine_test.rb +956 -0
  139. data/test/sass/functions_test.rb +126 -0
  140. data/test/sass/more_results/more1.css +9 -0
  141. data/test/sass/more_results/more1_with_line_comments.css +26 -0
  142. data/test/sass/more_results/more_import.css +29 -0
  143. data/test/sass/more_templates/_more_partial.sass +2 -0
  144. data/test/sass/more_templates/more1.sass +23 -0
  145. data/test/sass/more_templates/more_import.sass +11 -0
  146. data/test/sass/plugin_test.rb +229 -0
  147. data/test/sass/results/alt.css +4 -0
  148. data/test/sass/results/basic.css +9 -0
  149. data/test/sass/results/compact.css +5 -0
  150. data/test/sass/results/complex.css +87 -0
  151. data/test/sass/results/compressed.css +1 -0
  152. data/test/sass/results/expanded.css +19 -0
  153. data/test/sass/results/import.css +29 -0
  154. data/test/sass/results/line_numbers.css +49 -0
  155. data/test/sass/results/mixins.css +95 -0
  156. data/test/sass/results/multiline.css +24 -0
  157. data/test/sass/results/nested.css +22 -0
  158. data/test/sass/results/parent_ref.css +13 -0
  159. data/test/sass/results/script.css +16 -0
  160. data/test/sass/results/subdir/nested_subdir/nested_subdir.css +1 -0
  161. data/test/sass/results/subdir/subdir.css +3 -0
  162. data/test/sass/results/units.css +11 -0
  163. data/test/sass/script_test.rb +261 -0
  164. data/test/sass/templates/_partial.sass +2 -0
  165. data/test/sass/templates/alt.sass +16 -0
  166. data/test/sass/templates/basic.sass +23 -0
  167. data/test/sass/templates/bork1.sass +2 -0
  168. data/test/sass/templates/bork2.sass +2 -0
  169. data/test/sass/templates/bork3.sass +2 -0
  170. data/test/sass/templates/compact.sass +17 -0
  171. data/test/sass/templates/complex.sass +307 -0
  172. data/test/sass/templates/compressed.sass +15 -0
  173. data/test/sass/templates/expanded.sass +17 -0
  174. data/test/sass/templates/import.sass +11 -0
  175. data/test/sass/templates/importee.sass +19 -0
  176. data/test/sass/templates/line_numbers.sass +13 -0
  177. data/test/sass/templates/mixins.sass +76 -0
  178. data/test/sass/templates/multiline.sass +20 -0
  179. data/test/sass/templates/nested.sass +25 -0
  180. data/test/sass/templates/nested_bork1.sass +2 -0
  181. data/test/sass/templates/nested_bork2.sass +2 -0
  182. data/test/sass/templates/nested_bork3.sass +2 -0
  183. data/test/sass/templates/parent_ref.sass +25 -0
  184. data/test/sass/templates/script.sass +101 -0
  185. data/test/sass/templates/subdir/nested_subdir/_nested_partial.sass +2 -0
  186. data/test/sass/templates/subdir/nested_subdir/nested_subdir.sass +3 -0
  187. data/test/sass/templates/subdir/subdir.sass +6 -0
  188. data/test/sass/templates/units.sass +11 -0
  189. data/test/test_helper.rb +44 -0
  190. metadata +298 -0
@@ -0,0 +1,126 @@
1
+ require 'test/unit'
2
+ require File.dirname(__FILE__) + '/../../lib/sass'
3
+ require 'sass/script'
4
+
5
+ class SassFunctionTest < Test::Unit::TestCase
6
+ def test_hsl
7
+ # These tests adapted from the w3c browser tests
8
+ # http://www.w3.org/Style/CSS/Test/CSS3/Color/20070927/html4/t040204-hsl-h-rotating-b.htm
9
+ red = [255, 0, 0]
10
+ assert_rgb_hsl(red, ['0', '100%', '50%'])
11
+ assert_rgb_hsl(red, ['-360', '100%', '50%'])
12
+ assert_rgb_hsl(red, ['360', '100%', '50%'])
13
+ assert_rgb_hsl(red, ['6120', '100%', '50%'])
14
+
15
+ yellow = [255, 255, 0]
16
+ assert_rgb_hsl(yellow, ['60', '100%', '50%'])
17
+ assert_rgb_hsl(yellow, ['-300', '100%', '50%'])
18
+ assert_rgb_hsl(yellow, ['420', '100%', '50%'])
19
+ assert_rgb_hsl(yellow, ['-9660', '100%', '50%'])
20
+
21
+ green = [0, 255, 0]
22
+ assert_rgb_hsl(green, ['120', '100%', '50%'])
23
+ assert_rgb_hsl(green, ['-240', '100%', '50%'])
24
+ assert_rgb_hsl(green, ['480', '100%', '50%'])
25
+ assert_rgb_hsl(green, ['99840', '100%', '50%'])
26
+
27
+ cyan = [0, 255, 255]
28
+ assert_rgb_hsl(cyan, ['180', '100%', '50%'])
29
+ assert_rgb_hsl(cyan, ['-180', '100%', '50%'])
30
+ assert_rgb_hsl(cyan, ['540', '100%', '50%'])
31
+ assert_rgb_hsl(cyan, ['-900', '100%', '50%'])
32
+
33
+ blue = [0, 0, 255]
34
+ assert_rgb_hsl(blue, ['240', '100%', '50%'])
35
+ assert_rgb_hsl(blue, ['-120', '100%', '50%'])
36
+ assert_rgb_hsl(blue, ['600', '100%', '50%'])
37
+ assert_rgb_hsl(blue, ['-104880', '100%', '50%'])
38
+
39
+ purple = [255, 0, 255]
40
+ assert_rgb_hsl(purple, ['300', '100%', '50%'])
41
+ assert_rgb_hsl(purple, ['-60', '100%', '50%'])
42
+ assert_rgb_hsl(purple, ['660', '100%', '50%'])
43
+ assert_rgb_hsl(purple, ['2820', '100%', '50%'])
44
+ end
45
+
46
+ def test_hsl_checks_bounds
47
+ assert_error_message("Saturation -114 must be between 0% and 100% for `hsl'", "hsl(10, -114, 12)");
48
+ assert_error_message("Lightness 256 must be between 0% and 100% for `hsl'", "hsl(10, 10, 256%)");
49
+ end
50
+
51
+ def test_percentage
52
+ assert_equal("50%", evaluate("percentage(.5)"))
53
+ assert_equal("100%", evaluate("percentage(1)"))
54
+ assert_equal("25%", evaluate("percentage(25px / 100px)"))
55
+ assert_error_message("25px is not a unitless number for `percentage'", "percentage(25px)")
56
+ assert_error_message("#cccccc is not a unitless number for `percentage'", "percentage(#ccc)")
57
+ assert_error_message("string is not a unitless number for `percentage'", %Q{percentage("string")})
58
+ end
59
+
60
+ def test_round
61
+ assert_equal("5", evaluate("round(4.8)"))
62
+ assert_equal("5px", evaluate("round(4.8px)"))
63
+ assert_equal("5px", evaluate("round(5.49px)"))
64
+
65
+ assert_error_message("#cccccc is not a number for `round'", "round(#ccc)")
66
+ end
67
+
68
+ def test_floor
69
+ assert_equal("4", evaluate("floor(4.8)"))
70
+ assert_equal("4px", evaluate("floor(4.8px)"))
71
+
72
+ assert_error_message("foo is not a number for `floor'", "floor(\"foo\")")
73
+ end
74
+
75
+ def test_ceil
76
+ assert_equal("5", evaluate("ceil(4.1)"))
77
+ assert_equal("5px", evaluate("ceil(4.8px)"))
78
+
79
+ assert_error_message("a is not a number for `ceil'", "ceil(\"a\")")
80
+ end
81
+
82
+ def test_abs
83
+ assert_equal("5", evaluate("abs(-5)"))
84
+ assert_equal("5px", evaluate("abs(-5px)"))
85
+ assert_equal("5", evaluate("abs(5)"))
86
+ assert_equal("5px", evaluate("abs(5px)"))
87
+
88
+ assert_error_message("#aaaaaa is not a number for `abs'", "abs(#aaa)")
89
+ end
90
+
91
+ def test_rgb
92
+ assert_equal("#123456", evaluate("rgb(18, 52, 86)"))
93
+ assert_equal("#beaded", evaluate("rgb(190, 173, 237)"))
94
+ assert_equal("#00ff7f", evaluate("rgb(0, 255, 127)"))
95
+
96
+ assert_error_message("Color value 256 must be between 0 and 255 inclusive for `rgb'",
97
+ "rgb(256, 1, 1)")
98
+ assert_error_message("Color value 256 must be between 0 and 255 inclusive for `rgb'",
99
+ "rgb(1, 256, 1)")
100
+ assert_error_message("Color value 256 must be between 0 and 255 inclusive for `rgb'",
101
+ "rgb(1, 1, 256)")
102
+ assert_error_message("Color value 256 must be between 0 and 255 inclusive for `rgb'",
103
+ "rgb(1, 256, 257)")
104
+ assert_error_message("Color value -1 must be between 0 and 255 inclusive for `rgb'",
105
+ "rgb(-1, 1, 1)")
106
+ end
107
+
108
+ private
109
+
110
+ def assert_rgb_hsl(rgb, hsl)
111
+ hsl = hsl.map {|v| Sass::Script::Parser.parse v, 0, 0 }
112
+ assert_equal(rgb, Sass::Script::Functions::EvaluationContext.new({}).hsl(*hsl).value)
113
+ end
114
+
115
+ def evaluate(value)
116
+ Sass::Script::Parser.parse(value, 0, 0).perform(Sass::Environment.new).to_s
117
+ end
118
+
119
+ def assert_error_message(message, value)
120
+ evaluate(value)
121
+ flunk("Error message expected but not raised: #{message}")
122
+ rescue Sass::SyntaxError => e
123
+ assert_equal(message, e.message)
124
+ end
125
+
126
+ 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: #baf; }
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,229 @@
1
+ #!/usr/bin/env ruby
2
+ require File.dirname(__FILE__) + '/../test_helper'
3
+ require 'sass/plugin'
4
+ require 'fileutils'
5
+
6
+ class SassPluginTest < Test::Unit::TestCase
7
+ @@templates = %w{
8
+ complex script parent_ref import alt
9
+ subdir/subdir subdir/nested_subdir/nested_subdir
10
+ }
11
+
12
+ def setup
13
+ FileUtils.mkdir tempfile_loc
14
+ FileUtils.mkdir tempfile_loc(nil,"more_")
15
+ set_plugin_opts
16
+ Sass::Plugin.update_stylesheets
17
+ end
18
+
19
+ def teardown
20
+ clean_up_sassc
21
+ FileUtils.rm_r tempfile_loc
22
+ FileUtils.rm_r tempfile_loc(nil,"more_")
23
+ end
24
+
25
+ @@templates.each do |name|
26
+ define_method("test_template_renders_correctly (#{name})") do
27
+ assert_renders_correctly(name)
28
+ end
29
+ end
30
+
31
+ def test_no_update
32
+ File.delete(tempfile_loc('basic'))
33
+ assert Sass::Plugin.stylesheet_needs_update?('basic', template_loc, tempfile_loc)
34
+ Sass::Plugin.update_stylesheets
35
+ assert !Sass::Plugin.stylesheet_needs_update?('basic', template_loc, tempfile_loc)
36
+ end
37
+
38
+ def test_update_needed_when_modified
39
+ sleep 1
40
+ FileUtils.touch(template_loc('basic'))
41
+ assert Sass::Plugin.stylesheet_needs_update?('basic', template_loc, tempfile_loc)
42
+ Sass::Plugin.update_stylesheets
43
+ assert !Sass::Plugin.stylesheet_needs_update?('basic', template_loc, tempfile_loc)
44
+ end
45
+
46
+ def test_update_needed_when_dependency_modified
47
+ sleep 1
48
+ FileUtils.touch(template_loc('basic'))
49
+ assert Sass::Plugin.stylesheet_needs_update?('import', template_loc, tempfile_loc)
50
+ Sass::Plugin.update_stylesheets
51
+ assert !Sass::Plugin.stylesheet_needs_update?('import', template_loc, tempfile_loc)
52
+ end
53
+
54
+ def test_full_exception_handling
55
+ File.delete(tempfile_loc('bork1'))
56
+ Sass::Plugin.update_stylesheets
57
+ File.open(tempfile_loc('bork1')) do |file|
58
+ assert_equal(<<CSS.strip, file.read.split("\n")[0...6].join("\n"))
59
+ /*
60
+ Syntax error: Undefined variable: "!bork".
61
+ on line 2 of #{template_loc('bork1')}
62
+
63
+ 1: bork
64
+ 2: :bork= !bork
65
+ CSS
66
+ end
67
+ File.delete(tempfile_loc('bork1'))
68
+ end
69
+
70
+ def test_nonfull_exception_handling
71
+ Sass::Plugin.options[:full_exception] = false
72
+
73
+ File.delete(tempfile_loc('bork1'))
74
+ Sass::Plugin.update_stylesheets
75
+ assert_equal("/* Internal stylesheet error */", File.read(tempfile_loc('bork1')))
76
+ File.delete(tempfile_loc('bork1'))
77
+
78
+ Sass::Plugin.options[:full_exception] = true
79
+ end
80
+
81
+ def test_two_template_directories
82
+ set_plugin_opts :template_location => {
83
+ template_loc => tempfile_loc,
84
+ template_loc(nil,'more_') => tempfile_loc(nil,'more_')
85
+ }
86
+ Sass::Plugin.update_stylesheets
87
+ ['more1', 'more_import'].each { |name| assert_renders_correctly(name, :prefix => 'more_') }
88
+ end
89
+
90
+ def test_two_template_directories_with_line_annotations
91
+ set_plugin_opts :line_comments => true,
92
+ :style => :nested,
93
+ :template_location => {
94
+ template_loc => tempfile_loc,
95
+ template_loc(nil,'more_') => tempfile_loc(nil,'more_')
96
+ }
97
+ Sass::Plugin.update_stylesheets
98
+ assert_renders_correctly('more1_with_line_comments', 'more1', :prefix => 'more_')
99
+ end
100
+
101
+ def test_merb_update
102
+ begin
103
+ require 'merb'
104
+ rescue LoadError
105
+ puts "\nmerb couldn't be loaded, skipping a test"
106
+ return
107
+ end
108
+
109
+ require 'sass/plugin/merb'
110
+ if defined?(MerbHandler)
111
+ MerbHandler.send(:define_method, :process_without_sass) { |*args| }
112
+ else
113
+ Merb::Rack::Application.send(:define_method, :call_without_sass) { |*args| }
114
+ end
115
+
116
+ set_plugin_opts
117
+
118
+ File.delete(tempfile_loc('basic'))
119
+ assert Sass::Plugin.stylesheet_needs_update?('basic', template_loc, tempfile_loc)
120
+
121
+ if defined?(MerbHandler)
122
+ MerbHandler.new('.').process nil, nil
123
+ else
124
+ Merb::Rack::Application.new.call(::Rack::MockRequest.env_for('/'))
125
+ end
126
+
127
+ assert !Sass::Plugin.stylesheet_needs_update?('basic', template_loc, tempfile_loc)
128
+ end
129
+
130
+ def test_doesnt_render_partials
131
+ assert !File.exists?(tempfile_loc('_partial'))
132
+ end
133
+
134
+ ## Regression
135
+
136
+ def test_cached_dependencies_update
137
+ FileUtils.mv(template_loc("basic"), template_loc("basic", "more_"))
138
+ set_plugin_opts :load_paths => [result_loc, template_loc(nil, "more_")]
139
+
140
+ sleep 1
141
+ FileUtils.touch(template_loc("basic", "more_"))
142
+ assert Sass::Plugin.stylesheet_needs_update?("import", template_loc, tempfile_loc)
143
+ Sass::Plugin.update_stylesheets
144
+ assert_renders_correctly("import")
145
+ ensure
146
+ FileUtils.mv(template_loc("basic", "more_"), template_loc("basic"))
147
+ end
148
+
149
+ private
150
+
151
+ def assert_renders_correctly(*arguments)
152
+ options = arguments.last.is_a?(Hash) ? arguments.pop : {}
153
+ prefix = options[:prefix]
154
+ result_name = arguments.shift
155
+ tempfile_name = arguments.shift || result_name
156
+ expected_lines = File.read(result_loc(result_name, prefix)).split("\n")
157
+ actual_lines = File.read(tempfile_loc(tempfile_name, prefix)).split("\n")
158
+
159
+ if actual_lines.first == "/*" && expected_lines.first != "/*"
160
+ assert(false, actual_lines[0..actual_lines.enum_with_index.find {|l, i| l == "*/"}.last].join("\n"))
161
+ end
162
+
163
+ expected_lines.zip(actual_lines).each_with_index do |pair, line|
164
+ message = "template: #{result_name}\nline: #{line + 1}"
165
+ assert_equal(pair.first, pair.last, message)
166
+ end
167
+ if expected_lines.size < actual_lines.size
168
+ assert(false, "#{actual_lines.size - expected_lines.size} Trailing lines found in #{tempfile_name}.css: #{actual_lines[expected_lines.size..-1].join('\n')}")
169
+ end
170
+ end
171
+
172
+ def template_loc(name = nil, prefix = nil)
173
+ if name
174
+ absolutize "#{prefix}templates/#{name}.sass"
175
+ else
176
+ absolutize "#{prefix}templates"
177
+ end
178
+ end
179
+
180
+ def tempfile_loc(name = nil, prefix = nil)
181
+ if name
182
+ absolutize "#{prefix}tmp/#{name}.css"
183
+ else
184
+ absolutize "#{prefix}tmp"
185
+ end
186
+ end
187
+
188
+ def result_loc(name = nil, prefix = nil)
189
+ if name
190
+ absolutize "#{prefix}results/#{name}.css"
191
+ else
192
+ absolutize "#{prefix}results"
193
+ end
194
+ end
195
+
196
+ def absolutize(file)
197
+ "#{File.dirname(__FILE__)}/#{file}"
198
+ end
199
+
200
+ def set_plugin_opts(overrides = {})
201
+ Sass::Plugin.options = {
202
+ :template_location => template_loc,
203
+ :css_location => tempfile_loc,
204
+ :style => :compact,
205
+ :load_paths => [result_loc],
206
+ :always_update => true,
207
+ }.merge(overrides)
208
+ end
209
+
210
+ def wait_a_tick
211
+ time = Time.now
212
+ loop {break if Time.now.sec != time.sec}
213
+ end
214
+ end
215
+
216
+ module Sass::Plugin
217
+ class << self
218
+ public :stylesheet_needs_update?
219
+ end
220
+ end
221
+
222
+ class Sass::Engine
223
+ alias_method :old_render, :render
224
+
225
+ def render
226
+ raise "bork bork bork!" if @template[0] == "{bork now!}"
227
+ old_render
228
+ end
229
+ end