From c795f09f550364986be2f15948deb2393f4d1421 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafael=20Mendon=C3=A7a=20Fran=C3=A7a?= Date: Tue, 28 Feb 2012 11:29:59 -0300 Subject: [PATCH] Error handler --- lib/eex.ex | 12 +++++++++++- lib/eex/tokenizer.ex | 6 ++++++ test/elixir/eex/tokenizer_test.exs | 6 ++++++ test/elixir/eex_test.exs | 28 ++++++++++++++++++++++++++++ 4 files changed, 51 insertions(+), 1 deletion(-) diff --git a/lib/eex.ex b/lib/eex.ex index 49a63cd88a..5d50be7378 100644 --- a/lib/eex.ex +++ b/lib/eex.ex @@ -4,6 +4,8 @@ defmodule EEx do end end +defexception EEx::SyntaxError, message: nil + defmodule EEx::Compiler do def compile(source, engine) do tokens = EEx::Tokenizer.tokenize(source) @@ -40,10 +42,18 @@ defmodule EEx::Compiler do { buffer, t } end - defp generate_buffer([], _engine, buffer, _scope, _dict) do + defp generate_buffer([{ :end_expr, _, chars }|_], _engine, _buffer, [], _dict) do + raise SyntaxError, message: "unexpected token: #{inspect chars}" + end + + defp generate_buffer([], _engine, buffer, [], _dict) do buffer end + defp generate_buffer([], _engine, _buffer, _scope, _dict) do + raise SyntaxError, message: "undetermined end of string" + end + #### def wrap_expr(current, buffer, chars, dict) do diff --git a/lib/eex/tokenizer.ex b/lib/eex/tokenizer.ex index 08960a9e28..c0ea175694 100644 --- a/lib/eex/tokenizer.ex +++ b/lib/eex/tokenizer.ex @@ -61,6 +61,12 @@ defmodule EEx::Tokenizer do tokenize_expr t, [h|buffer] end + # Raise an error if the %> is not found + + defp tokenize_expr([], buffer) do + raise EEx::SyntaxError, message: "invalid token: #{inspect List.reverse(buffer)}" + end + # Receive an expression content and check # if it is a start or an end token. # Start tokens finish with `do` or `->` diff --git a/test/elixir/eex/tokenizer_test.exs b/test/elixir/eex/tokenizer_test.exs index ae1467b215..85a7a81724 100644 --- a/test/elixir/eex/tokenizer_test.exs +++ b/test/elixir/eex/tokenizer_test.exs @@ -48,4 +48,10 @@ defmodule EEx::TokenizerTest do { :end_expr, '', ' end ' } ], T.tokenize('foo <% if true do %>bar<% elsif: false %>baz<% end %>') end + + test "raise syntax error when there is start mark and no end mark" do + T.tokenize('foo <% :bar', 1) + rescue: error in [EEx::SyntaxError] + assert_equal "invalid token: ' :bar'", error.message + end end diff --git a/test/elixir/eex_test.exs b/test/elixir/eex_test.exs index 49d8000e7c..3d215329cb 100644 --- a/test/elixir/eex_test.exs +++ b/test/elixir/eex_test.exs @@ -52,6 +52,34 @@ defmodule EExTest do assert_eval "foo 1,2,3", "foo <% require Enum, as: E %><%= E.join [1,2,3], \",\" %>" end + test "compile with end of token" do + assert_eval "foo bar %>", "foo bar %>" + end + + test "raises a syntax error when the token is invalid" do + EEx.compile "foo <%= bar" + rescue: error in [EEx::SyntaxError] + assert_equal "invalid token: ' bar'", error.message + end + + test "raises a syntax error when end expression is found without a start expression" do + EEx.compile "foo <% end %>" + rescue: error in [EEx::SyntaxError] + assert_equal "unexpected token: ' end '", error.message + end + + test "raises a syntax error when start expression is found without an end expression" do + EEx.compile "foo <% if true do %>" + rescue: error in [EEx::SyntaxError] + assert_equal "undetermined end of string", error.message + end + + test "raises a syntax error when nested end expression is found without an start expression" do + EEx.compile "foo <%if true do %><% end %><% end %>" + rescue: error in [EEx::SyntaxError] + assert_equal "unexpected token: ' end '", error.message + end + defp assert_eval(expected, atual) do compiled = EEx.compile(atual) { result, _ } = Code.eval_quoted(compiled, [], __FILE__, __LINE__)