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,6 +1,6 @@
1
1
  <style>
2
2
  /* line 1 */
3
- p { border-style: dotted; border-width: 22px; border-color: #ff00ff; }
3
+ p { border-style: dotted; border-width: 22px; border-color: fuchsia; }
4
4
 
5
5
  /* line 6 */
6
6
  h1 { font-weight: normal; }
@@ -56,7 +56,9 @@ testtest
56
56
  </br>
57
57
  <p class='article bar foo' id='article_1'>Blah</p>
58
58
  <p class='article foo' id='article_1'>Blah</p>
59
+ <p class='article bar baz foo' id='article_1'>Blah</p>
59
60
  <p class='article quux qux' id='article_1'>Blump</p>
61
+ <p class='article' id='foo_bar_baz_article_1'>Whee</p>
60
62
  Woah inner quotes
61
63
  <p class='dynamic_quote' dyn='3' quotes="single '"></p>
62
64
  <p class='dynamic_self_closing' dyn='3' />
@@ -0,0 +1,44 @@
1
+ #!/usr/bin/env ruby
2
+ require File.dirname(__FILE__) + '/../test_helper'
3
+
4
+ begin
5
+ require 'json'
6
+ rescue LoadError
7
+ end
8
+
9
+ class SpecTest < Test::Unit::TestCase
10
+ spec_file = File.dirname(__FILE__) + '/spec/tests.json'
11
+ if !File.exists?(spec_file)
12
+ error = <<MSG.rstrip
13
+ Couldn't load haml-spec, skipping some tests.
14
+ To use haml-spec, run `git submodule update --init`
15
+ MSG
16
+ elsif !defined?(JSON)
17
+ error = "Couldn't load json, skipping some tests."
18
+ end
19
+
20
+ if error
21
+ define_method(:test_fake_couldnt_load_spec) {warn("\n" + error)}
22
+ else
23
+ JSON.parse(File.read(spec_file)).each do |name, tests|
24
+ tests.each do |subname, test|
25
+ define_method("test_spec: #{name} (#{subname})") do
26
+ options = convert_hash(test["config"])
27
+ options[:format] = options[:format].to_sym if options[:format]
28
+ engine = Haml::Engine.new(test["haml"], options)
29
+
30
+ result = engine.render(Object.new, convert_hash(test["locals"]))
31
+
32
+ assert_equal(test["html"], result.rstrip)
33
+ end
34
+ end
35
+ end
36
+ end
37
+
38
+ private
39
+
40
+ def convert_hash(hash)
41
+ return {} unless hash
42
+ Haml::Util.map_keys(hash) {|k| k.to_sym}
43
+ end
44
+ end
@@ -194,6 +194,26 @@ class TemplateTest < Test::Unit::TestCase
194
194
  assert_equal("2\n", render("= 1+1"))
195
195
  end
196
196
 
197
+ unless Haml::Util.ap_geq_3?
198
+ def test_form_for_error_return
199
+ assert_raise(Haml::Error) { render(<<HAML) }
200
+ = form_for :article, @article, :url => '' do |f|
201
+ Title:
202
+ = f.text_field :title
203
+ Body:
204
+ = f.text_field :body
205
+ HAML
206
+ end
207
+
208
+ def test_form_tag_error_return
209
+ assert_raise(Haml::Error) { render(<<HAML) }
210
+ = form_tag '' do
211
+ Title:
212
+ Body:
213
+ HAML
214
+ end
215
+ end
216
+
197
217
  def test_haml_options
198
218
  old_options = Haml::Template.options.dup
199
219
  Haml::Template.options[:suppress_eval] = true
@@ -268,7 +288,7 @@ END
268
288
  <input id="article_body" name="article[body]" size="30" type="text" value="World" />
269
289
  </form>
270
290
  HTML
271
- - form_for #{form_for_calling_convention(:article)}, :url => '' do |f|
291
+ - form_for :article, @article, :url => '' do |f|
272
292
  Title:
273
293
  = f.text_field :title
274
294
  Body:
@@ -367,7 +387,7 @@ HAML
367
387
  <input id="article_body" name="article[body]" size="30" type="text" value="World" />
368
388
  </form>
369
389
  HTML
370
- #{rails_block_helper_char} form_for #{form_for_calling_convention(:article)}, :url => '' do |f|
390
+ #{rails_block_helper_char} form_for :article, @article, :url => '' do |f|
371
391
  Title:
372
392
  = f.text_field :title
373
393
  Body:
@@ -62,19 +62,6 @@ click
62
62
  <input id="article_body" name="article[body]" size="30" type="text" value="World" />
63
63
  </form>
64
64
  </div>
65
- - elsif Haml::Util.ap_geq_3_beta_3?
66
- %p
67
- = form_tag ''
68
- %div
69
- = form_tag '' do
70
- %div= submit_tag 'save'
71
- - @foo = 'value one'
72
- = test_partial 'partial'
73
- = form_for @article, :as => :article, :url => '', :html => {:class => nil, :id => nil} do |f|
74
- Title:
75
- = f.text_field :title
76
- Body:
77
- = f.text_field :body
78
65
  - elsif Haml::Util.ap_geq_3?
79
66
  %p
80
67
  = form_tag ''
@@ -70,7 +70,9 @@
70
70
  Nested content
71
71
  %p.foo{:class => true ? 'bar' : 'baz'}[@article] Blah
72
72
  %p.foo{:class => false ? 'bar' : ''}[@article] Blah
73
+ %p.foo{:class => %w[bar baz]}[@article] Blah
73
74
  %p.qux{:class => 'quux'}[@article] Blump
75
+ %p#foo{:id => %w[bar baz]}[@article] Whee
74
76
  == #{"Woah inner quotes"}
75
77
  %p.dynamic_quote{:quotes => "single '", :dyn => 1 + 2}
76
78
  %p.dynamic_self_closing{:dyn => 1 + 2}/
@@ -54,11 +54,27 @@ class UtilTest < Test::Unit::TestCase
54
54
  powerset([1, 2, 3]))
55
55
  end
56
56
 
57
+ def test_restrict
58
+ assert_equal(0.5, restrict(0.5, 0..1))
59
+ assert_equal(1, restrict(2, 0..1))
60
+ assert_equal(1.3, restrict(2, 0..1.3))
61
+ assert_equal(0, restrict(-1, 0..1))
62
+ end
63
+
57
64
  def test_merge_adjacent_strings
58
65
  assert_equal(["foo bar baz", :bang, "biz bop", 12],
59
66
  merge_adjacent_strings(["foo ", "bar ", "baz", :bang, "biz", " bop", 12]))
60
67
  end
61
68
 
69
+ def test_strip_string_array
70
+ assert_equal(["foo ", " bar ", " baz"],
71
+ strip_string_array([" foo ", " bar ", " baz "]))
72
+ assert_equal([:foo, " bar ", " baz"],
73
+ strip_string_array([:foo, " bar ", " baz "]))
74
+ assert_equal(["foo ", " bar ", :baz],
75
+ strip_string_array([" foo ", " bar ", :baz]))
76
+ end
77
+
62
78
  def test_silence_warnings
63
79
  old_stderr, $stderr = $stderr, StringIO.new
64
80
  warn "Out"
@@ -69,6 +85,20 @@ class UtilTest < Test::Unit::TestCase
69
85
  $stderr = old_stderr
70
86
  end
71
87
 
88
+ def test_haml_warn
89
+ assert_warning("Foo!") {haml_warn "Foo!"}
90
+ end
91
+
92
+ def test_silence_haml_warnings
93
+ old_stderr, $stderr = $stderr, StringIO.new
94
+ silence_haml_warnings {warn "Out"}
95
+ assert_equal("Out\n", $stderr.string)
96
+ silence_haml_warnings {haml_warn "In"}
97
+ assert_equal("Out\n", $stderr.string)
98
+ ensure
99
+ $stderr = old_stderr
100
+ end
101
+
72
102
  def test_has
73
103
  assert(has?(:instance_method, String, :chomp!))
74
104
  assert(has?(:private_instance_method, Haml::Engine, :set_locals))
@@ -79,6 +109,24 @@ class UtilTest < Test::Unit::TestCase
79
109
  enum_with_index(%w[foo bar baz]).map {|s, i| "#{s}#{i}"})
80
110
  end
81
111
 
112
+ def test_enum_cons
113
+ assert_equal(%w[foobar barbaz],
114
+ enum_cons(%w[foo bar baz], 2).map {|s1, s2| "#{s1}#{s2}"})
115
+ end
116
+
117
+ def test_ord
118
+ assert_equal(102, ord("f"))
119
+ assert_equal(98, ord("bar"))
120
+ end
121
+
122
+ def test_caller_info
123
+ assert_equal(["/tmp/foo.rb", 12, "fizzle"], caller_info("/tmp/foo.rb:12: in `fizzle'"))
124
+ assert_equal(["/tmp/foo.rb", 12, nil], caller_info("/tmp/foo.rb:12"))
125
+ assert_equal(["(haml)", 12, "blah"], caller_info("(haml):12: in `blah'"))
126
+ assert_equal(["", 12, "boop"], caller_info(":12: in `boop'"))
127
+ assert_equal(["/tmp/foo.rb", -12, "fizzle"], caller_info("/tmp/foo.rb:-12: in `fizzle'"))
128
+ end
129
+
82
130
  def test_def_static_method
83
131
  klass = Class.new
84
132
  def_static_method(klass, :static_method, [:arg1, :arg2],
@@ -0,0 +1,61 @@
1
+ #!/usr/bin/env ruby
2
+ require File.dirname(__FILE__) + '/../test_helper'
3
+ require 'sass/callbacks'
4
+
5
+ class CallerBack
6
+ extend Sass::Callbacks
7
+ define_callback :foo
8
+ define_callback :bar
9
+
10
+ def do_foo
11
+ run_foo
12
+ end
13
+
14
+ def do_bar
15
+ run_bar 12
16
+ end
17
+ end
18
+
19
+ module ClassLevelCallerBack
20
+ extend Sass::Callbacks
21
+ define_callback :foo
22
+ extend self
23
+
24
+ def do_foo
25
+ run_foo
26
+ end
27
+ end
28
+
29
+ class SassCallbacksTest < Test::Unit::TestCase
30
+ def test_simple_callback
31
+ cb = CallerBack.new
32
+ there = false
33
+ cb.on_foo {there = true}
34
+ cb.do_foo
35
+ assert there, "Expected callback to be called."
36
+ end
37
+
38
+ def test_multiple_callbacks
39
+ cb = CallerBack.new
40
+ str = ""
41
+ cb.on_foo {str += "first"}
42
+ cb.on_foo {str += " second"}
43
+ cb.do_foo
44
+ assert_equal "first second", str
45
+ end
46
+
47
+ def test_callback_with_arg
48
+ cb = CallerBack.new
49
+ val = nil
50
+ cb.on_bar {|a| val = a}
51
+ cb.do_bar
52
+ assert_equal 12, val
53
+ end
54
+
55
+ def test_class_level_callback
56
+ there = false
57
+ ClassLevelCallerBack.on_foo {there = true}
58
+ ClassLevelCallerBack.do_foo
59
+ assert there, "Expected callback to be called."
60
+ end
61
+ end
@@ -0,0 +1,884 @@
1
+ #!/usr/bin/env ruby
2
+ require File.dirname(__FILE__) + '/../test_helper'
3
+
4
+ class ConversionTest < Test::Unit::TestCase
5
+ def test_basic
6
+ assert_renders <<SASS, <<SCSS
7
+ foo bar
8
+ baz: bang
9
+ bip: bop
10
+ SASS
11
+ foo bar {
12
+ baz: bang;
13
+ bip: bop; }
14
+ SCSS
15
+ assert_renders <<SASS, <<SCSS, :old => true
16
+ foo bar
17
+ :baz bang
18
+ :bip bop
19
+ SASS
20
+ foo bar {
21
+ baz: bang;
22
+ bip: bop; }
23
+ SCSS
24
+ end
25
+
26
+ def test_nesting
27
+ assert_renders <<SASS, <<SCSS
28
+ foo bar
29
+ baz bang
30
+ baz: bang
31
+ bip: bop
32
+ blat: boo
33
+ SASS
34
+ foo bar {
35
+ baz bang {
36
+ baz: bang;
37
+ bip: bop; }
38
+ blat: boo; }
39
+ SCSS
40
+ end
41
+
42
+ def test_nesting_with_parent_ref
43
+ assert_renders <<SASS, <<SCSS
44
+ foo bar
45
+ &:hover
46
+ baz: bang
47
+ SASS
48
+ foo bar {
49
+ &:hover {
50
+ baz: bang; } }
51
+ SCSS
52
+ end
53
+
54
+ def test_selector_interpolation
55
+ assert_renders <<SASS, <<SCSS
56
+ foo \#{$bar + "baz"}.bip
57
+ baz: bang
58
+ SASS
59
+ foo \#{$bar + "baz"}.bip {
60
+ baz: bang; }
61
+ SCSS
62
+ end
63
+
64
+ def test_multiline_selector_with_commas
65
+ assert_renders <<SASS, <<SCSS
66
+ foo bar,
67
+ baz bang
68
+ baz: bang
69
+ SASS
70
+ foo bar,
71
+ baz bang {
72
+ baz: bang; }
73
+ SCSS
74
+
75
+ assert_renders <<SASS, <<SCSS
76
+ blat
77
+ foo bar,
78
+ baz bang
79
+ baz: bang
80
+ SASS
81
+ blat {
82
+ foo bar,
83
+ baz bang {
84
+ baz: bang; } }
85
+ SCSS
86
+ end
87
+
88
+ def test_multiline_selector_without_commas
89
+ assert_scss_to_sass <<SASS, <<SCSS
90
+ foo bar baz bang
91
+ baz: bang
92
+ SASS
93
+ foo bar
94
+ baz bang {
95
+ baz: bang; }
96
+ SCSS
97
+
98
+ assert_scss_to_scss <<SCSS
99
+ foo bar
100
+ baz bang {
101
+ baz: bang; }
102
+ SCSS
103
+ end
104
+
105
+ def test_escaped_selector
106
+ assert_renders <<SASS, <<SCSS
107
+ foo bar
108
+ \\:hover
109
+ baz: bang
110
+ SASS
111
+ foo bar {
112
+ :hover {
113
+ baz: bang; } }
114
+ SCSS
115
+ end
116
+
117
+ def test_property_name_interpolation
118
+ assert_renders <<SASS, <<SCSS
119
+ foo bar
120
+ baz\#{$bang}bip\#{$bop}: 12
121
+ SASS
122
+ foo bar {
123
+ baz\#{$bang}bip\#{$bop}: 12; }
124
+ SCSS
125
+ end
126
+
127
+ def test_property_name_interpolation
128
+ assert_renders <<SASS, <<SCSS
129
+ foo bar
130
+ baz\#{$bang}bip\#{$bop}: 12
131
+ SASS
132
+ foo bar {
133
+ baz\#{$bang}bip\#{$bop}: 12; }
134
+ SCSS
135
+ end
136
+
137
+ def test_property_value_interpolation
138
+ assert_renders <<SASS, <<SCSS
139
+ foo bar
140
+ baz: 12 \#{$bang} bip \#{"bop"} blat
141
+ SASS
142
+ foo bar {
143
+ baz: 12 \#{$bang} bip \#{"bop"} blat; }
144
+ SCSS
145
+ end
146
+
147
+ def test_dynamic_properties
148
+ assert_renders <<SASS, <<SCSS
149
+ foo bar
150
+ baz: 12 $bang "bip"
151
+ SASS
152
+ foo bar {
153
+ baz: 12 $bang "bip"; }
154
+ SCSS
155
+
156
+ assert_sass_to_scss <<SCSS, <<SASS
157
+ foo bar {
158
+ baz: 12 $bang bip; }
159
+ SCSS
160
+ foo bar
161
+ baz= 12 $bang "bip"
162
+ SASS
163
+ end
164
+
165
+ def test_dynamic_properties_with_old
166
+ assert_renders <<SASS, <<SCSS, :old => true
167
+ foo bar
168
+ :baz 12 $bang "bip"
169
+ SASS
170
+ foo bar {
171
+ baz: 12 $bang "bip"; }
172
+ SCSS
173
+
174
+ assert_sass_to_scss <<SCSS, <<SASS, :old => true
175
+ foo bar {
176
+ baz: 12 $bang bip; }
177
+ SCSS
178
+ foo bar
179
+ :baz= 12 $bang "bip"
180
+ SASS
181
+ end
182
+
183
+ def test_multiline_properties
184
+ assert_scss_to_sass <<SASS, <<SCSS
185
+ foo bar
186
+ baz: bip bam boon
187
+ SASS
188
+ foo bar {
189
+ baz:
190
+ bip
191
+ bam
192
+ boon; }
193
+ SCSS
194
+
195
+ assert_scss_to_scss <<OUT, <<IN
196
+ foo bar {
197
+ baz: bip bam boon; }
198
+ OUT
199
+ foo bar {
200
+ baz:
201
+ bip
202
+ bam
203
+ boon; }
204
+ IN
205
+ end
206
+
207
+ def test_multiline_dynamic_properties
208
+ assert_scss_to_sass <<SASS, <<SCSS
209
+ foo bar
210
+ baz: $bip "bam" 12px
211
+ SASS
212
+ foo bar {
213
+ baz:
214
+ $bip
215
+ "bam"
216
+ 12px; }
217
+ SCSS
218
+
219
+ assert_scss_to_scss <<OUT, <<IN
220
+ foo bar {
221
+ baz: $bip "bam" 12px; }
222
+ OUT
223
+ foo bar {
224
+ baz:
225
+ $bip
226
+ "bam"
227
+ 12px; }
228
+ IN
229
+ end
230
+
231
+ def test_silent_comments
232
+ assert_renders <<SASS, <<SCSS
233
+ // foo
234
+
235
+ // bar
236
+
237
+ // baz
238
+
239
+ foo bar
240
+ a: b
241
+ SASS
242
+ // foo
243
+
244
+ // bar
245
+
246
+ // baz
247
+
248
+ foo bar {
249
+ a: b; }
250
+ SCSS
251
+
252
+ assert_renders <<SASS, <<SCSS
253
+ // foo
254
+ bar
255
+ baz
256
+ bang
257
+
258
+ foo bar
259
+ a: b
260
+ SASS
261
+ // foo
262
+ // bar
263
+ // baz
264
+ // bang
265
+
266
+ foo bar {
267
+ a: b; }
268
+ SCSS
269
+
270
+ assert_sass_to_scss <<SCSS, <<SASS
271
+ // foo
272
+ // bar
273
+ // baz
274
+ // bang
275
+
276
+ foo bar {
277
+ a: b; }
278
+ SCSS
279
+ // foo
280
+ // bar
281
+ // baz
282
+ // bang
283
+
284
+ foo bar
285
+ a: b
286
+ SASS
287
+ end
288
+
289
+ def test_loud_comments
290
+ assert_renders <<SASS, <<SCSS
291
+ /* foo
292
+
293
+ /* bar
294
+
295
+ /* baz
296
+
297
+ foo bar
298
+ a: b
299
+ SASS
300
+ /* foo */
301
+
302
+ /* bar */
303
+
304
+ /* baz */
305
+
306
+ foo bar {
307
+ a: b; }
308
+ SCSS
309
+
310
+ assert_scss_to_sass <<SASS, <<SCSS
311
+ /* foo
312
+ bar
313
+ baz
314
+ bang
315
+
316
+ foo bar
317
+ a: b
318
+ SASS
319
+ /* foo
320
+ bar
321
+ baz
322
+ bang */
323
+
324
+ foo bar {
325
+ a: b; }
326
+ SCSS
327
+
328
+ assert_scss_to_scss <<SCSS
329
+ /* foo
330
+ bar
331
+ baz
332
+ bang */
333
+
334
+ foo bar {
335
+ a: b; }
336
+ SCSS
337
+
338
+ assert_renders <<SASS, <<SCSS
339
+ /* foo
340
+ bar
341
+ baz
342
+ bang
343
+
344
+ foo bar
345
+ a: b
346
+ SASS
347
+ /* foo
348
+ * bar
349
+ * baz
350
+ * bang */
351
+
352
+ foo bar {
353
+ a: b; }
354
+ SCSS
355
+ end
356
+
357
+ def test_loud_comments_with_weird_indentation
358
+ assert_scss_to_sass <<SASS, <<SCSS
359
+ foo
360
+ /* foo
361
+ bar
362
+ baz
363
+ a: b
364
+ SASS
365
+ foo {
366
+ /* foo
367
+ bar
368
+ baz */
369
+ a: b; }
370
+ SCSS
371
+
372
+ assert_sass_to_scss <<SCSS, <<SASS
373
+ foo {
374
+ /* foo
375
+ * bar
376
+ * baz */
377
+ a: b; }
378
+ SCSS
379
+ foo
380
+ /* foo
381
+ bar
382
+ baz
383
+ a: b
384
+ SASS
385
+ end
386
+
387
+ def test_immediately_preceding_comments
388
+ assert_renders <<SASS, <<SCSS
389
+ /* Foo
390
+ Bar
391
+ Baz
392
+ .foo#bar
393
+ a: b
394
+ SASS
395
+ /* Foo
396
+ * Bar
397
+ * Baz */
398
+ .foo#bar {
399
+ a: b; }
400
+ SCSS
401
+
402
+ assert_renders <<SASS, <<SCSS
403
+ // Foo
404
+ Bar
405
+ Baz
406
+ =foo
407
+ a: b
408
+ SASS
409
+ // Foo
410
+ // Bar
411
+ // Baz
412
+ @mixin foo {
413
+ a: b; }
414
+ SCSS
415
+ end
416
+
417
+ def test_debug
418
+ assert_renders <<SASS, <<SCSS
419
+ foo
420
+ @debug 12px
421
+ bar: baz
422
+ SASS
423
+ foo {
424
+ @debug 12px;
425
+ bar: baz; }
426
+ SCSS
427
+ end
428
+
429
+ def test_directive_without_children
430
+ assert_renders <<SASS, <<SCSS
431
+ foo
432
+ @foo #bar "baz"
433
+ bar: baz
434
+ SASS
435
+ foo {
436
+ @foo #bar "baz";
437
+ bar: baz; }
438
+ SCSS
439
+ end
440
+
441
+ def test_directive_with_prop_children
442
+ assert_renders <<SASS, <<SCSS
443
+ foo
444
+ @foo #bar "baz"
445
+ a: b
446
+ c: d
447
+
448
+ bar: baz
449
+ SASS
450
+ foo {
451
+ @foo #bar "baz" {
452
+ a: b;
453
+ c: d; }
454
+
455
+ bar: baz; }
456
+ SCSS
457
+ end
458
+
459
+ def test_directive_with_rule_children
460
+ assert_renders <<SASS, <<SCSS
461
+ foo
462
+ @foo #bar "baz"
463
+ #blat
464
+ a: b
465
+ .bang
466
+ c: d
467
+ e: f
468
+
469
+ bar: baz
470
+ SASS
471
+ foo {
472
+ @foo #bar "baz" {
473
+ #blat {
474
+ a: b; }
475
+ .bang {
476
+ c: d;
477
+ e: f; } }
478
+
479
+ bar: baz; }
480
+ SCSS
481
+ end
482
+
483
+ def test_directive_with_rule_and_prop_children
484
+ assert_renders <<SASS, <<SCSS
485
+ foo
486
+ @foo #bar "baz"
487
+ g: h
488
+ #blat
489
+ a: b
490
+ .bang
491
+ c: d
492
+ e: f
493
+ i: j
494
+
495
+ bar: baz
496
+ SASS
497
+ foo {
498
+ @foo #bar "baz" {
499
+ g: h;
500
+ #blat {
501
+ a: b; }
502
+ .bang {
503
+ c: d;
504
+ e: f; }
505
+ i: j; }
506
+
507
+ bar: baz; }
508
+ SCSS
509
+ end
510
+
511
+ def test_for
512
+ assert_renders <<SASS, <<SCSS
513
+ foo
514
+ @for $a from $b to $c
515
+ a: b
516
+ @for $c from 1 to 16
517
+ d: e
518
+ f: g
519
+ SASS
520
+ foo {
521
+ @for $a from $b to $c {
522
+ a: b; }
523
+ @for $c from 1 to 16 {
524
+ d: e;
525
+ f: g; } }
526
+ SCSS
527
+ end
528
+
529
+ def test_while
530
+ assert_renders <<SASS, <<SCSS
531
+ foo
532
+ @while flaz($a + $b)
533
+ a: b
534
+ @while 1
535
+ d: e
536
+ f: g
537
+ SASS
538
+ foo {
539
+ @while flaz($a + $b) {
540
+ a: b; }
541
+ @while 1 {
542
+ d: e;
543
+ f: g; } }
544
+ SCSS
545
+ end
546
+
547
+ def test_if
548
+ assert_renders <<SASS, <<SCSS
549
+ foo
550
+ @if $foo or $bar
551
+ a: b
552
+ @if $baz
553
+ d: e
554
+ @else if $bang
555
+ f: g
556
+ @else
557
+ h: i
558
+ SASS
559
+ foo {
560
+ @if $foo or $bar {
561
+ a: b; }
562
+ @if $baz {
563
+ d: e; }
564
+ @else if $bang {
565
+ f: g; }
566
+ @else {
567
+ h: i; } }
568
+ SCSS
569
+ end
570
+
571
+ def test_import
572
+ assert_renders <<SASS, <<SCSS
573
+ @import foo
574
+
575
+ foo
576
+ bar: baz
577
+ SASS
578
+ @import "foo";
579
+
580
+ foo {
581
+ bar: baz; }
582
+ SCSS
583
+
584
+ assert_renders <<SASS, <<SCSS
585
+ @import foo.css
586
+
587
+ foo
588
+ bar: baz
589
+ SASS
590
+ @import "foo.css";
591
+
592
+ foo {
593
+ bar: baz; }
594
+ SCSS
595
+ end
596
+
597
+ def test_import_as_directive_in_sass
598
+ assert_sass_to_sass '@import "foo.css"'
599
+ assert_sass_to_sass '@import url(foo.css)'
600
+ end
601
+
602
+ def test_import_as_directive_in_scss
603
+ assert_renders <<SASS, <<SCSS
604
+ @import "foo.css" print
605
+ SASS
606
+ @import "foo.css" print;
607
+ SCSS
608
+
609
+ assert_renders <<SASS, <<SCSS
610
+ @import url(foo.css) screen, print
611
+ SASS
612
+ @import url(foo.css) screen, print;
613
+ SCSS
614
+ end
615
+
616
+ def test_adjacent_imports
617
+ assert_renders <<SASS, <<SCSS
618
+ @import foo.sass
619
+ @import bar.scss
620
+ @import baz
621
+ SASS
622
+ @import "foo.sass";
623
+ @import "bar.scss";
624
+ @import "baz";
625
+ SCSS
626
+ end
627
+
628
+ def test_non_adjacent_imports
629
+ assert_renders <<SASS, <<SCSS
630
+ @import foo.sass
631
+
632
+ @import bar.scss
633
+
634
+ @import baz
635
+ SASS
636
+ @import "foo.sass";
637
+
638
+ @import "bar.scss";
639
+
640
+ @import "baz";
641
+ SCSS
642
+ end
643
+
644
+ def test_argless_mixin_definition
645
+ assert_renders <<SASS, <<SCSS
646
+ =foo-bar
647
+ baz
648
+ a: b
649
+ SASS
650
+ @mixin foo-bar {
651
+ baz {
652
+ a: b; } }
653
+ SCSS
654
+
655
+ assert_scss_to_sass <<SASS, <<SCSS
656
+ =foo-bar
657
+ baz
658
+ a: b
659
+ SASS
660
+ @mixin foo-bar() {
661
+ baz {
662
+ a: b; } }
663
+ SCSS
664
+
665
+ assert_sass_to_scss <<SCSS, <<SASS
666
+ @mixin foo-bar {
667
+ baz {
668
+ a: b; } }
669
+ SCSS
670
+ =foo-bar()
671
+ baz
672
+ a: b
673
+ SASS
674
+ end
675
+
676
+ def test_mixin_definition_without_defaults
677
+ assert_renders <<SASS, <<SCSS
678
+ =foo-bar($baz, $bang)
679
+ baz
680
+ a: $baz $bang
681
+ SASS
682
+ @mixin foo-bar($baz, $bang) {
683
+ baz {
684
+ a: $baz $bang; } }
685
+ SCSS
686
+ end
687
+
688
+ def test_mixin_definition_with_defaults
689
+ assert_renders <<SASS, <<SCSS
690
+ =foo-bar($baz, $bang: 12px)
691
+ baz
692
+ a: $baz $bang
693
+ SASS
694
+ @mixin foo-bar($baz, $bang: 12px) {
695
+ baz {
696
+ a: $baz $bang; } }
697
+ SCSS
698
+
699
+ assert_scss_to_sass <<SASS, <<SCSS
700
+ =foo-bar($baz, $bang: foo)
701
+ baz
702
+ a: $baz $bang
703
+ SASS
704
+ @mixin foo-bar($baz, $bang = "foo") {
705
+ baz {
706
+ a: $baz $bang; } }
707
+ SCSS
708
+
709
+ assert_sass_to_scss <<SCSS, <<SASS
710
+ @mixin foo-bar($baz, $bang: foo) {
711
+ baz {
712
+ a: $baz $bang; } }
713
+ SCSS
714
+ =foo-bar($baz, $bang = "foo")
715
+ baz
716
+ a: $baz $bang
717
+ SASS
718
+ end
719
+
720
+ def test_argless_mixin_include
721
+ assert_renders <<SASS, <<SCSS
722
+ foo
723
+ +foo-bar
724
+ a: blip
725
+ SASS
726
+ foo {
727
+ @include foo-bar;
728
+ a: blip; }
729
+ SCSS
730
+ end
731
+
732
+ def test_mixin_include
733
+ assert_renders <<SASS, <<SCSS
734
+ foo
735
+ +foo-bar(12px, "blaz")
736
+ a: blip
737
+ SASS
738
+ foo {
739
+ @include foo-bar(12px, "blaz");
740
+ a: blip; }
741
+ SCSS
742
+ end
743
+
744
+ def test_variable_definition
745
+ assert_renders <<SASS, <<SCSS
746
+ $var1: 12px + 15px
747
+
748
+ foo
749
+ $var2: flaz(#abcdef)
750
+ val: $var1 $var2
751
+ SASS
752
+ $var1: 12px + 15px;
753
+
754
+ foo {
755
+ $var2: flaz(#abcdef);
756
+ val: $var1 $var2; }
757
+ SCSS
758
+
759
+ assert_sass_to_scss '$var: 12px $bar baz;', '$var = 12px $bar "baz"'
760
+ end
761
+
762
+ def test_guarded_variable_definition
763
+ assert_renders <<SASS, <<SCSS
764
+ $var1: 12px + 15px !default
765
+
766
+ foo
767
+ $var2: flaz(#abcdef) !default
768
+ val: $var1 $var2
769
+ SASS
770
+ $var1: 12px + 15px !default;
771
+
772
+ foo {
773
+ $var2: flaz(#abcdef) !default;
774
+ val: $var1 $var2; }
775
+ SCSS
776
+
777
+ assert_sass_to_scss '$var: 12px $bar baz !default;', '$var ||= 12px $bar "baz"'
778
+ end
779
+
780
+ # Sass 3 Deprecation conversions
781
+
782
+ def test_simple_quoted_strings_unquoted_with_equals
783
+ assert_sass_to_scss '$var: 1px foo + bar baz;', '!var = 1px "foo" + "bar" baz'
784
+ assert_sass_to_scss '$var: -foo-bar;', '!var = "-foo-bar"'
785
+ end
786
+
787
+ def test_complex_quoted_strings_explicitly_unquoted_with_equals
788
+ assert_sass_to_scss '$var: 1px unquote("foo + bar") baz;', '!var = 1px "foo + bar" baz'
789
+ assert_sass_to_scss "$var: unquote('foo\"bar');", '!var = "foo\"bar"'
790
+ end
791
+
792
+ def test_division_asserted_with_equals
793
+ assert_sass_to_scss <<SCSS, <<SASS
794
+ foo {
795
+ a: (1px / 2px); }
796
+ SCSS
797
+ foo
798
+ a = 1px / 2px
799
+ SASS
800
+ end
801
+
802
+ def test_division_not_asserted_with_equals_when_unnecessary
803
+ assert_sass_to_scss <<SCSS, <<SASS
804
+ $var: 1px / 2px;
805
+
806
+ foo {
807
+ a: $var; }
808
+ SCSS
809
+ !var = 1px / 2px
810
+
811
+ foo
812
+ a = !var
813
+ SASS
814
+
815
+ assert_sass_to_scss <<SCSS, <<SASS
816
+ $var: 1px;
817
+
818
+ foo {
819
+ a: $var / 2px; }
820
+ SCSS
821
+ !var = 1px
822
+
823
+ foo
824
+ a = !var / 2px
825
+ SASS
826
+
827
+ assert_sass_to_scss <<SCSS, <<SASS
828
+ foo {
829
+ a: 1 + 1px / 2px; }
830
+ SCSS
831
+ foo
832
+ a = 1 + 1px / 2px
833
+ SASS
834
+ end
835
+
836
+ private
837
+
838
+ def assert_sass_to_sass(sass, options = {})
839
+ assert_equal(sass.rstrip, to_sass(sass, options).rstrip,
840
+ "Expected Sass to transform to itself")
841
+ end
842
+
843
+ def assert_scss_to_sass(sass, scss, options = {})
844
+ assert_equal(sass.rstrip, to_sass(scss, options.merge(:syntax => :scss)).rstrip,
845
+ "Expected SCSS to transform to Sass")
846
+ end
847
+
848
+ def assert_scss_to_scss(scss, in_scss = nil, options = nil)
849
+ if in_scss.is_a?(Hash)
850
+ options = in_scss
851
+ in_scss = nil
852
+ end
853
+
854
+ in_scss ||= scss
855
+ options ||= {}
856
+
857
+ assert_equal(scss.rstrip, to_scss(in_scss, options.merge(:syntax => :scss)).rstrip,
858
+ "Expected SCSS to transform to #{scss == in_scss ? 'itself' : 'SCSS'}k")
859
+ end
860
+
861
+ def assert_sass_to_scss(scss, sass, options = {})
862
+ assert_equal(scss.rstrip, to_scss(sass, options).rstrip,
863
+ "Expected Sass to transform to SCSS")
864
+ end
865
+
866
+ def assert_renders(sass, scss, options = {})
867
+ assert_sass_to_sass(sass, options)
868
+ assert_scss_to_sass(sass, scss, options)
869
+ assert_scss_to_scss(scss, options)
870
+ assert_sass_to_scss(scss, sass, options)
871
+ end
872
+
873
+ def to_sass(scss, options = {})
874
+ Haml::Util.silence_haml_warnings do
875
+ Sass::Engine.new(scss, options).to_tree.to_sass(options)
876
+ end
877
+ end
878
+
879
+ def to_scss(sass, options = {})
880
+ Haml::Util.silence_haml_warnings do
881
+ Sass::Engine.new(sass, options).to_tree.to_scss(options)
882
+ end
883
+ end
884
+ end