diff --git a/lib/sass/constant.rb b/lib/sass/constant.rb index 6c03dc1d..1784ba97 100644 --- a/lib/sass/constant.rb +++ b/lib/sass/constant.rb @@ -126,12 +126,12 @@ module Sass Literal.parse(insert_constant(value, constants)) end elsif length == 2 - raise SyntaxError.new("Constant arithmetic error: #{original}") + raise SyntaxError.new("Constant arithmetic error: \"#{original}\"") elsif length == 3 Operation.new(operationalize(value[0], original, constants), operationalize(value[2], original, constants), value[1]) else unless length >= 5 && length % 2 == 1 - raise SyntaxError.new("Constant arithmetic error: #{original}") + raise SyntaxError.new("Constant arithmetic error: \"#{original}\"") 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) @@ -146,7 +146,7 @@ module Sass if value[0] == CONSTANT_CHAR to_return = constants[value[1..-1]] unless to_return - raise SyntaxError.new("Undefined constant: #{value}") + raise SyntaxError.new("Undefined constant: \"#{value}\"") end end to_return diff --git a/lib/sass/constant/operation.rb b/lib/sass/constant/operation.rb index 0295a4f4..2374f61a 100644 --- a/lib/sass/constant/operation.rb +++ b/lib/sass/constant/operation.rb @@ -23,7 +23,7 @@ module Sass::Constant literal1.send(@operator, literal2) rescue NoMethodError => e raise e unless e.name == @operator - raise Sass::SyntaxError.new("Undefined operation: #{literal1} #{@operator} #{literal2}") + raise Sass::SyntaxError.new("Undefined operation: \"#{literal1} #{@operator} #{literal2}\"") end end end diff --git a/lib/sass/engine.rb b/lib/sass/engine.rb index f7f41b42..4d9052cc 100644 --- a/lib/sass/engine.rb +++ b/lib/sass/engine.rb @@ -64,6 +64,7 @@ module Sass # Readies each line in the template for parsing, # and computes the tabulation of the line. def split_lines + old_tabs = 0 @template.each_with_index do |line, index| @line = index + 1 @@ -73,7 +74,12 @@ module Sass tabs = count_tabs(line) if tabs # if line isn't blank + if tabs - old_tabs > 1 + raise SyntaxError.new("Illegal Indentation: Only two space characters are allowed as tabulation.") + end @lines << [line.strip, tabs] + + old_tabs = tabs end end end @@ -84,7 +90,7 @@ module Sass def count_tabs(line) spaces = line.index(/[^ ]/) if spaces - if line[spaces] == ?\t + if spaces % 2 == 1 || line[spaces] == ?\t raise SyntaxError.new("Illegal Indentation: Only two space characters are allowed as tabulation.") end spaces / 2 @@ -151,7 +157,7 @@ module Sass def parse_constant(line) name, value = line.scan(Sass::Constant::MATCH)[0] unless name && value - raise SyntaxError.new("Invalid constant: #{line}", @line) + raise SyntaxError.new("Invalid constant: \"#{line}\"", @line) end @constants[name] = Sass::Constant.parse(value, @constants, @line) nil diff --git a/lib/sass/tree/attr_node.rb b/lib/sass/tree/attr_node.rb index 8b75f02a..9db036aa 100644 --- a/lib/sass/tree/attr_node.rb +++ b/lib/sass/tree/attr_node.rb @@ -18,7 +18,7 @@ module Sass::Tree to_return[0...-1] else if value.length < 1 - raise SyntaxError.new("Invalid attribute: \":#{name} #{value}\"", @line) + raise Sass::SyntaxError.new("Invalid attribute: \":#{name} #{value}\"", @line) end "#{real_name}: #{value};" diff --git a/test/sass/engine_test.rb b/test/sass/engine_test.rb index 9540c848..ec390d27 100644 --- a/test/sass/engine_test.rb +++ b/test/sass/engine_test.rb @@ -6,16 +6,28 @@ require 'sass/engine' class SassEngineTest < Test::Unit::TestCase EXCEPTION_MAP = { - "!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", + "!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"', + ":" => 'Invalid attribute: ":"', + ": a" => 'Invalid attribute: ": a"', + ":= a" => 'Invalid attribute: ":= a"', + "a\n :b" => 'Invalid attribute: ":b "', + ":a" => 'Attributes aren\'t allowed at the root of a document.', + "!" => 'Invalid constant: "!"', + "!a" => 'Invalid constant: "!a"', + "! a" => 'Invalid constant: "! a"', + "!a b" => 'Invalid constant: "!a b"', + "a\n\t:b c" => "Illegal Indentation: Only two space characters are allowed as tabulation.", + "a\n :b c" => "Illegal Indentation: Only two space characters are allowed as tabulation.", + "a\n :b c" => "Illegal Indentation: Only two space characters are allowed as tabulation.", } def test_basic_render @@ -29,10 +41,21 @@ class SassEngineTest < Test::Unit::TestCase rescue Sass::SyntaxError => err assert_equal(value, err.message) else - assert(false, "Exception not raised!") + assert(false, "Exception not raised for '#{key}'!") end end end + + def test_exception_line + to_render = "rule\n :attr val\n :broken\n" + begin + Sass::Engine.new(to_render).render + rescue Sass::SyntaxError => err + assert_equal(3, err.sass_line) + else + assert(false, "Exception not raised for '#{to_render}'!") + end + end private diff --git a/test/sass/plugin_test.rb b/test/sass/plugin_test.rb index 999d8b1e..f8b73973 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_equal("Undefined constant: !bork", file.gets.strip) + assert_equal("Undefined constant: \"!bork\"", file.gets.strip) end File.delete(tempfile_loc('bork')) Sass.const_set('RAILS_ENV', 'production')