haml-edge 2.3.179 → 2.3.180

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (92) hide show
  1. data/EDGE_GEM_VERSION +1 -1
  2. data/README.md +88 -149
  3. data/VERSION +1 -1
  4. data/bin/css2sass +7 -1
  5. data/bin/sass-convert +7 -0
  6. data/lib/haml/exec.rb +95 -22
  7. data/lib/haml/template.rb +1 -1
  8. data/lib/haml/util.rb +50 -0
  9. data/lib/sass.rb +1 -1
  10. data/lib/sass/css.rb +38 -210
  11. data/lib/sass/engine.rb +121 -47
  12. data/lib/sass/files.rb +28 -19
  13. data/lib/sass/plugin.rb +32 -43
  14. data/lib/sass/repl.rb +1 -1
  15. data/lib/sass/script.rb +25 -6
  16. data/lib/sass/script/bool.rb +1 -0
  17. data/lib/sass/script/color.rb +2 -2
  18. data/lib/sass/script/css_lexer.rb +22 -0
  19. data/lib/sass/script/css_parser.rb +28 -0
  20. data/lib/sass/script/funcall.rb +17 -9
  21. data/lib/sass/script/functions.rb +46 -1
  22. data/lib/sass/script/interpolation.rb +42 -0
  23. data/lib/sass/script/lexer.rb +142 -34
  24. data/lib/sass/script/literal.rb +28 -12
  25. data/lib/sass/script/node.rb +57 -1
  26. data/lib/sass/script/number.rb +18 -3
  27. data/lib/sass/script/operation.rb +44 -8
  28. data/lib/sass/script/parser.rb +149 -24
  29. data/lib/sass/script/string.rb +50 -2
  30. data/lib/sass/script/unary_operation.rb +25 -10
  31. data/lib/sass/script/variable.rb +20 -11
  32. data/lib/sass/scss.rb +14 -0
  33. data/lib/sass/scss/css_parser.rb +39 -0
  34. data/lib/sass/scss/parser.rb +683 -0
  35. data/lib/sass/scss/rx.rb +112 -0
  36. data/lib/sass/scss/script_lexer.rb +13 -0
  37. data/lib/sass/scss/script_parser.rb +25 -0
  38. data/lib/sass/tree/comment_node.rb +58 -16
  39. data/lib/sass/tree/debug_node.rb +7 -2
  40. data/lib/sass/tree/directive_node.rb +38 -34
  41. data/lib/sass/tree/for_node.rb +6 -0
  42. data/lib/sass/tree/if_node.rb +13 -0
  43. data/lib/sass/tree/import_node.rb +26 -7
  44. data/lib/sass/tree/mixin_def_node.rb +18 -0
  45. data/lib/sass/tree/mixin_node.rb +16 -1
  46. data/lib/sass/tree/node.rb +98 -27
  47. data/lib/sass/tree/prop_node.rb +97 -20
  48. data/lib/sass/tree/root_node.rb +37 -0
  49. data/lib/sass/tree/rule_node.rb +88 -60
  50. data/lib/sass/tree/variable_node.rb +9 -5
  51. data/lib/sass/tree/while_node.rb +4 -0
  52. data/test/haml/results/filters.xhtml +1 -1
  53. data/test/haml/util_test.rb +28 -0
  54. data/test/sass/conversion_test.rb +884 -0
  55. data/test/sass/css2sass_test.rb +46 -21
  56. data/test/sass/engine_test.rb +680 -160
  57. data/test/sass/functions_test.rb +27 -0
  58. data/test/sass/more_results/more_import.css +1 -1
  59. data/test/sass/more_templates/more_import.sass +3 -3
  60. data/test/sass/plugin_test.rb +28 -8
  61. data/test/sass/results/compact.css +1 -1
  62. data/test/sass/results/complex.css +5 -5
  63. data/test/sass/results/compressed.css +1 -1
  64. data/test/sass/results/expanded.css +1 -1
  65. data/test/sass/results/import.css +3 -1
  66. data/test/sass/results/mixins.css +12 -12
  67. data/test/sass/results/nested.css +1 -1
  68. data/test/sass/results/parent_ref.css +4 -4
  69. data/test/sass/results/script.css +3 -3
  70. data/test/sass/results/scss_import.css +15 -0
  71. data/test/sass/results/scss_importee.css +2 -0
  72. data/test/sass/script_conversion_test.rb +153 -0
  73. data/test/sass/script_test.rb +44 -54
  74. data/test/sass/scss/css_test.rb +811 -0
  75. data/test/sass/scss/rx_test.rb +156 -0
  76. data/test/sass/scss/scss_test.rb +871 -0
  77. data/test/sass/scss/test_helper.rb +37 -0
  78. data/test/sass/templates/alt.sass +2 -2
  79. data/test/sass/templates/bork1.sass +1 -1
  80. data/test/sass/templates/import.sass +4 -4
  81. data/test/sass/templates/importee.sass +3 -3
  82. data/test/sass/templates/line_numbers.sass +1 -1
  83. data/test/sass/templates/mixins.sass +2 -2
  84. data/test/sass/templates/nested_mixin_bork.sass +1 -1
  85. data/test/sass/templates/options.sass +1 -1
  86. data/test/sass/templates/parent_ref.sass +2 -2
  87. data/test/sass/templates/script.sass +69 -69
  88. data/test/sass/templates/scss_import.scss +10 -0
  89. data/test/sass/templates/scss_importee.scss +1 -0
  90. data/test/sass/templates/units.sass +10 -10
  91. data/test/test_helper.rb +4 -4
  92. metadata +27 -2
@@ -13,6 +13,10 @@ module Sass::Script::Functions::UserFunctions
13
13
  def user_defined
14
14
  Sass::Script::String.new("I'm a user-defined string!")
15
15
  end
16
+
17
+ def _preceding_underscore
18
+ Sass::Script::String.new("I'm another user-defined string!")
19
+ end
16
20
  end
17
21
 
18
22
  class SassFunctionTest < Test::Unit::TestCase
@@ -465,10 +469,33 @@ class SassFunctionTest < Test::Unit::TestCase
465
469
  assert_error_message("\"foo\" is not a color for `complement'", "complement(\"foo\")")
466
470
  end
467
471
 
472
+ def test_unquote
473
+ assert_equal('foo', evaluate('unquote("foo")'))
474
+ assert_equal('foo', evaluate('unquote(foo)'))
475
+ end
476
+
477
+ def test_unquote_tests_type
478
+ assert_error_message("#ff0000 is not a string for `unquote'", "unquote(#f00)")
479
+ end
480
+
481
+ def test_quote
482
+ assert_equal('"foo"', evaluate('quote(foo)'))
483
+ assert_equal('"foo"', evaluate('quote("foo")'))
484
+ end
485
+
486
+ def test_quote_tests_type
487
+ assert_error_message("#ff0000 is not a string for `quote'", "quote(#f00)")
488
+ end
489
+
468
490
  def test_user_defined_function
469
491
  assert_equal("I'm a user-defined string!", evaluate("user_defined()"))
470
492
  end
471
493
 
494
+ def test_user_defined_function_with_preceding_underscore
495
+ assert_equal("I'm another user-defined string!", evaluate("_preceding_underscore()"))
496
+ assert_equal("I'm another user-defined string!", evaluate("-preceding-underscore()"))
497
+ end
498
+
472
499
  def test_options_on_new_literals_fails
473
500
  assert_error_message(<<MSG, "call-options-on-new-literal()")
474
501
  The #options attribute is not set on this Sass::Script::String.
@@ -24,6 +24,6 @@ body { font: Arial; background: blue; }
24
24
 
25
25
  @import url(basic.css);
26
26
  @import url(../results/complex.css);
27
- #foo { background-color: #baf; }
27
+ #foo { background-color: #bbaaff; }
28
28
 
29
29
  nonimported { myconst: hello; otherconst: goodbye; post-mixin: here; }
@@ -1,4 +1,4 @@
1
- !preconst = "hello"
1
+ $preconst: hello
2
2
 
3
3
  =premixin
4
4
  pre-mixin: here
@@ -6,6 +6,6 @@
6
6
  @import importee, basic, basic.css, ../results/complex.css, more_partial
7
7
 
8
8
  nonimported
9
- :myconst = !preconst
10
- :otherconst = !postconst
9
+ :myconst $preconst
10
+ :otherconst $postconst
11
11
  +postmixin
@@ -5,7 +5,7 @@ require 'fileutils'
5
5
 
6
6
  class SassPluginTest < Test::Unit::TestCase
7
7
  @@templates = %w{
8
- complex script parent_ref import alt
8
+ complex script parent_ref import scss_import alt
9
9
  subdir/subdir subdir/nested_subdir/nested_subdir
10
10
  options
11
11
  }
@@ -50,6 +50,23 @@ class SassPluginTest < Test::Unit::TestCase
50
50
  assert_needs_update 'import'
51
51
  Sass::Plugin.update_stylesheets
52
52
  assert_stylesheet_updated 'basic'
53
+ assert_stylesheet_updated 'import'
54
+ end
55
+
56
+ def test_update_needed_when_scss_dependency_modified
57
+ touch 'scss_importee'
58
+ assert_needs_update 'import'
59
+ Sass::Plugin.update_stylesheets
60
+ assert_stylesheet_updated 'scss_importee'
61
+ assert_stylesheet_updated 'import'
62
+ end
63
+
64
+ def test_scss_update_needed_when_dependency_modified
65
+ touch 'basic'
66
+ assert_needs_update 'scss_import'
67
+ Sass::Plugin.update_stylesheets
68
+ assert_stylesheet_updated 'basic'
69
+ assert_stylesheet_updated 'scss_import'
53
70
  end
54
71
 
55
72
  def test_full_exception_handling
@@ -58,11 +75,11 @@ class SassPluginTest < Test::Unit::TestCase
58
75
  File.open(tempfile_loc('bork1')) do |file|
59
76
  assert_equal(<<CSS.strip, file.read.split("\n")[0...6].join("\n"))
60
77
  /*
61
- Syntax error: Undefined variable: "!bork".
78
+ Syntax error: Undefined variable: "$bork".
62
79
  on line 2 of #{template_loc('bork1')}
63
80
 
64
81
  1: bork
65
- 2: :bork= !bork
82
+ 2: :bork $bork
66
83
  CSS
67
84
  end
68
85
  File.delete(tempfile_loc('bork1'))
@@ -203,7 +220,7 @@ CSS
203
220
  Sass::Plugin.options[:always_update] = false
204
221
  touch 'bork1'
205
222
  assert_callback(:compilation_error,
206
- lambda {|e| e.message == 'Undefined variable: "!bork".'},
223
+ lambda {|e| e.message == 'Undefined variable: "$bork".'},
207
224
  template_loc("bork1"), tempfile_loc("bork1"))
208
225
  end
209
226
 
@@ -324,12 +341,12 @@ CSS
324
341
  end
325
342
 
326
343
  def assert_needs_update(name)
327
- assert(Sass::Plugin.stylesheet_needs_update?(name, template_loc, tempfile_loc),
344
+ assert(Sass::Plugin.stylesheet_needs_update?(tempfile_loc(name), template_loc(name)),
328
345
  "Expected #{template_loc(name)} to need an update.")
329
346
  end
330
347
 
331
348
  def assert_doesnt_need_update(name)
332
- assert(!Sass::Plugin.stylesheet_needs_update?(name, template_loc, tempfile_loc),
349
+ assert(!Sass::Plugin.stylesheet_needs_update?(tempfile_loc(name), template_loc(name)),
333
350
  "Expected #{template_loc(name)} not to need an update.")
334
351
  end
335
352
 
@@ -338,12 +355,15 @@ CSS
338
355
  end
339
356
 
340
357
  def reset_mtimes
341
- Dir["{#{template_loc},#{tempfile_loc}}/**/*.{css,sass}"].each {|f| File.utime(Time.now, Time.now - 1, f)}
358
+ atime = Time.now
359
+ mtime = Time.now - 5
360
+ Dir["{#{template_loc},#{tempfile_loc}}/**/*.{css,sass,scss}"].each {|f| File.utime(atime, mtime, f)}
342
361
  end
343
362
 
344
363
  def template_loc(name = nil, prefix = nil)
345
364
  if name
346
- absolutize "#{prefix}templates/#{name}.sass"
365
+ scss = absolutize "#{prefix}templates/#{name}.scss"
366
+ File.exists?(scss) ? scss : absolutize("#{prefix}templates/#{name}.sass")
347
367
  else
348
368
  absolutize "#{prefix}templates"
349
369
  end
@@ -1,4 +1,4 @@
1
- #main { width: 15em; color: #0000ff; }
1
+ #main { width: 15em; color: blue; }
2
2
  #main p { border-style: dotted; /* Nested comment More nested stuff */ border-width: 2px; }
3
3
  #main .cool { width: 100px; }
4
4
 
@@ -1,10 +1,10 @@
1
- body { margin: 0; font: 0.85em "Lucida Grande", "Trebuchet MS", Verdana, sans-serif; color: #fff; background: url(/images/global_bg.gif); }
1
+ body { margin: 0; font: 0.85em "Lucida Grande", "Trebuchet MS", Verdana, sans-serif; color: white; background: url(/images/global_bg.gif); }
2
2
 
3
3
  #page { width: 900px; margin: 0 auto; background: #440008; border-top-width: 5px; border-top-style: solid; border-top-color: #ff8500; }
4
4
 
5
5
  #header { height: 75px; padding: 0; }
6
6
  #header h1 { float: left; width: 274px; height: 75px; margin: 0; background-image: url(/images/global_logo.gif); /* Crazy nested comment */ background-repeat: no-repeat; text-indent: -9999px; }
7
- #header .status { float: right; padding-top: .5em; padding-left: .5em; padding-right: .5em; padding-bottom: 0; }
7
+ #header .status { float: right; padding-top: 0.5em; padding-left: 0.5em; padding-right: 0.5em; padding-bottom: 0; }
8
8
  #header .status p { float: left; margin-top: 0; margin-right: 0.5em; margin-bottom: 0; margin-left: 0; }
9
9
  #header .status ul { float: left; margin: 0; padding: 0; }
10
10
  #header .status li { list-style-type: none; display: inline; margin: 0 5px; }
@@ -16,9 +16,9 @@ body { margin: 0; font: 0.85em "Lucida Grande", "Trebuchet MS", Verdana, sans-se
16
16
 
17
17
  #menu { clear: both; text-align: right; height: 20px; border-bottom: 5px solid #006b95; background: #00a4e4; }
18
18
  #menu .contests ul { margin: 0 5px 0 0; padding: 0; }
19
- #menu .contests ul li { list-style-type: none; margin: 0 5px; padding: 5px 5px 0 5px; display: inline; font-size: 1.1em; color: #fff; background: #00a4e4; }
19
+ #menu .contests ul li { list-style-type: none; margin: 0 5px; padding: 5px 5px 0 5px; display: inline; font-size: 1.1em; color: white; background: #00a4e4; }
20
20
  #menu .contests ul li / This rule isn't a comment! { red: green; }
21
- #menu .contests a:link, #menu .contests a:visited { color: #fff; text-decoration: none; font-weight: bold; }
21
+ #menu .contests a:link, #menu .contests a:visited { color: white; text-decoration: none; font-weight: bold; }
22
22
  #menu .contests a:hover { text-decoration: underline; }
23
23
 
24
24
  #content { clear: both; }
@@ -82,6 +82,6 @@ body { margin: 0; font: 0.85em "Lucida Grande", "Trebuchet MS", Verdana, sans-se
82
82
 
83
83
  img { border: none; }
84
84
 
85
- button.short { width: 60px; height: 22px; padding: 0 0 2px 0; color: #fff; border: none; background: url(/images/btn_short.gif) no-repeat; }
85
+ button.short { width: 60px; height: 22px; padding: 0 0 2px 0; color: white; border: none; background: url(/images/btn_short.gif) no-repeat; }
86
86
 
87
87
  table { border-collapse: collapse; }
@@ -1 +1 @@
1
- #main{width:15em;color:#0000ff}#main p{border-style:dotted;border-width:2px}#main .cool{width:100px}#left{font-size:2em;font-weight:bold;float:left}
1
+ #main{width:15em;color:blue}#main p{border-style:dotted;border-width:2px}#main .cool{width:100px}#left{font-size:2em;font-weight:bold;float:left}
@@ -1,6 +1,6 @@
1
1
  #main {
2
2
  width: 15em;
3
- color: #0000ff;
3
+ color: blue;
4
4
  }
5
5
  #main p {
6
6
  border-style: dotted;
@@ -12,6 +12,8 @@ body { font: Arial; background: blue; }
12
12
 
13
13
  midrule { inthe: middle; }
14
14
 
15
+ scss { imported: yes; }
16
+
15
17
  body { font: Arial; background: blue; }
16
18
 
17
19
  #page { width: 700px; height: 100; }
@@ -24,6 +26,6 @@ body { font: Arial; background: blue; }
24
26
 
25
27
  @import url(basic.css);
26
28
  @import url(../results/complex.css);
27
- #foo { background-color: #baf; }
29
+ #foo { background-color: #bbaaff; }
28
30
 
29
31
  nonimported { myconst: hello; otherconst: goodbye; post-mixin: here; }
@@ -1,12 +1,12 @@
1
1
  #main {
2
2
  width: 15em;
3
- color: #0000ff;
3
+ color: blue;
4
4
  }
5
5
  #main p {
6
6
  border-top-width: 2px;
7
7
  border-top-color: #ffcc00;
8
8
  border-left-width: 1px;
9
- border-left-color: #000;
9
+ border-left-color: black;
10
10
  -moz-border-radius: 10px;
11
11
  border-style: dotted;
12
12
  border-width: 2px;
@@ -19,7 +19,7 @@
19
19
  border-top-width: 2px;
20
20
  border-top-color: #ffcc00;
21
21
  border-left-width: 1px;
22
- border-left-color: #000;
22
+ border-left-color: black;
23
23
  -moz-border-radius: 10px;
24
24
  font-size: 2em;
25
25
  font-weight: bold;
@@ -30,9 +30,9 @@
30
30
  border-top-width: 2px;
31
31
  border-top-color: #ffcc00;
32
32
  border-left-width: 1px;
33
- border-left-color: #000;
33
+ border-left-color: black;
34
34
  -moz-border-radius: 10px;
35
- color: #f00;
35
+ color: red;
36
36
  font-size: 20px;
37
37
  float: right;
38
38
  }
@@ -41,12 +41,12 @@
41
41
  border-top-width: 2px;
42
42
  border-top-color: #ffcc00;
43
43
  border-left-width: 1px;
44
- border-left-color: #000;
44
+ border-left-color: black;
45
45
  -moz-border-radius: 10px;
46
46
  }
47
47
 
48
48
  .complex {
49
- color: #f00;
49
+ color: red;
50
50
  font-size: 20px;
51
51
  text-decoration: none;
52
52
  }
@@ -59,12 +59,12 @@
59
59
  }
60
60
  * html .complex {
61
61
  height: 1px;
62
- color: #f00;
62
+ color: red;
63
63
  font-size: 20px;
64
64
  }
65
65
 
66
66
  .more-complex {
67
- color: #f00;
67
+ color: red;
68
68
  font-size: 20px;
69
69
  text-decoration: none;
70
70
  display: inline;
@@ -80,16 +80,16 @@
80
80
  }
81
81
  * html .more-complex {
82
82
  height: 1px;
83
- color: #f00;
83
+ color: red;
84
84
  font-size: 20px;
85
85
  }
86
86
  .more-complex a:hover {
87
87
  text-decoration: underline;
88
- color: #f00;
88
+ color: red;
89
89
  font-size: 20px;
90
90
  border-top-width: 2px;
91
91
  border-top-color: #ffcc00;
92
92
  border-left-width: 1px;
93
- border-left-color: #000;
93
+ border-left-color: black;
94
94
  -moz-border-radius: 10px;
95
95
  }
@@ -1,6 +1,6 @@
1
1
  #main {
2
2
  width: 15em;
3
- color: #0000ff; }
3
+ color: blue; }
4
4
  #main p {
5
5
  border-style: dotted;
6
6
  /* Nested comment
@@ -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