| # -*- coding: utf-8 -*- |
| require File.dirname(__FILE__) + '/../test_helper' |
| require 'sass/engine' |
| |
| class SassScriptConversionTest < MiniTest::Test |
| def test_bool |
| assert_renders "true" |
| assert_renders "false" |
| end |
| |
| def test_color |
| assert_renders "#abcdef" |
| assert_renders "blue" |
| assert_renders "rgba(0, 1, 2, 0.2)" |
| assert_renders "#abc" |
| assert_renders "#0000ff" |
| end |
| |
| def test_number |
| assert_renders "10" |
| assert_renders "10.35" |
| assert_renders "12px" |
| assert_renders "12.45px" |
| |
| assert_equal "12.3456789013", render("12.34567890129") |
| end |
| |
| def test_string |
| assert_renders '"foo"' |
| assert_renders '"bar baz"' |
| assert_equal '"baz bang"', render("'baz bang'") |
| end |
| |
| def test_string_quotes |
| assert_equal "'quote\"quote'", render('"quote\\"quote"') |
| assert_equal '"quote\'quote"', render("'quote\\'quote'") |
| assert_renders '"quote\'quote\\"quote"' |
| assert_equal '"quote\'quote\\"quote"', render("'quote\\'quote\"quote'") |
| end |
| |
| def test_string_escapes |
| assert_renders '"foo\\\\bar"' |
| end |
| |
| def test_funcall |
| assert_renders "foo(true, blue)" |
| assert_renders "hsla(20deg, 30%, 50%, 0.3)" |
| assert_renders "blam()" |
| |
| assert_renders "-\xC3\xBFoo(12px)" |
| assert_renders "-foo(12px)" |
| end |
| |
| def test_funcall_with_keyword_args |
| assert_renders "foo(arg1, arg2, $karg1: val, $karg2: val2)" |
| assert_renders "foo($karg1: val, $karg2: val2)" |
| end |
| |
| def test_funcall_with_hyphen_conversion_keyword_arg |
| assert_renders "foo($a-b_c: val)" |
| end |
| |
| def test_url |
| assert_renders "url(foo.gif)" |
| assert_renders "url($var)" |
| assert_renders "url(\#{$var}/flip.gif)" |
| end |
| |
| def test_variable |
| assert_renders "$foo-bar" |
| assert_renders "$flaznicate" |
| end |
| |
| def test_null |
| assert_renders "null" |
| end |
| |
| def test_space_list |
| assert_renders "foo bar baz" |
| assert_renders "foo (bar baz) bip" |
| assert_renders "foo (bar, baz) bip" |
| end |
| |
| def test_comma_list |
| assert_renders "foo, bar, baz" |
| assert_renders "foo, (bar, baz), bip" |
| assert_renders "foo, bar baz, bip" |
| end |
| |
| def test_space_list_adds_parens_for_clarity |
| assert_renders "(1 + 1) (2 / 4) (3 * 5)" |
| end |
| |
| def test_comma_list_doesnt_add_parens |
| assert_renders "1 + 1, 2 / 4, 3 * 5" |
| end |
| |
| def test_empty_list |
| assert_renders "()" |
| end |
| |
| def test_list_in_args |
| assert_renders "foo((a, b, c))" |
| assert_renders "foo($arg: (a, b, c))" |
| assert_renders "foo(a, b, (a, b, c)...)" |
| end |
| |
| def test_singleton_list |
| assert_renders "(1,)" |
| assert_renders "(1 2 3,)" |
| assert_renders "((1, 2, 3),)" |
| end |
| |
| def test_map |
| assert_renders "(foo: bar)" |
| assert_renders "(foo: bar, baz: bip)" |
| assert_renders "(foo: bar, baz: (bip: bap))" |
| end |
| |
| def test_map_in_list |
| assert_renders "(foo: bar) baz" |
| assert_renders "(foo: bar), (baz: bip)" |
| end |
| |
| def test_list_in_map |
| assert_renders "(foo: bar baz)" |
| assert_renders "(foo: (bar, baz), bip: bop)" |
| end |
| |
| def test_selector |
| assert_renders "&" |
| end |
| |
| def self.test_precedence(outer, inner) |
| op_outer = Sass::Script::Lexer::OPERATORS_REVERSE[outer] |
| op_inner = Sass::Script::Lexer::OPERATORS_REVERSE[inner] |
| class_eval <<RUBY |
| def test_precedence_#{outer}_#{inner} |
| assert_renders "$foo #{op_outer} $bar #{op_inner} $baz" |
| assert_renders "$foo #{op_inner} $bar #{op_outer} $baz" |
| |
| assert_renders "($foo #{op_outer} $bar) #{op_inner} $baz" |
| assert_renders "$foo #{op_inner} ($bar #{op_outer} $baz)" |
| |
| assert_equal "$foo #{op_outer} $bar #{op_inner} $baz", |
| render("$foo #{op_outer} ($bar #{op_inner} $baz)") |
| assert_equal "$foo #{op_inner} $bar #{op_outer} $baz", |
| render("($foo #{op_inner} $bar) #{op_outer} $baz") |
| end |
| RUBY |
| end |
| |
| def self.assert_associative(op_name, sibling_name) |
| op = separator_for(op_name) |
| sibling = separator_for(sibling_name) |
| class_eval <<RUBY |
| def test_associative_#{op_name}_#{sibling_name} |
| assert_renders "$foo#{op}$bar#{op}$baz" |
| |
| assert_equal "$foo#{op}$bar#{op}$baz", |
| render("$foo#{op}($bar#{op}$baz)") |
| assert_equal "$foo#{op}$bar#{op}$baz", |
| render("($foo#{op}$bar)#{op}$baz") |
| |
| assert_equal "$foo#{op}$bar#{sibling}$baz", |
| render("$foo#{op}($bar#{sibling}$baz)") |
| assert_equal "$foo#{sibling}$bar#{op}$baz", |
| render("($foo#{sibling}$bar)#{op}$baz") |
| end |
| RUBY |
| end |
| |
| def self.separator_for(op_name) |
| case op_name |
| when :comma; ", " |
| when :space; " " |
| else; " #{Sass::Script::Lexer::OPERATORS_REVERSE[op_name]} " |
| end |
| end |
| |
| def self.assert_non_associative(op_name, sibling_name) |
| op = Sass::Script::Lexer::OPERATORS_REVERSE[op_name] |
| sibling = Sass::Script::Lexer::OPERATORS_REVERSE[sibling_name] |
| class_eval <<RUBY |
| def test_non_associative_#{op_name}_#{sibling_name} |
| assert_renders "$foo #{op} $bar #{op} $baz" |
| |
| assert_renders "$foo #{op} ($bar #{op} $baz)" |
| assert_equal "$foo #{op} $bar #{op} $baz", |
| render("($foo #{op} $bar) #{op} $baz") |
| |
| assert_renders "$foo #{op} ($bar #{sibling} $baz)" |
| assert_equal "$foo #{sibling} $bar #{op} $baz", |
| render("($foo #{sibling} $bar) #{op} $baz") |
| end |
| RUBY |
| end |
| |
| test_precedence :or, :and |
| test_precedence :and, :eq |
| test_precedence :and, :neq |
| test_precedence :eq, :gt |
| test_precedence :eq, :gte |
| test_precedence :eq, :lt |
| test_precedence :eq, :lte |
| test_precedence :gt, :plus |
| test_precedence :gt, :minus |
| test_precedence :plus, :times |
| test_precedence :plus, :div |
| test_precedence :plus, :mod |
| |
| assert_associative :plus, :minus |
| assert_associative :times, :div |
| assert_associative :times, :mod |
| |
| assert_non_associative :minus, :plus |
| assert_non_associative :div, :times |
| assert_non_associative :mod, :times |
| assert_non_associative :gt, :gte |
| assert_non_associative :gte, :lt |
| assert_non_associative :lt, :lte |
| assert_non_associative :lte, :gt |
| |
| def test_comma_precedence |
| assert_renders "$foo, $bar, $baz" |
| |
| assert_renders "$foo ($bar, $baz)" |
| assert_renders "($foo, $bar) $baz" |
| |
| assert_equal "$foo, $bar $baz", render("$foo, ($bar $baz)") |
| assert_equal "$foo $bar, $baz", render("($foo $bar), $baz") |
| |
| assert_equal "$foo, ($bar, $baz)", render("$foo, ($bar, $baz)") |
| assert_equal "($foo, $bar), $baz", render("($foo, $bar), $baz") |
| end |
| |
| def test_space_precedence |
| assert_renders "$foo $bar $baz" |
| |
| assert_renders "$foo or ($bar $baz)" |
| assert_renders "($foo $bar) or $baz" |
| |
| assert_renders "$foo ($bar or $baz)" |
| assert_renders "($foo or $bar) $baz" |
| |
| assert_equal "$foo ($bar $baz)", render("$foo ($bar $baz)") |
| assert_equal "($foo $bar) $baz", render("($foo $bar) $baz") |
| end |
| |
| def test_unary_op |
| assert_renders "-12px" |
| assert_renders '/"foo"' |
| assert_renders 'not true' |
| |
| assert_renders "-(foo(12px))" |
| assert_renders "-(-foo(12px))" |
| assert_renders "-(_foo(12px))" |
| assert_renders "-(\xC3\xBFoo(12px))" |
| assert_renders "-(blue)" |
| |
| assert_equal 'not true or false', render('(not true) or false') |
| assert_equal 'not (true or false)', render('not (true or false)') |
| end |
| |
| def test_interpolation |
| assert_equal 'unquote("#{$foo}#{$bar}#{$baz}")', render("$foo\#{$bar}$baz") |
| assert_equal 'unquote("#{$foo}#{$bar} #{$baz}")', render("$foo\#{$bar} $baz") |
| assert_equal 'unquote("#{$foo} #{$bar}#{$baz}")', render("$foo \#{$bar}$baz") |
| assert_renders "$foo \#{$bar} $baz" |
| assert_renders "$foo \#{$bar}\#{$bang} $baz" |
| assert_renders "$foo \#{$bar} \#{$bang} $baz" |
| assert_equal 'unquote("#{$bar}#{$baz}")', render("\#{$bar}$baz") |
| assert_equal 'unquote("#{$foo}#{$bar}")', render("$foo\#{$bar}") |
| assert_renders "\#{$bar}" |
| end |
| |
| def test_interpolation_in_function |
| assert_renders 'flabnabbit(#{1 + "foo"})' |
| assert_equal 'flabnabbit(unquote("#{$foo} #{1 + "foo"}#{$baz}"))', |
| render('flabnabbit($foo #{1 + "foo"}$baz)') |
| assert_renders 'flabnabbit($foo #{1 + "foo"}#{2 + "bar"} $baz)' |
| end |
| |
| def test_interpolation_in_string_function |
| assert_renders 'calc(#{1 + "foo"})' |
| assert_renders 'calc(foo#{1 + "foo"}baz)' |
| end |
| |
| def test_interpolation_near_operators |
| assert_renders '#{1 + 2} , #{3 + 4}' |
| assert_renders '#{1 + 2}, #{3 + 4}' |
| assert_renders '#{1 + 2} ,#{3 + 4}' |
| assert_renders '#{1 + 2},#{3 + 4}' |
| assert_renders '#{1 + 2}, #{3 + 4}, #{5 + 6}' |
| assert_renders '3, #{3 + 4}, 11' |
| |
| assert_renders '3 / #{3 + 4}' |
| assert_renders '3 /#{3 + 4}' |
| assert_renders '3/ #{3 + 4}' |
| assert_renders '3/#{3 + 4}' |
| |
| assert_equal 'unquote("#{1 + 2} * 7")', render('#{1 + 2} * 7') |
| assert_equal 'unquote("#{1 + 2}* 7")', render('#{1 + 2}* 7') |
| assert_equal 'unquote("#{1 + 2} *7")', render('#{1 + 2} *7') |
| assert_equal 'unquote("#{1 + 2}*7")', render('#{1 + 2}*7') |
| |
| assert_renders '-#{1 + 2}' |
| assert_equal 'unquote("- #{1 + 2}")', render('- #{1 + 2}') |
| |
| assert_equal 'unquote("5 + #{1 + 2} * #{3 + 4}")', render('5 + #{1 + 2} * #{3 + 4}') |
| assert_equal 'unquote("5 +#{1 + 2} * #{3 + 4}")', render('5 +#{1 + 2} * #{3 + 4}') |
| assert_equal 'unquote("5+#{1 + 2} * #{3 + 4}")', render('5+#{1 + 2} * #{3 + 4}') |
| assert_equal 'unquote("#{1 + 2} * #{3 + 4} + 5")', render('#{1 + 2} * #{3 + 4} + 5') |
| assert_equal 'unquote("#{1 + 2} * #{3 + 4}+ 5")', render('#{1 + 2} * #{3 + 4}+ 5') |
| assert_equal 'unquote("#{1 + 2} * #{3 + 4}+5")', render('#{1 + 2} * #{3 + 4}+5') |
| |
| assert_equal '5 / unquote("#{1 + 2} + #{3 + 4}")', render('5 / (#{1 + 2} + #{3 + 4})') |
| assert_equal '5 / unquote("#{1 + 2} + #{3 + 4}")', render('5 /(#{1 + 2} + #{3 + 4})') |
| assert_equal '5 / unquote("#{1 + 2} + #{3 + 4}")', render('5 /( #{1 + 2} + #{3 + 4} )') |
| assert_equal 'unquote("#{1 + 2} + #{3 + 4}") / 5', render('(#{1 + 2} + #{3 + 4}) / 5') |
| assert_equal 'unquote("#{1 + 2} + #{3 + 4}") / 5', render('(#{1 + 2} + #{3 + 4})/ 5') |
| assert_equal 'unquote("#{1 + 2} + #{3 + 4}") / 5', render('( #{1 + 2} + #{3 + 4} )/ 5') |
| |
| assert_equal 'unquote("#{1 + 2} + #{2 + 3}")', render('#{1 + 2} + 2 + 3') |
| assert_equal 'unquote("#{1 + 2} +#{2 + 3}")', render('#{1 + 2} +2 + 3') |
| end |
| |
| def test_string_interpolation |
| assert_renders '"foo#{$bar}baz"' |
| assert_renders '"foo #{$bar}baz"' |
| assert_renders '"foo#{$bar} baz"' |
| assert_renders '"foo #{$bar} baz"' |
| assert_renders '"foo #{$bar}#{$bang} baz"' |
| assert_renders '"foo #{$bar} #{$bang} baz"' |
| assert_renders '"#{$bar}baz"' |
| assert_renders '"foo#{$bar}"' |
| assert_renders '"#{$bar}"' |
| |
| assert_renders "'\"\#{\"bar\"}\"'" |
| assert_renders '"\#{bar}"' |
| |
| assert_equal '"foo#{$bar}baz"', render("'foo\#{$bar}baz'") |
| end |
| |
| def test_bracketed_lists |
| assert_renders("[]") |
| assert_renders("[foo, bar]") |
| assert_renders("[[foo]]") |
| assert_renders("[(foo bar)]") |
| assert_renders("[foo bar,]") |
| assert_renders("[(foo,)]") |
| end |
| |
| private |
| |
| def assert_renders(script, options = {}) |
| assert_equal(script, render(script, options)) |
| end |
| |
| def render(script, options = {}) |
| munge_filename(options) |
| node = Sass::Script.parse(script, 1, 0, options.merge(:_convert => true)) |
| node.to_sass |
| end |
| end |