haml 2.2.17 → 2.2.18

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.

@@ -72,6 +72,7 @@ class EngineTest < Test::Unit::TestCase
72
72
  "/ foo\n\n bar" => ["Illegal nesting: nesting within a tag that already has content is illegal.", 3],
73
73
  "!!!\n\n bar" => ["Illegal nesting: nesting within a header command is illegal.", 3],
74
74
  "foo\n:ruby\n 1\n 2\n 3\n- raise 'foo'" => ["foo", 6],
75
+ "foo\n:erb\n 1\n 2\n 3\n- raise 'foo'" => ["foo", 6],
75
76
  "= raise 'foo'\nfoo\nbar\nbaz\nbang" => ["foo", 1],
76
77
  }
77
78
 
@@ -567,6 +568,17 @@ HTML
567
568
  HAML
568
569
  end
569
570
 
571
+ def test_erb_filter_with_multiline_expr
572
+ assert_equal(<<HTML, render(<<HAML))
573
+ foobarbaz
574
+ HTML
575
+ :erb
576
+ <%= "foo" +
577
+ "bar" +
578
+ "baz" %>
579
+ HAML
580
+ end
581
+
570
582
  def test_silent_script_with_hyphen_case
571
583
  assert_equal("", render("- 'foo-case-bar-case'"))
572
584
  end
@@ -595,6 +607,15 @@ HTML
595
607
  HAML
596
608
  end
597
609
 
610
+ def test_html_attributes_with_hash
611
+ assert_equal("<a href='#' rel='top'>Foo</a>\n",
612
+ render('%a(href="#" rel="top") Foo'))
613
+ assert_equal("<a href='#'>Foo</a>\n",
614
+ render('%a(href="#") #{"Foo"}'))
615
+
616
+ assert_equal("<a href='#\"'></a>\n", render('%a(href="#\\"")'))
617
+ end
618
+
598
619
  # HTML escaping tests
599
620
 
600
621
  def test_ampersand_equals_should_escape
File without changes
File without changes
@@ -11,7 +11,7 @@ local function get_tests(filename)
11
11
  end
12
12
  end
13
13
 
14
- local fh = assert(io.open(get_tests("tests-new.json")))
14
+ local fh = assert(io.open(get_tests("tests.json")))
15
15
  local input = fh:read '*a'
16
16
  fh:close()
17
17
 
@@ -31,6 +31,11 @@
31
31
  "html" : "<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Frameset//EN\" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-frameset.dtd\">"
32
32
  },
33
33
 
34
+ "an HTML 5 doctype with XHTML syntax" : {
35
+ "haml" : "!!! 5",
36
+ "html" : "<!DOCTYPE html>"
37
+ },
38
+
34
39
  "an HTML 5 XML prolog (silent)" : {
35
40
  "haml" : "!!! XML",
36
41
  "html" : "",
@@ -147,8 +152,12 @@
147
152
  "an implicit div with a CSS class" : {
148
153
  "haml" : ".class1",
149
154
  "html" : "<div class='class1'></div>"
150
- }
155
+ },
151
156
 
157
+ "multiple simple Haml tags" : {
158
+ "haml" : "%div\n %div\n %p",
159
+ "html" : "<div>\n <div>\n <p></p>\n </div>\n</div>"
160
+ }
152
161
  },
153
162
 
154
163
  "tags with unusual HTML characters" : {
@@ -208,8 +217,12 @@
208
217
  "a tag with CSS" : {
209
218
  "haml" : "%p.class1 hello",
210
219
  "html" : "<p class='class1'>hello</p>"
211
- }
220
+ },
212
221
 
222
+ "multiple simple tags" : {
223
+ "haml" : "%div\n %div\n %p text",
224
+ "html" : "<div>\n <div>\n <p>text</p>\n </div>\n</div>"
225
+ }
213
226
  },
214
227
 
215
228
  "tags with nested content" : {
@@ -222,6 +235,11 @@
222
235
  "a tag with CSS" : {
223
236
  "haml" : "%p.class1\n hello",
224
237
  "html" : "<p class='class1'>\n hello\n</p>"
238
+ },
239
+
240
+ "multiple simple tags" : {
241
+ "haml" : "%div\n %div\n %p\n text",
242
+ "html" : "<div>\n <div>\n <p>\n text\n </p>\n </div>\n</div>"
225
243
  }
226
244
 
227
245
  },
@@ -374,14 +392,6 @@
374
392
  "locals" : {
375
393
  "var" : "a"
376
394
  }
377
- },
378
-
379
- "an interpolated attribute" : {
380
- "haml" : "%p{:a =>\"#{var}\"}",
381
- "html" : "<p a='value'></p>",
382
- "locals" : {
383
- "var" : "value"
384
- }
385
395
  }
386
396
 
387
397
  },
@@ -446,14 +456,6 @@
446
456
 
447
457
  "interpolation": {
448
458
 
449
- "interpolation inside code" : {
450
- "haml" : "%p= \"#{var}\"",
451
- "html" : "<p>value</p>",
452
- "locals" : {
453
- "var" : "value"
454
- }
455
- },
456
-
457
459
  "interpolation inside inline content" : {
458
460
  "haml" : "%p #{var}",
459
461
  "html" : "<p>value</p>",
@@ -483,6 +485,50 @@
483
485
  }
484
486
  }
485
487
 
488
+ },
489
+
490
+ "HTML escaping" : {
491
+
492
+ "code following '&='" : {
493
+ "haml" : "&= '<\"&>'",
494
+ "html" : "&lt;&quot;&amp;&gt;"
495
+ },
496
+
497
+ "code following '=' when escape_haml is set to true" : {
498
+ "haml" : "= '<\"&>'",
499
+ "html" : "&lt;&quot;&amp;&gt;",
500
+ "config" : {
501
+ "escape_html" : "true"
502
+ }
503
+ },
504
+
505
+ "code following '!=' when escape_haml is set to true" : {
506
+ "haml" : "!= '<\"&>'",
507
+ "html" : "<\"&>",
508
+ "config" : {
509
+ "escape_html" : "true"
510
+ }
511
+ }
512
+
513
+ },
514
+
515
+ "Boolean attributes" : {
516
+
517
+ "boolean attribute with XHTML" : {
518
+ "haml" : "%input(checked=true)",
519
+ "html" : "<input checked='checked' />",
520
+ "config" : {
521
+ "format" : "xhtml"
522
+ }
523
+ },
524
+
525
+ "boolean attribute with HTML" : {
526
+ "haml" : "%input(checked=true)",
527
+ "html" : "<input checked>",
528
+ "config" : {
529
+ "format" : "html5"
530
+ }
531
+ }
486
532
  }
487
533
 
488
534
  }
@@ -258,7 +258,7 @@ END
258
258
  end
259
259
 
260
260
  def test_xss_protection_with_safe_strings
261
- assert_equal("Foo & Bar\n", render('= "Foo & Bar".html_safe!', :action_view))
261
+ assert_equal("Foo & Bar\n", render('= Haml::Util.html_safe("Foo & Bar")', :action_view))
262
262
  end
263
263
 
264
264
  def test_xss_protection_with_bang
@@ -274,11 +274,11 @@ END
274
274
  end
275
275
 
276
276
  def test_xss_protection_with_safe_strings_in_interpolation
277
- assert_equal("Foo & Bar\n", render('Foo #{"&".html_safe!} Bar', :action_view))
277
+ assert_equal("Foo & Bar\n", render('Foo #{Haml::Util.html_safe("&")} Bar', :action_view))
278
278
  end
279
279
 
280
280
  def test_xss_protection_with_mixed_strings_in_interpolation
281
- assert_equal("Foo & Bar &amp; Baz\n", render('Foo #{"&".html_safe!} Bar #{"&"} Baz', :action_view))
281
+ assert_equal("Foo & Bar &amp; Baz\n", render('Foo #{Haml::Util.html_safe("&")} Bar #{"&"} Baz', :action_view))
282
282
  end
283
283
 
284
284
  def test_rendered_string_is_html_safe
@@ -292,5 +292,19 @@ END
292
292
  def test_xss_html_escaping_with_non_strings
293
293
  assert_equal("4\n", render("= html_escape(4)"))
294
294
  end
295
+
296
+ def test_xss_protection_with_concat
297
+ assert_equal("Foo &amp; Bar", render('- concat "Foo & Bar"', :action_view))
298
+ end
299
+
300
+ def test_xss_protection_with_concat_with_safe_string
301
+ assert_equal("Foo & Bar", render('- concat(Haml::Util.html_safe("Foo & Bar"))', :action_view))
302
+ end
303
+
304
+ if Haml::Util.has?(:instance_method, ActionView::Helpers::TextHelper, :safe_concat)
305
+ def test_xss_protection_with_safe_concat
306
+ assert_equal("Foo & Bar", render('- safe_concat "Foo & Bar"', :action_view))
307
+ end
308
+ end
295
309
  end
296
310
  end
File without changes
@@ -1,3 +1,4 @@
1
+ #!/usr/bin/env ruby
1
2
  require 'test/unit'
2
3
  require File.dirname(__FILE__) + '/../test_helper'
3
4
  require 'sass/css'
@@ -96,6 +96,7 @@ MSG
96
96
  '@if' => "Invalid if directive '@if': expected expression.",
97
97
  '@while' => "Invalid while directive '@while': expected expression.",
98
98
  '@debug' => "Invalid debug directive '@debug': expected expression.",
99
+ "/* foo\n bar\n baz" => "Inconsistent indentation: previous line was indented by 4 spaces, but this line was indented by 2 spaces.",
99
100
 
100
101
  # Regression tests
101
102
  "a\n b:\n c\n d" => ["Illegal nesting: Only properties may be nested beneath properties.", 3],
@@ -691,6 +692,36 @@ foo {
691
692
  CSS
692
693
  end
693
694
 
695
+ def test_comment_indentation_at_beginning_of_doc
696
+ assert_equal <<CSS, render(<<SASS)
697
+ /* foo
698
+ * bar
699
+ * baz */
700
+ foo {
701
+ a: b; }
702
+ CSS
703
+ /* foo
704
+ bar
705
+ baz
706
+ foo
707
+ a: b
708
+ SASS
709
+ end
710
+
711
+ def test_unusual_comment_indentation
712
+ assert_equal <<CSS, render(<<SASS)
713
+ foo {
714
+ /* foo
715
+ * bar
716
+ * baz */ }
717
+ CSS
718
+ foo
719
+ /* foo
720
+ bar
721
+ baz
722
+ SASS
723
+ end
724
+
694
725
  def test_attribute_selector_with_spaces
695
726
  assert_equal(<<CSS, render(<<SASS))
696
727
  a b[foo = bar] {
@@ -1,3 +1,4 @@
1
+ #!/usr/bin/env ruby
1
2
  require 'test/unit'
2
3
  require File.dirname(__FILE__) + '/../../lib/sass'
3
4
  require 'sass/script'
@@ -14,6 +14,7 @@ class SassPluginTest < Test::Unit::TestCase
14
14
  FileUtils.mkdir tempfile_loc(nil,"more_")
15
15
  set_plugin_opts
16
16
  Sass::Plugin.update_stylesheets
17
+ reset_mtimes
17
18
  end
18
19
 
19
20
  def teardown
@@ -30,23 +31,21 @@ class SassPluginTest < Test::Unit::TestCase
30
31
 
31
32
  def test_no_update
32
33
  File.delete(tempfile_loc('basic'))
33
- assert Sass::Plugin.stylesheet_needs_update?('basic', template_loc, tempfile_loc)
34
+ assert_needs_update 'basic'
34
35
  Sass::Plugin.update_stylesheets
35
36
  assert_stylesheet_updated 'basic'
36
37
  end
37
38
 
38
39
  def test_update_needed_when_modified
39
- sleep 1
40
- FileUtils.touch(template_loc('basic'))
41
- assert Sass::Plugin.stylesheet_needs_update?('basic', template_loc, tempfile_loc)
40
+ touch 'basic'
41
+ assert_needs_update 'basic'
42
42
  Sass::Plugin.update_stylesheets
43
43
  assert_stylesheet_updated 'basic'
44
44
  end
45
45
 
46
46
  def test_update_needed_when_dependency_modified
47
- sleep 1
48
- FileUtils.touch(template_loc('basic'))
49
- assert Sass::Plugin.stylesheet_needs_update?('import', template_loc, tempfile_loc)
47
+ touch 'basic'
48
+ assert_needs_update 'import'
50
49
  Sass::Plugin.update_stylesheets
51
50
  assert_stylesheet_updated 'basic'
52
51
  end
@@ -108,7 +107,7 @@ class SassPluginTest < Test::Unit::TestCase
108
107
  set_plugin_opts
109
108
 
110
109
  File.delete(tempfile_loc('basic'))
111
- assert Sass::Plugin.stylesheet_needs_update?('basic', template_loc, tempfile_loc)
110
+ assert_needs_update 'basic'
112
111
 
113
112
  if defined?(MerbHandler)
114
113
  MerbHandler.new('.').process nil, nil
@@ -129,9 +128,8 @@ class SassPluginTest < Test::Unit::TestCase
129
128
  FileUtils.mv(template_loc("basic"), template_loc("basic", "more_"))
130
129
  set_plugin_opts :load_paths => [result_loc, template_loc(nil, "more_")]
131
130
 
132
- sleep 1
133
- FileUtils.touch(template_loc("basic", "more_"))
134
- assert Sass::Plugin.stylesheet_needs_update?("import", template_loc, tempfile_loc)
131
+ touch 'basic', 'more_'
132
+ assert_needs_update "import"
135
133
  Sass::Plugin.update_stylesheets
136
134
  assert_renders_correctly("import")
137
135
  ensure
@@ -162,7 +160,7 @@ class SassPluginTest < Test::Unit::TestCase
162
160
  end
163
161
 
164
162
  def assert_stylesheet_updated(name)
165
- assert !Sass::Plugin.stylesheet_needs_update?(name, template_loc, tempfile_loc)
163
+ assert_doesnt_need_update name
166
164
 
167
165
  # Make sure it isn't an exception
168
166
  expected_lines = File.read(result_loc(name)).split("\n")
@@ -172,6 +170,24 @@ class SassPluginTest < Test::Unit::TestCase
172
170
  end
173
171
  end
174
172
 
173
+ def assert_needs_update(name)
174
+ assert(Sass::Plugin.stylesheet_needs_update?(name, template_loc, tempfile_loc),
175
+ "Expected #{template_loc(name)} to need an update.")
176
+ end
177
+
178
+ def assert_doesnt_need_update(name)
179
+ assert(!Sass::Plugin.stylesheet_needs_update?(name, template_loc, tempfile_loc),
180
+ "Expected #{template_loc(name)} not to need an update.")
181
+ end
182
+
183
+ def touch(*args)
184
+ FileUtils.touch(template_loc(*args))
185
+ end
186
+
187
+ def reset_mtimes
188
+ Dir["{#{template_loc},#{tempfile_loc}}/**/*.{css,sass}"].each {|f| File.utime(Time.now, Time.now - 1, f)}
189
+ end
190
+
175
191
  def template_loc(name = nil, prefix = nil)
176
192
  if name
177
193
  absolutize "#{prefix}templates/#{name}.sass"
@@ -209,11 +225,6 @@ class SassPluginTest < Test::Unit::TestCase
209
225
  :always_update => true,
210
226
  }.merge(overrides)
211
227
  end
212
-
213
- def wait_a_tick
214
- time = Time.now
215
- loop {break if Time.now.sec != time.sec}
216
- end
217
228
  end
218
229
 
219
230
  module Sass::Plugin
@@ -65,19 +65,19 @@ SASS
65
65
  assert_warning(<<WARN) {eval("foo")}
66
66
  DEPRECATION WARNING:
67
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 2.4.
68
+ Implicit strings have been deprecated and will be removed in version 3.0.
69
69
  'foo' was not quoted. Please add double quotes (e.g. "foo").
70
70
  WARN
71
71
  assert_warning(<<WARN) {eval("1 + foo")}
72
72
  DEPRECATION WARNING:
73
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 2.4.
74
+ Implicit strings have been deprecated and will be removed in version 3.0.
75
75
  'foo' was not quoted. Please add double quotes (e.g. "foo").
76
76
  WARN
77
77
  assert_warning(<<WARN) {render("@if 1 + foo")}
78
78
  DEPRECATION WARNING:
79
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 2.4.
80
+ Implicit strings have been deprecated and will be removed in version 3.0.
81
81
  'foo' was not quoted. Please add double quotes (e.g. "foo").
82
82
  WARN
83
83
 
@@ -85,7 +85,7 @@ WARN
85
85
  assert_warning(<<WARN) {render("@if if")}
86
86
  DEPRECATION WARNING:
87
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 2.4.
88
+ Implicit strings have been deprecated and will be removed in version 3.0.
89
89
  'if' was not quoted. Please add double quotes (e.g. "if").
90
90
  WARN
91
91
  end
@@ -94,7 +94,7 @@ WARN
94
94
  assert_warning <<WARN do
95
95
  DEPRECATION WARNING:
96
96
  On line 2, character 6 of 'test_inaccessible_functions_inline.sass'
97
- Implicit strings have been deprecated and will be removed in version 2.4.
97
+ Implicit strings have been deprecated and will be removed in version 3.0.
98
98
  'to_s' was not quoted. Please add double quotes (e.g. "to_s").
99
99
  WARN
100
100
  assert_equal "send(to_s)", resolve("send(to_s)", :line => 2)
@@ -108,14 +108,14 @@ WARN
108
108
  assert_warning(<<WARN) {eval("!a-!b", {}, env("a" => a, "b" => b))}
109
109
  DEPRECATION WARNING:
110
110
  On line 1, character 3 of 'test_hyphen_warning_inline.sass'
111
- - will be allowed as part of variable names in version 2.4.
111
+ - will be allowed as part of variable names in version 3.0.
112
112
  Please add whitespace to separate it from the previous token.
113
113
  WARN
114
114
 
115
115
  assert_warning(<<WARN) {eval("true-false")}
116
116
  DEPRECATION WARNING:
117
117
  On line 1, character 5 of 'test_hyphen_warning_inline.sass'
118
- - will be allowed as part of variable names in version 2.4.
118
+ - will be allowed as part of variable names in version 3.0.
119
119
  Please add whitespace to separate it from the previous token.
120
120
  WARN
121
121
  end
@@ -0,0 +1,549 @@
1
+ #!/usr/bin/env ruby
2
+ require File.dirname(__FILE__) + '/../test_helper'
3
+
4
+ class ToSassTest < 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_renders <<SASS, <<SCSS
90
+ foo bar baz bang
91
+ baz: bang
92
+ SASS
93
+ foo bar
94
+ baz bang {
95
+ baz: bang; }
96
+ SCSS
97
+ end
98
+
99
+ def test_escaped_selector
100
+ assert_renders <<SASS, <<SCSS
101
+ foo bar
102
+ \\:hover
103
+ baz: bang
104
+ SASS
105
+ foo bar {
106
+ :hover {
107
+ baz: bang; } }
108
+ SCSS
109
+ end
110
+
111
+ def test_property_name_interpolation
112
+ assert_renders <<SASS, <<SCSS
113
+ foo bar
114
+ baz\#{!bang}bip\#{!bop}: 12
115
+ SASS
116
+ foo bar {
117
+ baz\#{!bang}bip\#{!bop}: 12; }
118
+ SCSS
119
+ end
120
+
121
+ def test_property_name_interpolation
122
+ assert_renders <<SASS, <<SCSS
123
+ foo bar
124
+ baz\#{!bang}bip\#{!bop}: 12
125
+ SASS
126
+ foo bar {
127
+ baz\#{!bang}bip\#{!bop}: 12; }
128
+ SCSS
129
+ end
130
+
131
+ def test_property_value_interpolation
132
+ assert_renders <<SASS, <<SCSS
133
+ foo bar
134
+ baz: 12 \#{!bang} bip \#{"bop"} blat
135
+ SASS
136
+ foo bar {
137
+ baz: 12 \#{!bang} bip \#{"bop"} blat; }
138
+ SCSS
139
+ end
140
+
141
+ def test_dynamic_properties
142
+ assert_renders <<SASS, <<SCSS
143
+ foo bar
144
+ baz= 12 !bang "bip"
145
+ SASS
146
+ foo bar {
147
+ baz= 12 !bang "bip"; }
148
+ SCSS
149
+ end
150
+
151
+ def test_dynamic_properties_with_old
152
+ assert_renders <<SASS, <<SCSS, :old => true
153
+ foo bar
154
+ :baz= 12 !bang "bip"
155
+ SASS
156
+ foo bar {
157
+ baz= 12 !bang "bip"; }
158
+ SCSS
159
+ end
160
+
161
+ def test_multiline_properties
162
+ assert_renders <<SASS, <<SCSS
163
+ foo bar
164
+ baz: bip bam boon
165
+ SASS
166
+ foo bar {
167
+ baz:
168
+ bip
169
+ bam
170
+ boon; }
171
+ SCSS
172
+ end
173
+
174
+ def test_multiline_dynamic_properties
175
+ assert_renders <<SASS, <<SCSS
176
+ foo bar
177
+ baz= !bip "bam" 12px
178
+ SASS
179
+ foo bar {
180
+ baz=
181
+ !bip
182
+ "bam"
183
+ 12px; }
184
+ SCSS
185
+ end
186
+
187
+ def test_silent_comments
188
+ assert_renders <<SASS, <<SCSS
189
+ // foo
190
+
191
+ // bar
192
+
193
+ // baz
194
+
195
+ foo bar
196
+ a: b
197
+ SASS
198
+ // foo
199
+
200
+ // bar
201
+
202
+ // baz
203
+
204
+ foo bar {
205
+ a: b; }
206
+ SCSS
207
+
208
+ assert_renders <<SASS, <<SCSS
209
+ // foo
210
+ bar
211
+ baz
212
+ bang
213
+
214
+ foo bar
215
+ a: b
216
+ SASS
217
+ // foo
218
+ // bar
219
+ // baz
220
+ // bang
221
+
222
+ foo bar {
223
+ a: b; }
224
+ SCSS
225
+ end
226
+
227
+
228
+ def test_loud_comments
229
+ assert_renders <<SASS, <<SCSS
230
+ /* foo
231
+
232
+ /* bar
233
+
234
+ /* baz
235
+
236
+ foo bar
237
+ a: b
238
+ SASS
239
+ /* foo */
240
+
241
+ /* bar */
242
+
243
+ /* baz */
244
+
245
+ foo bar {
246
+ a: b; }
247
+ SCSS
248
+
249
+ assert_renders <<SASS, <<SCSS
250
+ /* foo
251
+ bar
252
+ baz
253
+ bang
254
+
255
+ foo bar
256
+ a: b
257
+ SASS
258
+ /* foo
259
+ bar
260
+ baz
261
+ bang */
262
+
263
+ foo bar {
264
+ a: b; }
265
+ SCSS
266
+
267
+ assert_renders <<SASS, <<SCSS
268
+ /* foo
269
+ bar
270
+ baz
271
+ bang
272
+
273
+ foo bar
274
+ a: b
275
+ SASS
276
+ /* foo
277
+ * bar
278
+ * baz
279
+ * bang */
280
+
281
+ foo bar {
282
+ a: b; }
283
+ SCSS
284
+ end
285
+
286
+ def test_loud_comments_with_weird_indentation
287
+ assert_renders <<SASS, <<SCSS
288
+ foo
289
+ /* foo
290
+ bar
291
+ baz
292
+ a: b
293
+ SASS
294
+ foo {
295
+ /* foo
296
+ bar
297
+ baz */
298
+ a: b; }
299
+ SCSS
300
+ end
301
+
302
+ def test_debug
303
+ assert_renders <<SASS, <<SCSS
304
+ foo
305
+ @debug 12px
306
+ bar: baz
307
+ SASS
308
+ foo {
309
+ @debug 12px;
310
+ bar: baz; }
311
+ SCSS
312
+ end
313
+
314
+ def test_directive_without_children
315
+ assert_renders <<SASS, <<SCSS
316
+ foo
317
+ @foo #bar "baz"
318
+ bar: baz
319
+ SASS
320
+ foo {
321
+ @foo #bar "baz";
322
+ bar: baz; }
323
+ SCSS
324
+ end
325
+
326
+ def test_directive_with_prop_children
327
+ assert_renders <<SASS, <<SCSS
328
+ foo
329
+ @foo #bar "baz"
330
+ a: b
331
+ c: d
332
+
333
+ bar: baz
334
+ SASS
335
+ foo {
336
+ @foo #bar "baz" {
337
+ a: b;
338
+ c: d; }
339
+
340
+ bar: baz; }
341
+ SCSS
342
+ end
343
+
344
+ def test_directive_with_rule_children
345
+ assert_renders <<SASS, <<SCSS
346
+ foo
347
+ @foo #bar "baz"
348
+ #blat
349
+ a: b
350
+ .bang
351
+ c: d
352
+ e: f
353
+
354
+ bar: baz
355
+ SASS
356
+ foo {
357
+ @foo #bar "baz" {
358
+ #blat {
359
+ a: b; }
360
+ .bang {
361
+ c: d;
362
+ e: f; } }
363
+
364
+ bar: baz; }
365
+ SCSS
366
+ end
367
+
368
+ def test_directive_with_rule_and_prop_children
369
+ assert_renders <<SASS, <<SCSS
370
+ foo
371
+ @foo #bar "baz"
372
+ g: h
373
+ #blat
374
+ a: b
375
+ .bang
376
+ c: d
377
+ e: f
378
+ i: j
379
+
380
+ bar: baz
381
+ SASS
382
+ foo {
383
+ @foo #bar "baz" {
384
+ g: h;
385
+ #blat {
386
+ a: b; }
387
+ .bang {
388
+ c: d;
389
+ e: f; }
390
+ i: j; }
391
+
392
+ bar: baz; }
393
+ SCSS
394
+ end
395
+
396
+ def test_for
397
+ assert_renders <<SASS, <<SCSS
398
+ foo
399
+ @for !a from !b to !c
400
+ a: b
401
+ @for !c from 1 to 16
402
+ d: e
403
+ f: g
404
+ SASS
405
+ foo {
406
+ @for !a from !b to !c {
407
+ a: b; }
408
+ @for !c from 1 to 16 {
409
+ d: e;
410
+ f: g; } }
411
+ SCSS
412
+ end
413
+
414
+ def test_if
415
+ assert_renders <<SASS, <<SCSS
416
+ foo
417
+ @if !foo or !bar
418
+ a: b
419
+ @if !baz
420
+ d: e
421
+ @else if !bang
422
+ f: g
423
+ @else
424
+ h: i
425
+ SASS
426
+ foo {
427
+ @if !foo or !bar {
428
+ a: b; }
429
+ @if !baz {
430
+ d: e; }
431
+ @else if !bang {
432
+ f: g; }
433
+ @else {
434
+ h: i; } }
435
+ SCSS
436
+ end
437
+
438
+ def test_import
439
+ assert_renders <<SASS, <<SCSS
440
+ @import foo
441
+
442
+ foo
443
+ bar: baz
444
+ SASS
445
+ @import "foo";
446
+
447
+ foo {
448
+ bar: baz; }
449
+ SCSS
450
+
451
+ assert_renders <<SASS, <<SCSS
452
+ @import foo.css
453
+
454
+ foo
455
+ bar: baz
456
+ SASS
457
+ @import "foo.css";
458
+
459
+ foo {
460
+ bar: baz; }
461
+ SCSS
462
+ end
463
+
464
+ def test_import_as_directive_in_sass
465
+ assert_sass_to_sass '@import "foo.css"'
466
+ assert_sass_to_sass '@import url(foo.css)'
467
+ end
468
+
469
+ def test_import_as_directive_in_scss
470
+ assert_renders <<SASS, <<SCSS
471
+ @import "foo.css" print
472
+ SASS
473
+ @import "foo.css" print;
474
+ SCSS
475
+
476
+ assert_renders <<SASS, <<SCSS
477
+ @import url(foo.css) screen, print
478
+ SASS
479
+ @import url(foo.css) screen, print;
480
+ SCSS
481
+ end
482
+
483
+ def test_argless_mixin_definition
484
+ assert_renders <<SASS, <<SCSS
485
+ =foo-bar
486
+ baz
487
+ a: b
488
+ SASS
489
+ @mixin foo-bar {
490
+ baz {
491
+ a: b; } }
492
+ SCSS
493
+
494
+ assert_renders <<SASS, render(<<SCSS)
495
+ =foo-bar
496
+ baz
497
+ a: b
498
+ SASS
499
+ @mixin foo-bar() {
500
+ baz {
501
+ a: b; } }
502
+ SCSS
503
+ end
504
+
505
+ def test_mixin_definition_without_defaults
506
+ assert_renders <<SASS, <<SCSS
507
+ =foo-bar(!baz, !bang)
508
+ baz
509
+ a = !baz !bang
510
+ SASS
511
+ @mixin foo-bar(!baz, !bang) {
512
+ baz {
513
+ a = !baz !bang; } }
514
+ SCSS
515
+ end
516
+
517
+ def test_mixin_definition_with_defaults
518
+ assert_renders <<SASS, <<SCSS
519
+ =foo-bar(!baz, !bang = 12px)
520
+ baz
521
+ a = !baz !bang
522
+ SASS
523
+ @mixin foo-bar(!baz, !bang = 12px) {
524
+ baz {
525
+ a = !baz !bang; } }
526
+ SCSS
527
+ end
528
+
529
+ private
530
+
531
+ def assert_sass_to_sass(sass, options = {})
532
+ assert_equal(sass.rstrip, render(sass, options).rstrip,
533
+ "Expected Sass to transform to itself")
534
+ end
535
+
536
+ def assert_scss_to_sass(sass, scss, options = {})
537
+ assert_equal(sass.rstrip, render(scss, options.merge(:syntax => :scss)).rstrip,
538
+ "Expected SCSS to transform to Sass")
539
+ end
540
+
541
+ def assert_renders(sass, scss, options = {})
542
+ assert_sass_to_sass(sass, options)
543
+ assert_scss_to_sass(sass, scss, options)
544
+ end
545
+
546
+ def render(scss, options = {})
547
+ Sass::Engine.new(scss, options).to_tree.to_sass(options)
548
+ end
549
+ end