blob: ebd9a3a8a50c6b323e23984a3a6b5a58797ff710 [file] [log] [blame]
# -*- 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