diff --git a/lib/sass/constant.rb b/lib/sass/constant.rb index 7e03c5ee..1dac51ed 100644 --- a/lib/sass/constant.rb +++ b/lib/sass/constant.rb @@ -34,7 +34,8 @@ module Sass SECOND_ORDER = [:plus, :minus] class << self - def parse(value, constants) + def parse(value, constants, line) + @@line = line operationalize(parenthesize(tokenize(value)), value, constants).to_s end @@ -121,11 +122,13 @@ module Sass Literal.parse(insert_constant(value, constants)) end elsif length == 2 - raise "Syntax error:\n#{original}" + raise SyntaxError.new("Constant arithmetic error: #{original}", @@line) elsif length == 3 - Operation.new(operationalize(value[0], original, constants), operationalize(value[2], original, constants), value[1]) + Operation.new(operationalize(value[0], original, constants), operationalize(value[2], original, constants), value[1], @@line) else - raise "Syntax error:\n#{original}" unless length >= 5 && length % 2 == 1 + unless length >= 5 && length % 2 == 1 + raise SyntaxError.new("Constant arithmetic error: #{original}", @@line) + end if SECOND_ORDER.include?(value[1]) && FIRST_ORDER.include?(value[3]) operationalize([value[0], value[1], operationalize(value[2..4], original, constants), *value[5..-1]], original, constants) else @@ -138,7 +141,9 @@ module Sass to_return = value if value[0] == CONSTANT_CHAR to_return = constants[value[1..-1]] - raise "Undefined constant:\n#{value}" unless to_return + unless to_return + raise SyntaxError.new("Undefined constant: #{value}", @@line) + end end to_return end diff --git a/lib/sass/constant/operation.rb b/lib/sass/constant/operation.rb index f4e2e4c7..2dec5d26 100644 --- a/lib/sass/constant/operation.rb +++ b/lib/sass/constant/operation.rb @@ -4,10 +4,11 @@ require 'sass/constant/color' module Sass::Constant class Operation - def initialize(operand1, operand2, operator) + def initialize(operand1, operand2, operator, line) @operand1 = operand1 @operand2 = operand2 @operator = operator + @line = line end def to_s @@ -23,7 +24,7 @@ module Sass::Constant literal1.send(@operator, literal2) rescue NoMethodError => e raise e unless e.name == @operator - raise "Undefined operation:\n#{literal1} #{@operator} #{literal2}\n" + raise Sass::SyntaxError.new("Undefined operation: #{literal1} #{@operator} #{literal2}", @line) end end end diff --git a/lib/sass/engine.rb b/lib/sass/engine.rb index 147b23e9..f7f41b42 100644 --- a/lib/sass/engine.rb +++ b/lib/sass/engine.rb @@ -142,7 +142,7 @@ module Sass if name[-1] == SCRIPT_CHAR name.slice!(-1) - value = Sass::Constant.parse(value, @constants).to_s + value = Sass::Constant.parse(value, @constants, @line).to_s end Tree::AttrNode.new(name, value) @@ -153,7 +153,7 @@ module Sass unless name && value raise SyntaxError.new("Invalid constant: #{line}", @line) end - @constants[name] = Sass::Constant.parse(value, @constants) + @constants[name] = Sass::Constant.parse(value, @constants, @line) nil end end diff --git a/test/sass/engine_test.rb b/test/sass/engine_test.rb index a417b937..9540c848 100644 --- a/test/sass/engine_test.rb +++ b/test/sass/engine_test.rb @@ -6,16 +6,16 @@ require 'sass/engine' class SassEngineTest < Test::Unit::TestCase EXCEPTION_MAP = { - "!a = 1 + " => "Syntax error:\n1 +", - "!a = 1 + 2 +" => "Syntax error:\n1 + 2 +", - "!a = #aaa - a" => "Undefined operation:\n#afafaf minus a", - "!a = #aaa / a" => "Undefined operation:\n#afafaf div a", - "!a = #aaa * a" => "Undefined operation:\n#afafaf times a", - "!a = #aaa % a" => "Undefined operation:\n#afafaf mod a", - "!a = 1 - a" => "Undefined operation:\n1 minus a", - "!a = 1 * a" => "Undefined operation:\n1 times a", - "!a = 1 / a" => "Undefined operation:\n1 div a", - "!a = 1 % a" => "Undefined operation:\n1 mod a", + "!a = 1 + " => "Constant arithmetic error: 1 +", + "!a = 1 + 2 +" => "Constant arithmetic error: 1 + 2 +", + "!a = #aaa - a" => "Undefined operation: #afafaf minus a", + "!a = #aaa / a" => "Undefined operation: #afafaf div a", + "!a = #aaa * a" => "Undefined operation: #afafaf times a", + "!a = #aaa % a" => "Undefined operation: #afafaf mod a", + "!a = 1 - a" => "Undefined operation: 1 minus a", + "!a = 1 * a" => "Undefined operation: 1 times a", + "!a = 1 / a" => "Undefined operation: 1 div a", + "!a = 1 % a" => "Undefined operation: 1 mod a", } def test_basic_render @@ -24,11 +24,13 @@ class SassEngineTest < Test::Unit::TestCase def test_exceptions EXCEPTION_MAP.each do |key, value| - val_lines = value.split("\n") begin Sass::Engine.new(key).render - rescue RuntimeError => res_lines; end - val_lines.zip(res_lines.to_s.split("\n")) { |val, res| assert_equal(val, res) } + rescue Sass::SyntaxError => err + assert_equal(value, err.message) + else + assert(false, "Exception not raised!") + end end end diff --git a/test/sass/plugin_test.rb b/test/sass/plugin_test.rb index 47389a86..999d8b1e 100644 --- a/test/sass/plugin_test.rb +++ b/test/sass/plugin_test.rb @@ -35,7 +35,7 @@ class SassPluginTest < Test::Unit::TestCase def test_exception_handling File.open(tempfile_loc('bork')) do |file| - assert file.gets + file.gets == "Undefined constant:\n!bork\n" + assert_equal("Undefined constant: !bork", file.gets.strip) end File.delete(tempfile_loc('bork')) Sass.const_set('RAILS_ENV', 'production')