haml 2.0.10 → 2.2.0
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.
- data/.yardopts +5 -0
- data/MIT-LICENSE +1 -1
- data/README.md +347 -0
- data/Rakefile +124 -19
- data/VERSION +1 -1
- data/VERSION_NAME +1 -0
- data/extra/haml-mode.el +397 -78
- data/extra/sass-mode.el +148 -36
- data/extra/update_watch.rb +13 -0
- data/lib/haml.rb +15 -993
- data/lib/haml/buffer.rb +131 -84
- data/lib/haml/engine.rb +129 -97
- data/lib/haml/error.rb +7 -7
- data/lib/haml/exec.rb +127 -42
- data/lib/haml/filters.rb +107 -42
- data/lib/haml/helpers.rb +210 -156
- data/lib/haml/helpers/action_view_extensions.rb +34 -39
- data/lib/haml/helpers/action_view_mods.rb +132 -139
- data/lib/haml/html.rb +77 -65
- data/lib/haml/precompiler.rb +404 -213
- data/lib/haml/shared.rb +78 -0
- data/lib/haml/template.rb +14 -14
- data/lib/haml/template/patch.rb +2 -2
- data/lib/haml/template/plugin.rb +2 -3
- data/lib/haml/util.rb +211 -6
- data/lib/haml/version.rb +30 -13
- data/lib/sass.rb +7 -856
- data/lib/sass/css.rb +169 -161
- data/lib/sass/engine.rb +344 -328
- data/lib/sass/environment.rb +79 -0
- data/lib/sass/error.rb +33 -11
- data/lib/sass/files.rb +139 -0
- data/lib/sass/plugin.rb +160 -117
- data/lib/sass/plugin/merb.rb +7 -6
- data/lib/sass/plugin/rails.rb +5 -6
- data/lib/sass/repl.rb +58 -0
- data/lib/sass/script.rb +59 -0
- data/lib/sass/script/bool.rb +17 -0
- data/lib/sass/script/color.rb +183 -0
- data/lib/sass/script/funcall.rb +50 -0
- data/lib/sass/script/functions.rb +198 -0
- data/lib/sass/script/lexer.rb +178 -0
- data/lib/sass/script/literal.rb +177 -0
- data/lib/sass/script/node.rb +14 -0
- data/lib/sass/script/number.rb +381 -0
- data/lib/sass/script/operation.rb +45 -0
- data/lib/sass/script/parser.rb +172 -0
- data/lib/sass/script/string.rb +12 -0
- data/lib/sass/script/unary_operation.rb +34 -0
- data/lib/sass/script/variable.rb +31 -0
- data/lib/sass/tree/comment_node.rb +73 -10
- data/lib/sass/tree/debug_node.rb +30 -0
- data/lib/sass/tree/directive_node.rb +42 -17
- data/lib/sass/tree/file_node.rb +41 -0
- data/lib/sass/tree/for_node.rb +48 -0
- data/lib/sass/tree/if_node.rb +54 -0
- data/lib/sass/tree/mixin_def_node.rb +29 -0
- data/lib/sass/tree/mixin_node.rb +48 -0
- data/lib/sass/tree/node.rb +214 -11
- data/lib/sass/tree/prop_node.rb +109 -0
- data/lib/sass/tree/rule_node.rb +178 -51
- data/lib/sass/tree/variable_node.rb +34 -0
- data/lib/sass/tree/while_node.rb +31 -0
- data/test/haml/engine_test.rb +331 -36
- data/test/haml/helper_test.rb +12 -1
- data/test/haml/results/content_for_layout.xhtml +0 -3
- data/test/haml/results/filters.xhtml +2 -0
- data/test/haml/results/list.xhtml +1 -1
- data/test/haml/template_test.rb +7 -2
- data/test/haml/templates/content_for_layout.haml +0 -2
- data/test/haml/templates/list.haml +1 -1
- data/test/haml/util_test.rb +92 -0
- data/test/sass/css2sass_test.rb +69 -24
- data/test/sass/engine_test.rb +586 -64
- data/test/sass/functions_test.rb +125 -0
- data/test/sass/more_results/more1.css +9 -0
- data/test/sass/more_results/more1_with_line_comments.css +26 -0
- data/test/sass/more_results/more_import.css +29 -0
- data/test/sass/more_templates/_more_partial.sass +2 -0
- data/test/sass/more_templates/more1.sass +23 -0
- data/test/sass/more_templates/more_import.sass +11 -0
- data/test/sass/plugin_test.rb +81 -28
- data/test/sass/results/line_numbers.css +49 -0
- data/test/sass/results/{constants.css → script.css} +4 -4
- data/test/sass/results/subdir/subdir.css +2 -0
- data/test/sass/results/units.css +11 -0
- data/test/sass/script_test.rb +258 -0
- data/test/sass/templates/import.sass +1 -1
- data/test/sass/templates/importee.sass +7 -2
- data/test/sass/templates/line_numbers.sass +13 -0
- data/test/sass/templates/{constants.sass → script.sass} +11 -10
- data/test/sass/templates/subdir/nested_subdir/_nested_partial.sass +2 -0
- data/test/sass/templates/subdir/subdir.sass +2 -2
- data/test/sass/templates/units.sass +11 -0
- data/test/test_helper.rb +14 -0
- metadata +77 -19
- data/FAQ +0 -138
- data/README.rdoc +0 -319
- data/lib/sass/constant.rb +0 -216
- data/lib/sass/constant/color.rb +0 -101
- data/lib/sass/constant/literal.rb +0 -54
- data/lib/sass/constant/nil.rb +0 -9
- data/lib/sass/constant/number.rb +0 -87
- data/lib/sass/constant/operation.rb +0 -30
- data/lib/sass/constant/string.rb +0 -22
- data/lib/sass/tree/attr_node.rb +0 -57
- data/lib/sass/tree/value_node.rb +0 -20
@@ -0,0 +1,125 @@
|
|
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
|
+
|
95
|
+
assert_error_message("Color value 256 must be between 0 and 255 inclusive for `rgb'",
|
96
|
+
"rgb(256, 1, 1)")
|
97
|
+
assert_error_message("Color value 256 must be between 0 and 255 inclusive for `rgb'",
|
98
|
+
"rgb(1, 256, 1)")
|
99
|
+
assert_error_message("Color value 256 must be between 0 and 255 inclusive for `rgb'",
|
100
|
+
"rgb(1, 1, 256)")
|
101
|
+
assert_error_message("Color value 256 must be between 0 and 255 inclusive for `rgb'",
|
102
|
+
"rgb(1, 256, 257)")
|
103
|
+
assert_error_message("Color value -1 must be between 0 and 255 inclusive for `rgb'",
|
104
|
+
"rgb(-1, 1, 1)")
|
105
|
+
end
|
106
|
+
|
107
|
+
private
|
108
|
+
|
109
|
+
def assert_rgb_hsl(rgb, hsl)
|
110
|
+
hsl = hsl.map {|v| Sass::Script::Parser.parse v, 0, 0 }
|
111
|
+
assert_equal(rgb, Sass::Script::Functions::EvaluationContext.new({}).hsl(*hsl).value)
|
112
|
+
end
|
113
|
+
|
114
|
+
def evaluate(value)
|
115
|
+
Sass::Script::Parser.parse(value, 0, 0).perform(Sass::Environment.new).to_s
|
116
|
+
end
|
117
|
+
|
118
|
+
def assert_error_message(message, value)
|
119
|
+
evaluate(value)
|
120
|
+
flunk("Error message expected but not raised: #{message}")
|
121
|
+
rescue Sass::SyntaxError => e
|
122
|
+
assert_equal(message, e.message)
|
123
|
+
end
|
124
|
+
|
125
|
+
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,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
|
data/test/sass/plugin_test.rb
CHANGED
@@ -5,18 +5,21 @@ require 'fileutils'
|
|
5
5
|
|
6
6
|
class SassPluginTest < Test::Unit::TestCase
|
7
7
|
@@templates = %w{
|
8
|
-
complex
|
8
|
+
complex script parent_ref import alt
|
9
9
|
subdir/subdir subdir/nested_subdir/nested_subdir
|
10
10
|
}
|
11
11
|
|
12
12
|
def setup
|
13
|
-
FileUtils.mkdir
|
13
|
+
FileUtils.mkdir tempfile_loc
|
14
|
+
FileUtils.mkdir tempfile_loc(nil,"more_")
|
14
15
|
set_plugin_opts
|
15
16
|
Sass::Plugin.update_stylesheets
|
16
17
|
end
|
17
18
|
|
18
19
|
def teardown
|
19
|
-
|
20
|
+
clean_up_sassc
|
21
|
+
FileUtils.rm_r tempfile_loc
|
22
|
+
FileUtils.rm_r tempfile_loc(nil,"more_")
|
20
23
|
end
|
21
24
|
|
22
25
|
def test_templates_should_render_correctly
|
@@ -25,32 +28,32 @@ class SassPluginTest < Test::Unit::TestCase
|
|
25
28
|
|
26
29
|
def test_no_update
|
27
30
|
File.delete(tempfile_loc('basic'))
|
28
|
-
assert Sass::Plugin.stylesheet_needs_update?('basic')
|
31
|
+
assert Sass::Plugin.stylesheet_needs_update?('basic', template_loc, tempfile_loc)
|
29
32
|
Sass::Plugin.update_stylesheets
|
30
|
-
assert !Sass::Plugin.stylesheet_needs_update?('basic')
|
33
|
+
assert !Sass::Plugin.stylesheet_needs_update?('basic', template_loc, tempfile_loc)
|
31
34
|
end
|
32
35
|
|
33
36
|
def test_update_needed_when_modified
|
34
37
|
sleep(1)
|
35
38
|
FileUtils.touch(template_loc('basic'))
|
36
|
-
assert Sass::Plugin.stylesheet_needs_update?('basic')
|
39
|
+
assert Sass::Plugin.stylesheet_needs_update?('basic', template_loc, tempfile_loc)
|
37
40
|
Sass::Plugin.update_stylesheets
|
38
|
-
assert !Sass::Plugin.stylesheet_needs_update?('basic')
|
41
|
+
assert !Sass::Plugin.stylesheet_needs_update?('basic', template_loc, tempfile_loc)
|
39
42
|
end
|
40
43
|
|
41
44
|
def test_update_needed_when_dependency_modified
|
42
45
|
sleep(1)
|
43
46
|
FileUtils.touch(template_loc('basic'))
|
44
|
-
assert Sass::Plugin.stylesheet_needs_update?('import')
|
47
|
+
assert Sass::Plugin.stylesheet_needs_update?('import', template_loc, tempfile_loc)
|
45
48
|
Sass::Plugin.update_stylesheets
|
46
|
-
assert !Sass::Plugin.stylesheet_needs_update?('import')
|
49
|
+
assert !Sass::Plugin.stylesheet_needs_update?('import', template_loc, tempfile_loc)
|
47
50
|
end
|
48
51
|
|
49
52
|
def test_full_exception_handling
|
50
53
|
File.delete(tempfile_loc('bork'))
|
51
54
|
Sass::Plugin.update_stylesheets
|
52
55
|
File.open(tempfile_loc('bork')) do |file|
|
53
|
-
assert_equal("/*\nSass::SyntaxError: Undefined
|
56
|
+
assert_equal("/*\nSass::SyntaxError: Undefined variable: \"!bork\".\non line 2 of #{template_loc('bork')}\n\n1: bork\n2: :bork= !bork", file.read.split("\n")[0...6].join("\n"))
|
54
57
|
end
|
55
58
|
File.delete(tempfile_loc('bork'))
|
56
59
|
end
|
@@ -65,14 +68,34 @@ class SassPluginTest < Test::Unit::TestCase
|
|
65
68
|
|
66
69
|
Sass::Plugin.options[:full_exception] = true
|
67
70
|
end
|
71
|
+
|
72
|
+
def test_two_template_directories
|
73
|
+
set_plugin_opts :template_location => {
|
74
|
+
template_loc => tempfile_loc,
|
75
|
+
template_loc(nil,'more_') => tempfile_loc(nil,'more_')
|
76
|
+
}
|
77
|
+
Sass::Plugin.update_stylesheets
|
78
|
+
['more1', 'more_import'].each { |name| assert_renders_correctly(name, :prefix => 'more_') }
|
79
|
+
end
|
80
|
+
|
81
|
+
def test_two_template_directories_with_line_annotations
|
82
|
+
set_plugin_opts :line_comments => true,
|
83
|
+
:style => :nested,
|
84
|
+
:template_location => {
|
85
|
+
template_loc => tempfile_loc,
|
86
|
+
template_loc(nil,'more_') => tempfile_loc(nil,'more_')
|
87
|
+
}
|
88
|
+
Sass::Plugin.update_stylesheets
|
89
|
+
assert_renders_correctly('more1_with_line_comments', 'more1', :prefix => 'more_')
|
90
|
+
end
|
68
91
|
|
69
92
|
def test_rails_update
|
70
93
|
File.delete(tempfile_loc('basic'))
|
71
|
-
assert Sass::Plugin.stylesheet_needs_update?('basic')
|
94
|
+
assert Sass::Plugin.stylesheet_needs_update?('basic', template_loc, tempfile_loc)
|
72
95
|
|
73
96
|
ActionController::Base.new.process
|
74
97
|
|
75
|
-
assert !Sass::Plugin.stylesheet_needs_update?('basic')
|
98
|
+
assert !Sass::Plugin.stylesheet_needs_update?('basic', template_loc, tempfile_loc)
|
76
99
|
end
|
77
100
|
|
78
101
|
def test_merb_update
|
@@ -93,7 +116,7 @@ class SassPluginTest < Test::Unit::TestCase
|
|
93
116
|
set_plugin_opts
|
94
117
|
|
95
118
|
File.delete(tempfile_loc('basic'))
|
96
|
-
assert Sass::Plugin.stylesheet_needs_update?('basic')
|
119
|
+
assert Sass::Plugin.stylesheet_needs_update?('basic', template_loc, tempfile_loc)
|
97
120
|
|
98
121
|
if defined?(MerbHandler)
|
99
122
|
MerbHandler.new('.').process nil, nil
|
@@ -101,7 +124,7 @@ class SassPluginTest < Test::Unit::TestCase
|
|
101
124
|
Merb::Rack::Application.new.call(::Rack::MockRequest.env_for('/'))
|
102
125
|
end
|
103
126
|
|
104
|
-
assert !Sass::Plugin.stylesheet_needs_update?('basic')
|
127
|
+
assert !Sass::Plugin.stylesheet_needs_update?('basic', template_loc, tempfile_loc)
|
105
128
|
end
|
106
129
|
|
107
130
|
def test_doesnt_render_partials
|
@@ -110,33 +133,63 @@ class SassPluginTest < Test::Unit::TestCase
|
|
110
133
|
|
111
134
|
private
|
112
135
|
|
113
|
-
def assert_renders_correctly(
|
114
|
-
|
115
|
-
|
136
|
+
def assert_renders_correctly(*arguments)
|
137
|
+
options = arguments.last.is_a?(Hash) ? arguments.pop : {}
|
138
|
+
prefix = options[:prefix]
|
139
|
+
result_name = arguments.shift
|
140
|
+
tempfile_name = arguments.shift || result_name
|
141
|
+
expected_lines = File.read(result_loc(result_name, prefix)).split("\n")
|
142
|
+
actual_lines = File.read(tempfile_loc(tempfile_name, prefix)).split("\n")
|
143
|
+
|
144
|
+
if actual_lines.first == "/*" && expected_lines.first != "/*"
|
145
|
+
assert(false, actual_lines[0..actual_lines.enum_with_index.find {|l, i| l == "*/"}.last].join("\n"))
|
146
|
+
end
|
147
|
+
|
148
|
+
expected_lines.zip(actual_lines).each_with_index do |pair, line|
|
149
|
+
message = "template: #{result_name}\nline: #{line + 1}"
|
116
150
|
assert_equal(pair.first, pair.last, message)
|
117
151
|
end
|
152
|
+
if expected_lines.size < actual_lines.size
|
153
|
+
assert(false, "#{actual_lines.size - expected_lines.size} Trailing lines found in #{tempfile_name}.css: #{actual_lines[expected_lines.size..-1].join('\n')}")
|
154
|
+
end
|
118
155
|
end
|
119
156
|
|
120
|
-
def template_loc(name)
|
121
|
-
|
157
|
+
def template_loc(name = nil, prefix = nil)
|
158
|
+
if name
|
159
|
+
absolutize "#{prefix}templates/#{name}.sass"
|
160
|
+
else
|
161
|
+
absolutize "#{prefix}templates"
|
162
|
+
end
|
122
163
|
end
|
123
164
|
|
124
|
-
def tempfile_loc(name)
|
125
|
-
|
165
|
+
def tempfile_loc(name = nil, prefix = nil)
|
166
|
+
if name
|
167
|
+
absolutize "#{prefix}tmp/#{name}.css"
|
168
|
+
else
|
169
|
+
absolutize "#{prefix}tmp"
|
170
|
+
end
|
126
171
|
end
|
127
172
|
|
128
|
-
def result_loc(name)
|
129
|
-
|
173
|
+
def result_loc(name = nil, prefix = nil)
|
174
|
+
if name
|
175
|
+
absolutize "#{prefix}results/#{name}.css"
|
176
|
+
else
|
177
|
+
absolutize "#{prefix}results"
|
178
|
+
end
|
179
|
+
end
|
180
|
+
|
181
|
+
def absolutize(file)
|
182
|
+
"#{File.dirname(__FILE__)}/#{file}"
|
130
183
|
end
|
131
184
|
|
132
|
-
def set_plugin_opts
|
185
|
+
def set_plugin_opts(overrides = {})
|
133
186
|
Sass::Plugin.options = {
|
134
|
-
:template_location =>
|
135
|
-
:css_location =>
|
187
|
+
:template_location => template_loc,
|
188
|
+
:css_location => tempfile_loc,
|
136
189
|
:style => :compact,
|
137
|
-
:load_paths => [
|
190
|
+
:load_paths => [result_loc],
|
138
191
|
:always_update => true,
|
139
|
-
}
|
192
|
+
}.merge(overrides)
|
140
193
|
end
|
141
194
|
end
|
142
195
|
|
@@ -0,0 +1,49 @@
|
|
1
|
+
/* line 1, ../templates/line_numbers.sass */
|
2
|
+
foo {
|
3
|
+
bar: baz; }
|
4
|
+
|
5
|
+
/* line 6, ../templates/importee.sass */
|
6
|
+
imported {
|
7
|
+
otherconst: 12;
|
8
|
+
myconst: goodbye; }
|
9
|
+
/* line 5, ../templates/line_numbers.sass */
|
10
|
+
imported squggle {
|
11
|
+
blat: bang; }
|
12
|
+
|
13
|
+
/* line 3, ../templates/basic.sass */
|
14
|
+
body {
|
15
|
+
font: Arial;
|
16
|
+
background: blue; }
|
17
|
+
|
18
|
+
/* line 7, ../templates/basic.sass */
|
19
|
+
#page {
|
20
|
+
width: 700px;
|
21
|
+
height: 100; }
|
22
|
+
/* line 10, ../templates/basic.sass */
|
23
|
+
#page #header {
|
24
|
+
height: 300px; }
|
25
|
+
/* line 12, ../templates/basic.sass */
|
26
|
+
#page #header h1 {
|
27
|
+
font-size: 50px;
|
28
|
+
color: blue; }
|
29
|
+
|
30
|
+
/* line 18, ../templates/basic.sass */
|
31
|
+
#content.user.show #container.top #column.left {
|
32
|
+
width: 100px; }
|
33
|
+
/* line 20, ../templates/basic.sass */
|
34
|
+
#content.user.show #container.top #column.right {
|
35
|
+
width: 600px; }
|
36
|
+
/* line 22, ../templates/basic.sass */
|
37
|
+
#content.user.show #container.bottom {
|
38
|
+
background: brown; }
|
39
|
+
|
40
|
+
/* line 13, ../templates/importee.sass */
|
41
|
+
midrule {
|
42
|
+
inthe: middle; }
|
43
|
+
|
44
|
+
/* line 12, ../templates/line_numbers.sass */
|
45
|
+
umph {
|
46
|
+
foo: bar; }
|
47
|
+
/* line 18, ../templates/importee.sass */
|
48
|
+
umph baz {
|
49
|
+
blat: bang; }
|