Невозможно установить SyntaxError в ExUnit

Вот код, который я тестирую:

defmodule BracketParser do
    @spec parse_line(binary) :: binary
    def parse_line(line), do: parse_line_as_list(String.graphemes(line), false, [])
    defp parse_line_as_list([], true, _acc) do
        IO.puts("hello")
        raise SyntaxError
    end
    defp parse_line_as_list([], _collect, acc) do
        Enum.reverse(acc) |> IO.iodata_to_binary
    end
    defp parse_line_as_list(["{" | t], _collect, acc) do
        parse_line_as_list(t, true, acc)
    end
    defp parse_line_as_list(["}" | t], _collect, acc) do
        parse_line_as_list(t, false, acc)
    end
    defp parse_line_as_list([h | t], true, acc) do
        parse_line_as_list(t, true, [h | acc])
    end
    defp parse_line_as_list([_h | t], collect, acc) do
        parse_line_as_list(t, collect, acc)
    end
end

Это мой тест:

ExUnit.start

defmodule TestBracketParser do
    use ExUnit.Case

    test "should get the text inside a pair of brackets" do
        assert_raise SyntaxError, fn() -> BracketParser.parse_line("{bill") end
    end
end

Цель состоит в том, чтобы иметь синтаксический анализатор, который собирает текст между {} символы. Я ожидаю, что код вызовет синтаксическую ошибку, если список пуст и флаг коллекции установлен в значение true. Однако, когда я запускаю этот код, я получаю это:

  1) test should get the text inside a pair of brackets (TestBracketParser)
     test_parse_brackets.exs:6
     Got exception SyntaxError but it failed to produce a message with:

     ** (FunctionClauseError) no function clause matching in IO.chardata_to_string/1
         (elixir) lib/io.ex:461: IO.chardata_to_string(nil)
         (elixir) lib/path.ex:312: Path.relative_to/2
         (elixir) lib/exception.ex:713: SyntaxError.message/1
         (ex_unit) lib/ex_unit/assertions.ex:658: ExUnit.Assertions.check_error_message/2
         (ex_unit) lib/ex_unit/assertions.ex:639: ExUnit.Assertions.assert_raise/2
         test_parse_brackets.exs:10: TestBracketParser."test should get the text inside a pair of brackets"/1
         (ex_unit) lib/ex_unit/runner.ex:306: ExUnit.Runner.exec_test/1
         (stdlib) timer.erl:166: :timer.tc/1
         (ex_unit) lib/ex_unit/runner.ex:245: anonymous fn/4 in ExUnit.Runner.spawn_test/3

Я понятия не имею, почему существует FunctionClauseError быть брошенным Кажется, я учел все закономерности. Что я делаю неправильно?

1 ответ

В качестве документации для raise состояния,

Если msg это атом, он просто вызывает raise/2 с атомом в качестве первого аргумента и [] в качестве второго аргумента.

raise/2 позвоню exception/1 функция на аргумент.

В вашем случае вы должны использовать raise "SyntaxError" или предоставить модуль под названием SyntaxError что вызывает defexception/1,

Другие вопросы по тегам