wireframe-haml 2.1.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.
- data/README.rdoc +332 -0
- data/VERSION.yml +4 -0
- data/bin/css2sass +7 -0
- data/bin/haml +9 -0
- data/bin/html2haml +7 -0
- data/bin/sass +8 -0
- data/lib/haml/buffer.rb +255 -0
- data/lib/haml/engine.rb +268 -0
- data/lib/haml/error.rb +22 -0
- data/lib/haml/exec.rb +395 -0
- data/lib/haml/filters.rb +276 -0
- data/lib/haml/helpers/action_view_extensions.rb +45 -0
- data/lib/haml/helpers/action_view_mods.rb +181 -0
- data/lib/haml/helpers.rb +468 -0
- data/lib/haml/html.rb +218 -0
- data/lib/haml/precompiler.rb +889 -0
- data/lib/haml/shared.rb +45 -0
- data/lib/haml/template/patch.rb +58 -0
- data/lib/haml/template/plugin.rb +72 -0
- data/lib/haml/template.rb +51 -0
- data/lib/haml/util.rb +77 -0
- data/lib/haml/version.rb +47 -0
- data/lib/haml.rb +1042 -0
- data/lib/sass/css.rb +388 -0
- data/lib/sass/engine.rb +499 -0
- data/lib/sass/environment.rb +33 -0
- data/lib/sass/error.rb +35 -0
- data/lib/sass/plugin/merb.rb +56 -0
- data/lib/sass/plugin/rails.rb +24 -0
- data/lib/sass/plugin.rb +203 -0
- data/lib/sass/repl.rb +51 -0
- data/lib/sass/script/bool.rb +13 -0
- data/lib/sass/script/color.rb +97 -0
- data/lib/sass/script/funcall.rb +28 -0
- data/lib/sass/script/functions.rb +122 -0
- data/lib/sass/script/lexer.rb +152 -0
- data/lib/sass/script/literal.rb +60 -0
- data/lib/sass/script/number.rb +231 -0
- data/lib/sass/script/operation.rb +30 -0
- data/lib/sass/script/parser.rb +142 -0
- data/lib/sass/script/string.rb +42 -0
- data/lib/sass/script/unary_operation.rb +21 -0
- data/lib/sass/script/variable.rb +20 -0
- data/lib/sass/script.rb +38 -0
- data/lib/sass/tree/attr_node.rb +64 -0
- data/lib/sass/tree/comment_node.rb +34 -0
- data/lib/sass/tree/debug_node.rb +22 -0
- data/lib/sass/tree/directive_node.rb +50 -0
- data/lib/sass/tree/file_node.rb +27 -0
- data/lib/sass/tree/for_node.rb +29 -0
- data/lib/sass/tree/if_node.rb +27 -0
- data/lib/sass/tree/mixin_def_node.rb +18 -0
- data/lib/sass/tree/mixin_node.rb +34 -0
- data/lib/sass/tree/node.rb +99 -0
- data/lib/sass/tree/rule_node.rb +120 -0
- data/lib/sass/tree/variable_node.rb +24 -0
- data/lib/sass/tree/while_node.rb +20 -0
- data/lib/sass.rb +1062 -0
- data/test/benchmark.rb +99 -0
- data/test/haml/engine_test.rb +734 -0
- data/test/haml/helper_test.rb +224 -0
- data/test/haml/html2haml_test.rb +92 -0
- data/test/haml/markaby/standard.mab +52 -0
- data/test/haml/mocks/article.rb +6 -0
- data/test/haml/results/content_for_layout.xhtml +15 -0
- data/test/haml/results/eval_suppressed.xhtml +9 -0
- data/test/haml/results/filters.xhtml +62 -0
- data/test/haml/results/helpers.xhtml +93 -0
- data/test/haml/results/helpful.xhtml +10 -0
- data/test/haml/results/just_stuff.xhtml +68 -0
- data/test/haml/results/list.xhtml +12 -0
- data/test/haml/results/nuke_inner_whitespace.xhtml +40 -0
- data/test/haml/results/nuke_outer_whitespace.xhtml +148 -0
- data/test/haml/results/original_engine.xhtml +20 -0
- data/test/haml/results/partial_layout.xhtml +5 -0
- data/test/haml/results/partials.xhtml +21 -0
- data/test/haml/results/render_layout.xhtml +3 -0
- data/test/haml/results/silent_script.xhtml +74 -0
- data/test/haml/results/standard.xhtml +42 -0
- data/test/haml/results/tag_parsing.xhtml +23 -0
- data/test/haml/results/very_basic.xhtml +5 -0
- data/test/haml/results/whitespace_handling.xhtml +89 -0
- data/test/haml/rhtml/_av_partial_1.rhtml +12 -0
- data/test/haml/rhtml/_av_partial_2.rhtml +8 -0
- data/test/haml/rhtml/action_view.rhtml +62 -0
- data/test/haml/rhtml/standard.rhtml +54 -0
- data/test/haml/template_test.rb +204 -0
- data/test/haml/templates/_av_partial_1.haml +9 -0
- data/test/haml/templates/_av_partial_1_ugly.haml +9 -0
- data/test/haml/templates/_av_partial_2.haml +5 -0
- data/test/haml/templates/_av_partial_2_ugly.haml +5 -0
- data/test/haml/templates/_layout.erb +3 -0
- data/test/haml/templates/_layout_for_partial.haml +3 -0
- data/test/haml/templates/_partial.haml +8 -0
- data/test/haml/templates/_text_area.haml +3 -0
- data/test/haml/templates/action_view.haml +47 -0
- data/test/haml/templates/action_view_ugly.haml +47 -0
- data/test/haml/templates/breakage.haml +8 -0
- data/test/haml/templates/content_for_layout.haml +10 -0
- data/test/haml/templates/eval_suppressed.haml +11 -0
- data/test/haml/templates/filters.haml +66 -0
- data/test/haml/templates/helpers.haml +95 -0
- data/test/haml/templates/helpful.haml +11 -0
- data/test/haml/templates/just_stuff.haml +83 -0
- data/test/haml/templates/list.haml +12 -0
- data/test/haml/templates/nuke_inner_whitespace.haml +32 -0
- data/test/haml/templates/nuke_outer_whitespace.haml +144 -0
- data/test/haml/templates/original_engine.haml +17 -0
- data/test/haml/templates/partial_layout.haml +3 -0
- data/test/haml/templates/partialize.haml +1 -0
- data/test/haml/templates/partials.haml +12 -0
- data/test/haml/templates/render_layout.haml +2 -0
- data/test/haml/templates/silent_script.haml +40 -0
- data/test/haml/templates/standard.haml +42 -0
- data/test/haml/templates/standard_ugly.haml +1 -0
- data/test/haml/templates/tag_parsing.haml +21 -0
- data/test/haml/templates/very_basic.haml +4 -0
- data/test/haml/templates/whitespace_handling.haml +87 -0
- data/test/linked_rails.rb +12 -0
- data/test/sass/css2sass_test.rb +193 -0
- data/test/sass/engine_test.rb +786 -0
- data/test/sass/functions_test.rb +96 -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 +208 -0
- data/test/sass/results/alt.css +4 -0
- data/test/sass/results/basic.css +9 -0
- data/test/sass/results/compact.css +5 -0
- data/test/sass/results/complex.css +87 -0
- data/test/sass/results/compressed.css +1 -0
- data/test/sass/results/expanded.css +19 -0
- data/test/sass/results/import.css +29 -0
- data/test/sass/results/line_numbers.css +49 -0
- data/test/sass/results/mixins.css +95 -0
- data/test/sass/results/multiline.css +24 -0
- data/test/sass/results/nested.css +22 -0
- data/test/sass/results/parent_ref.css +13 -0
- data/test/sass/results/script.css +16 -0
- data/test/sass/results/subdir/nested_subdir/nested_subdir.css +1 -0
- data/test/sass/results/subdir/subdir.css +3 -0
- data/test/sass/results/units.css +11 -0
- data/test/sass/script_test.rb +153 -0
- data/test/sass/templates/_partial.sass +2 -0
- data/test/sass/templates/alt.sass +16 -0
- data/test/sass/templates/basic.sass +23 -0
- data/test/sass/templates/bork.sass +2 -0
- data/test/sass/templates/bork2.sass +2 -0
- data/test/sass/templates/compact.sass +17 -0
- data/test/sass/templates/complex.sass +309 -0
- data/test/sass/templates/compressed.sass +15 -0
- data/test/sass/templates/expanded.sass +17 -0
- data/test/sass/templates/import.sass +11 -0
- data/test/sass/templates/importee.sass +19 -0
- data/test/sass/templates/line_numbers.sass +13 -0
- data/test/sass/templates/mixins.sass +76 -0
- data/test/sass/templates/multiline.sass +20 -0
- data/test/sass/templates/nested.sass +25 -0
- data/test/sass/templates/parent_ref.sass +25 -0
- data/test/sass/templates/script.sass +101 -0
- data/test/sass/templates/subdir/nested_subdir/_nested_partial.sass +2 -0
- data/test/sass/templates/subdir/nested_subdir/nested_subdir.sass +3 -0
- data/test/sass/templates/subdir/subdir.sass +6 -0
- data/test/sass/templates/units.sass +11 -0
- data/test/test_helper.rb +21 -0
- metadata +247 -0
|
@@ -0,0 +1,786 @@
|
|
|
1
|
+
#!/usr/bin/env ruby
|
|
2
|
+
require File.dirname(__FILE__) + '/../test_helper'
|
|
3
|
+
require 'sass/engine'
|
|
4
|
+
require 'stringio'
|
|
5
|
+
|
|
6
|
+
class SassEngineTest < Test::Unit::TestCase
|
|
7
|
+
# A map of erroneous Sass documents to the error messages they should produce.
|
|
8
|
+
# The error messages may be arrays;
|
|
9
|
+
# if so, the second element should be the line number that should be reported for the error.
|
|
10
|
+
# If this isn't provided, the tests will assume the line number should be the last line of the document.
|
|
11
|
+
EXCEPTION_MAP = {
|
|
12
|
+
"!a = 1 + " => 'Expected expression, was end of text.',
|
|
13
|
+
"!a = 1 + 2 +" => 'Expected expression, was end of text.',
|
|
14
|
+
"!a = 1 + 2 + %" => 'Expected expression, was mod token.',
|
|
15
|
+
"!a = foo(\"bar\"" => 'Expected rparen token, was end of text.',
|
|
16
|
+
"!a = 1 }" => 'Unexpected end_interpolation token.',
|
|
17
|
+
"!a = 1 }foo\"" => 'Unexpected end_interpolation token.',
|
|
18
|
+
"!a = #aaa - \"a\"" => 'Undefined operation: "#aaaaaa minus a".',
|
|
19
|
+
"!a = #aaa / \"a\"" => 'Undefined operation: "#aaaaaa div a".',
|
|
20
|
+
"!a = #aaa * \"a\"" => 'Undefined operation: "#aaaaaa times a".',
|
|
21
|
+
"!a = #aaa % \"a\"" => 'Undefined operation: "#aaaaaa mod a".',
|
|
22
|
+
"!a = 1 - \"a\"" => 'Undefined operation: "1 minus a".',
|
|
23
|
+
"!a = 1 * \"a\"" => 'Undefined operation: "1 times a".',
|
|
24
|
+
"!a = 1 / \"a\"" => 'Undefined operation: "1 div a".',
|
|
25
|
+
"!a = 1 % \"a\"" => 'Undefined operation: "1 mod a".',
|
|
26
|
+
":" => 'Invalid attribute: ":".',
|
|
27
|
+
": a" => 'Invalid attribute: ": a".',
|
|
28
|
+
":= a" => 'Invalid attribute: ":= a".',
|
|
29
|
+
"a\n :b" => 'Invalid attribute: ":b ".',
|
|
30
|
+
"a\n :b: c" => 'Invalid attribute: ":b: c".',
|
|
31
|
+
"a\n :b:c d" => 'Invalid attribute: ":b:c d".',
|
|
32
|
+
"a\n :b=c d" => 'Invalid attribute: ":b=c d".',
|
|
33
|
+
"a\n :b c;" => 'Invalid attribute: ":b c;" (This isn\'t CSS!).',
|
|
34
|
+
"a\n b : c" => 'Invalid attribute: "b : c".',
|
|
35
|
+
"a\n b=c: d" => 'Invalid attribute: "b=c: d".',
|
|
36
|
+
":a" => 'Attributes aren\'t allowed at the root of a document.',
|
|
37
|
+
"!" => 'Invalid variable: "!".',
|
|
38
|
+
"!a" => 'Invalid variable: "!a".',
|
|
39
|
+
"! a" => 'Invalid variable: "! a".',
|
|
40
|
+
"!a b" => 'Invalid variable: "!a b".',
|
|
41
|
+
"!a = 1b + 2c" => "Incompatible units: 'c' and 'b'.",
|
|
42
|
+
"a\n :b= 1b * 2c" => "2b*c isn't a valid CSS value.",
|
|
43
|
+
"a\n :b= 1b % 2c" => "Cannot modulo by a number with units: 2c.",
|
|
44
|
+
"!a = 2px + #ccc" => "Cannot add a number with units (2px) to a color (#cccccc).",
|
|
45
|
+
"!a = #ccc + 2px" => "Cannot add a number with units (2px) to a color (#cccccc).",
|
|
46
|
+
"& a\n :b c" => ["Base-level rules cannot contain the parent-selector-referencing character '&'.", 1],
|
|
47
|
+
"a\n :b\n c" => "Illegal nesting: Only attributes may be nested beneath attributes.",
|
|
48
|
+
"a,\n :b c" => ["Rules can\'t end in commas.", 1],
|
|
49
|
+
"a," => "Rules can\'t end in commas.",
|
|
50
|
+
"a,\n!b = 1" => ["Rules can\'t end in commas.", 1],
|
|
51
|
+
"!a = b\n :c d\n" => "Illegal nesting: Nothing may be nested beneath variable declarations.",
|
|
52
|
+
"@import foo.sass" => "File to import not found or unreadable: foo.sass.",
|
|
53
|
+
"@import templates/basic\n foo" => "Illegal nesting: Nothing may be nested beneath import directives.",
|
|
54
|
+
"foo\n @import templates/basic" => "Import directives may only be used at the root of a document.",
|
|
55
|
+
%Q{!foo = "bar" "baz" !} => %Q{Syntax error in '"bar" "baz" !' at character 20.},
|
|
56
|
+
"=foo\n :color red\n.bar\n +bang" => "Undefined mixin 'bang'.",
|
|
57
|
+
".bar\n =foo\n :color red\n" => ["Mixins may only be defined at the root of a document.", 2],
|
|
58
|
+
"=foo\n :color red\n.bar\n +foo\n :color red" => "Illegal nesting: Nothing may be nested beneath mixin directives.",
|
|
59
|
+
" a\n b: c" => ["Indenting at the beginning of the document is illegal.", 1],
|
|
60
|
+
" \n \n\t\n a\n b: c" => ["Indenting at the beginning of the document is illegal.", 4],
|
|
61
|
+
"a\n b: c\n b: c" => ["Inconsistent indentation: 1 space was used for indentation, but the rest of the document was indented using 2 spaces.", 3],
|
|
62
|
+
"a\n b: c\na\n b: c" => ["Inconsistent indentation: 1 space was used for indentation, but the rest of the document was indented using 2 spaces.", 4],
|
|
63
|
+
"a\n\t\tb: c\n\tb: c" => ["Inconsistent indentation: 1 tab was used for indentation, but the rest of the document was indented using 2 tabs.", 3],
|
|
64
|
+
"a\n b: c\n b: c" => ["Inconsistent indentation: 3 spaces were used for indentation, but the rest of the document was indented using 2 spaces.", 3],
|
|
65
|
+
"a\n b: c\n a\n d: e" => ["Inconsistent indentation: 3 spaces were used for indentation, but the rest of the document was indented using 2 spaces.", 4],
|
|
66
|
+
"a\n b: c\na\n d: e" => ["The line was indented 2 levels deeper than the previous line.", 4],
|
|
67
|
+
"a\n b: c\n a\n d: e" => ["The line was indented 3 levels deeper than the previous line.", 4],
|
|
68
|
+
"a\n \tb: c" => ["Indentation can't use both tabs and spaces.", 2],
|
|
69
|
+
"=a(" => 'Invalid mixin "a(".',
|
|
70
|
+
"=a(b)" => 'Mixin argument "b" must begin with an exclamation point (!).',
|
|
71
|
+
"=a(,)" => "Mixin arguments can't be empty.",
|
|
72
|
+
"=a(!)" => "Mixin arguments can't be empty.",
|
|
73
|
+
"=a(!foo bar)" => "Invalid variable \"!foo bar\".",
|
|
74
|
+
"=foo\n bar: baz\n+foo" => ["Attributes aren't allowed at the root of a document.", 2],
|
|
75
|
+
"a-\#{!b\n c: d" => ["Expected end_interpolation token, was end of text.", 1],
|
|
76
|
+
"=a(!b = 1, !c)" => "Required arguments must not follow optional arguments \"!c\".",
|
|
77
|
+
"=a(!b = 1)\n :a= !b\ndiv\n +a(1,2)" => "Mixin a takes 1 argument but 2 were passed.",
|
|
78
|
+
"=a(!b)\n :a= !b\ndiv\n +a" => "Mixin a is missing parameter !b.",
|
|
79
|
+
"@else\n a\n b: c" => ["@else must come after @if.", 1],
|
|
80
|
+
"@if false\n@else foo" => "Invalid else directive '@else foo': expected 'if <expr>'.",
|
|
81
|
+
"@if false\n@else if " => "Invalid else directive '@else if': expected 'if <expr>'.",
|
|
82
|
+
"a\n !b = 12\nc\n d = !b" => 'Undefined variable: "!b".',
|
|
83
|
+
"=foo\n !b = 12\nc\n +foo\n d = !b" => 'Undefined variable: "!b".',
|
|
84
|
+
'@for !a from 1 to "foo"' => '"foo" is not an integer.',
|
|
85
|
+
'@for !a from 1 to 1.232323' => '1.232 is not an integer.',
|
|
86
|
+
'@if' => "Invalid if directive '@if': expected expression.",
|
|
87
|
+
'@while' => "Invalid while directive '@while': expected expression.",
|
|
88
|
+
'@debug' => "Invalid debug directive '@debug': expected expression.",
|
|
89
|
+
|
|
90
|
+
# Regression tests
|
|
91
|
+
"a\n b:\n c\n d" => ["Illegal nesting: Only attributes may be nested beneath attributes.", 3],
|
|
92
|
+
"& foo\n bar: baz\n blat: bang" => ["Base-level rules cannot contain the parent-selector-referencing character '&'.", 1],
|
|
93
|
+
"a\n b: c\n& foo\n bar: baz\n blat: bang" => ["Base-level rules cannot contain the parent-selector-referencing character '&'.", 3],
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
def test_basic_render
|
|
97
|
+
renders_correctly "basic", { :style => :compact }
|
|
98
|
+
end
|
|
99
|
+
|
|
100
|
+
def test_empty_render
|
|
101
|
+
assert_equal "", render("")
|
|
102
|
+
end
|
|
103
|
+
|
|
104
|
+
def test_multiple_calls_to_render
|
|
105
|
+
sass = Sass::Engine.new("a\n b: c")
|
|
106
|
+
assert_equal sass.render, sass.render
|
|
107
|
+
end
|
|
108
|
+
|
|
109
|
+
def test_alternate_styles
|
|
110
|
+
renders_correctly "expanded", { :style => :expanded }
|
|
111
|
+
renders_correctly "compact", { :style => :compact }
|
|
112
|
+
renders_correctly "nested", { :style => :nested }
|
|
113
|
+
renders_correctly "compressed", { :style => :compressed }
|
|
114
|
+
end
|
|
115
|
+
|
|
116
|
+
def test_flexible_tabulation
|
|
117
|
+
assert_equal("p {\n a: b; }\n p q {\n c: d; }\n",
|
|
118
|
+
render("p\n a: b\n q\n c: d\n"))
|
|
119
|
+
assert_equal("p {\n a: b; }\n p q {\n c: d; }\n",
|
|
120
|
+
render("p\n\ta: b\n\tq\n\t\tc: d\n"))
|
|
121
|
+
end
|
|
122
|
+
|
|
123
|
+
def test_exceptions
|
|
124
|
+
EXCEPTION_MAP.each do |key, value|
|
|
125
|
+
begin
|
|
126
|
+
Sass::Engine.new(key).render
|
|
127
|
+
rescue Sass::SyntaxError => err
|
|
128
|
+
value = [value] unless value.is_a?(Array)
|
|
129
|
+
|
|
130
|
+
assert_equal(value.first, err.message, "Line: #{key}")
|
|
131
|
+
assert_equal(value[1] || key.split("\n").length, err.sass_line, "Line: #{key}")
|
|
132
|
+
assert_match(/\(sass\):[0-9]+/, err.backtrace[0], "Line: #{key}")
|
|
133
|
+
else
|
|
134
|
+
assert(false, "Exception not raised for\n#{key}")
|
|
135
|
+
end
|
|
136
|
+
end
|
|
137
|
+
end
|
|
138
|
+
|
|
139
|
+
def test_exception_line
|
|
140
|
+
to_render = <<SASS
|
|
141
|
+
rule
|
|
142
|
+
:attr val
|
|
143
|
+
// comment!
|
|
144
|
+
|
|
145
|
+
:broken
|
|
146
|
+
SASS
|
|
147
|
+
begin
|
|
148
|
+
Sass::Engine.new(to_render).render
|
|
149
|
+
rescue Sass::SyntaxError => err
|
|
150
|
+
assert_equal(5, err.sass_line)
|
|
151
|
+
else
|
|
152
|
+
assert(false, "Exception not raised for '#{to_render}'!")
|
|
153
|
+
end
|
|
154
|
+
end
|
|
155
|
+
|
|
156
|
+
def test_imported_exception
|
|
157
|
+
[nil, 2].each do |i|
|
|
158
|
+
begin
|
|
159
|
+
Sass::Engine.new("@import bork#{i}", :load_paths => [File.dirname(__FILE__) + '/templates/']).render
|
|
160
|
+
rescue Sass::SyntaxError => err
|
|
161
|
+
assert_equal(2, err.sass_line)
|
|
162
|
+
assert_match(/bork#{i}\.sass$/, err.sass_filename)
|
|
163
|
+
else
|
|
164
|
+
assert(false, "Exception not raised for imported template: bork#{i}")
|
|
165
|
+
end
|
|
166
|
+
end
|
|
167
|
+
end
|
|
168
|
+
|
|
169
|
+
def test_css_import
|
|
170
|
+
assert_equal("@import url(./fonts.css) screen;", render("@import url(./fonts.css) screen"))
|
|
171
|
+
assert_equal("@import \"./fonts.css\" screen;", render("@import \"./fonts.css\" screen"))
|
|
172
|
+
end
|
|
173
|
+
|
|
174
|
+
def test_sass_import
|
|
175
|
+
renders_correctly "import", { :style => :compact, :load_paths => [File.dirname(__FILE__) + "/templates"] }
|
|
176
|
+
end
|
|
177
|
+
|
|
178
|
+
def test_units
|
|
179
|
+
renders_correctly "units"
|
|
180
|
+
end
|
|
181
|
+
|
|
182
|
+
def test_default_function
|
|
183
|
+
assert_equal("foo {\n bar: url(foo.png); }\n", render(%Q{foo\n bar = url("foo.png")\n}));
|
|
184
|
+
assert_equal("foo {\n bar: url(); }\n", render("foo\n bar = url()\n"));
|
|
185
|
+
end
|
|
186
|
+
|
|
187
|
+
def test_string_minus
|
|
188
|
+
assert_equal("foo {\n bar: baz-boom-bat; }\n", render(%Q{foo\n bar = "baz"-"boom"-"bat"}))
|
|
189
|
+
assert_equal("foo {\n bar: -baz-boom; }\n", render(%Q{foo\n bar = -"baz"-"boom"}))
|
|
190
|
+
end
|
|
191
|
+
|
|
192
|
+
def test_string_div
|
|
193
|
+
assert_equal("foo {\n bar: baz/boom/bat; }\n", render(%Q{foo\n bar = "baz"/"boom"/"bat"}))
|
|
194
|
+
assert_equal("foo {\n bar: /baz/boom; }\n", render(%Q{foo\n bar = /"baz"/"boom"}))
|
|
195
|
+
end
|
|
196
|
+
|
|
197
|
+
def test_basic_multiline_selector
|
|
198
|
+
assert_equal("#foo #bar,\n#baz #boom {\n foo: bar; }\n",
|
|
199
|
+
render("#foo #bar,\n#baz #boom\n :foo bar"))
|
|
200
|
+
assert_equal("#foo #bar,\n#foo #baz {\n foo: bar; }\n",
|
|
201
|
+
render("#foo\n #bar,\n #baz\n :foo bar"))
|
|
202
|
+
assert_equal("#foo,\n#bar {\n foo: bar; }\n #foo #baz,\n #bar #baz {\n foo: bar; }\n",
|
|
203
|
+
render("#foo,\n#bar\n :foo bar\n #baz\n :foo bar"))
|
|
204
|
+
assert_equal("#foo #bar, #baz #boom { foo: bar; }\n",
|
|
205
|
+
render("#foo #bar,\n#baz #boom\n :foo bar", :style => :compact))
|
|
206
|
+
|
|
207
|
+
assert_equal("#foo #bar,#baz #boom{foo:bar}\n",
|
|
208
|
+
render("#foo #bar,\n#baz #boom\n :foo bar", :style => :compressed))
|
|
209
|
+
end
|
|
210
|
+
|
|
211
|
+
def test_complex_multiline_selector
|
|
212
|
+
renders_correctly "multiline"
|
|
213
|
+
end
|
|
214
|
+
|
|
215
|
+
def test_colon_only
|
|
216
|
+
begin
|
|
217
|
+
render("a\n b: c", :attribute_syntax => :normal)
|
|
218
|
+
rescue Sass::SyntaxError => e
|
|
219
|
+
assert_equal("Illegal attribute syntax: can't use alternate syntax when :attribute_syntax => :normal is set.",
|
|
220
|
+
e.message)
|
|
221
|
+
else
|
|
222
|
+
assert(false, "SyntaxError not raised for :attribute_syntax => :normal")
|
|
223
|
+
end
|
|
224
|
+
|
|
225
|
+
begin
|
|
226
|
+
render("a\n :b c", :attribute_syntax => :alternate)
|
|
227
|
+
rescue Sass::SyntaxError => e
|
|
228
|
+
assert_equal("Illegal attribute syntax: can't use normal syntax when :attribute_syntax => :alternate is set.",
|
|
229
|
+
e.message)
|
|
230
|
+
else
|
|
231
|
+
assert(false, "SyntaxError not raised for :attribute_syntax => :alternate")
|
|
232
|
+
end
|
|
233
|
+
end
|
|
234
|
+
|
|
235
|
+
def test_pseudo_elements
|
|
236
|
+
assert_equal(<<CSS, render(<<SASS))
|
|
237
|
+
::first-line {
|
|
238
|
+
size: 10em; }
|
|
239
|
+
CSS
|
|
240
|
+
::first-line
|
|
241
|
+
size: 10em
|
|
242
|
+
SASS
|
|
243
|
+
end
|
|
244
|
+
|
|
245
|
+
def test_directive
|
|
246
|
+
assert_equal("@a b;", render("@a b"))
|
|
247
|
+
|
|
248
|
+
assert_equal("@a {\n b: c; }\n", render("@a\n :b c"))
|
|
249
|
+
assert_equal("@a { b: c; }\n", render("@a\n :b c", :style => :compact))
|
|
250
|
+
assert_equal("@a {\n b: c;\n}\n", render("@a\n :b c", :style => :expanded))
|
|
251
|
+
assert_equal("@a{b:c}\n", render("@a\n :b c", :style => :compressed))
|
|
252
|
+
|
|
253
|
+
assert_equal("@a {\n b: c;\n d: e; }\n",
|
|
254
|
+
render("@a\n :b c\n :d e"))
|
|
255
|
+
assert_equal("@a { b: c; d: e; }\n",
|
|
256
|
+
render("@a\n :b c\n :d e", :style => :compact))
|
|
257
|
+
assert_equal("@a {\n b: c;\n d: e;\n}\n",
|
|
258
|
+
render("@a\n :b c\n :d e", :style => :expanded))
|
|
259
|
+
assert_equal("@a{b:c;d:e}\n",
|
|
260
|
+
render("@a\n :b c\n :d e", :style => :compressed))
|
|
261
|
+
|
|
262
|
+
assert_equal("@a {\n #b {\n c: d; } }\n",
|
|
263
|
+
render("@a\n #b\n :c d"))
|
|
264
|
+
assert_equal("@a { #b { c: d; } }\n",
|
|
265
|
+
render("@a\n #b\n :c d", :style => :compact))
|
|
266
|
+
assert_equal("@a {\n #b {\n c: d;\n }\n}\n",
|
|
267
|
+
render("@a\n #b\n :c d", :style => :expanded))
|
|
268
|
+
assert_equal("@a{#b{c:d}}\n",
|
|
269
|
+
render("@a\n #b\n :c d", :style => :compressed))
|
|
270
|
+
|
|
271
|
+
assert_equal("@a {\n #b {\n a: b; }\n #b #c {\n d: e; } }\n",
|
|
272
|
+
render("@a\n #b\n :a b\n #c\n :d e"))
|
|
273
|
+
assert_equal("@a { #b { a: b; }\n #b #c { d: e; } }\n",
|
|
274
|
+
render("@a\n #b\n :a b\n #c\n :d e", :style => :compact))
|
|
275
|
+
assert_equal("@a {\n #b {\n a: b;\n }\n #b #c {\n d: e;\n }\n}\n",
|
|
276
|
+
render("@a\n #b\n :a b\n #c\n :d e", :style => :expanded))
|
|
277
|
+
assert_equal("@a{#b{a:b}#b #c{d:e}}\n",
|
|
278
|
+
render("@a\n #b\n :a b\n #c\n :d e", :style => :compressed))
|
|
279
|
+
|
|
280
|
+
assert_equal("@a {\n #foo,\n #bar {\n b: c; } }\n",
|
|
281
|
+
render("@a\n #foo, \n #bar\n :b c"))
|
|
282
|
+
assert_equal("@a { #foo, #bar { b: c; } }\n",
|
|
283
|
+
render("@a\n #foo, \n #bar\n :b c", :style => :compact))
|
|
284
|
+
assert_equal("@a {\n #foo,\n #bar {\n b: c;\n }\n}\n",
|
|
285
|
+
render("@a\n #foo, \n #bar\n :b c", :style => :expanded))
|
|
286
|
+
assert_equal("@a{#foo,#bar{b:c}}\n",
|
|
287
|
+
render("@a\n #foo, \n #bar\n :b c", :style => :compressed))
|
|
288
|
+
|
|
289
|
+
to_render = <<END
|
|
290
|
+
@a
|
|
291
|
+
:b c
|
|
292
|
+
#d
|
|
293
|
+
:e f
|
|
294
|
+
:g h
|
|
295
|
+
END
|
|
296
|
+
rendered = <<END
|
|
297
|
+
@a { b: c;
|
|
298
|
+
#d { e: f; }
|
|
299
|
+
g: h; }
|
|
300
|
+
END
|
|
301
|
+
assert_equal(rendered, render(to_render, :style => :compact))
|
|
302
|
+
|
|
303
|
+
assert_equal("@a{b:c;#d{e:f}g:h}\n", render(to_render, :style => :compressed))
|
|
304
|
+
end
|
|
305
|
+
|
|
306
|
+
def test_line_annotations
|
|
307
|
+
assert_equal(<<CSS, render(<<SASS, :line_comments => true, :style => :compact))
|
|
308
|
+
/* line 2, test_line_annotations_inline.sass */
|
|
309
|
+
foo bar { foo: bar; }
|
|
310
|
+
/* line 5, test_line_annotations_inline.sass */
|
|
311
|
+
foo baz { blip: blop; }
|
|
312
|
+
|
|
313
|
+
/* line 9, test_line_annotations_inline.sass */
|
|
314
|
+
floodle { flop: blop; }
|
|
315
|
+
|
|
316
|
+
/* line 18, test_line_annotations_inline.sass */
|
|
317
|
+
bup { mix: on; }
|
|
318
|
+
/* line 15, test_line_annotations_inline.sass */
|
|
319
|
+
bup mixin { moop: mup; }
|
|
320
|
+
|
|
321
|
+
/* line 22, test_line_annotations_inline.sass */
|
|
322
|
+
bip hop, skip hop { a: b; }
|
|
323
|
+
CSS
|
|
324
|
+
foo
|
|
325
|
+
bar
|
|
326
|
+
foo: bar
|
|
327
|
+
|
|
328
|
+
baz
|
|
329
|
+
blip: blop
|
|
330
|
+
|
|
331
|
+
|
|
332
|
+
floodle
|
|
333
|
+
|
|
334
|
+
flop: blop
|
|
335
|
+
|
|
336
|
+
=mxn
|
|
337
|
+
mix: on
|
|
338
|
+
mixin
|
|
339
|
+
moop: mup
|
|
340
|
+
|
|
341
|
+
bup
|
|
342
|
+
+mxn
|
|
343
|
+
|
|
344
|
+
bip, skip
|
|
345
|
+
hop
|
|
346
|
+
a: b
|
|
347
|
+
SASS
|
|
348
|
+
end
|
|
349
|
+
|
|
350
|
+
def test_line_annotations_with_filename
|
|
351
|
+
renders_correctly "line_numbers", :line_comments => true, :load_paths => [File.dirname(__FILE__) + "/templates"]
|
|
352
|
+
end
|
|
353
|
+
|
|
354
|
+
def test_empty_first_line
|
|
355
|
+
assert_equal("#a {\n b: c; }\n", render("#a\n\n b: c"))
|
|
356
|
+
end
|
|
357
|
+
|
|
358
|
+
def test_escaped_rule
|
|
359
|
+
assert_equal(":focus {\n a: b; }\n", render("\\:focus\n a: b"))
|
|
360
|
+
assert_equal("a {\n b: c; }\n a :focus {\n d: e; }\n", render("\\a\n b: c\n \\:focus\n d: e"))
|
|
361
|
+
end
|
|
362
|
+
|
|
363
|
+
def test_cr_newline
|
|
364
|
+
assert_equal("foo {\n a: b;\n c: d;\n e: f; }\n", render("foo\r a: b\r\n c: d\n\r e: f"))
|
|
365
|
+
end
|
|
366
|
+
|
|
367
|
+
def test_or_eq
|
|
368
|
+
assert_equal("foo {\n a: b; }\n", render(%Q{!foo = "b"\n!foo ||= "c"\nfoo\n a = !foo}))
|
|
369
|
+
assert_equal("foo {\n a: b; }\n", render(%Q{!foo ||= "b"\nfoo\n a = !foo}))
|
|
370
|
+
end
|
|
371
|
+
|
|
372
|
+
def test_mixins
|
|
373
|
+
renders_correctly "mixins", { :style => :expanded }
|
|
374
|
+
end
|
|
375
|
+
|
|
376
|
+
def test_mixins_dont_interfere_with_sibling_combinator
|
|
377
|
+
assert_equal("foo + bar {\n a: b; }\nfoo + baz {\n c: d; }\n",
|
|
378
|
+
render("foo\n +\n bar\n a: b\n baz\n c: d"))
|
|
379
|
+
end
|
|
380
|
+
|
|
381
|
+
def test_mixin_args
|
|
382
|
+
assert_equal("blat {\n baz: hi; }\n", render(<<SASS))
|
|
383
|
+
=foo(!bar)
|
|
384
|
+
baz = !bar
|
|
385
|
+
blat
|
|
386
|
+
+foo(\"hi\")
|
|
387
|
+
SASS
|
|
388
|
+
assert_equal("blat {\n baz: 3; }\n", render(<<SASS))
|
|
389
|
+
=foo(!a, !b)
|
|
390
|
+
baz = !a + !b
|
|
391
|
+
blat
|
|
392
|
+
+foo(1, 2)
|
|
393
|
+
SASS
|
|
394
|
+
assert_equal("blat {\n baz: 4;\n baz: 3;\n baz: 5;\n bang: 3; }\n", render(<<SASS))
|
|
395
|
+
=foo(!c = (6 + 4) / 2)
|
|
396
|
+
baz = !c
|
|
397
|
+
!c = 3
|
|
398
|
+
blat
|
|
399
|
+
+foo(!c + 1)
|
|
400
|
+
+foo((!c + 3)/2)
|
|
401
|
+
+foo
|
|
402
|
+
bang = !c
|
|
403
|
+
SASS
|
|
404
|
+
end
|
|
405
|
+
|
|
406
|
+
def test_default_values_for_mixin_arguments
|
|
407
|
+
assert_equal("white {\n color: white; }\n\nblack {\n color: black; }\n", render(<<SASS))
|
|
408
|
+
=foo(!a = #FFF)
|
|
409
|
+
:color= !a
|
|
410
|
+
white
|
|
411
|
+
+foo
|
|
412
|
+
black
|
|
413
|
+
+foo(#000)
|
|
414
|
+
SASS
|
|
415
|
+
assert_equal(<<CSS, render(<<SASS))
|
|
416
|
+
one {
|
|
417
|
+
color: white;
|
|
418
|
+
padding: 1px;
|
|
419
|
+
margin: 4px; }
|
|
420
|
+
|
|
421
|
+
two {
|
|
422
|
+
color: white;
|
|
423
|
+
padding: 2px;
|
|
424
|
+
margin: 5px; }
|
|
425
|
+
|
|
426
|
+
three {
|
|
427
|
+
color: white;
|
|
428
|
+
padding: 2px;
|
|
429
|
+
margin: 3px; }
|
|
430
|
+
CSS
|
|
431
|
+
!a = 5px
|
|
432
|
+
=foo(!a, !b = 1px, !c = 3px + !b)
|
|
433
|
+
:color= !a
|
|
434
|
+
:padding= !b
|
|
435
|
+
:margin= !c
|
|
436
|
+
one
|
|
437
|
+
+foo(#fff)
|
|
438
|
+
two
|
|
439
|
+
+foo(#fff, 2px)
|
|
440
|
+
three
|
|
441
|
+
+foo(#fff, 2px, 3px)
|
|
442
|
+
SASS
|
|
443
|
+
end
|
|
444
|
+
|
|
445
|
+
def test_interpolation
|
|
446
|
+
assert_equal("a-1 {\n b-2-3: c-3; }\n", render(<<SASS))
|
|
447
|
+
!a = 1
|
|
448
|
+
!b = 2
|
|
449
|
+
!c = 3
|
|
450
|
+
a-\#{!a}
|
|
451
|
+
b-\#{!b}-\#{!c}: c-\#{!a + !b}
|
|
452
|
+
SASS
|
|
453
|
+
end
|
|
454
|
+
|
|
455
|
+
def test_booleans
|
|
456
|
+
assert_equal(<<CSS, render(<<SASS))
|
|
457
|
+
a {
|
|
458
|
+
b: true;
|
|
459
|
+
c: false;
|
|
460
|
+
t1: true;
|
|
461
|
+
t2: true;
|
|
462
|
+
t3: true;
|
|
463
|
+
t4: true;
|
|
464
|
+
f1: false;
|
|
465
|
+
f2: false;
|
|
466
|
+
f3: false;
|
|
467
|
+
f4: false; }
|
|
468
|
+
CSS
|
|
469
|
+
a
|
|
470
|
+
b = true
|
|
471
|
+
c = false
|
|
472
|
+
t1 = true and true
|
|
473
|
+
t2 = false or true
|
|
474
|
+
t3 = true or false
|
|
475
|
+
t4 = true or true
|
|
476
|
+
f1 = false or false
|
|
477
|
+
f2 = false and true
|
|
478
|
+
f3 = true and false
|
|
479
|
+
f4 = false and false
|
|
480
|
+
SASS
|
|
481
|
+
assert_equal(<<CSS, render(<<SASS))
|
|
482
|
+
a {
|
|
483
|
+
b: true;
|
|
484
|
+
c: false; }
|
|
485
|
+
CSS
|
|
486
|
+
!var = true
|
|
487
|
+
a
|
|
488
|
+
b = not not !var
|
|
489
|
+
c = not !var
|
|
490
|
+
SASS
|
|
491
|
+
end
|
|
492
|
+
|
|
493
|
+
def test_boolean_ops
|
|
494
|
+
assert_equal("a {\n b: 1;\n c: 2;\n d: 3; }\n", render(<<SASS))
|
|
495
|
+
a
|
|
496
|
+
b = false or 1
|
|
497
|
+
c = 2 or 3
|
|
498
|
+
d = 2 and 3
|
|
499
|
+
SASS
|
|
500
|
+
end
|
|
501
|
+
|
|
502
|
+
def test_relational_ops
|
|
503
|
+
assert_equal(<<CSS, render(<<SASS))
|
|
504
|
+
a {
|
|
505
|
+
gt1: false;
|
|
506
|
+
gt2: false;
|
|
507
|
+
gt3: true;
|
|
508
|
+
gte1: false;
|
|
509
|
+
gte2: true;
|
|
510
|
+
gte3: true;
|
|
511
|
+
lt1: true;
|
|
512
|
+
lt2: false;
|
|
513
|
+
lt3: false;
|
|
514
|
+
lte1: true;
|
|
515
|
+
lte2: true;
|
|
516
|
+
lte3: false; }
|
|
517
|
+
CSS
|
|
518
|
+
a
|
|
519
|
+
gt1 = 1 > 2
|
|
520
|
+
gt2 = 2 > 2
|
|
521
|
+
gt3 = 3 > 2
|
|
522
|
+
gte1 = 1 >= 2
|
|
523
|
+
gte2 = 2 >= 2
|
|
524
|
+
gte3 = 3 >= 2
|
|
525
|
+
lt1 = 1 < 2
|
|
526
|
+
lt2 = 2 < 2
|
|
527
|
+
lt3 = 3 < 2
|
|
528
|
+
lte1 = 1 <= 2
|
|
529
|
+
lte2 = 2 <= 2
|
|
530
|
+
lte3 = 3 <= 2
|
|
531
|
+
SASS
|
|
532
|
+
end
|
|
533
|
+
|
|
534
|
+
def test_functions
|
|
535
|
+
assert_equal("a {\n b: #80ff80; }\n", render("a\n b = hsl(120, 100%, 75%)"))
|
|
536
|
+
assert_equal("a {\n b: #81ff81; }\n", render("a\n b = hsl(120, 100%, 75%) + #010001"))
|
|
537
|
+
end
|
|
538
|
+
|
|
539
|
+
def test_if_directive
|
|
540
|
+
assert_equal("a {\n b: 1; }\n", render(<<SASS))
|
|
541
|
+
!var = true
|
|
542
|
+
a
|
|
543
|
+
@if !var
|
|
544
|
+
b: 1
|
|
545
|
+
@if not !var
|
|
546
|
+
b: 2
|
|
547
|
+
SASS
|
|
548
|
+
end
|
|
549
|
+
|
|
550
|
+
def test_equals
|
|
551
|
+
assert_equal(<<CSS, render(<<SASS))
|
|
552
|
+
a {
|
|
553
|
+
t1: true;
|
|
554
|
+
t2: true;
|
|
555
|
+
t3: true;
|
|
556
|
+
f1: false;
|
|
557
|
+
f2: false; }
|
|
558
|
+
CSS
|
|
559
|
+
!foo = "foo"
|
|
560
|
+
a
|
|
561
|
+
t1 = "foo" == !foo
|
|
562
|
+
t2 = 1 == 1.0
|
|
563
|
+
t3 = false != true
|
|
564
|
+
f1 = 1em == 1px
|
|
565
|
+
f2 = 12 != 12
|
|
566
|
+
SASS
|
|
567
|
+
end
|
|
568
|
+
|
|
569
|
+
def test_for
|
|
570
|
+
assert_equal(<<CSS, render(<<SASS))
|
|
571
|
+
a-0 {
|
|
572
|
+
2i: 0; }
|
|
573
|
+
|
|
574
|
+
a-1 {
|
|
575
|
+
2i: 2; }
|
|
576
|
+
|
|
577
|
+
a-2 {
|
|
578
|
+
2i: 4; }
|
|
579
|
+
|
|
580
|
+
a-3 {
|
|
581
|
+
2i: 6; }
|
|
582
|
+
|
|
583
|
+
b-1 {
|
|
584
|
+
j-1: 0; }
|
|
585
|
+
|
|
586
|
+
b-2 {
|
|
587
|
+
j-1: 1; }
|
|
588
|
+
|
|
589
|
+
b-3 {
|
|
590
|
+
j-1: 2; }
|
|
591
|
+
|
|
592
|
+
b-4 {
|
|
593
|
+
j-1: 3; }
|
|
594
|
+
CSS
|
|
595
|
+
!a = 3
|
|
596
|
+
@for !i from 0 to !a + 1
|
|
597
|
+
a-\#{!i}
|
|
598
|
+
2i = 2 * !i
|
|
599
|
+
|
|
600
|
+
@for !j from 1 through 4
|
|
601
|
+
b-\#{!j}
|
|
602
|
+
j-1 = !j - 1
|
|
603
|
+
SASS
|
|
604
|
+
end
|
|
605
|
+
|
|
606
|
+
def test_while
|
|
607
|
+
assert_equal(<<CSS, render(<<SASS))
|
|
608
|
+
a-5 {
|
|
609
|
+
blooble: gloop; }
|
|
610
|
+
|
|
611
|
+
a-4 {
|
|
612
|
+
blooble: gloop; }
|
|
613
|
+
|
|
614
|
+
a-3 {
|
|
615
|
+
blooble: gloop; }
|
|
616
|
+
|
|
617
|
+
a-2 {
|
|
618
|
+
blooble: gloop; }
|
|
619
|
+
|
|
620
|
+
a-1 {
|
|
621
|
+
blooble: gloop; }
|
|
622
|
+
CSS
|
|
623
|
+
!a = 5
|
|
624
|
+
@while !a != 0
|
|
625
|
+
a-\#{!a}
|
|
626
|
+
blooble: gloop
|
|
627
|
+
!a = !a - 1
|
|
628
|
+
SASS
|
|
629
|
+
end
|
|
630
|
+
|
|
631
|
+
def test_else
|
|
632
|
+
assert_equal(<<CSS, render(<<SASS))
|
|
633
|
+
a {
|
|
634
|
+
t1: t;
|
|
635
|
+
t2: t;
|
|
636
|
+
t3: t;
|
|
637
|
+
t4: t; }
|
|
638
|
+
CSS
|
|
639
|
+
a
|
|
640
|
+
@if true
|
|
641
|
+
t1: t
|
|
642
|
+
@else
|
|
643
|
+
f1: f
|
|
644
|
+
|
|
645
|
+
@if false
|
|
646
|
+
f2: f
|
|
647
|
+
@else
|
|
648
|
+
t2: t
|
|
649
|
+
|
|
650
|
+
@if false
|
|
651
|
+
f3: f1
|
|
652
|
+
@else if 1 + 1 == 3
|
|
653
|
+
f3: f2
|
|
654
|
+
@else
|
|
655
|
+
t3: t
|
|
656
|
+
|
|
657
|
+
@if false
|
|
658
|
+
f4: f1
|
|
659
|
+
@else if 1 + 1 == 2
|
|
660
|
+
t4: t
|
|
661
|
+
@else
|
|
662
|
+
f4: f2
|
|
663
|
+
|
|
664
|
+
@if false
|
|
665
|
+
f5: f1
|
|
666
|
+
@else if false
|
|
667
|
+
f5: f2
|
|
668
|
+
SASS
|
|
669
|
+
end
|
|
670
|
+
|
|
671
|
+
def test_operation_precedence
|
|
672
|
+
assert_equal(<<CSS, render(<<SASS))
|
|
673
|
+
a {
|
|
674
|
+
p1: false true;
|
|
675
|
+
p2: true;
|
|
676
|
+
p3: true;
|
|
677
|
+
p4: true;
|
|
678
|
+
p5: true;
|
|
679
|
+
p6: 11; }
|
|
680
|
+
CSS
|
|
681
|
+
a
|
|
682
|
+
p1 = true and false false or true
|
|
683
|
+
p2 = false and true or true and true
|
|
684
|
+
p3 = 1 == 2 or 3 == 3
|
|
685
|
+
p4 = 1 < 2 == 3 >= 3
|
|
686
|
+
p5 = 1 + 3 > 4 - 2
|
|
687
|
+
p6 = 1 + 2 * 3 + 4
|
|
688
|
+
SASS
|
|
689
|
+
end
|
|
690
|
+
|
|
691
|
+
def test_variable_reassignment
|
|
692
|
+
assert_equal(<<CSS, render(<<SASS))
|
|
693
|
+
a {
|
|
694
|
+
b: 1;
|
|
695
|
+
c: 2; }
|
|
696
|
+
CSS
|
|
697
|
+
!a = 1
|
|
698
|
+
a
|
|
699
|
+
b = !a
|
|
700
|
+
!a = 2
|
|
701
|
+
c = !a
|
|
702
|
+
SASS
|
|
703
|
+
end
|
|
704
|
+
|
|
705
|
+
def test_variable_scope
|
|
706
|
+
assert_equal(<<CSS, render(<<SASS))
|
|
707
|
+
a {
|
|
708
|
+
b-1: c;
|
|
709
|
+
b-2: c;
|
|
710
|
+
d: 12; }
|
|
711
|
+
|
|
712
|
+
b {
|
|
713
|
+
d: 17; }
|
|
714
|
+
CSS
|
|
715
|
+
!i = 12
|
|
716
|
+
a
|
|
717
|
+
@for !i from 1 through 2
|
|
718
|
+
b-\#{!i}: c
|
|
719
|
+
d = !i
|
|
720
|
+
|
|
721
|
+
=foo
|
|
722
|
+
!i = 17
|
|
723
|
+
|
|
724
|
+
b
|
|
725
|
+
+foo
|
|
726
|
+
d = !i
|
|
727
|
+
SASS
|
|
728
|
+
end
|
|
729
|
+
|
|
730
|
+
def test_argument_error
|
|
731
|
+
assert_raise(Sass::SyntaxError) { render("a\n b = hsl(1)") }
|
|
732
|
+
end
|
|
733
|
+
|
|
734
|
+
def test_comments_at_the_top_of_a_document
|
|
735
|
+
render(<<SASS)
|
|
736
|
+
//
|
|
737
|
+
This is a comment that
|
|
738
|
+
continues to the second line.
|
|
739
|
+
foo
|
|
740
|
+
bar: baz
|
|
741
|
+
SASS
|
|
742
|
+
end
|
|
743
|
+
|
|
744
|
+
def test_loud_comments_containing_a_comment_close
|
|
745
|
+
actual_css = render(<<SASS)
|
|
746
|
+
/*
|
|
747
|
+
This is a comment that
|
|
748
|
+
continues to the second line. */
|
|
749
|
+
foo
|
|
750
|
+
bar: baz
|
|
751
|
+
SASS
|
|
752
|
+
assert_equal(<<CSS, actual_css)
|
|
753
|
+
/*
|
|
754
|
+
* This is a comment that
|
|
755
|
+
* continues to the second line. */
|
|
756
|
+
foo {
|
|
757
|
+
bar: baz; }
|
|
758
|
+
CSS
|
|
759
|
+
end
|
|
760
|
+
|
|
761
|
+
private
|
|
762
|
+
|
|
763
|
+
def render(sass, options = {})
|
|
764
|
+
munge_filename options
|
|
765
|
+
Sass::Engine.new(sass, options).render
|
|
766
|
+
end
|
|
767
|
+
|
|
768
|
+
def renders_correctly(name, options={})
|
|
769
|
+
sass_file = load_file(name, "sass")
|
|
770
|
+
css_file = load_file(name, "css")
|
|
771
|
+
options[:filename] ||= filename(name, "sass")
|
|
772
|
+
options[:css_filename] ||= filename(name, "css")
|
|
773
|
+
css_result = Sass::Engine.new(sass_file, options).render
|
|
774
|
+
assert_equal css_file, css_result
|
|
775
|
+
end
|
|
776
|
+
|
|
777
|
+
def load_file(name, type = "sass")
|
|
778
|
+
@result = ''
|
|
779
|
+
File.new(filename(name, type)).each_line { |l| @result += l }
|
|
780
|
+
@result
|
|
781
|
+
end
|
|
782
|
+
|
|
783
|
+
def filename(name, type)
|
|
784
|
+
File.dirname(__FILE__) + "/#{type == 'sass' ? 'templates' : 'results'}/#{name}.#{type}"
|
|
785
|
+
end
|
|
786
|
+
end
|