haml 2.2.24 → 3.0.0.beta.1

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

Potentially problematic release.


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

Files changed (168) hide show
  1. data/.yardopts +0 -1
  2. data/README.md +91 -151
  3. data/REMEMBER +11 -1
  4. data/Rakefile +73 -55
  5. data/VERSION +1 -1
  6. data/VERSION_NAME +1 -1
  7. data/bin/css2sass +7 -1
  8. data/bin/sass-convert +7 -0
  9. data/extra/haml-mode.el +2 -1
  10. data/lib/haml/buffer.rb +22 -4
  11. data/lib/haml/engine.rb +5 -1
  12. data/lib/haml/exec.rb +231 -46
  13. data/lib/haml/filters.rb +19 -8
  14. data/lib/haml/helpers.rb +47 -20
  15. data/lib/haml/helpers/action_view_extensions.rb +2 -4
  16. data/lib/haml/helpers/action_view_mods.rb +11 -8
  17. data/lib/haml/helpers/xss_mods.rb +13 -2
  18. data/lib/haml/html.rb +179 -48
  19. data/lib/haml/html/erb.rb +141 -0
  20. data/lib/haml/precompiler.rb +40 -15
  21. data/lib/haml/railtie.rb +1 -5
  22. data/lib/haml/root.rb +3 -0
  23. data/lib/haml/template.rb +4 -14
  24. data/lib/haml/util.rb +120 -30
  25. data/lib/haml/version.rb +25 -2
  26. data/lib/sass.rb +5 -1
  27. data/lib/sass/callbacks.rb +50 -0
  28. data/lib/sass/css.rb +40 -191
  29. data/lib/sass/engine.rb +170 -74
  30. data/lib/sass/environment.rb +8 -2
  31. data/lib/sass/error.rb +163 -25
  32. data/lib/sass/files.rb +31 -28
  33. data/lib/sass/plugin.rb +268 -87
  34. data/lib/sass/plugin/rails.rb +9 -4
  35. data/lib/sass/repl.rb +1 -1
  36. data/lib/sass/script.rb +31 -29
  37. data/lib/sass/script/bool.rb +1 -0
  38. data/lib/sass/script/color.rb +290 -23
  39. data/lib/sass/script/css_lexer.rb +22 -0
  40. data/lib/sass/script/css_parser.rb +28 -0
  41. data/lib/sass/script/funcall.rb +22 -3
  42. data/lib/sass/script/functions.rb +523 -33
  43. data/lib/sass/script/interpolation.rb +42 -0
  44. data/lib/sass/script/lexer.rb +169 -52
  45. data/lib/sass/script/literal.rb +58 -9
  46. data/lib/sass/script/node.rb +79 -1
  47. data/lib/sass/script/number.rb +20 -5
  48. data/lib/sass/script/operation.rb +49 -3
  49. data/lib/sass/script/parser.rb +162 -28
  50. data/lib/sass/script/string.rb +50 -2
  51. data/lib/sass/script/unary_operation.rb +25 -2
  52. data/lib/sass/script/variable.rb +21 -4
  53. data/lib/sass/scss.rb +14 -0
  54. data/lib/sass/scss/css_parser.rb +39 -0
  55. data/lib/sass/scss/parser.rb +683 -0
  56. data/lib/sass/scss/rx.rb +112 -0
  57. data/lib/sass/scss/script_lexer.rb +13 -0
  58. data/lib/sass/scss/script_parser.rb +25 -0
  59. data/lib/sass/tree/comment_node.rb +69 -27
  60. data/lib/sass/tree/debug_node.rb +7 -2
  61. data/lib/sass/tree/directive_node.rb +41 -35
  62. data/lib/sass/tree/for_node.rb +6 -0
  63. data/lib/sass/tree/if_node.rb +13 -1
  64. data/lib/sass/tree/import_node.rb +52 -27
  65. data/lib/sass/tree/mixin_def_node.rb +18 -0
  66. data/lib/sass/tree/mixin_node.rb +41 -6
  67. data/lib/sass/tree/node.rb +197 -70
  68. data/lib/sass/tree/prop_node.rb +152 -57
  69. data/lib/sass/tree/root_node.rb +118 -0
  70. data/lib/sass/tree/rule_node.rb +193 -96
  71. data/lib/sass/tree/variable_node.rb +9 -5
  72. data/lib/sass/tree/while_node.rb +4 -0
  73. data/test/benchmark.rb +5 -5
  74. data/test/haml/engine_test.rb +147 -10
  75. data/test/haml/{rhtml/_av_partial_1.rhtml → erb/_av_partial_1.erb} +1 -1
  76. data/test/haml/{rhtml/_av_partial_2.rhtml → erb/_av_partial_2.erb} +1 -1
  77. data/test/haml/{rhtml/action_view.rhtml → erb/action_view.erb} +1 -1
  78. data/test/haml/{rhtml/standard.rhtml → erb/standard.erb} +0 -0
  79. data/test/haml/helper_test.rb +91 -24
  80. data/test/haml/html2haml/erb_tests.rb +410 -0
  81. data/test/haml/html2haml_test.rb +210 -66
  82. data/test/haml/results/filters.xhtml +1 -1
  83. data/test/haml/results/just_stuff.xhtml +2 -0
  84. data/test/haml/spec_test.rb +44 -0
  85. data/test/haml/template_test.rb +22 -2
  86. data/test/haml/templates/helpers.haml +0 -13
  87. data/test/haml/templates/just_stuff.haml +2 -0
  88. data/test/haml/util_test.rb +48 -0
  89. data/test/sass/callbacks_test.rb +61 -0
  90. data/test/sass/conversion_test.rb +884 -0
  91. data/test/sass/css2sass_test.rb +99 -18
  92. data/test/sass/data/hsl-rgb.txt +319 -0
  93. data/test/sass/engine_test.rb +1049 -131
  94. data/test/sass/functions_test.rb +398 -47
  95. data/test/sass/more_results/more_import.css +1 -1
  96. data/test/sass/more_templates/more_import.sass +3 -3
  97. data/test/sass/plugin_test.rb +184 -10
  98. data/test/sass/results/compact.css +1 -1
  99. data/test/sass/results/complex.css +5 -5
  100. data/test/sass/results/compressed.css +1 -1
  101. data/test/sass/results/expanded.css +1 -1
  102. data/test/sass/results/import.css +3 -1
  103. data/test/sass/results/mixins.css +12 -12
  104. data/test/sass/results/nested.css +1 -1
  105. data/test/sass/results/options.css +1 -0
  106. data/test/sass/results/parent_ref.css +4 -4
  107. data/test/sass/results/script.css +3 -3
  108. data/test/sass/results/scss_import.css +15 -0
  109. data/test/sass/results/scss_importee.css +2 -0
  110. data/test/sass/script_conversion_test.rb +153 -0
  111. data/test/sass/script_test.rb +137 -70
  112. data/test/sass/scss/css_test.rb +811 -0
  113. data/test/sass/scss/rx_test.rb +156 -0
  114. data/test/sass/scss/scss_test.rb +871 -0
  115. data/test/sass/scss/test_helper.rb +37 -0
  116. data/test/sass/templates/alt.sass +2 -2
  117. data/test/sass/templates/bork1.sass +2 -0
  118. data/test/sass/templates/bork3.sass +2 -0
  119. data/test/sass/templates/bork4.sass +2 -0
  120. data/test/sass/templates/import.sass +4 -4
  121. data/test/sass/templates/importee.sass +3 -3
  122. data/test/sass/templates/line_numbers.sass +1 -1
  123. data/test/sass/templates/mixin_bork.sass +5 -0
  124. data/test/sass/templates/mixins.sass +2 -2
  125. data/test/sass/templates/nested_bork1.sass +2 -0
  126. data/test/sass/templates/nested_bork2.sass +2 -0
  127. data/test/sass/templates/nested_bork3.sass +2 -0
  128. data/test/sass/templates/nested_bork4.sass +2 -0
  129. data/test/sass/templates/nested_mixin_bork.sass +6 -0
  130. data/test/sass/templates/options.sass +2 -0
  131. data/test/sass/templates/parent_ref.sass +2 -2
  132. data/test/sass/templates/script.sass +69 -69
  133. data/test/sass/templates/scss_import.scss +10 -0
  134. data/test/sass/templates/scss_importee.scss +1 -0
  135. data/test/sass/templates/units.sass +10 -10
  136. data/test/test_helper.rb +20 -8
  137. data/vendor/fssm/LICENSE +20 -0
  138. data/vendor/fssm/README.markdown +55 -0
  139. data/vendor/fssm/Rakefile +59 -0
  140. data/vendor/fssm/VERSION.yml +5 -0
  141. data/vendor/fssm/example.rb +9 -0
  142. data/vendor/fssm/fssm.gemspec +77 -0
  143. data/vendor/fssm/lib/fssm.rb +33 -0
  144. data/vendor/fssm/lib/fssm/backends/fsevents.rb +36 -0
  145. data/vendor/fssm/lib/fssm/backends/inotify.rb +26 -0
  146. data/vendor/fssm/lib/fssm/backends/polling.rb +25 -0
  147. data/vendor/fssm/lib/fssm/backends/rubycocoa/fsevents.rb +131 -0
  148. data/vendor/fssm/lib/fssm/monitor.rb +26 -0
  149. data/vendor/fssm/lib/fssm/path.rb +91 -0
  150. data/vendor/fssm/lib/fssm/pathname.rb +502 -0
  151. data/vendor/fssm/lib/fssm/state/directory.rb +57 -0
  152. data/vendor/fssm/lib/fssm/state/file.rb +24 -0
  153. data/vendor/fssm/lib/fssm/support.rb +63 -0
  154. data/vendor/fssm/lib/fssm/tree.rb +176 -0
  155. data/vendor/fssm/profile/prof-cache.rb +40 -0
  156. data/vendor/fssm/profile/prof-fssm-pathname.html +1231 -0
  157. data/vendor/fssm/profile/prof-pathname.rb +68 -0
  158. data/vendor/fssm/profile/prof-plain-pathname.html +988 -0
  159. data/vendor/fssm/profile/prof.html +2379 -0
  160. data/vendor/fssm/spec/path_spec.rb +75 -0
  161. data/vendor/fssm/spec/root/duck/quack.txt +0 -0
  162. data/vendor/fssm/spec/root/file.css +0 -0
  163. data/vendor/fssm/spec/root/file.rb +0 -0
  164. data/vendor/fssm/spec/root/file.yml +0 -0
  165. data/vendor/fssm/spec/root/moo/cow.txt +0 -0
  166. data/vendor/fssm/spec/spec_helper.rb +14 -0
  167. metadata +94 -14
  168. data/test/sass/templates/bork.sass +0 -2
@@ -1,13 +1,13 @@
1
- a { color: #000; }
2
- a:hover { color: #f00; }
1
+ a { color: black; }
2
+ a:hover { color: red; }
3
3
 
4
4
  p, div { width: 100em; }
5
5
  p foo, div foo { width: 10em; }
6
6
  p:hover, p bar, div:hover, div bar { height: 20em; }
7
7
 
8
8
  #cool { border-style: solid; border-width: 2em; }
9
- .ie7 #cool, .ie6 #cool { content: string(Totally not cool.); }
10
- .firefox #cool { content: string(Quite cool.); }
9
+ .ie7 #cool, .ie6 #cool { content: string("Totally not cool."); }
10
+ .firefox #cool { content: string("Quite cool."); }
11
11
 
12
12
  .wow, .snazzy { font-family: fantasy; }
13
13
  .wow:hover, .wow:visited, .snazzy:hover, .snazzy:visited { font-weight: bold; }
@@ -1,7 +1,7 @@
1
- #main { content: Hello!; qstr: Quo"ted"!; hstr: Hyph-en!; width: 30em; background-color: #000; color: #ffffaa; short-color: #112233; named-color: olive; con: foo bar(9 hi there boom); con2: noquo quo; }
1
+ #main { content: Hello!; qstr: 'Quo"ted"!'; hstr: Hyph-en!; width: 30em; background-color: black; color: #ffffaa; short-color: #112233; named-color: olive; con: "foo" bar(9 hi there "boom"); con2: "noquo" quo; }
2
2
  #main #sidebar { background-color: #00ff98; num-normal: 10; num-dec: 10.2; num-dec0: 99; num-neg: -10; esc: 10 +12; many: 6; order: 7; complex: #4c9db1hi16; }
3
3
 
4
- #plus { num-num: 7; num-num-un: 25em; num-num-un2: 23em; num-num-neg: 9.87; num-str: 100px; num-col: #b7b7b7; num-perc: 31%; str-str: hi there; str-str2: hi there; str-col: 14em solid #112233; str-num: times: 13; col-num: #ff7b9d; col-col: #5173ff; }
4
+ #plus { num-num: 7; num-num-un: 25em; num-num-un2: 23em; num-num-neg: 9.87; num-str: 100px; num-col: #b7b7b7; num-perc: 31%; str-str: "hi there"; str-str2: "hi there"; str-col: "14em solid #112233"; str-num: "times: 13"; col-num: #ff7b9d; col-col: #5173ff; }
5
5
 
6
6
  #minus { num-num: 900; col-num: #f9f9f4; col-col: #000035; unary-num: -1; unary-const: 10; unary-paren: -11; unary-two: 12; unary-many: 12; unary-crazy: -15; }
7
7
 
@@ -11,6 +11,6 @@
11
11
 
12
12
  #mod { num-num: 2; col-col: #0f0e05; col-num: #020001; }
13
13
 
14
- #const { escaped-quote: !foo; default: Hello! !important; }
14
+ #const { escaped-quote: $foo !bar; default: Hello! !important; }
15
15
 
16
16
  #regression { a: 4; }
@@ -0,0 +1,15 @@
1
+ imported { otherconst: hello; myconst: goodbye; pre-mixin: here; }
2
+
3
+ body { font: Arial; background: blue; }
4
+
5
+ #page { width: 700px; height: 100; }
6
+ #page #header { height: 300px; }
7
+ #page #header h1 { font-size: 50px; color: blue; }
8
+
9
+ #content.user.show #container.top #column.left { width: 100px; }
10
+ #content.user.show #container.top #column.right { width: 600px; }
11
+ #content.user.show #container.bottom { background: brown; }
12
+
13
+ midrule { inthe: middle; }
14
+
15
+ nonimported { myconst: hello; otherconst: goodbye; post-mixin: here; }
@@ -0,0 +1,2 @@
1
+ scss {
2
+ imported: yes; }
@@ -0,0 +1,153 @@
1
+ #!/usr/bin/env ruby
2
+ # -*- coding: utf-8 -*-
3
+ require File.dirname(__FILE__) + '/../test_helper'
4
+ require 'sass/engine'
5
+
6
+ class SassScriptConversionTest < Test::Unit::TestCase
7
+ def test_bool
8
+ assert_renders "true"
9
+ assert_renders "false"
10
+ end
11
+
12
+ def test_color
13
+ assert_renders "#abcdef"
14
+ assert_renders "blue"
15
+ assert_renders "rgba(0, 1, 2, 0.2)"
16
+
17
+ assert_equal "#aabbcc", render("#abc")
18
+ assert_equal "blue", render("#0000ff")
19
+ end
20
+
21
+ def test_number
22
+ assert_renders "10"
23
+ assert_renders "10.35"
24
+ assert_renders "12px"
25
+ assert_renders "12.45px"
26
+
27
+ assert_equal "12.346", render("12.345678901")
28
+ end
29
+
30
+ def test_string
31
+ assert_renders '"foo"'
32
+ assert_renders '"bar baz"'
33
+ assert_equal '"baz bang"', render("'baz bang'")
34
+ end
35
+
36
+ def test_string_quotes
37
+ assert_equal "'quote\"quote'", render('"quote\\"quote"')
38
+ assert_equal '"quote\'quote"', render("'quote\\'quote'")
39
+ assert_renders '"quote\'quote\\"quote"'
40
+ assert_equal '"quote\'quote\\"quote"', render("'quote\\'quote\"quote'")
41
+ end
42
+
43
+ def test_string_escapes
44
+ assert_renders '"foo\\\\bar"'
45
+ end
46
+
47
+ def test_funcall
48
+ assert_renders "foo(true, blue)"
49
+ assert_renders "hsla(20deg, 30%, 50%, 0.3)"
50
+ assert_renders "blam()"
51
+
52
+ assert_renders "-\xC3\xBFoo(12px)"
53
+ assert_renders "-foo(12px)"
54
+ end
55
+
56
+ def test_variable
57
+ assert_renders "$foo-bar"
58
+ assert_renders "$flaznicate"
59
+ assert_warning(<<WARN) {assert_equal "$tumbly-wumbly", render("!tumbly-wumbly")}
60
+ DEPRECATION WARNING:
61
+ On line 1, character 1 of 'test_variable_inline.sass'
62
+ Variables with ! have been deprecated and will be removed in version 3.2.
63
+ Use "$tumbly-wumbly" instead.
64
+
65
+ You can use `sass-convert --in-place --from sass2 file.sass' to convert files automatically.
66
+ WARN
67
+ end
68
+
69
+ def test_important
70
+ assert_renders "!important"
71
+ assert_renders "$foo !important"
72
+ end
73
+
74
+ def test_comma_operator
75
+ assert_renders "$foo, $bar $baz"
76
+ assert_renders "$foo $bar, $baz"
77
+
78
+ assert_renders "($foo, $bar) $baz"
79
+ assert_renders "$foo ($bar, $baz)"
80
+
81
+ assert_equal "$foo, $bar $baz", render("$foo, ($bar $baz)")
82
+ assert_equal "$foo $bar, $baz", render("($foo $bar), $baz")
83
+ end
84
+
85
+ def test_concat_operator
86
+ assert_renders "$foo $bar or $baz"
87
+ assert_renders "$foo or $bar $baz"
88
+
89
+ assert_renders "($foo $bar) or $baz"
90
+ assert_renders "$foo or ($bar $baz)"
91
+
92
+ assert_equal "$foo $bar or $baz", render("$foo ($bar or $baz)")
93
+ assert_equal "$foo or $bar $baz", render("($foo or $bar) $baz")
94
+ end
95
+
96
+ def self.test_precedence(outer, inner)
97
+ op_outer = Sass::Script::Lexer::OPERATORS_REVERSE[outer]
98
+ op_inner = Sass::Script::Lexer::OPERATORS_REVERSE[inner]
99
+ class_eval <<RUBY
100
+ def test_precedence_#{outer}_#{inner}
101
+ assert_renders "$foo #{op_outer} $bar #{op_inner} $baz"
102
+ assert_renders "$foo #{op_inner} $bar #{op_outer} $baz"
103
+
104
+ assert_renders "($foo #{op_outer} $bar) #{op_inner} $baz"
105
+ assert_renders "$foo #{op_inner} ($bar #{op_outer} $baz)"
106
+
107
+ assert_equal "$foo #{op_outer} $bar #{op_inner} $baz",
108
+ render("$foo #{op_outer} ($bar #{op_inner} $baz)")
109
+ assert_equal "$foo #{op_inner} $bar #{op_outer} $baz",
110
+ render("($foo #{op_inner} $bar) #{op_outer} $baz")
111
+ end
112
+ RUBY
113
+ end
114
+
115
+ test_precedence :or, :and
116
+ test_precedence :and, :eq
117
+ test_precedence :and, :neq
118
+ test_precedence :eq, :gt
119
+ test_precedence :eq, :gte
120
+ test_precedence :eq, :lt
121
+ test_precedence :eq, :lte
122
+ test_precedence :gt, :plus
123
+ test_precedence :gt, :minus
124
+ test_precedence :plus, :times
125
+ test_precedence :plus, :div
126
+ test_precedence :plus, :mod
127
+
128
+ def test_unary_op
129
+ assert_renders "-12px"
130
+ assert_renders '/"foo"'
131
+ assert_renders 'not true'
132
+
133
+ assert_renders "-(foo(12px))"
134
+ assert_renders "-(-foo(12px))"
135
+ assert_renders "-(_foo(12px))"
136
+ assert_renders "-(\xC3\xBFoo(12px))"
137
+ assert_renders "-(blue)"
138
+
139
+ assert_equal 'not true or false', render('(not true) or false')
140
+ assert_equal 'not (true or false)', render('not (true or false)')
141
+ end
142
+
143
+ private
144
+
145
+ def assert_renders(script, options = {})
146
+ assert_equal(script, render(script, options))
147
+ end
148
+
149
+ def render(script, options = {})
150
+ munge_filename(options)
151
+ Sass::Script.parse(script, 1, 0, options).to_sass
152
+ end
153
+ end
@@ -2,6 +2,13 @@
2
2
  require File.dirname(__FILE__) + '/../test_helper'
3
3
  require 'sass/engine'
4
4
 
5
+ module Sass::Script::Functions::UserFunctions
6
+ def assert_options(val)
7
+ val.options[:foo]
8
+ Sass::Script::String.new("Options defined!")
9
+ end
10
+ end
11
+
5
12
  class SassScriptTest < Test::Unit::TestCase
6
13
  include Sass::Script
7
14
 
@@ -10,10 +17,27 @@ class SassScriptTest < Test::Unit::TestCase
10
17
  assert_raise(Sass::SyntaxError, "Color values must be between 0 and 255") {Color.new([256, 2, 3])}
11
18
  end
12
19
 
20
+ def test_color_checks_rgba_input
21
+ assert_raise(Sass::SyntaxError, "Alpha channel must be between 0 and 1") {Color.new([1, 2, 3, 1.1])}
22
+ assert_raise(Sass::SyntaxError, "Alpha channel must be between 0 and 1") {Color.new([1, 2, 3, -0.1])}
23
+ end
24
+
13
25
  def test_string_escapes
26
+ assert_equal "'", resolve("\"'\"")
14
27
  assert_equal '"', resolve("\"\\\"\"")
15
28
  assert_equal "\\", resolve("\"\\\\\"")
16
29
  assert_equal "\\02fa", resolve("\"\\02fa\"")
30
+
31
+ assert_equal "'", resolve("'\\''")
32
+ assert_equal '"', resolve("'\"'")
33
+ assert_equal "\\", resolve("'\\\\'")
34
+ assert_equal "\\02fa", resolve("'\\02fa'")
35
+ end
36
+
37
+ def test_string_interpolation
38
+ assert_equal "foo2bar", resolve('\'foo#{1 + 1}bar\'')
39
+ assert_equal "foo2bar", resolve('"foo#{1 + 1}bar"')
40
+ assert_equal "foo1bar5baz4bang", resolve('\'foo#{1 + "bar#{2 + 3}baz" + 4}bang\'')
17
41
  end
18
42
 
19
43
  def test_color_names
@@ -22,14 +46,57 @@ class SassScriptTest < Test::Unit::TestCase
22
46
  assert_equal "#fffffe", resolve("white - #000001")
23
47
  end
24
48
 
25
- def test_implicit_strings
26
- silence_warnings do
27
- assert_equal Sass::Script::String.new("foo"), eval("foo")
28
- assert_equal Sass::Script::String.new("foo bar"), eval("foo bar")
29
- assert_equal Sass::Script::String.new("foo/bar"), eval("foo/bar")
49
+ def test_rgba_color_literals
50
+ assert_equal Sass::Script::Color.new([1, 2, 3, 0.75]), eval("rgba(1, 2, 3, 0.75)")
51
+ assert_equal "rgba(1, 2, 3, 0.75)", resolve("rgba(1, 2, 3, 0.75)")
52
+
53
+ assert_equal Sass::Script::Color.new([1, 2, 3, 0]), eval("rgba(1, 2, 3, 0)")
54
+ assert_equal "rgba(1, 2, 3, 0)", resolve("rgba(1, 2, 3, 0)")
55
+
56
+ assert_equal Sass::Script::Color.new([1, 2, 3]), eval("rgba(1, 2, 3, 1)")
57
+ assert_equal Sass::Script::Color.new([1, 2, 3, 1]), eval("rgba(1, 2, 3, 1)")
58
+ assert_equal "#010203", resolve("rgba(1, 2, 3, 1)")
59
+ assert_equal "white", resolve("rgba(255, 255, 255, 1)")
60
+ end
61
+
62
+ def test_rgba_color_math
63
+ assert_equal "rgba(50, 50, 100, 0.35)", resolve("rgba(1, 1, 2, 0.35) * rgba(50, 50, 50, 0.35)")
64
+ assert_equal "rgba(52, 52, 52, 0.25)", resolve("rgba(2, 2, 2, 0.25) + rgba(50, 50, 50, 0.25)")
65
+
66
+ assert_raise(Sass::SyntaxError, "Alpha channels must be equal: rgba(1, 2, 3, 0.15) + rgba(50, 50, 50, 0.75)") do
67
+ resolve("rgba(1, 2, 3, 0.15) + rgba(50, 50, 50, 0.75)")
68
+ end
69
+ assert_raise(Sass::SyntaxError, "Alpha channels must be equal: #123456 * rgba(50, 50, 50, 0.75)") do
70
+ resolve("#123456 * rgba(50, 50, 50, 0.75)")
71
+ end
72
+ assert_raise(Sass::SyntaxError, "Alpha channels must be equal: #123456 / #123456") do
73
+ resolve("rgba(50, 50, 50, 0.75) / #123456")
30
74
  end
31
75
  end
32
76
 
77
+ def test_rgba_number_math
78
+ assert_equal "rgba(49, 49, 49, 0.75)", resolve("rgba(50, 50, 50, 0.75) - 1")
79
+ assert_equal "rgba(100, 100, 100, 0.75)", resolve("rgba(50, 50, 50, 0.75) * 2")
80
+ end
81
+
82
+ def test_compressed_colors
83
+ assert_equal "#123456", resolve("#123456", :style => :compressed)
84
+ assert_equal "rgba(1, 2, 3, 0.5)", resolve("rgba(1, 2, 3, 0.5)", :style => :compressed)
85
+ assert_equal "#123", resolve("#112233", :style => :compressed)
86
+ assert_equal "#000", resolve("black", :style => :compressed)
87
+ assert_equal "red", resolve("#f00", :style => :compressed)
88
+ assert_equal "blue", resolve("#00f", :style => :compressed)
89
+ assert_equal "navy", resolve("#000080", :style => :compressed)
90
+ assert_equal "navy #fff", resolve("#000080 white", :style => :compressed)
91
+ assert_equal "This color is #fff", resolve('"This color is #{ white }"', :style => :compressed)
92
+ end
93
+
94
+ def test_implicit_strings
95
+ assert_equal Sass::Script::String.new("foo"), eval("foo")
96
+ assert_equal Sass::Script::String.new("foo bar"), eval("foo bar")
97
+ assert_equal Sass::Script::String.new("foo/bar"), eval("foo/bar")
98
+ end
99
+
33
100
  def test_interpolation
34
101
  assert_equal "foo bar, baz bang", resolve('"foo #{"bar"}, #{"baz"} bang"')
35
102
  assert_equal "foo bar baz bang", resolve('"foo #{"#{"ba" + "r"} baz"} bang"')
@@ -61,63 +128,23 @@ foo \#{"\\\#{" + "baz"} bang
61
128
  SASS
62
129
  end
63
130
 
64
- def test_implicit_string_warning
65
- assert_warning(<<WARN) {eval("foo")}
66
- DEPRECATION WARNING:
67
- On line 1, character 1 of 'test_implicit_string_warning_inline.sass'
68
- Implicit strings have been deprecated and will be removed in version 3.0.
69
- 'foo' was not quoted. Please add double quotes (e.g. "foo").
70
- WARN
71
- assert_warning(<<WARN) {eval("1 + foo")}
72
- DEPRECATION WARNING:
73
- On line 1, character 5 of 'test_implicit_string_warning_inline.sass'
74
- Implicit strings have been deprecated and will be removed in version 3.0.
75
- 'foo' was not quoted. Please add double quotes (e.g. "foo").
76
- WARN
77
- assert_warning(<<WARN) {render("@if 1 + foo")}
78
- DEPRECATION WARNING:
79
- On line 1, character 9 of 'test_implicit_string_warning_inline.sass'
80
- Implicit strings have been deprecated and will be removed in version 3.0.
81
- 'foo' was not quoted. Please add double quotes (e.g. "foo").
82
- WARN
83
-
84
- # Regression
85
- assert_warning(<<WARN) {render("@if if")}
86
- DEPRECATION WARNING:
87
- On line 1, character 5 of 'test_implicit_string_warning_inline.sass'
88
- Implicit strings have been deprecated and will be removed in version 3.0.
89
- 'if' was not quoted. Please add double quotes (e.g. "if").
90
- WARN
91
- end
92
-
93
131
  def test_inaccessible_functions
94
- assert_warning <<WARN do
95
- DEPRECATION WARNING:
96
- On line 2, character 6 of 'test_inaccessible_functions_inline.sass'
97
- Implicit strings have been deprecated and will be removed in version 3.0.
98
- 'to_s' was not quoted. Please add double quotes (e.g. "to_s").
99
- WARN
100
- assert_equal "send(to_s)", resolve("send(to_s)", :line => 2)
101
- end
132
+ assert_equal "send(to_s)", resolve("send(to_s)", :line => 2)
102
133
  assert_equal "public_instance_methods()", resolve("public_instance_methods()")
103
134
  end
104
135
 
105
- def test_hyphen_warning
106
- a = Sass::Script::String.new("a")
107
- b = Sass::Script::String.new("b")
108
- assert_warning(<<WARN) {eval("!a-!b", {}, env("a" => a, "b" => b))}
109
- DEPRECATION WARNING:
110
- On line 1, character 3 of 'test_hyphen_warning_inline.sass'
111
- - will be allowed as part of variable names in version 3.0.
112
- Please add whitespace to separate it from the previous token.
113
- WARN
136
+ def test_default_functions
137
+ assert_equal "url(12)", resolve("url(12)")
138
+ assert_equal 'blam("foo")', resolve('blam("foo")')
139
+ end
114
140
 
115
- assert_warning(<<WARN) {eval("true-false")}
116
- DEPRECATION WARNING:
117
- On line 1, character 5 of 'test_hyphen_warning_inline.sass'
118
- - will be allowed as part of variable names in version 3.0.
119
- Please add whitespace to separate it from the previous token.
120
- WARN
141
+ def test_function_results_have_options
142
+ assert_equal "Options defined!", resolve("assert_options(abs(1))")
143
+ assert_equal "Options defined!", resolve("assert_options(round(1.2))")
144
+ end
145
+
146
+ def test_hyphenated_variables
147
+ assert_equal("a-b", resolve("$a-b", {}, env("a-b" => Sass::Script::String.new("a-b"))))
121
148
  end
122
149
 
123
150
  def test_ruby_equality
@@ -155,27 +182,27 @@ WARN
155
182
  assert_equal "2", resolve("1 + 1")
156
183
  assert_equal "0", resolve("1 - 1")
157
184
  assert_equal "8", resolve("2 * 4")
158
- assert_equal "0.5", resolve("2 / 4")
159
- assert_equal "2", resolve("4 / 2")
185
+ assert_equal "0.5", resolve("(2 / 4)")
186
+ assert_equal "2", resolve("(4 / 2)")
160
187
 
161
188
  assert_equal "-1", resolve("-1")
162
189
  end
163
190
 
164
191
  def test_string_ops
165
- assert_equal "foo bar", resolve('"foo" "bar"')
192
+ assert_equal '"foo" "bar"', resolve('"foo" "bar"')
166
193
  assert_equal "true 1", resolve('true 1')
167
- assert_equal "foo, bar", resolve('"foo" , "bar"')
194
+ assert_equal '"foo", "bar"', resolve("'foo' , 'bar'")
168
195
  assert_equal "true, 1", resolve('true , 1')
169
196
  assert_equal "foobar", resolve('"foo" + "bar"')
170
197
  assert_equal "true1", resolve('true + 1')
171
- assert_equal "foo-bar", resolve('"foo" - "bar"')
198
+ assert_equal '"foo"-"bar"', resolve("'foo' - 'bar'")
172
199
  assert_equal "true-1", resolve('true - 1')
173
- assert_equal "foo/bar", resolve('"foo" / "bar"')
200
+ assert_equal '"foo"/"bar"', resolve('"foo" / "bar"')
174
201
  assert_equal "true/1", resolve('true / 1')
175
202
 
176
- assert_equal "-bar", resolve('- "bar"')
203
+ assert_equal '-"bar"', resolve("- 'bar'")
177
204
  assert_equal "-true", resolve('- true')
178
- assert_equal "/bar", resolve('/ "bar"')
205
+ assert_equal '/"bar"', resolve('/ "bar"')
179
206
  assert_equal "/true", resolve('/ true')
180
207
  end
181
208
 
@@ -195,7 +222,7 @@ WARN
195
222
  end
196
223
 
197
224
  def test_equals
198
- assert_equal("true", resolve('"foo" == !foo', {},
225
+ assert_equal("true", resolve('"foo" == $foo', {},
199
226
  env("foo" => Sass::Script::String.new("foo"))))
200
227
  assert_equal "true", resolve("1 == 1.0")
201
228
  assert_equal "true", resolve("false != true")
@@ -225,7 +252,46 @@ WARN
225
252
  assert_equal "true", resolve("1.1cm == 11mm")
226
253
  end
227
254
 
228
- # Regression tests
255
+ def test_operations_have_options
256
+ assert_equal "Options defined!", resolve("assert_options(1 + 1)")
257
+ assert_equal "Options defined!", resolve("assert_options('bar' + 'baz')")
258
+ end
259
+
260
+ def test_slash_compiles_literally_when_left_alone
261
+ assert_equal "1px/2px", resolve("1px/2px")
262
+ assert_equal "1px/2px/3px/4px", resolve("1px/2px/3px/4px")
263
+
264
+ assert_equal "1px/2px redpx bluepx", resolve("1px/2px redpx bluepx")
265
+ assert_equal "foo 1px/2px/3px bar", resolve("foo 1px/2px/3px bar")
266
+ end
267
+
268
+ def test_slash_divides_with_parens
269
+ assert_equal "0.5", resolve("(1px/2px)")
270
+ assert_equal "0.5", resolve("(1px)/2px")
271
+ assert_equal "0.5", resolve("1px/(2px)")
272
+ end
273
+
274
+ def test_slash_divides_with_other_arithmetic
275
+ assert_equal "0.5px", resolve("1px*1px/2px")
276
+ assert_equal "0.5px", resolve("1px/2px*1px")
277
+ assert_equal "0.5", resolve("0+1px/2px")
278
+ assert_equal "0.5", resolve("1px/2px+0")
279
+ end
280
+
281
+ def test_slash_divides_with_variable
282
+ assert_equal "0.5", resolve("$var/2px", {}, env("var" => eval("1px")))
283
+ assert_equal "0.5", resolve("1px/$var", {}, env("var" => eval("2px")))
284
+ assert_equal "0.5", resolve("$var", {}, env("var" => eval("1px/2px")))
285
+ end
286
+
287
+ # Regression Tests
288
+
289
+ def test_funcall_has_higher_precedence_than_color_name
290
+ assert_equal "teal(12)", resolve("teal(12)")
291
+ assert_equal "tealbang(12)", resolve("tealbang(12)")
292
+ assert_equal "teal-bang(12)", resolve("teal-bang(12)")
293
+ assert_equal "teal+bang(12)", resolve("teal\\+bang(12)")
294
+ end
229
295
 
230
296
  def test_interpolation_after_hash
231
297
  assert_equal "#2", resolve('"##{1 + 1}"')
@@ -235,13 +301,14 @@ WARN
235
301
 
236
302
  def resolve(str, opts = {}, environment = env)
237
303
  munge_filename opts
238
- eval(str, opts, environment).to_s
304
+ val = eval(str, opts, environment)
305
+ val.is_a?(Sass::Script::String) ? val.value : val.to_s
239
306
  end
240
307
 
241
308
  def eval(str, opts = {}, environment = env)
242
309
  munge_filename opts
243
- Sass::Script.parse(str, opts[:line] || 1,
244
- opts[:offset] || 0, opts[:filename]).perform(environment)
310
+ Sass::Script.parse(str, opts.delete(:line) || 1,
311
+ opts.delete(:offset) || 0, opts).perform(environment)
245
312
  end
246
313
 
247
314
  def render(sass, options = {})