sass 3.1.0.alpha.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (205) hide show
  1. data/.yardopts +11 -0
  2. data/CONTRIBUTING +3 -0
  3. data/EDGE_GEM_VERSION +1 -0
  4. data/MIT-LICENSE +20 -0
  5. data/README.md +201 -0
  6. data/REVISION +1 -0
  7. data/Rakefile +353 -0
  8. data/VERSION +1 -0
  9. data/VERSION_NAME +1 -0
  10. data/bin/css2sass +13 -0
  11. data/bin/sass +8 -0
  12. data/bin/sass-convert +7 -0
  13. data/extra/update_watch.rb +13 -0
  14. data/init.rb +18 -0
  15. data/lib/sass.rb +71 -0
  16. data/lib/sass/cache_store.rb +208 -0
  17. data/lib/sass/callbacks.rb +66 -0
  18. data/lib/sass/css.rb +294 -0
  19. data/lib/sass/engine.rb +792 -0
  20. data/lib/sass/environment.rb +143 -0
  21. data/lib/sass/error.rb +201 -0
  22. data/lib/sass/exec.rb +619 -0
  23. data/lib/sass/importers.rb +22 -0
  24. data/lib/sass/importers/base.rb +138 -0
  25. data/lib/sass/importers/filesystem.rb +121 -0
  26. data/lib/sass/less.rb +363 -0
  27. data/lib/sass/plugin.rb +126 -0
  28. data/lib/sass/plugin/compiler.rb +346 -0
  29. data/lib/sass/plugin/configuration.rb +123 -0
  30. data/lib/sass/plugin/generic.rb +15 -0
  31. data/lib/sass/plugin/merb.rb +48 -0
  32. data/lib/sass/plugin/rack.rb +47 -0
  33. data/lib/sass/plugin/rails.rb +41 -0
  34. data/lib/sass/plugin/staleness_checker.rb +145 -0
  35. data/lib/sass/railtie.rb +8 -0
  36. data/lib/sass/repl.rb +58 -0
  37. data/lib/sass/root.rb +7 -0
  38. data/lib/sass/script.rb +63 -0
  39. data/lib/sass/script/bool.rb +18 -0
  40. data/lib/sass/script/color.rb +490 -0
  41. data/lib/sass/script/css_lexer.rb +29 -0
  42. data/lib/sass/script/css_parser.rb +31 -0
  43. data/lib/sass/script/funcall.rb +78 -0
  44. data/lib/sass/script/functions.rb +852 -0
  45. data/lib/sass/script/interpolation.rb +70 -0
  46. data/lib/sass/script/lexer.rb +337 -0
  47. data/lib/sass/script/literal.rb +236 -0
  48. data/lib/sass/script/node.rb +101 -0
  49. data/lib/sass/script/number.rb +420 -0
  50. data/lib/sass/script/operation.rb +92 -0
  51. data/lib/sass/script/parser.rb +392 -0
  52. data/lib/sass/script/string.rb +67 -0
  53. data/lib/sass/script/string_interpolation.rb +93 -0
  54. data/lib/sass/script/unary_operation.rb +57 -0
  55. data/lib/sass/script/variable.rb +48 -0
  56. data/lib/sass/scss.rb +17 -0
  57. data/lib/sass/scss/css_parser.rb +51 -0
  58. data/lib/sass/scss/parser.rb +838 -0
  59. data/lib/sass/scss/rx.rb +126 -0
  60. data/lib/sass/scss/sass_parser.rb +11 -0
  61. data/lib/sass/scss/script_lexer.rb +15 -0
  62. data/lib/sass/scss/script_parser.rb +25 -0
  63. data/lib/sass/scss/static_parser.rb +40 -0
  64. data/lib/sass/selector.rb +361 -0
  65. data/lib/sass/selector/abstract_sequence.rb +62 -0
  66. data/lib/sass/selector/comma_sequence.rb +82 -0
  67. data/lib/sass/selector/sequence.rb +236 -0
  68. data/lib/sass/selector/simple.rb +113 -0
  69. data/lib/sass/selector/simple_sequence.rb +135 -0
  70. data/lib/sass/shared.rb +78 -0
  71. data/lib/sass/tree/comment_node.rb +128 -0
  72. data/lib/sass/tree/debug_node.rb +36 -0
  73. data/lib/sass/tree/directive_node.rb +75 -0
  74. data/lib/sass/tree/extend_node.rb +65 -0
  75. data/lib/sass/tree/for_node.rb +67 -0
  76. data/lib/sass/tree/if_node.rb +81 -0
  77. data/lib/sass/tree/import_node.rb +124 -0
  78. data/lib/sass/tree/mixin_def_node.rb +60 -0
  79. data/lib/sass/tree/mixin_node.rb +123 -0
  80. data/lib/sass/tree/node.rb +490 -0
  81. data/lib/sass/tree/prop_node.rb +220 -0
  82. data/lib/sass/tree/root_node.rb +125 -0
  83. data/lib/sass/tree/rule_node.rb +273 -0
  84. data/lib/sass/tree/variable_node.rb +39 -0
  85. data/lib/sass/tree/warn_node.rb +42 -0
  86. data/lib/sass/tree/while_node.rb +48 -0
  87. data/lib/sass/util.rb +687 -0
  88. data/lib/sass/util/subset_map.rb +101 -0
  89. data/lib/sass/version.rb +109 -0
  90. data/rails/init.rb +1 -0
  91. data/test/sass/cache_test.rb +74 -0
  92. data/test/sass/callbacks_test.rb +61 -0
  93. data/test/sass/conversion_test.rb +1210 -0
  94. data/test/sass/css2sass_test.rb +364 -0
  95. data/test/sass/data/hsl-rgb.txt +319 -0
  96. data/test/sass/engine_test.rb +2273 -0
  97. data/test/sass/extend_test.rb +1348 -0
  98. data/test/sass/functions_test.rb +565 -0
  99. data/test/sass/importer_test.rb +104 -0
  100. data/test/sass/less_conversion_test.rb +632 -0
  101. data/test/sass/mock_importer.rb +49 -0
  102. data/test/sass/more_results/more1.css +9 -0
  103. data/test/sass/more_results/more1_with_line_comments.css +26 -0
  104. data/test/sass/more_results/more_import.css +29 -0
  105. data/test/sass/more_templates/_more_partial.sass +2 -0
  106. data/test/sass/more_templates/more1.sass +23 -0
  107. data/test/sass/more_templates/more_import.sass +11 -0
  108. data/test/sass/plugin_test.rb +430 -0
  109. data/test/sass/results/alt.css +4 -0
  110. data/test/sass/results/basic.css +9 -0
  111. data/test/sass/results/compact.css +5 -0
  112. data/test/sass/results/complex.css +86 -0
  113. data/test/sass/results/compressed.css +1 -0
  114. data/test/sass/results/expanded.css +19 -0
  115. data/test/sass/results/import.css +31 -0
  116. data/test/sass/results/line_numbers.css +49 -0
  117. data/test/sass/results/mixins.css +95 -0
  118. data/test/sass/results/multiline.css +24 -0
  119. data/test/sass/results/nested.css +22 -0
  120. data/test/sass/results/options.css +1 -0
  121. data/test/sass/results/parent_ref.css +13 -0
  122. data/test/sass/results/script.css +16 -0
  123. data/test/sass/results/scss_import.css +31 -0
  124. data/test/sass/results/scss_importee.css +2 -0
  125. data/test/sass/results/subdir/nested_subdir/nested_subdir.css +1 -0
  126. data/test/sass/results/subdir/subdir.css +3 -0
  127. data/test/sass/results/units.css +11 -0
  128. data/test/sass/results/warn.css +0 -0
  129. data/test/sass/results/warn_imported.css +0 -0
  130. data/test/sass/script_conversion_test.rb +254 -0
  131. data/test/sass/script_test.rb +459 -0
  132. data/test/sass/scss/css_test.rb +897 -0
  133. data/test/sass/scss/rx_test.rb +156 -0
  134. data/test/sass/scss/scss_test.rb +1088 -0
  135. data/test/sass/scss/test_helper.rb +37 -0
  136. data/test/sass/templates/_partial.sass +2 -0
  137. data/test/sass/templates/alt.sass +16 -0
  138. data/test/sass/templates/basic.sass +23 -0
  139. data/test/sass/templates/bork1.sass +2 -0
  140. data/test/sass/templates/bork2.sass +2 -0
  141. data/test/sass/templates/bork3.sass +2 -0
  142. data/test/sass/templates/bork4.sass +2 -0
  143. data/test/sass/templates/compact.sass +17 -0
  144. data/test/sass/templates/complex.sass +305 -0
  145. data/test/sass/templates/compressed.sass +15 -0
  146. data/test/sass/templates/expanded.sass +17 -0
  147. data/test/sass/templates/import.sass +12 -0
  148. data/test/sass/templates/importee.less +2 -0
  149. data/test/sass/templates/importee.sass +19 -0
  150. data/test/sass/templates/line_numbers.sass +13 -0
  151. data/test/sass/templates/mixin_bork.sass +5 -0
  152. data/test/sass/templates/mixins.sass +76 -0
  153. data/test/sass/templates/multiline.sass +20 -0
  154. data/test/sass/templates/nested.sass +25 -0
  155. data/test/sass/templates/nested_bork1.sass +2 -0
  156. data/test/sass/templates/nested_bork2.sass +2 -0
  157. data/test/sass/templates/nested_bork3.sass +2 -0
  158. data/test/sass/templates/nested_bork4.sass +2 -0
  159. data/test/sass/templates/nested_mixin_bork.sass +6 -0
  160. data/test/sass/templates/options.sass +2 -0
  161. data/test/sass/templates/parent_ref.sass +25 -0
  162. data/test/sass/templates/script.sass +101 -0
  163. data/test/sass/templates/scss_import.scss +11 -0
  164. data/test/sass/templates/scss_importee.scss +1 -0
  165. data/test/sass/templates/subdir/nested_subdir/_nested_partial.sass +2 -0
  166. data/test/sass/templates/subdir/nested_subdir/nested_subdir.sass +3 -0
  167. data/test/sass/templates/subdir/subdir.sass +6 -0
  168. data/test/sass/templates/units.sass +11 -0
  169. data/test/sass/templates/warn.sass +3 -0
  170. data/test/sass/templates/warn_imported.sass +4 -0
  171. data/test/sass/test_helper.rb +8 -0
  172. data/test/sass/util/subset_map_test.rb +91 -0
  173. data/test/sass/util_test.rb +275 -0
  174. data/test/test_helper.rb +64 -0
  175. data/vendor/fssm/LICENSE +20 -0
  176. data/vendor/fssm/README.markdown +55 -0
  177. data/vendor/fssm/Rakefile +59 -0
  178. data/vendor/fssm/VERSION.yml +5 -0
  179. data/vendor/fssm/example.rb +9 -0
  180. data/vendor/fssm/fssm.gemspec +77 -0
  181. data/vendor/fssm/lib/fssm.rb +33 -0
  182. data/vendor/fssm/lib/fssm/backends/fsevents.rb +36 -0
  183. data/vendor/fssm/lib/fssm/backends/inotify.rb +26 -0
  184. data/vendor/fssm/lib/fssm/backends/polling.rb +25 -0
  185. data/vendor/fssm/lib/fssm/backends/rubycocoa/fsevents.rb +131 -0
  186. data/vendor/fssm/lib/fssm/monitor.rb +26 -0
  187. data/vendor/fssm/lib/fssm/path.rb +91 -0
  188. data/vendor/fssm/lib/fssm/pathname.rb +502 -0
  189. data/vendor/fssm/lib/fssm/state/directory.rb +57 -0
  190. data/vendor/fssm/lib/fssm/state/file.rb +24 -0
  191. data/vendor/fssm/lib/fssm/support.rb +63 -0
  192. data/vendor/fssm/lib/fssm/tree.rb +176 -0
  193. data/vendor/fssm/profile/prof-cache.rb +40 -0
  194. data/vendor/fssm/profile/prof-fssm-pathname.html +1231 -0
  195. data/vendor/fssm/profile/prof-pathname.rb +68 -0
  196. data/vendor/fssm/profile/prof-plain-pathname.html +988 -0
  197. data/vendor/fssm/profile/prof.html +2379 -0
  198. data/vendor/fssm/spec/path_spec.rb +75 -0
  199. data/vendor/fssm/spec/root/duck/quack.txt +0 -0
  200. data/vendor/fssm/spec/root/file.css +0 -0
  201. data/vendor/fssm/spec/root/file.rb +0 -0
  202. data/vendor/fssm/spec/root/file.yml +0 -0
  203. data/vendor/fssm/spec/root/moo/cow.txt +0 -0
  204. data/vendor/fssm/spec/spec_helper.rb +14 -0
  205. metadata +297 -0
@@ -0,0 +1,2273 @@
1
+ #!/usr/bin/env ruby
2
+ # -*- coding: utf-8 -*-
3
+ require File.dirname(__FILE__) + '/../test_helper'
4
+ require File.dirname(__FILE__) + '/test_helper'
5
+ require 'sass/engine'
6
+ require 'stringio'
7
+ require 'mock_importer'
8
+
9
+ module Sass::Script::Functions::UserFunctions
10
+ def option(name)
11
+ Sass::Script::String.new(@options[name.value.to_sym].to_s)
12
+ end
13
+ end
14
+
15
+ class SassEngineTest < Test::Unit::TestCase
16
+ FAKE_FILE_NAME = __FILE__.gsub(/rb$/,"sass")
17
+ # A map of erroneous Sass documents to the error messages they should produce.
18
+ # The error messages may be arrays;
19
+ # if so, the second element should be the line number that should be reported for the error.
20
+ # If this isn't provided, the tests will assume the line number should be the last line of the document.
21
+ EXCEPTION_MAP = {
22
+ "$a: 1 + " => 'Invalid CSS after "1 +": expected expression (e.g. 1px, bold), was ""',
23
+ "$a: 1 + 2 +" => 'Invalid CSS after "1 + 2 +": expected expression (e.g. 1px, bold), was ""',
24
+ "$a: 1 + 2 + %" => 'Invalid CSS after "1 + 2 + ": expected expression (e.g. 1px, bold), was "%"',
25
+ "$a: foo(\"bar\"" => 'Invalid CSS after "foo("bar"": expected ")", was ""',
26
+ "$a: 1 }" => 'Invalid CSS after "1 ": expected expression (e.g. 1px, bold), was "}"',
27
+ "$a: 1 }foo\"" => 'Invalid CSS after "1 ": expected expression (e.g. 1px, bold), was "}foo""',
28
+ ":" => 'Invalid property: ":".',
29
+ ": a" => 'Invalid property: ": a".',
30
+ "a\n :b" => <<MSG,
31
+ Invalid property: ":b" (no value).
32
+ If ":b" should be a selector, use "\\:b" instead.
33
+ MSG
34
+ "a\n b:" => 'Invalid property: "b:" (no value).',
35
+ "a\n :b: c" => 'Invalid property: ":b: c".',
36
+ "a\n :b:c d" => 'Invalid property: ":b:c d".',
37
+ "a\n :b c;" => 'Invalid CSS after "c": expected expression (e.g. 1px, bold), was ";"',
38
+ "a\n b: c;" => 'Invalid CSS after "c": expected expression (e.g. 1px, bold), was ";"',
39
+ ".foo ^bar\n a: b" => ['Invalid CSS after ".foo ": expected selector, was "^bar"', 1],
40
+ "a\n @extend .foo ^bar" => 'Invalid CSS after ".foo ": expected selector, was "^bar"',
41
+ "a: b" => 'Properties aren\'t allowed at the root of a document.',
42
+ ":a b" => 'Properties aren\'t allowed at the root of a document.',
43
+ "!" => 'Invalid variable: "!".',
44
+ "$a" => 'Invalid variable: "$a".',
45
+ "! a" => 'Invalid variable: "! a".',
46
+ "$a b" => 'Invalid variable: "$a b".',
47
+ "$a: 1b + 2c" => "Incompatible units: 'c' and 'b'.",
48
+ "$a: 1b < 2c" => "Incompatible units: 'c' and 'b'.",
49
+ "$a: 1b > 2c" => "Incompatible units: 'c' and 'b'.",
50
+ "$a: 1b <= 2c" => "Incompatible units: 'c' and 'b'.",
51
+ "$a: 1b >= 2c" => "Incompatible units: 'c' and 'b'.",
52
+ "a\n b: 1b * 2c" => "2b*c isn't a valid CSS value.",
53
+ "a\n b: 1b % 2c" => "Cannot modulo by a number with units: 2c.",
54
+ "$a: 2px + #ccc" => "Cannot add a number with units (2px) to a color (#cccccc).",
55
+ "$a: #ccc + 2px" => "Cannot add a number with units (2px) to a color (#cccccc).",
56
+ "& a\n :b c" => ["Base-level rules cannot contain the parent-selector-referencing character '&'.", 1],
57
+ "a\n :b\n c" => "Illegal nesting: Only properties may be nested beneath properties.",
58
+ "a,\n :b c" => ["Rules can\'t end in commas.", 1],
59
+ "a," => "Rules can\'t end in commas.",
60
+ "a,\n$b: 1" => ["Rules can\'t end in commas.", 1],
61
+ "$a: b\n :c d\n" => "Illegal nesting: Nothing may be nested beneath variable declarations.",
62
+ "@import foo.sass" => "File to import not found or unreadable: foo.sass.",
63
+ "a,\n$b: 1" => ["Rules can\'t end in commas.", 1],
64
+ "$a: b\n :c d\n" => "Illegal nesting: Nothing may be nested beneath variable declarations.",
65
+ "@import foo.sass" => <<MSG,
66
+ File to import not found or unreadable: foo.sass.
67
+ Load path: .
68
+ MSG
69
+ "@import templates/basic\n foo" => "Illegal nesting: Nothing may be nested beneath import directives.",
70
+ "foo\n @import templates/basic" => "Import directives may only be used at the root of a document.",
71
+ "foo\n @import #{File.dirname(__FILE__)}/templates/basic" => "Import directives may only be used at the root of a document.",
72
+ '$foo: "bar" "baz" !' => %Q{Invalid CSS after ""bar" "baz" ": expected expression (e.g. 1px, bold), was "!"},
73
+ "=foo\n :color red\n.bar\n +bang" => "Undefined mixin 'bang'.",
74
+ "=foo\n :color red\n.bar\n +bang_bop" => "Undefined mixin 'bang_bop'.",
75
+ "=foo\n :color red\n.bar\n +bang-bop" => "Undefined mixin 'bang-bop'.",
76
+ ".bar\n =foo\n :color red\n" => ["Mixins may only be defined at the root of a document.", 2],
77
+ "=foo\n :color red\n.bar\n +foo\n :color red" => "Illegal nesting: Nothing may be nested beneath mixin directives.",
78
+ " a\n b: c" => ["Indenting at the beginning of the document is illegal.", 1],
79
+ " \n \n\t\n a\n b: c" => ["Indenting at the beginning of the document is illegal.", 4],
80
+ "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],
81
+ "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],
82
+ "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],
83
+ "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],
84
+ "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],
85
+ "a\n b: c\na\n d: e" => ["The line was indented 2 levels deeper than the previous line.", 4],
86
+ "a\n b: c\n a\n d: e" => ["The line was indented 3 levels deeper than the previous line.", 4],
87
+ "a\n \tb: c" => ["Indentation can't use both tabs and spaces.", 2],
88
+ "=a(" => 'Invalid CSS after "(": expected variable (e.g. $foo), was ""',
89
+ "=a(b)" => 'Invalid CSS after "(": expected variable (e.g. $foo), was "b)"',
90
+ "=a(,)" => 'Invalid CSS after "(": expected variable (e.g. $foo), was ",)"',
91
+ "=a($)" => 'Invalid CSS after "(": expected variable (e.g. $foo), was "$)"',
92
+ "=a($foo bar)" => 'Invalid CSS after "($foo ": expected ")", was "bar)"',
93
+ "=foo\n bar: baz\n+foo" => ["Properties aren't allowed at the root of a document.", 2],
94
+ "a-\#{$b\n c: d" => ['Invalid CSS after "a-#{$b": expected "}", was ""', 1],
95
+ "=a($b = 1, $c)" => "Required argument $c must come before any optional arguments.",
96
+ "=a($b = 1)\n a: $b\ndiv\n +a(1,2)" => "Mixin a takes 1 argument but 2 were passed.",
97
+ "=a($b)\n a: $b\ndiv\n +a" => "Mixin a is missing parameter $b.",
98
+ "@else\n a\n b: c" => ["@else must come after @if.", 1],
99
+ "@if false\n@else foo" => "Invalid else directive '@else foo': expected 'if <expr>'.",
100
+ "@if false\n@else if " => "Invalid else directive '@else if': expected 'if <expr>'.",
101
+ "a\n !b: 12\nc\n d: !b" => 'Undefined variable: "$b".',
102
+ "a\n $b: 12\nc\n d: $b" => 'Undefined variable: "$b".',
103
+ "=foo\n $b: 12\nc\n +foo\n d: $b" => 'Undefined variable: "$b".',
104
+ "c\n d: $b-foo" => 'Undefined variable: "$b-foo".',
105
+ "c\n d: $b_foo" => 'Undefined variable: "$b_foo".',
106
+ '@for $a from "foo" to 1' => '"foo" is not an integer.',
107
+ '@for $a from 1 to "2"' => '"2" is not an integer.',
108
+ '@for $a from 1 to "foo"' => '"foo" is not an integer.',
109
+ '@for $a from 1 to 1.232323' => '1.232 is not an integer.',
110
+ '@for $a from 1px to 3em' => "Incompatible units: 'em' and 'px'.",
111
+ '@if' => "Invalid if directive '@if': expected expression.",
112
+ '@while' => "Invalid while directive '@while': expected expression.",
113
+ '@debug' => "Invalid debug directive '@debug': expected expression.",
114
+ %Q{@debug "a message"\n "nested message"} => "Illegal nesting: Nothing may be nested beneath debug directives.",
115
+ '@warn' => "Invalid warn directive '@warn': expected expression.",
116
+ %Q{@warn "a message"\n "nested message"} => "Illegal nesting: Nothing may be nested beneath warn directives.",
117
+ "/* foo\n bar\n baz" => "Inconsistent indentation: previous line was indented by 4 spaces, but this line was indented by 2 spaces.",
118
+
119
+ # Regression tests
120
+ "a\n b:\n c\n d" => ["Illegal nesting: Only properties may be nested beneath properties.", 3],
121
+ "& foo\n bar: baz\n blat: bang" => ["Base-level rules cannot contain the parent-selector-referencing character '&'.", 1],
122
+ "a\n b: c\n& foo\n bar: baz\n blat: bang" => ["Base-level rules cannot contain the parent-selector-referencing character '&'.", 3],
123
+ }
124
+
125
+ def teardown
126
+ clean_up_sassc
127
+ end
128
+
129
+ def test_basic_render
130
+ renders_correctly "basic", { :style => :compact }
131
+ end
132
+
133
+ def test_empty_render
134
+ assert_equal "", render("")
135
+ end
136
+
137
+ def test_multiple_calls_to_render
138
+ sass = Sass::Engine.new("a\n b: c")
139
+ assert_equal sass.render, sass.render
140
+ end
141
+
142
+ def test_alternate_styles
143
+ renders_correctly "expanded", { :style => :expanded }
144
+ renders_correctly "compact", { :style => :compact }
145
+ renders_correctly "nested", { :style => :nested }
146
+ renders_correctly "compressed", { :style => :compressed }
147
+ end
148
+
149
+ def test_compile
150
+ assert_equal "div { hello: world; }\n", Sass.compile("$who: world\ndiv\n hello: $who", :syntax => :sass, :style => :compact)
151
+ assert_equal "div { hello: world; }\n", Sass.compile("$who: world; div { hello: $who }", :style => :compact)
152
+ end
153
+
154
+ def test_compile_file
155
+ FileUtils.mkdir_p(absolutize("tmp"))
156
+ open(absolutize("tmp/test_compile_file.sass"), "w") {|f| f.write("$who: world\ndiv\n hello: $who")}
157
+ open(absolutize("tmp/test_compile_file.scss"), "w") {|f| f.write("$who: world; div { hello: $who }")}
158
+ assert_equal "div { hello: world; }\n", Sass.compile_file(absolutize("tmp/test_compile_file.sass"), :style => :compact)
159
+ assert_equal "div { hello: world; }\n", Sass.compile_file(absolutize("tmp/test_compile_file.scss"), :style => :compact)
160
+ ensure
161
+ FileUtils.rm_rf(absolutize("tmp"))
162
+ end
163
+
164
+ def test_compile_file_to_css_file
165
+ FileUtils.mkdir_p(absolutize("tmp"))
166
+ open(absolutize("tmp/test_compile_file.sass"), "w") {|f| f.write("$who: world\ndiv\n hello: $who")}
167
+ open(absolutize("tmp/test_compile_file.scss"), "w") {|f| f.write("$who: world; div { hello: $who }")}
168
+ Sass.compile_file(absolutize("tmp/test_compile_file.sass"), absolutize("tmp/test_compile_file_sass.css"), :style => :compact)
169
+ Sass.compile_file(absolutize("tmp/test_compile_file.scss"), absolutize("tmp/test_compile_file_scss.css"), :style => :compact)
170
+ assert_equal "div { hello: world; }\n", File.read(absolutize("tmp/test_compile_file_sass.css"))
171
+ assert_equal "div { hello: world; }\n", File.read(absolutize("tmp/test_compile_file_scss.css"))
172
+ ensure
173
+ FileUtils.rm_rf(absolutize("tmp"))
174
+ end
175
+
176
+ def test_flexible_tabulation
177
+ assert_equal("p {\n a: b; }\n p q {\n c: d; }\n",
178
+ render("p\n a: b\n q\n c: d\n"))
179
+ assert_equal("p {\n a: b; }\n p q {\n c: d; }\n",
180
+ render("p\n\ta: b\n\tq\n\t\tc: d\n"))
181
+ end
182
+
183
+ EXCEPTION_MAP.each do |key, value|
184
+ define_method("test_exception (#{key.inspect})") do
185
+ line = 10
186
+ begin
187
+ silence_warnings {Sass::Engine.new(key, :filename => FAKE_FILE_NAME, :line => line).render}
188
+ rescue Sass::SyntaxError => err
189
+ value = [value] unless value.is_a?(Array)
190
+
191
+ assert_equal(value.first.rstrip, err.message, "Line: #{key}")
192
+ assert_equal(FAKE_FILE_NAME, err.sass_filename)
193
+ assert_equal((value[1] || key.split("\n").length) + line - 1, err.sass_line, "Line: #{key}")
194
+ assert_match(/#{Regexp.escape(FAKE_FILE_NAME)}:[0-9]+/, err.backtrace[0], "Line: #{key}")
195
+ else
196
+ assert(false, "Exception not raised for\n#{key}")
197
+ end
198
+ end
199
+ end
200
+
201
+ def test_exception_line
202
+ to_render = <<SASS
203
+ rule
204
+ :prop val
205
+ // comment!
206
+
207
+ :broken
208
+ SASS
209
+ begin
210
+ Sass::Engine.new(to_render).render
211
+ rescue Sass::SyntaxError => err
212
+ assert_equal(5, err.sass_line)
213
+ else
214
+ assert(false, "Exception not raised for '#{to_render}'!")
215
+ end
216
+ end
217
+
218
+ def test_exception_location
219
+ to_render = <<SASS
220
+ rule
221
+ :prop val
222
+ // comment!
223
+
224
+ :broken
225
+ SASS
226
+ begin
227
+ Sass::Engine.new(to_render, :filename => FAKE_FILE_NAME, :line => (__LINE__-7)).render
228
+ rescue Sass::SyntaxError => err
229
+ assert_equal(FAKE_FILE_NAME, err.sass_filename)
230
+ assert_equal((__LINE__-6), err.sass_line)
231
+ else
232
+ assert(false, "Exception not raised for '#{to_render}'!")
233
+ end
234
+ end
235
+
236
+ def test_imported_exception
237
+ [1, 2, 3, 4].each do |i|
238
+ begin
239
+ Sass::Engine.new("@import bork#{i}", :load_paths => [File.dirname(__FILE__) + '/templates/']).render
240
+ rescue Sass::SyntaxError => err
241
+ assert_equal(2, err.sass_line)
242
+ assert_match(/(\/|^)bork#{i}\.sass$/, err.sass_filename)
243
+
244
+ assert_hash_has(err.sass_backtrace.first,
245
+ :filename => err.sass_filename, :line => err.sass_line)
246
+
247
+ assert_nil(err.sass_backtrace[1][:filename])
248
+ assert_equal(1, err.sass_backtrace[1][:line])
249
+
250
+ assert_match(/(\/|^)bork#{i}\.sass:2$/, err.backtrace.first)
251
+ assert_equal("(sass):1", err.backtrace[1])
252
+ else
253
+ assert(false, "Exception not raised for imported template: bork#{i}")
254
+ end
255
+ end
256
+ end
257
+
258
+ def test_double_imported_exception
259
+ [1, 2, 3, 4].each do |i|
260
+ begin
261
+ Sass::Engine.new("@import nested_bork#{i}", :load_paths => [File.dirname(__FILE__) + '/templates/']).render
262
+ rescue Sass::SyntaxError => err
263
+ assert_equal(2, err.sass_line)
264
+ assert_match(/(\/|^)bork#{i}\.sass$/, err.sass_filename)
265
+
266
+ assert_hash_has(err.sass_backtrace.first,
267
+ :filename => err.sass_filename, :line => err.sass_line)
268
+
269
+ assert_match(/(\/|^)nested_bork#{i}\.sass$/, err.sass_backtrace[1][:filename])
270
+ assert_equal(2, err.sass_backtrace[1][:line])
271
+
272
+ assert_nil(err.sass_backtrace[2][:filename])
273
+ assert_equal(1, err.sass_backtrace[2][:line])
274
+
275
+ assert_match(/(\/|^)bork#{i}\.sass:2$/, err.backtrace.first)
276
+ assert_match(/(\/|^)nested_bork#{i}\.sass:2$/, err.backtrace[1])
277
+ assert_equal("(sass):1", err.backtrace[2])
278
+ else
279
+ assert(false, "Exception not raised for imported template: bork#{i}")
280
+ end
281
+ end
282
+ end
283
+
284
+ def test_mixin_exception
285
+ render(<<SASS)
286
+ =error-mixin($a)
287
+ color: $a * 1em * 1px
288
+
289
+ =outer-mixin($a)
290
+ +error-mixin($a)
291
+
292
+ .error
293
+ +outer-mixin(12)
294
+ SASS
295
+ assert(false, "Exception not raised")
296
+ rescue Sass::SyntaxError => err
297
+ assert_equal(2, err.sass_line)
298
+ assert_equal(filename_for_test, err.sass_filename)
299
+ assert_equal("error-mixin", err.sass_mixin)
300
+
301
+ assert_hash_has(err.sass_backtrace.first, :line => err.sass_line,
302
+ :filename => err.sass_filename, :mixin => err.sass_mixin)
303
+ assert_hash_has(err.sass_backtrace[1], :line => 5,
304
+ :filename => filename_for_test, :mixin => "outer-mixin")
305
+ assert_hash_has(err.sass_backtrace[2], :line => 8,
306
+ :filename => filename_for_test, :mixin => nil)
307
+
308
+ assert_equal("#{filename_for_test}:2:in `error-mixin'", err.backtrace.first)
309
+ assert_equal("#{filename_for_test}:5:in `outer-mixin'", err.backtrace[1])
310
+ assert_equal("#{filename_for_test}:8", err.backtrace[2])
311
+ end
312
+
313
+ def test_mixin_callsite_exception
314
+ render(<<SASS)
315
+ =one-arg-mixin($a)
316
+ color: $a
317
+
318
+ =outer-mixin($a)
319
+ +one-arg-mixin($a, 12)
320
+
321
+ .error
322
+ +outer-mixin(12)
323
+ SASS
324
+ assert(false, "Exception not raised")
325
+ rescue Sass::SyntaxError => err
326
+ assert_hash_has(err.sass_backtrace.first, :line => 5,
327
+ :filename => filename_for_test, :mixin => "one-arg-mixin")
328
+ assert_hash_has(err.sass_backtrace[1], :line => 5,
329
+ :filename => filename_for_test, :mixin => "outer-mixin")
330
+ assert_hash_has(err.sass_backtrace[2], :line => 8,
331
+ :filename => filename_for_test, :mixin => nil)
332
+ end
333
+
334
+ def test_mixin_exception_cssize
335
+ render(<<SASS)
336
+ =parent-ref-mixin
337
+ & foo
338
+ a: b
339
+
340
+ =outer-mixin
341
+ +parent-ref-mixin
342
+
343
+ +outer-mixin
344
+ SASS
345
+ assert(false, "Exception not raised")
346
+ rescue Sass::SyntaxError => err
347
+ assert_hash_has(err.sass_backtrace.first, :line => 2,
348
+ :filename => filename_for_test, :mixin => "parent-ref-mixin")
349
+ assert_hash_has(err.sass_backtrace[1], :line => 6,
350
+ :filename => filename_for_test, :mixin => "outer-mixin")
351
+ assert_hash_has(err.sass_backtrace[2], :line => 8,
352
+ :filename => filename_for_test, :mixin => nil)
353
+ end
354
+
355
+ def test_mixin_and_import_exception
356
+ Sass::Engine.new("@import nested_mixin_bork", :load_paths => [File.dirname(__FILE__) + '/templates/']).render
357
+ assert(false, "Exception not raised")
358
+ rescue Sass::SyntaxError => err
359
+ assert_match(/(\/|^)nested_mixin_bork\.sass$/, err.sass_backtrace.first[:filename])
360
+ assert_hash_has(err.sass_backtrace.first, :mixin => "error-mixin", :line => 4)
361
+
362
+ assert_match(/(\/|^)mixin_bork\.sass$/, err.sass_backtrace[1][:filename])
363
+ assert_hash_has(err.sass_backtrace[1], :mixin => "outer-mixin", :line => 2)
364
+
365
+ assert_match(/(\/|^)mixin_bork\.sass$/, err.sass_backtrace[2][:filename])
366
+ assert_hash_has(err.sass_backtrace[2], :mixin => nil, :line => 5)
367
+
368
+ assert_match(/(\/|^)nested_mixin_bork\.sass$/, err.sass_backtrace[3][:filename])
369
+ assert_hash_has(err.sass_backtrace[3], :mixin => nil, :line => 6)
370
+
371
+ assert_hash_has(err.sass_backtrace[4], :filename => nil, :mixin => nil, :line => 1)
372
+ end
373
+
374
+ def test_basic_mixin_loop_exception
375
+ render <<SASS
376
+ @mixin foo
377
+ @include foo
378
+ @include foo
379
+ SASS
380
+ assert(false, "Exception not raised")
381
+ rescue Sass::SyntaxError => err
382
+ assert_equal("An @include loop has been found: foo includes itself", err.message)
383
+ assert_hash_has(err.sass_backtrace[0], :mixin => "foo", :line => 2)
384
+ end
385
+
386
+ def test_double_mixin_loop_exception
387
+ render <<SASS
388
+ @mixin foo
389
+ @include bar
390
+ @mixin bar
391
+ @include foo
392
+ @include foo
393
+ SASS
394
+ assert(false, "Exception not raised")
395
+ rescue Sass::SyntaxError => err
396
+ assert_equal(<<MESSAGE.rstrip, err.message)
397
+ An @include loop has been found:
398
+ foo includes bar
399
+ bar includes foo
400
+ MESSAGE
401
+ assert_hash_has(err.sass_backtrace[0], :mixin => "bar", :line => 4)
402
+ assert_hash_has(err.sass_backtrace[1], :mixin => "foo", :line => 2)
403
+ end
404
+
405
+ def test_deep_mixin_loop_exception
406
+ render <<SASS
407
+ @mixin foo
408
+ @include bar
409
+
410
+ @mixin bar
411
+ @include baz
412
+
413
+ @mixin baz
414
+ @include foo
415
+
416
+ @include foo
417
+ SASS
418
+ assert(false, "Exception not raised")
419
+ rescue Sass::SyntaxError => err
420
+ assert_equal(<<MESSAGE.rstrip, err.message)
421
+ An @include loop has been found:
422
+ foo includes bar
423
+ bar includes baz
424
+ baz includes foo
425
+ MESSAGE
426
+ assert_hash_has(err.sass_backtrace[0], :mixin => "baz", :line => 8)
427
+ assert_hash_has(err.sass_backtrace[1], :mixin => "bar", :line => 5)
428
+ assert_hash_has(err.sass_backtrace[2], :mixin => "foo", :line => 2)
429
+ end
430
+
431
+ def test_exception_css_with_offset
432
+ opts = {:full_exception => true, :line => 362}
433
+ render(("a\n b: c\n" * 10) + "d\n e:\n" + ("f\n g: h\n" * 10), opts)
434
+ rescue Sass::SyntaxError => e
435
+ assert_equal(<<CSS, Sass::SyntaxError.exception_to_css(e, opts).split("\n")[0..15].join("\n"))
436
+ /*
437
+ Syntax error: Invalid property: "e:" (no value).
438
+ on line 383 of test_exception_css_with_offset_inline.sass
439
+
440
+ 378: a
441
+ 379: b: c
442
+ 380: a
443
+ 381: b: c
444
+ 382: d
445
+ 383: e:
446
+ 384: f
447
+ 385: g: h
448
+ 386: f
449
+ 387: g: h
450
+ 388: f
451
+ CSS
452
+ else
453
+ assert(false, "Exception not raised for test_exception_css_with_offset")
454
+ end
455
+
456
+ def test_exception_css_with_mixins
457
+ opts = {:full_exception => true}
458
+ render(<<SASS, opts)
459
+ =error-mixin($a)
460
+ color: $a * 1em * 1px
461
+
462
+ =outer-mixin($a)
463
+ +error-mixin($a)
464
+
465
+ .error
466
+ +outer-mixin(12)
467
+ SASS
468
+ rescue Sass::SyntaxError => e
469
+ assert_equal(<<CSS, Sass::SyntaxError.exception_to_css(e, opts).split("\n")[0..13].join("\n"))
470
+ /*
471
+ Syntax error: 12em*px isn't a valid CSS value.
472
+ on line 2 of test_exception_css_with_mixins_inline.sass, in `error-mixin'
473
+ from line 5 of test_exception_css_with_mixins_inline.sass, in `outer-mixin'
474
+ from line 8 of test_exception_css_with_mixins_inline.sass
475
+
476
+ 1: =error-mixin($a)
477
+ 2: color: $a * 1em * 1px
478
+ 3:
479
+ 4: =outer-mixin($a)
480
+ 5: +error-mixin($a)
481
+ 6:
482
+ 7: .error
483
+ CSS
484
+ else
485
+ assert(false, "Exception not raised")
486
+ end
487
+
488
+ def test_cssize_exception_css
489
+ opts = {:full_exception => true}
490
+ render(<<SASS, opts)
491
+ .filler
492
+ stuff: "stuff!"
493
+
494
+ a: b
495
+
496
+ .more.filler
497
+ a: b
498
+ SASS
499
+ rescue Sass::SyntaxError => e
500
+ assert_equal(<<CSS, Sass::SyntaxError.exception_to_css(e, opts).split("\n")[0..11].join("\n"))
501
+ /*
502
+ Syntax error: Properties aren't allowed at the root of a document.
503
+ on line 4 of test_cssize_exception_css_inline.sass
504
+
505
+ 1: .filler
506
+ 2: stuff: "stuff!"
507
+ 3:
508
+ 4: a: b
509
+ 5:
510
+ 6: .more.filler
511
+ 7: a: b
512
+ CSS
513
+ else
514
+ assert(false, "Exception not raised")
515
+ end
516
+
517
+ def test_css_import
518
+ assert_equal("@import url(./fonts.css);\n", render("@import \"./fonts.css\""))
519
+ end
520
+
521
+ def test_http_import
522
+ assert_equal("@import url(http://fonts.googleapis.com/css?family=Droid+Sans);\n",
523
+ render("@import \"http://fonts.googleapis.com/css?family=Droid+Sans\""))
524
+ end
525
+
526
+ def test_url_import
527
+ assert_equal("@import url(fonts.sass);\n", render("@import url(fonts.sass)"))
528
+ end
529
+
530
+ def test_sass_import
531
+ sassc_file = sassc_path("importee")
532
+ assert !File.exists?(sassc_file)
533
+ renders_correctly "import", { :style => :compact, :load_paths => [File.dirname(__FILE__) + "/templates"] }
534
+ assert File.exists?(sassc_file)
535
+ end
536
+
537
+ def test_nonexistent_extensionless_import
538
+ assert_raise_message(Sass::SyntaxError, <<ERR.rstrip) do
539
+ File to import not found or unreadable: nonexistent.
540
+ Load path: .
541
+ ERR
542
+ assert_equal("@import url(nonexistent.css);\n", render("@import nonexistent"))
543
+ end
544
+ end
545
+
546
+ def test_no_cache
547
+ assert !File.exists?(sassc_path("importee"))
548
+ renders_correctly("import", {
549
+ :style => :compact, :cache => false,
550
+ :load_paths => [File.dirname(__FILE__) + "/templates"],
551
+ })
552
+ assert !File.exists?(sassc_path("importee"))
553
+ end
554
+
555
+ def test_units
556
+ renders_correctly "units"
557
+ end
558
+
559
+ def test_default_function
560
+ assert_equal(<<CSS, render(<<SASS))
561
+ foo {
562
+ bar: url("foo.png"); }
563
+ CSS
564
+ foo
565
+ bar: url("foo.png")
566
+ SASS
567
+ assert_equal("foo {\n bar: url(); }\n", render("foo\n bar: url()\n"));
568
+ end
569
+
570
+ def test_string_minus
571
+ assert_equal("foo {\n bar: baz-boom-bat; }\n", render(%Q{foo\n bar: baz-boom-bat}))
572
+ assert_equal("foo {\n bar: -baz-boom; }\n", render(%Q{foo\n bar: -baz-boom}))
573
+ end
574
+
575
+ def test_string_div
576
+ assert_equal("foo {\n bar: baz/boom/bat; }\n", render(%Q{foo\n bar: baz/boom/bat}))
577
+ assert_equal("foo {\n bar: /baz/boom; }\n", render(%Q{foo\n bar: /baz/boom}))
578
+ end
579
+
580
+ def test_basic_multiline_selector
581
+ assert_equal("#foo #bar,\n#baz #boom {\n foo: bar; }\n",
582
+ render("#foo #bar,\n#baz #boom\n :foo bar"))
583
+ assert_equal("#foo #bar,\n#foo #baz {\n foo: bar; }\n",
584
+ render("#foo\n #bar,\n #baz\n :foo bar"))
585
+ assert_equal("#foo,\n#bar {\n foo: bar; }\n #foo #baz,\n #bar #baz {\n foo: bar; }\n",
586
+ render("#foo,\n#bar\n :foo bar\n #baz\n :foo bar"))
587
+ assert_equal("#foo #bar, #baz #boom { foo: bar; }\n",
588
+ render("#foo #bar,\n#baz #boom\n :foo bar", :style => :compact))
589
+
590
+ assert_equal("#foo #bar,#baz #boom{foo:bar}\n",
591
+ render("#foo #bar,\n#baz #boom\n :foo bar", :style => :compressed))
592
+ end
593
+
594
+ def test_complex_multiline_selector
595
+ renders_correctly "multiline"
596
+ end
597
+
598
+ def test_colon_only
599
+ begin
600
+ render("a\n b: c", :property_syntax => :old)
601
+ rescue Sass::SyntaxError => e
602
+ assert_equal("Illegal property syntax: can't use new syntax when :property_syntax => :old is set.",
603
+ e.message)
604
+ assert_equal(2, e.sass_line)
605
+ else
606
+ assert(false, "SyntaxError not raised for :property_syntax => :old")
607
+ end
608
+
609
+ begin
610
+ render("a\n :b c", :property_syntax => :new)
611
+ assert_equal(2, e.sass_line)
612
+ rescue Sass::SyntaxError => e
613
+ assert_equal("Illegal property syntax: can't use old syntax when :property_syntax => :new is set.",
614
+ e.message)
615
+ else
616
+ assert(false, "SyntaxError not raised for :property_syntax => :new")
617
+ end
618
+ end
619
+
620
+ def test_pseudo_elements
621
+ assert_equal(<<CSS, render(<<SASS))
622
+ ::first-line {
623
+ size: 10em; }
624
+ CSS
625
+ ::first-line
626
+ size: 10em
627
+ SASS
628
+ end
629
+
630
+ def test_directive
631
+ assert_equal("@a b;\n", render("@a b"))
632
+
633
+ assert_equal("@a {\n b: c; }\n", render("@a\n :b c"))
634
+ assert_equal("@a { b: c; }\n", render("@a\n :b c", :style => :compact))
635
+ assert_equal("@a {\n b: c;\n}\n", render("@a\n :b c", :style => :expanded))
636
+ assert_equal("@a{b:c}\n", render("@a\n :b c", :style => :compressed))
637
+
638
+ assert_equal("@a {\n b: c;\n d: e; }\n",
639
+ render("@a\n :b c\n :d e"))
640
+ assert_equal("@a { b: c; d: e; }\n",
641
+ render("@a\n :b c\n :d e", :style => :compact))
642
+ assert_equal("@a {\n b: c;\n d: e;\n}\n",
643
+ render("@a\n :b c\n :d e", :style => :expanded))
644
+ assert_equal("@a{b:c;d:e}\n",
645
+ render("@a\n :b c\n :d e", :style => :compressed))
646
+
647
+ assert_equal("@a {\n #b {\n c: d; } }\n",
648
+ render("@a\n #b\n :c d"))
649
+ assert_equal("@a { #b { c: d; } }\n",
650
+ render("@a\n #b\n :c d", :style => :compact))
651
+ assert_equal("@a {\n #b {\n c: d;\n }\n}\n",
652
+ render("@a\n #b\n :c d", :style => :expanded))
653
+ assert_equal("@a{#b{c:d}}\n",
654
+ render("@a\n #b\n :c d", :style => :compressed))
655
+
656
+ assert_equal("@a {\n #b {\n a: b; }\n #b #c {\n d: e; } }\n",
657
+ render("@a\n #b\n :a b\n #c\n :d e"))
658
+ assert_equal("@a { #b { a: b; }\n #b #c { d: e; } }\n",
659
+ render("@a\n #b\n :a b\n #c\n :d e", :style => :compact))
660
+ assert_equal("@a {\n #b {\n a: b;\n }\n #b #c {\n d: e;\n }\n}\n",
661
+ render("@a\n #b\n :a b\n #c\n :d e", :style => :expanded))
662
+ assert_equal("@a{#b{a:b}#b #c{d:e}}\n",
663
+ render("@a\n #b\n :a b\n #c\n :d e", :style => :compressed))
664
+
665
+ assert_equal("@a {\n #foo,\n #bar {\n b: c; } }\n",
666
+ render("@a\n #foo, \n #bar\n :b c"))
667
+ assert_equal("@a { #foo, #bar { b: c; } }\n",
668
+ render("@a\n #foo, \n #bar\n :b c", :style => :compact))
669
+ assert_equal("@a {\n #foo,\n #bar {\n b: c;\n }\n}\n",
670
+ render("@a\n #foo, \n #bar\n :b c", :style => :expanded))
671
+ assert_equal("@a{#foo,#bar{b:c}}\n",
672
+ render("@a\n #foo, \n #bar\n :b c", :style => :compressed))
673
+
674
+ to_render = <<END
675
+ @a
676
+ :b c
677
+ #d
678
+ :e f
679
+ :g h
680
+ END
681
+ rendered = <<END
682
+ @a { b: c;
683
+ #d { e: f; }
684
+ g: h; }
685
+ END
686
+ assert_equal(rendered, render(to_render, :style => :compact))
687
+
688
+ assert_equal("@a{b:c;#d{e:f}g:h}\n", render(to_render, :style => :compressed))
689
+ end
690
+
691
+ def test_property_hacks
692
+ assert_equal(<<CSS, render(<<SASS))
693
+ foo {
694
+ _name: val;
695
+ *name: val;
696
+ #name: val;
697
+ .name: val;
698
+ name/**/: val;
699
+ name/*\\**/: val;
700
+ name: val; }
701
+ CSS
702
+ foo
703
+ _name: val
704
+ *name: val
705
+ #name: val
706
+ .name: val
707
+ name/**/: val
708
+ name/*\\**/: val
709
+ name: val
710
+ SASS
711
+ end
712
+
713
+ def test_properties_with_space_after_colon
714
+ assert_equal <<CSS, render(<<SASS)
715
+ foo {
716
+ bar: baz;
717
+ bizz: bap; }
718
+ CSS
719
+ foo
720
+ bar : baz
721
+ bizz : bap
722
+ SASS
723
+ end
724
+
725
+ def test_line_annotations
726
+ assert_equal(<<CSS, render(<<SASS, :line_comments => true, :style => :compact))
727
+ /* line 2, test_line_annotations_inline.sass */
728
+ foo bar { foo: bar; }
729
+ /* line 5, test_line_annotations_inline.sass */
730
+ foo baz { blip: blop; }
731
+
732
+ /* line 9, test_line_annotations_inline.sass */
733
+ floodle { flop: blop; }
734
+
735
+ /* line 18, test_line_annotations_inline.sass */
736
+ bup { mix: on; }
737
+ /* line 15, test_line_annotations_inline.sass */
738
+ bup mixin { moop: mup; }
739
+
740
+ /* line 22, test_line_annotations_inline.sass */
741
+ bip hop, skip hop { a: b; }
742
+ CSS
743
+ foo
744
+ bar
745
+ foo: bar
746
+
747
+ baz
748
+ blip: blop
749
+
750
+
751
+ floodle
752
+
753
+ flop: blop
754
+
755
+ =mxn
756
+ mix: on
757
+ mixin
758
+ moop: mup
759
+
760
+ bup
761
+ +mxn
762
+
763
+ bip, skip
764
+ hop
765
+ a: b
766
+ SASS
767
+ end
768
+
769
+ def test_line_annotations_with_filename
770
+ renders_correctly "line_numbers", :line_comments => true, :load_paths => [File.dirname(__FILE__) + "/templates"]
771
+ end
772
+
773
+ def test_debug_info
774
+ esc_file_name = Sass::SCSS::RX.escape_ident(Sass::Util.scope("test_debug_info_inline.sass"))
775
+
776
+ assert_equal(<<CSS, render(<<SASS, :debug_info => true, :style => :compact))
777
+ @media -sass-debug-info{filename{font-family:file\\:\\/\\/#{esc_file_name}}line{font-family:\\000032}}
778
+ foo bar { foo: bar; }
779
+ @media -sass-debug-info{filename{font-family:file\\:\\/\\/#{esc_file_name}}line{font-family:\\000035}}
780
+ foo baz { blip: blop; }
781
+
782
+ @media -sass-debug-info{filename{font-family:file\\:\\/\\/#{esc_file_name}}line{font-family:\\000039}}
783
+ floodle { flop: blop; }
784
+
785
+ @media -sass-debug-info{filename{font-family:file\\:\\/\\/#{esc_file_name}}line{font-family:\\0000318}}
786
+ bup { mix: on; }
787
+ @media -sass-debug-info{filename{font-family:file\\:\\/\\/#{esc_file_name}}line{font-family:\\0000315}}
788
+ bup mixin { moop: mup; }
789
+
790
+ @media -sass-debug-info{filename{font-family:file\\:\\/\\/#{esc_file_name}}line{font-family:\\0000322}}
791
+ bip hop, skip hop { a: b; }
792
+ CSS
793
+ foo
794
+ bar
795
+ foo: bar
796
+
797
+ baz
798
+ blip: blop
799
+
800
+
801
+ floodle
802
+
803
+ flop: blop
804
+
805
+ =mxn
806
+ mix: on
807
+ mixin
808
+ moop: mup
809
+
810
+ bup
811
+ +mxn
812
+
813
+ bip, skip
814
+ hop
815
+ a: b
816
+ SASS
817
+ end
818
+
819
+ def test_debug_info_without_filename
820
+ assert_equal(<<CSS, Sass::Engine.new(<<SASS, :debug_info => true).render)
821
+ @media -sass-debug-info{filename{font-family:}line{font-family:\\000031}}
822
+ foo {
823
+ a: b; }
824
+ CSS
825
+ foo
826
+ a: b
827
+ SASS
828
+ end
829
+
830
+ def test_debug_info_with_compressed
831
+ assert_equal(<<CSS, render(<<SASS, :debug_info => true, :style => :compressed))
832
+ foo{a:b}
833
+ CSS
834
+ foo
835
+ a: b
836
+ SASS
837
+ end
838
+
839
+ def test_debug_info_with_line_annotations
840
+ esc_file_name = Sass::SCSS::RX.escape_ident(Sass::Util.scope("test_debug_info_with_line_annotations_inline.sass"))
841
+
842
+ assert_equal(<<CSS, render(<<SASS, :debug_info => true, :line_comments => true))
843
+ @media -sass-debug-info{filename{font-family:file\\:\\/\\/#{esc_file_name}}line{font-family:\\000031}}
844
+ foo {
845
+ a: b; }
846
+ CSS
847
+ foo
848
+ a: b
849
+ SASS
850
+ end
851
+
852
+ def test_empty_first_line
853
+ assert_equal("#a {\n b: c; }\n", render("#a\n\n b: c"))
854
+ end
855
+
856
+ def test_escaped_rule
857
+ assert_equal(":focus {\n a: b; }\n", render("\\:focus\n a: b"))
858
+ assert_equal("a {\n b: c; }\n a :focus {\n d: e; }\n", render("\\a\n b: c\n \\:focus\n d: e"))
859
+ end
860
+
861
+ def test_cr_newline
862
+ 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"))
863
+ end
864
+
865
+ def test_property_with_content_and_nested_props
866
+ assert_equal(<<CSS, render(<<SASS))
867
+ foo {
868
+ a: b;
869
+ a-c: d;
870
+ a-c-e: f; }
871
+ CSS
872
+ foo
873
+ a: b
874
+ c: d
875
+ e: f
876
+ SASS
877
+
878
+ assert_equal(<<CSS, render(<<SASS))
879
+ foo {
880
+ a: b;
881
+ a-c-e: f; }
882
+ CSS
883
+ foo
884
+ a: b
885
+ c:
886
+ e: f
887
+ SASS
888
+ end
889
+
890
+ def test_equals_warning_for_properties
891
+ assert_warning(<<WARN) {assert_equal(<<CSS, render(<<SASS))}
892
+ DEPRECATION WARNING:
893
+ On line 3, character 3 of 'test_equals_warning_for_properties_inline.sass'
894
+ Setting properties with = has been deprecated and will be removed in version 3.2.
895
+ Use "a: $var" instead.
896
+
897
+ You can use `sass-convert --in-place --from sass2 file.sass' to convert files automatically.
898
+ WARN
899
+ foo {
900
+ a: 2px 3px; }
901
+ CSS
902
+ $var: 2px 3px
903
+ foo
904
+ a = $var
905
+ SASS
906
+ end
907
+
908
+ def test_equals_warning_for_dynamic_properties
909
+ assert_warning(<<WARN) {assert_equal(<<CSS, render(<<SASS))}
910
+ DEPRECATION WARNING:
911
+ On line 4, character 3 of 'test_equals_warning_for_dynamic_properties_inline.sass'
912
+ Setting properties with = has been deprecated and will be removed in version 3.2.
913
+ Use "a-\#{$i}: $var" instead.
914
+
915
+ You can use `sass-convert --in-place --from sass2 file.sass' to convert files automatically.
916
+ WARN
917
+ foo {
918
+ a-12: 2px 3px; }
919
+ CSS
920
+ $var: 2px 3px
921
+ $i: 12
922
+ foo
923
+ a-\#{$i} = $var
924
+ SASS
925
+ end
926
+
927
+ def test_equals_warning_for_property_with_string
928
+ assert_warning(<<WARN) {assert_equal(<<CSS, render(<<SASS))}
929
+ DEPRECATION WARNING:
930
+ On line 2, character 3 of 'test_equals_warning_for_property_with_string_inline.sass'
931
+ Setting properties with = has been deprecated and will be removed in version 3.2.
932
+ Use "a: foo" instead.
933
+
934
+ You can use `sass-convert --in-place --from sass2 file.sass' to convert files automatically.
935
+ WARN
936
+ foo {
937
+ a: foo; }
938
+ CSS
939
+ foo
940
+ a = "foo"
941
+ SASS
942
+ end
943
+
944
+ def test_equals_warning_for_property_with_division
945
+ assert_warning(<<WARN) {assert_equal(<<CSS, render(<<SASS))}
946
+ DEPRECATION WARNING:
947
+ On line 2, character 3 of 'test_equals_warning_for_property_with_division_inline.sass'
948
+ Setting properties with = has been deprecated and will be removed in version 3.2.
949
+ Use "a: (1px / 2px)" instead.
950
+
951
+ You can use `sass-convert --in-place --from sass2 file.sass' to convert files automatically.
952
+ WARN
953
+ foo {
954
+ a: 0.5; }
955
+ CSS
956
+ foo
957
+ a = 1px/2px
958
+ SASS
959
+ end
960
+
961
+ def test_guarded_assign
962
+ assert_equal("foo {\n a: b; }\n", render(%Q{$foo: b\n$foo: c !default\nfoo\n a: $foo}))
963
+ assert_equal("foo {\n a: b; }\n", render(%Q{$foo: b !default\nfoo\n a: $foo}))
964
+ end
965
+
966
+ def test_mixins
967
+ renders_correctly "mixins", { :style => :expanded }
968
+ end
969
+
970
+ def test_directive_style_mixins
971
+ assert_equal <<CSS, render(<<SASS)
972
+ bar {
973
+ prop: baz; }
974
+ CSS
975
+ @mixin foo($arg)
976
+ prop: $arg
977
+
978
+ bar
979
+ @include foo(baz)
980
+ SASS
981
+ end
982
+
983
+ def test_mixins_dont_interfere_with_sibling_combinator
984
+ assert_equal("foo + bar {\n a: b; }\nfoo + baz {\n c: d; }\n",
985
+ render("foo\n +\n bar\n a: b\n baz\n c: d"))
986
+ end
987
+
988
+ def test_mixin_args
989
+ assert_equal("blat {\n baz: hi; }\n", render(<<SASS))
990
+ =foo($bar)
991
+ baz: $bar
992
+ blat
993
+ +foo(hi)
994
+ SASS
995
+ assert_equal("blat {\n baz: 3; }\n", render(<<SASS))
996
+ =foo($a, $b)
997
+ baz: $a + $b
998
+ blat
999
+ +foo(1, 2)
1000
+ SASS
1001
+ assert_equal("blat {\n baz: 4;\n baz: 3;\n baz: 5;\n bang: 3; }\n", render(<<SASS))
1002
+ =foo($c: (6 + 4) / 2)
1003
+ baz: $c
1004
+ $c: 3
1005
+ blat
1006
+ +foo($c + 1)
1007
+ +foo(($c + 3)/2)
1008
+ +foo
1009
+ bang: $c
1010
+ SASS
1011
+ end
1012
+
1013
+ def test_default_values_for_mixin_arguments
1014
+ assert_equal("white {\n color: white; }\n\nblack {\n color: black; }\n", render(<<SASS))
1015
+ =foo($a: #FFF)
1016
+ :color $a
1017
+ white
1018
+ +foo
1019
+ black
1020
+ +foo(#000)
1021
+ SASS
1022
+ assert_equal(<<CSS, render(<<SASS))
1023
+ one {
1024
+ color: white;
1025
+ padding: 1px;
1026
+ margin: 4px; }
1027
+
1028
+ two {
1029
+ color: white;
1030
+ padding: 2px;
1031
+ margin: 5px; }
1032
+
1033
+ three {
1034
+ color: white;
1035
+ padding: 2px;
1036
+ margin: 3px; }
1037
+ CSS
1038
+ $a: 5px
1039
+ =foo($a, $b: 1px, $c: 3px + $b)
1040
+ :color $a
1041
+ :padding $b
1042
+ :margin $c
1043
+ one
1044
+ +foo(#fff)
1045
+ two
1046
+ +foo(#fff, 2px)
1047
+ three
1048
+ +foo(#fff, 2px, 3px)
1049
+ SASS
1050
+ end
1051
+
1052
+ def test_hyphen_underscore_insensitive_mixins
1053
+ assert_equal(<<CSS, render(<<SASS))
1054
+ a {
1055
+ b: 12;
1056
+ c: foo; }
1057
+ CSS
1058
+ =mixin-hyphen
1059
+ b: 12
1060
+
1061
+ =mixin_under
1062
+ c: foo
1063
+
1064
+ a
1065
+ +mixin_hyphen
1066
+ +mixin-under
1067
+ SASS
1068
+ end
1069
+
1070
+ def test_equals_warning_for_mixin_args
1071
+ assert_warning(<<WARN) {assert_equal(<<CSS, render(<<SASS))}
1072
+ DEPRECATION WARNING:
1073
+ On line 1, character 10 of 'test_equals_warning_for_mixin_args_inline.sass'
1074
+ Setting mixin argument defaults with = has been deprecated and will be removed in version 3.2.
1075
+ Use "$arg: 1px" instead.
1076
+
1077
+ You can use `sass-convert --in-place --from sass2 file.sass' to convert files automatically.
1078
+ WARN
1079
+ bar {
1080
+ a: 1px; }
1081
+ CSS
1082
+ =foo($arg = 1px)
1083
+ a: $arg
1084
+
1085
+ bar
1086
+ +foo
1087
+ SASS
1088
+ end
1089
+
1090
+ def test_css_identifier_mixin
1091
+ assert_equal(<<CSS, render(<<SASS))
1092
+ a {
1093
+ foo: 12; }
1094
+ CSS
1095
+ =\\{foo\\(12\\)($a)
1096
+ foo: $a
1097
+
1098
+ a
1099
+ +\\{foo\\(12\\)(12)
1100
+ SASS
1101
+ end
1102
+
1103
+ def test_interpolation
1104
+ assert_equal("a-1 {\n b-2-3: c-3; }\n", render(<<SASS))
1105
+ $a: 1
1106
+ $b: 2
1107
+ $c: 3
1108
+ a-\#{$a}
1109
+ b-\#{$b}-\#{$c}: c-\#{$a + $b}
1110
+ SASS
1111
+ end
1112
+
1113
+ def test_complex_property_interpolation
1114
+ assert_equal(<<CSS, render(<<SASS))
1115
+ a-1 {
1116
+ b-2 3-fizzap18: c-3; }
1117
+ CSS
1118
+ $a: 1
1119
+ $b: 2
1120
+ $c: 3
1121
+ a-\#{$a}
1122
+ b-\#{$b $c}-\#{fizzap + ($c + 15)}: c-\#{$a + $b}
1123
+ SASS
1124
+ end
1125
+
1126
+ def test_if_directive
1127
+ assert_equal("a {\n b: 1; }\n", render(<<SASS))
1128
+ $var: true
1129
+ a
1130
+ @if $var
1131
+ b: 1
1132
+ @if not $var
1133
+ b: 2
1134
+ SASS
1135
+ end
1136
+
1137
+ def test_for
1138
+ assert_equal(<<CSS, render(<<SASS))
1139
+ a-0 {
1140
+ two-i: 0; }
1141
+
1142
+ a-1 {
1143
+ two-i: 2; }
1144
+
1145
+ a-2 {
1146
+ two-i: 4; }
1147
+
1148
+ a-3 {
1149
+ two-i: 6; }
1150
+
1151
+ b-1 {
1152
+ j-1: 0; }
1153
+
1154
+ b-2 {
1155
+ j-1: 1; }
1156
+
1157
+ b-3 {
1158
+ j-1: 2; }
1159
+
1160
+ b-4 {
1161
+ j-1: 3; }
1162
+ CSS
1163
+ $a: 3
1164
+ @for $i from 0 to $a + 1
1165
+ a-\#{$i}
1166
+ two-i: 2 * $i
1167
+
1168
+ @for $j from 1 through 4
1169
+ b-\#{$j}
1170
+ j-1: $j - 1
1171
+ SASS
1172
+ end
1173
+
1174
+ def test_for_with_bang_var
1175
+ assert_warning(<<WARN) {assert_equal(<<CSS, render(<<SASS))}
1176
+ DEPRECATION WARNING:
1177
+ On line 1, character 6 of 'test_for_with_bang_var_inline.sass'
1178
+ Variables with ! have been deprecated and will be removed in version 3.2.
1179
+ Use "$bar" instead.
1180
+
1181
+ You can use `sass-convert --in-place --from sass2 file.sass' to convert files automatically.
1182
+ WARN
1183
+ a-0 {
1184
+ b: c; }
1185
+
1186
+ a-1 {
1187
+ b: c; }
1188
+
1189
+ a-2 {
1190
+ b: c; }
1191
+ CSS
1192
+ @for !bar from 0 to 3
1193
+ a-\#{$bar}
1194
+ b: c
1195
+ SASS
1196
+ end
1197
+
1198
+ def test_while
1199
+ assert_equal(<<CSS, render(<<SASS))
1200
+ a-5 {
1201
+ blooble: gloop; }
1202
+
1203
+ a-4 {
1204
+ blooble: gloop; }
1205
+
1206
+ a-3 {
1207
+ blooble: gloop; }
1208
+
1209
+ a-2 {
1210
+ blooble: gloop; }
1211
+
1212
+ a-1 {
1213
+ blooble: gloop; }
1214
+ CSS
1215
+ $a: 5
1216
+ @while $a != 0
1217
+ a-\#{$a}
1218
+ blooble: gloop
1219
+ $a: $a - 1
1220
+ SASS
1221
+ end
1222
+
1223
+ def test_else
1224
+ assert_equal(<<CSS, render(<<SASS))
1225
+ a {
1226
+ t1: t;
1227
+ t2: t;
1228
+ t3: t;
1229
+ t4: t; }
1230
+ CSS
1231
+ a
1232
+ @if true
1233
+ t1: t
1234
+ @else
1235
+ f1: f
1236
+
1237
+ @if false
1238
+ f2: f
1239
+ @else
1240
+ t2: t
1241
+
1242
+ @if false
1243
+ f3: f1
1244
+ @else if 1 + 1 == 3
1245
+ f3: f2
1246
+ @else
1247
+ t3: t
1248
+
1249
+ @if false
1250
+ f4: f1
1251
+ @else if 1 + 1 == 2
1252
+ t4: t
1253
+ @else
1254
+ f4: f2
1255
+
1256
+ @if false
1257
+ f5: f1
1258
+ @else if false
1259
+ f5: f2
1260
+ SASS
1261
+ end
1262
+
1263
+ def test_variable_reassignment
1264
+ assert_equal(<<CSS, render(<<SASS))
1265
+ a {
1266
+ b: 1;
1267
+ c: 2; }
1268
+ CSS
1269
+ $a: 1
1270
+ a
1271
+ b: $a
1272
+ $a: 2
1273
+ c: $a
1274
+ SASS
1275
+ end
1276
+
1277
+ def test_bang_variables
1278
+ assert_warning(<<WARN) {assert_equal(<<CSS, render(<<SASS))}
1279
+ DEPRECATION WARNING:
1280
+ On line 1, character 1 of 'test_bang_variables_inline.sass'
1281
+ Variables with ! have been deprecated and will be removed in version 3.2.
1282
+ Use "$bang-var" instead.
1283
+
1284
+ You can use `sass-convert --in-place --from sass2 file.sass' to convert files automatically.
1285
+ WARN
1286
+ foo {
1287
+ a: 1px; }
1288
+ CSS
1289
+ !bang-var: 1px
1290
+ foo
1291
+ a: $bang-var
1292
+ SASS
1293
+
1294
+ assert_warning(<<WARN) {assert_equal(<<CSS, render(<<SASS))}
1295
+ DEPRECATION WARNING:
1296
+ On line 3, character 6 of 'test_bang_variables_inline.sass'
1297
+ Variables with ! have been deprecated and will be removed in version 3.2.
1298
+ Use "$dollar-var" instead.
1299
+
1300
+ You can use `sass-convert --in-place --from sass2 file.sass' to convert files automatically.
1301
+ WARN
1302
+ foo {
1303
+ a: 1px; }
1304
+ CSS
1305
+ $dollar-var: 1px
1306
+ foo
1307
+ a: !dollar-var
1308
+ SASS
1309
+ end
1310
+
1311
+ def test_equals_warning_for_variables
1312
+ assert_warning(<<WARN) {assert_equal(<<CSS, render(<<SASS))}
1313
+ DEPRECATION WARNING:
1314
+ On line 2, character 1 of 'test_equals_warning_for_variables_inline.sass'
1315
+ Setting variables with = has been deprecated and will be removed in version 3.2.
1316
+ Use "$equals-var: 2px 3px" instead.
1317
+
1318
+ You can use `sass-convert --in-place --from sass2 file.sass' to convert files automatically.
1319
+ WARN
1320
+ foo {
1321
+ a: 2px 3px; }
1322
+ CSS
1323
+
1324
+ $equals-var = 2px 3px
1325
+ foo
1326
+ a: $equals-var
1327
+ SASS
1328
+ end
1329
+
1330
+ def test_equals_warning_for_guarded_variables
1331
+ assert_warning(<<WARN) {assert_equal(<<CSS, render(<<SASS))}
1332
+ DEPRECATION WARNING:
1333
+ On line 2, character 1 of 'test_equals_warning_for_guarded_variables_inline.sass'
1334
+ Setting variable defaults with ||= has been deprecated and will be removed in version 3.2.
1335
+ Use "$equals-var: 2px 3px !default" instead.
1336
+
1337
+ You can use `sass-convert --in-place --from sass2 file.sass' to convert files automatically.
1338
+ WARN
1339
+ foo {
1340
+ a: 2px 3px; }
1341
+ CSS
1342
+
1343
+ $equals-var ||= 2px 3px
1344
+ foo
1345
+ a: $equals-var
1346
+ SASS
1347
+ end
1348
+
1349
+ def test_variable_scope
1350
+ assert_equal(<<CSS, render(<<SASS))
1351
+ a {
1352
+ b-1: c;
1353
+ b-2: c;
1354
+ d: 12; }
1355
+
1356
+ b {
1357
+ d: 17; }
1358
+ CSS
1359
+ $i: 12
1360
+ a
1361
+ @for $i from 1 through 2
1362
+ b-\#{$i}: c
1363
+ d: $i
1364
+
1365
+ =foo
1366
+ $i: 17
1367
+
1368
+ b
1369
+ +foo
1370
+ d: $i
1371
+ SASS
1372
+ end
1373
+
1374
+ def test_hyphen_underscore_insensitive_variables
1375
+ assert_equal(<<CSS, render(<<SASS))
1376
+ a {
1377
+ b: c; }
1378
+
1379
+ d {
1380
+ e: 13;
1381
+ f: foobar; }
1382
+ CSS
1383
+ $var-hyphen: 12
1384
+ $var_under: foo
1385
+
1386
+ a
1387
+ $var_hyphen: 1 + $var_hyphen
1388
+ $var-under: $var-under + bar
1389
+ b: c
1390
+
1391
+ d
1392
+ e: $var-hyphen
1393
+ f: $var_under
1394
+ SASS
1395
+ end
1396
+
1397
+ def test_css_identifier_variable
1398
+ assert_equal(<<CSS, render(<<SASS))
1399
+ a {
1400
+ b: 12; }
1401
+ CSS
1402
+ $\\{foo\\(12\\): 12
1403
+
1404
+ a
1405
+ b: $\\{foo\\(12\\)
1406
+ SASS
1407
+ end
1408
+
1409
+ def test_important
1410
+ assert_equal(<<CSS, render(<<SASS))
1411
+ a {
1412
+ b: 12px !important; }
1413
+ CSS
1414
+ $foo: 12px
1415
+ a
1416
+ b: $foo !important
1417
+ SASS
1418
+ end
1419
+
1420
+ def test_argument_error
1421
+ assert_raise(Sass::SyntaxError) { render("a\n b: hsl(1)") }
1422
+ end
1423
+
1424
+ def test_comments_at_the_top_of_a_document
1425
+ render(<<SASS)
1426
+ //
1427
+ This is a comment that
1428
+ continues to the second line.
1429
+ foo
1430
+ bar: baz
1431
+ SASS
1432
+ end
1433
+
1434
+ def test_loud_comments_containing_a_comment_close
1435
+ actual_css = render(<<SASS)
1436
+ /*
1437
+ This is a comment that
1438
+ continues to the second line. */
1439
+ foo
1440
+ bar: baz
1441
+ SASS
1442
+ assert_equal(<<CSS, actual_css)
1443
+ /* This is a comment that
1444
+ * continues to the second line. */
1445
+ foo {
1446
+ bar: baz; }
1447
+ CSS
1448
+ end
1449
+
1450
+ def test_loud_comments_with_starred_lines
1451
+ assert_equal(<<CSS, render(<<SASS))
1452
+ /* This is a comment that
1453
+ * continues to the second line.
1454
+ * And even to the third! */
1455
+ CSS
1456
+ /* This is a comment that
1457
+ * continues to the second line.
1458
+ * And even to the third!
1459
+ SASS
1460
+ end
1461
+
1462
+ def test_loud_comments_with_no_space_after_starred_lines
1463
+ assert_equal(<<CSS, render(<<SASS))
1464
+ /*bip bop
1465
+ *beep boop
1466
+ *bap blimp */
1467
+ CSS
1468
+ /*bip bop
1469
+ *beep boop
1470
+ *bap blimp
1471
+ SASS
1472
+ end
1473
+
1474
+ def test_comment_indentation_at_beginning_of_doc
1475
+ assert_equal <<CSS, render(<<SASS)
1476
+ /* foo
1477
+ * bar
1478
+ * baz */
1479
+ foo {
1480
+ a: b; }
1481
+ CSS
1482
+ /* foo
1483
+ bar
1484
+ baz
1485
+ foo
1486
+ a: b
1487
+ SASS
1488
+ end
1489
+
1490
+ def test_unusual_comment_indentation
1491
+ assert_equal <<CSS, render(<<SASS)
1492
+ foo {
1493
+ /* foo
1494
+ * bar
1495
+ * baz */ }
1496
+ CSS
1497
+ foo
1498
+ /* foo
1499
+ bar
1500
+ baz
1501
+ SASS
1502
+ end
1503
+
1504
+ def test_loud_comment_with_close
1505
+ assert_equal <<CSS, render(<<SASS)
1506
+ foo {
1507
+ /* foo
1508
+ * bar */ }
1509
+ CSS
1510
+ foo
1511
+ /* foo
1512
+ bar */
1513
+ SASS
1514
+ end
1515
+
1516
+ def test_loud_comment_with_separate_line_close
1517
+ assert_equal <<CSS, render(<<SASS)
1518
+ foo {
1519
+ /* foo
1520
+ * bar
1521
+ */ }
1522
+ CSS
1523
+ foo
1524
+ /* foo
1525
+ * bar
1526
+ */
1527
+ SASS
1528
+ end
1529
+
1530
+ def test_attribute_selector_with_spaces
1531
+ assert_equal(<<CSS, render(<<SASS))
1532
+ a b[foo=bar] {
1533
+ c: d; }
1534
+ CSS
1535
+ a
1536
+ b[foo = bar]
1537
+ c: d
1538
+ SASS
1539
+ end
1540
+
1541
+ def test_quoted_colon
1542
+ assert_equal(<<CSS, render(<<SASS))
1543
+ a b[foo="bar: baz"] {
1544
+ c: d; }
1545
+ CSS
1546
+ a
1547
+ b[foo="bar: baz"]
1548
+ c: d
1549
+ SASS
1550
+ end
1551
+
1552
+ def test_quoted_comma
1553
+ assert_equal(<<CSS, render(<<SASS))
1554
+ a b[foo="bar, baz"] {
1555
+ c: d; }
1556
+ CSS
1557
+ a
1558
+ b[foo="bar, baz"]
1559
+ c: d
1560
+ SASS
1561
+ end
1562
+
1563
+ def test_quoted_ampersand
1564
+ assert_equal(<<CSS, render(<<SASS))
1565
+ a b[foo="bar & baz"] {
1566
+ c: d; }
1567
+ CSS
1568
+ a
1569
+ b[foo="bar & baz"]
1570
+ c: d
1571
+ SASS
1572
+ end
1573
+
1574
+ def test_empty_selector_warning
1575
+ assert_warning(<<END) {render("foo bar")}
1576
+ WARNING on line 1 of test_empty_selector_warning_inline.sass:
1577
+ This selector doesn't have any properties and will not be rendered.
1578
+ END
1579
+ end
1580
+
1581
+ def test_root_level_pseudo_class_with_new_properties
1582
+ assert_equal(<<CSS, render(<<SASS, :property_syntax => :new))
1583
+ :focus {
1584
+ outline: 0; }
1585
+ CSS
1586
+ :focus
1587
+ outline: 0
1588
+ SASS
1589
+ end
1590
+
1591
+ def test_pseudo_class_with_new_properties
1592
+ assert_equal(<<CSS, render(<<SASS, :property_syntax => :new))
1593
+ p :focus {
1594
+ outline: 0; }
1595
+ CSS
1596
+ p
1597
+ :focus
1598
+ outline: 0
1599
+ SASS
1600
+ end
1601
+
1602
+ def test_nil_option
1603
+ assert_equal(<<CSS, render(<<SASS, :format => nil))
1604
+ foo {
1605
+ a: b; }
1606
+ CSS
1607
+ foo
1608
+ a: b
1609
+ SASS
1610
+ end
1611
+
1612
+ def test_interpolation_in_raw_functions
1613
+ assert_equal(<<CSS, render(<<SASS))
1614
+ foo {
1615
+ filter: progid:Microsoft.foo.bar.Baz(flip=foobar, bang=#00ff00cc); }
1616
+ CSS
1617
+ foo
1618
+ filter: progid:Microsoft.foo.bar.Baz(flip=\#{foo + bar}, bang=#00ff00cc)
1619
+ SASS
1620
+ end
1621
+
1622
+ # SassScript string behavior
1623
+
1624
+ def test_plus_preserves_quotedness
1625
+ assert_equal(<<CSS, render(<<SASS))
1626
+ foo {
1627
+ a: "foo1";
1628
+ b: "1foo";
1629
+ c: foo1;
1630
+ d: 1foo;
1631
+ e: "foobar";
1632
+ f: foobar; }
1633
+ CSS
1634
+ foo
1635
+ a: "foo" + 1
1636
+ b: 1 + "foo"
1637
+ c: foo + 1
1638
+ d: 1 + foo
1639
+ e: "foo" + bar
1640
+ f: foo + "bar"
1641
+ SASS
1642
+ end
1643
+
1644
+ def test_colon_properties_preserve_quotedness
1645
+ assert_equal(<<CSS, render(<<SASS))
1646
+ foo {
1647
+ a: "foo";
1648
+ b: bar;
1649
+ c: "foo" bar;
1650
+ d: foo, "bar"; }
1651
+ CSS
1652
+ foo
1653
+ a: "foo"
1654
+ b: bar
1655
+ c: "foo" bar
1656
+ d: foo, "bar"
1657
+ SASS
1658
+ end
1659
+
1660
+ def test_colon_variables_preserve_quotedness
1661
+ assert_equal(<<CSS, render(<<SASS))
1662
+ foo {
1663
+ a: "foo";
1664
+ b: bar; }
1665
+ CSS
1666
+ $a: "foo"
1667
+ $b: bar
1668
+
1669
+ foo
1670
+ a: $a
1671
+ b: $b
1672
+ SASS
1673
+ end
1674
+
1675
+ def test_colon_args_preserve_quotedness
1676
+ assert_equal(<<CSS, render(<<SASS))
1677
+ foo {
1678
+ a: "foo";
1679
+ b: bar;
1680
+ c: "foo" bar;
1681
+ d: foo, "bar"; }
1682
+ CSS
1683
+ =foo($a: "foo", $b: bar, $c: "foo" bar, $d: (foo, "bar"))
1684
+ foo
1685
+ a: $a
1686
+ b: $b
1687
+ c: $c
1688
+ d: $d
1689
+
1690
+ +foo
1691
+ SASS
1692
+ end
1693
+
1694
+ def test_interpolation_unquotes_strings
1695
+ assert_equal(<<CSS, render(<<SASS))
1696
+ .foo-bar {
1697
+ a: b; }
1698
+ CSS
1699
+ .foo-\#{"bar"}
1700
+ a: b
1701
+ SASS
1702
+
1703
+ assert_equal(<<CSS, render(<<SASS))
1704
+ .foo {
1705
+ a: b c; }
1706
+ CSS
1707
+ .foo
1708
+ a: b \#{"c"}
1709
+ SASS
1710
+ end
1711
+
1712
+ def test_interpolation_unquotes_strings_in_vars
1713
+ assert_equal(<<CSS, render(<<SASS))
1714
+ .foo-bar {
1715
+ a: b; }
1716
+ CSS
1717
+ $var: "bar"
1718
+
1719
+ .foo-\#{$var}
1720
+ a: b
1721
+ SASS
1722
+ end
1723
+
1724
+ def test_interpolation_doesnt_deep_unquote_strings
1725
+ assert_equal(<<CSS, render(<<SASS))
1726
+ .foo- "bar" "baz" {
1727
+ a: b; }
1728
+ CSS
1729
+ .foo-\#{"bar" "baz"}
1730
+ a: b
1731
+ SASS
1732
+ end
1733
+
1734
+ # Deprecated equals behavior
1735
+
1736
+ def test_equals_properties_unquote_strings
1737
+ silence_warnings do
1738
+ assert_equal(<<CSS, render(<<SASS))
1739
+ foo {
1740
+ a: foo;
1741
+ b: bar;
1742
+ c: foo bar;
1743
+ d: foo, bar baz;
1744
+ e: foo bar, bar; }
1745
+ CSS
1746
+ foo
1747
+ a= "foo"
1748
+ b= bar
1749
+ c= "foo" bar
1750
+ d= foo, "bar baz"
1751
+ e= "foo bar", bar
1752
+ SASS
1753
+ end
1754
+ end
1755
+
1756
+ def test_equals_properties_unquote_value
1757
+ silence_warnings do
1758
+ assert_equal(<<CSS, render(<<SASS))
1759
+ foo {
1760
+ a: foo; }
1761
+ CSS
1762
+ $var: "foo"
1763
+
1764
+ foo
1765
+ a= $var
1766
+ SASS
1767
+ end
1768
+ end
1769
+
1770
+ def test_equals_properties_deep_unquote_vars
1771
+ silence_warnings do
1772
+ assert_equal(<<CSS, render(<<SASS))
1773
+ foo {
1774
+ a: foo bar;
1775
+ b: bar foo; }
1776
+ CSS
1777
+ $var: "foo"
1778
+
1779
+ foo
1780
+ a= $var "bar"
1781
+ b= "bar" $var
1782
+ SASS
1783
+ end
1784
+ end
1785
+
1786
+ def test_equals_vars_unquote_strings
1787
+ silence_warnings do
1788
+ assert_equal(<<CSS, render(<<SASS))
1789
+ foo {
1790
+ a: foo;
1791
+ b: bar;
1792
+ c: foo bar;
1793
+ d: foo, bar; }
1794
+ CSS
1795
+ $a = "foo"
1796
+ $b = bar
1797
+ $c = "foo" bar
1798
+ $d = foo, "bar"
1799
+
1800
+ foo
1801
+ a: $a
1802
+ b: $b
1803
+ c: $c
1804
+ d: $d
1805
+ SASS
1806
+ end
1807
+ end
1808
+
1809
+ def test_equals_vars_unquote_value
1810
+ silence_warnings do
1811
+ assert_equal(<<CSS, render(<<SASS))
1812
+ foo {
1813
+ a: foo; }
1814
+ CSS
1815
+ $var1: "foo"
1816
+ $var2 = $var1
1817
+
1818
+ foo
1819
+ a: $var2
1820
+ SASS
1821
+ end
1822
+ end
1823
+
1824
+ def test_equals_vars_deep_unquote_vars
1825
+ silence_warnings do
1826
+ assert_equal(<<CSS, render(<<SASS))
1827
+ foo {
1828
+ a: foo bar;
1829
+ b: bar foo; }
1830
+ CSS
1831
+ $var: "foo"
1832
+ $a = $var "bar"
1833
+ $b = "bar" $var
1834
+
1835
+ foo
1836
+ a: $a
1837
+ b: $b
1838
+ SASS
1839
+ end
1840
+ end
1841
+
1842
+ def test_equals_args_unquote_strings
1843
+ silence_warnings do
1844
+ assert_equal(<<CSS, render(<<SASS))
1845
+ foo {
1846
+ a: foo;
1847
+ b: bar;
1848
+ c: foo bar;
1849
+ d: foo, bar; }
1850
+ CSS
1851
+ =foo($a = "foo", $b = bar, $c = "foo" bar, $d = (foo, "bar"))
1852
+ foo
1853
+ a: $a
1854
+ b: $b
1855
+ c: $c
1856
+ d: $d
1857
+
1858
+ +foo
1859
+ SASS
1860
+ end
1861
+ end
1862
+
1863
+ def test_equals_args_unquote_value
1864
+ silence_warnings do
1865
+ assert_equal(<<CSS, render(<<SASS))
1866
+ foo {
1867
+ a: foo; }
1868
+ CSS
1869
+ $var1: "foo"
1870
+
1871
+ =foo($var2 = $var1)
1872
+ foo
1873
+ a: $var2
1874
+
1875
+ +foo
1876
+ SASS
1877
+ end
1878
+ end
1879
+
1880
+ def test_equals_args_deep_unquote_vars
1881
+ silence_warnings do
1882
+ assert_equal(<<CSS, render(<<SASS))
1883
+ foo {
1884
+ a: foo bar;
1885
+ b: bar foo; }
1886
+ CSS
1887
+ $var: "foo"
1888
+ =foo($a = $var "bar", $b = "bar" $var)
1889
+ foo
1890
+ a: $a
1891
+ b: $b
1892
+
1893
+ +foo
1894
+ SASS
1895
+ end
1896
+ end
1897
+
1898
+ def test_equals_properties_force_division
1899
+ silence_warnings do
1900
+ assert_equal(<<CSS, render(<<SASS))
1901
+ foo {
1902
+ a: 0.5; }
1903
+ CSS
1904
+ foo
1905
+ a = 1px/2px
1906
+ SASS
1907
+ end
1908
+ end
1909
+
1910
+ def test_warn_directive
1911
+ expected_warning = <<EXPECTATION
1912
+ WARNING: this is a warning
1913
+ on line 4 of test_warn_directive_inline.sass
1914
+
1915
+ WARNING: this is a mixin warning
1916
+ on line 2 of test_warn_directive_inline.sass, in `foo'
1917
+ from line 7 of test_warn_directive_inline.sass
1918
+ EXPECTATION
1919
+ assert_warning expected_warning do
1920
+ assert_equal <<CSS, render(<<SASS)
1921
+ bar {
1922
+ c: d; }
1923
+ CSS
1924
+ =foo
1925
+ @warn "this is a mixin warning"
1926
+
1927
+ @warn "this is a warning"
1928
+ bar
1929
+ c: d
1930
+ +foo
1931
+ SASS
1932
+ end
1933
+ end
1934
+
1935
+ def test_warn_directive_when_quiet
1936
+ assert_warning "" do
1937
+ assert_equal <<CSS, render(<<SASS, :quiet => true)
1938
+ CSS
1939
+ @warn "this is a warning"
1940
+ SASS
1941
+ end
1942
+ end
1943
+
1944
+ def test_warn_with_imports
1945
+ expected_warning = <<WARN
1946
+ WARNING: In the main file
1947
+ on line 1 of #{File.dirname(__FILE__)}/templates/warn.sass
1948
+
1949
+ WARNING: Imported
1950
+ on line 1 of #{File.dirname(__FILE__)}/templates/warn_imported.sass
1951
+ from line 2 of #{File.dirname(__FILE__)}/templates/warn.sass
1952
+
1953
+ WARNING: In an imported mixin
1954
+ on line 4 of #{File.dirname(__FILE__)}/templates/warn_imported.sass, in `emits-a-warning'
1955
+ from line 3 of #{File.dirname(__FILE__)}/templates/warn.sass
1956
+ WARN
1957
+ assert_warning expected_warning do
1958
+ renders_correctly "warn", :style => :compact, :load_paths => [File.dirname(__FILE__) + "/templates"]
1959
+ end
1960
+ end
1961
+
1962
+ # Regression tests
1963
+
1964
+ def test_parens_in_mixins
1965
+ assert_equal(<<CSS, render(<<SASS))
1966
+ .foo {
1967
+ color: #01ff7f;
1968
+ background-color: #000102; }
1969
+ CSS
1970
+ =foo($c1, $c2: rgb(0, 1, 2))
1971
+ color: $c1
1972
+ background-color: $c2
1973
+
1974
+ .foo
1975
+ +foo(rgb(1,255,127))
1976
+ SASS
1977
+ end
1978
+
1979
+ def test_comment_beneath_prop
1980
+ assert_equal(<<RESULT, render(<<SOURCE))
1981
+ .box {
1982
+ border-style: solid; }
1983
+ RESULT
1984
+ .box
1985
+ :border
1986
+ //:color black
1987
+ :style solid
1988
+ SOURCE
1989
+
1990
+ assert_equal(<<RESULT, render(<<SOURCE))
1991
+ .box {
1992
+ /* :color black */
1993
+ border-style: solid; }
1994
+ RESULT
1995
+ .box
1996
+ :border
1997
+ /* :color black
1998
+ :style solid
1999
+ SOURCE
2000
+
2001
+ assert_equal(<<RESULT, render(<<SOURCE, :style => :compressed))
2002
+ .box{border-style:solid}
2003
+ RESULT
2004
+ .box
2005
+ :border
2006
+ /*:color black
2007
+ :style solid
2008
+ SOURCE
2009
+ end
2010
+
2011
+ def test_compressed_comment_beneath_directive
2012
+ assert_equal(<<RESULT, render(<<SOURCE, :style => :compressed))
2013
+ @foo{a:b}
2014
+ RESULT
2015
+ @foo
2016
+ a: b
2017
+ /*b: c
2018
+ SOURCE
2019
+ end
2020
+
2021
+ def test_comment_with_crazy_indentation
2022
+ assert_equal(<<CSS, render(<<SASS))
2023
+ /* This is a loud comment:
2024
+ * Where the indentation is wonky. */
2025
+ .comment {
2026
+ width: 1px; }
2027
+ CSS
2028
+ /*
2029
+ This is a loud comment:
2030
+ Where the indentation is wonky.
2031
+ //
2032
+ This is a silent comment:
2033
+ Where the indentation is wonky.
2034
+ .comment
2035
+ width: 1px
2036
+ SASS
2037
+ end
2038
+
2039
+ def test_plus_with_space
2040
+ assert_equal(<<CSS, render(<<SASS))
2041
+ a + b {
2042
+ color: green; }
2043
+ CSS
2044
+ a
2045
+ + b
2046
+ color: green
2047
+ SASS
2048
+ end
2049
+
2050
+ def test_empty_line_comment
2051
+ assert_equal(<<CSS, render(<<SASS))
2052
+ /* Foo
2053
+ *
2054
+ * Bar */
2055
+ CSS
2056
+ /*
2057
+ Foo
2058
+
2059
+ Bar
2060
+ SASS
2061
+ end
2062
+
2063
+ def test_empty_comment
2064
+ assert_equal(<<CSS, render(<<SASS))
2065
+ /* */
2066
+ a {
2067
+ /* */
2068
+ b: c; }
2069
+ CSS
2070
+ /*
2071
+ a
2072
+ /*
2073
+ b: c
2074
+ SASS
2075
+ end
2076
+
2077
+ def test_options_available_in_environment
2078
+ assert_equal(<<CSS, render(<<SASS))
2079
+ a {
2080
+ b: nested; }
2081
+ CSS
2082
+ a
2083
+ b: option("style")
2084
+ SASS
2085
+ end
2086
+
2087
+ def test_mixin_no_arg_error
2088
+ assert_raise_message(Sass::SyntaxError, 'Invalid CSS after "($bar,": expected variable (e.g. $foo), was ")"') do
2089
+ render(<<SASS)
2090
+ =foo($bar,)
2091
+ bip: bap
2092
+ SASS
2093
+ end
2094
+ end
2095
+
2096
+ def test_import_with_commas_in_url
2097
+ assert_equal <<CSS, render(<<SASS)
2098
+ @import url(foo.css?bar,baz);
2099
+ CSS
2100
+ @import url(foo.css?bar,baz)
2101
+ SASS
2102
+ end
2103
+
2104
+ # Encodings
2105
+
2106
+ unless Sass::Util.ruby1_8?
2107
+ def test_encoding_error
2108
+ render("foo\nbar\nb\xFEaz".force_encoding("utf-8"))
2109
+ assert(false, "Expected exception")
2110
+ rescue Sass::SyntaxError => e
2111
+ assert_equal(3, e.sass_line)
2112
+ assert_equal('Invalid UTF-8 character "\xFE"', e.message)
2113
+ end
2114
+
2115
+ def test_ascii_incompatible_encoding_error
2116
+ template = "foo\nbar\nb_z".encode("utf-16le")
2117
+ template[9] = "\xFE".force_encoding("utf-16le")
2118
+ render(template)
2119
+ assert(false, "Expected exception")
2120
+ rescue Sass::SyntaxError => e
2121
+ assert_equal(3, e.sass_line)
2122
+ assert_equal('Invalid UTF-16LE character "\xFE"', e.message)
2123
+ end
2124
+
2125
+ def test_same_charset_as_encoding
2126
+ assert_renders_encoded(<<CSS, <<SASS)
2127
+ @charset "utf-8";
2128
+ fóó {
2129
+ a: b; }
2130
+ CSS
2131
+ @charset "utf-8"
2132
+ fóó
2133
+ a: b
2134
+ SASS
2135
+ end
2136
+
2137
+ def test_different_charset_than_encoding
2138
+ assert_renders_encoded(<<CSS.force_encoding("IBM866"), <<SASS)
2139
+ @charset "ibm866";
2140
+ fóó {
2141
+ a: b; }
2142
+ CSS
2143
+ @charset "ibm866"
2144
+ fóó
2145
+ a: b
2146
+ SASS
2147
+ end
2148
+
2149
+ def test_different_encoding_than_system
2150
+ assert_renders_encoded(<<CSS.encode("IBM866"), <<SASS.encode("IBM866"))
2151
+ тАЬ {
2152
+ a: b; }
2153
+ CSS
2154
+ тАЬ
2155
+ a: b
2156
+ SASS
2157
+ end
2158
+
2159
+ def test_multibyte_charset
2160
+ assert_renders_encoded(<<CSS.encode("UTF-16BE"), <<SASS.encode("UTF-16BE").force_encoding("UTF-8"))
2161
+ @charset "utf-16be";
2162
+ fóó {
2163
+ a: b; }
2164
+ CSS
2165
+ @charset "utf-16be"
2166
+ fóó
2167
+ a: b
2168
+ SASS
2169
+ end
2170
+
2171
+ def test_multibyte_charset_without_endian_specifier
2172
+ assert_renders_encoded(<<CSS.encode("UTF-32LE"), <<SASS.encode("UTF-32LE").force_encoding("UTF-8"))
2173
+ @charset "utf-32";
2174
+ fóó {
2175
+ a: b; }
2176
+ CSS
2177
+ @charset "utf-32"
2178
+ fóó
2179
+ a: b
2180
+ SASS
2181
+ end
2182
+
2183
+ def test_utf8_bom
2184
+ assert_renders_encoded(<<CSS, <<SASS.force_encoding("BINARY"))
2185
+ fóó {
2186
+ a: b; }
2187
+ CSS
2188
+ \uFEFFfóó
2189
+ a: b
2190
+ SASS
2191
+ end
2192
+
2193
+ def test_utf16le_bom
2194
+ assert_renders_encoded(<<CSS.encode("UTF-16LE"), <<SASS.encode("UTF-16LE").force_encoding("BINARY"))
2195
+ fóó {
2196
+ a: b; }
2197
+ CSS
2198
+ \uFEFFfóó
2199
+ a: b
2200
+ SASS
2201
+ end
2202
+
2203
+ def test_utf32be_bom
2204
+ assert_renders_encoded(<<CSS.encode("UTF-32BE"), <<SASS.encode("UTF-32BE").force_encoding("BINARY"))
2205
+ fóó {
2206
+ a: b; }
2207
+ CSS
2208
+ \uFEFFfóó
2209
+ a: b
2210
+ SASS
2211
+ end
2212
+ end
2213
+
2214
+ def test_original_filename_set
2215
+ importer = MockImporter.new
2216
+ importer.add_import("imported", "div{color:red}")
2217
+
2218
+ original_filename = filename_for_test
2219
+ engine = Sass::Engine.new('@import "imported"; div{color:blue}',
2220
+ :filename => original_filename, :load_paths => [importer], :syntax => :scss)
2221
+ engine.render
2222
+
2223
+ assert_equal original_filename, engine.options[:original_filename]
2224
+ assert_equal original_filename, importer.engine("imported").options[:original_filename]
2225
+ end
2226
+
2227
+
2228
+ private
2229
+
2230
+ def assert_hash_has(hash, expected)
2231
+ expected.each {|k, v| assert_equal(v, hash[k])}
2232
+ end
2233
+
2234
+ def assert_renders_encoded(css, sass)
2235
+ result = render(sass)
2236
+ assert_equal css.encoding, result.encoding
2237
+ assert_equal css, result
2238
+ end
2239
+
2240
+ def render(sass, options = {})
2241
+ munge_filename options
2242
+ Sass::Engine.new(sass, options).render
2243
+ end
2244
+
2245
+ def renders_correctly(name, options={})
2246
+ sass_file = load_file(name, "sass")
2247
+ css_file = load_file(name, "css")
2248
+ options[:filename] ||= filename(name, "sass")
2249
+ options[:syntax] ||= :sass
2250
+ options[:css_filename] ||= filename(name, "css")
2251
+ css_result = Sass::Engine.new(sass_file, options).render
2252
+ assert_equal css_file, css_result
2253
+ end
2254
+
2255
+ def load_file(name, type = "sass")
2256
+ @result = ''
2257
+ File.new(filename(name, type)).each_line { |l| @result += l }
2258
+ @result
2259
+ end
2260
+
2261
+ def filename(name, type)
2262
+ File.dirname(__FILE__) + "/#{type == 'sass' ? 'templates' : 'results'}/#{name}.#{type}"
2263
+ end
2264
+
2265
+ def sassc_path(template)
2266
+ sassc_path = File.join(File.dirname(__FILE__) + "/templates/#{template}.sass")
2267
+ engine = Sass::Engine.new("", :filename => sassc_path,
2268
+ :importer => Sass::Importers::Filesystem.new("."))
2269
+ key = engine.send(:sassc_key)
2270
+ File.join(engine.options[:cache_location], key)
2271
+ end
2272
+ end
2273
+