From e1fbf751d5f7dfd08fe95a48269f144626b4ec3d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Przemys=C5=82aw=20Wojtasik?= Date: Fri, 18 Feb 2022 14:00:52 +0100 Subject: [PATCH 1/3] Add double quote atoms --- lib/gradient/elixir_expr.ex | 4 ++-- lib/gradient/elixir_type.ex | 5 ++++- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/lib/gradient/elixir_expr.ex b/lib/gradient/elixir_expr.ex index a28c30ca..0c64b315 100644 --- a/lib/gradient/elixir_expr.ex +++ b/lib/gradient/elixir_expr.ex @@ -35,7 +35,7 @@ defmodule Gradient.ElixirExpr do def pp_expr({:atom, _, val}) do case Atom.to_string(val) do "Elixir." <> mod -> mod - str -> ":" <> str + str -> ":\"" <> str <> "\"" end end @@ -420,7 +420,7 @@ defmodule Gradient.ElixirExpr do if shortand_syntax do {:atom, _, key} = key - Atom.to_string(key) <> ": " <> value + "\"" <> Atom.to_string(key) <> "\": " <> value else pp_expr(key) <> " => " <> value end diff --git a/lib/gradient/elixir_type.ex b/lib/gradient/elixir_type.ex index a6022f9d..3731a727 100644 --- a/lib/gradient/elixir_type.ex +++ b/lib/gradient/elixir_type.ex @@ -84,7 +84,10 @@ defmodule Gradient.ElixirType do end def pretty_print({:atom, _, val}) do - ":" <> Atom.to_string(val) + case Atom.to_string(val) do + "Elixir." <> mod -> mod + str -> ":\"" <> str <> "\"" + end end def pretty_print({:integer, _, val}) do From f678b91bfc2f730a97b60ce32c0a92826d057ffc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Przemys=C5=82aw=20Wojtasik?= Date: Fri, 18 Feb 2022 14:02:58 +0100 Subject: [PATCH 2/3] Make ElixirFmt ANSI colours configurable --- lib/gradient/elixir_expr.ex | 2 +- lib/gradient/elixir_fmt.ex | 109 +++++++++++++++++++++++++++--------- lib/gradient/elixir_type.ex | 17 ++++-- lib/gradient/types.ex | 1 + 4 files changed, 95 insertions(+), 34 deletions(-) diff --git a/lib/gradient/elixir_expr.ex b/lib/gradient/elixir_expr.ex index 0c64b315..d7aaf57c 100644 --- a/lib/gradient/elixir_expr.ex +++ b/lib/gradient/elixir_expr.ex @@ -11,7 +11,7 @@ defmodule Gradient.ElixirExpr do @doc """ Convert abstract expressions to Elixir code and format output with formatter. """ - @spec pp_expr_format([expr()], keyword()) :: iodata() + @spec pp_expr_format(expr() | [expr()], keyword()) :: iodata() def pp_expr_format(exprs, fmt_opts \\ []) do exprs |> pp_expr() diff --git a/lib/gradient/elixir_fmt.ex b/lib/gradient/elixir_fmt.ex index 372fbef8..40c6f9bd 100644 --- a/lib/gradient/elixir_fmt.ex +++ b/lib/gradient/elixir_fmt.ex @@ -1,12 +1,40 @@ defmodule Gradient.ElixirFmt do @moduledoc """ - Module that handles formatting and printing error messages produced by Gradient in Elixir. + Module that handles formatting and printing error messages produced by Gradualizer in Elixir. + + Options: + - `ex_colors`: list of color options: + - {`use_colors`, boolean()}: - wheather to use the colors, default: true + - {`expression`, ansicode()}: color of the expressions, default: :yellow + - {`type`, ansicode()}: color of the types, default: :cyan + - {`underscored_line`, ansicode()}: color of the underscored line pointed the error in code, default: :red + + - `ex_fmt_expr_fun`: function to pretty print an expression AST in Elixir `(abstract_expr()) -> iodata()`. + + - `ex_fmt_type_fun`: function to pretty print an type AST in Elixir `(abstract_type() -> iodata())`. + + - Gradualizer options, but some of them are overwritten by Gradient. """ @behaviour Gradient.Fmt alias :gradualizer_fmt, as: FmtLib alias Gradient.ElixirType alias Gradient.ElixirExpr + alias Gradient.Types + + @type colors_opts() :: [ + use_colors: boolean(), + expression: IO.ANSI.ansicode(), + type: IO.ANSI.ansicode(), + underscored_line: IO.ANSI.ansicode() + ] + @type options() :: [ + ex_colors: colors_opts(), + ex_fmt_type_fun: (Types.abstract_type() -> iodata()), + ex_fmt_expr_fun: (Types.abstract_expr() -> iodata()) + ] + + @default_colors [use_colors: true, expression: :yellow, type: :cyan, underscored_line: :red] def print_errors(errors, opts) do for {file, e} <- errors do @@ -29,8 +57,9 @@ defmodule Gradient.ElixirFmt do end def format_error(error, opts) do - opts = Keyword.put_new(opts, :fmt_type_fun, &ElixirType.pretty_print/1) - opts = Keyword.put_new(opts, :fmt_expr_fun, &ElixirExpr.pp_expr/1) + opts = Keyword.put_new(opts, :color, false) + opts = Keyword.put_new(opts, :fmt_type_fun, pp_type_fun(opts)) + opts = Keyword.put_new(opts, :fmt_expr_fun, pp_expr_fun(opts)) format_type_error(error, opts) end @@ -120,7 +149,7 @@ defmodule Gradient.ElixirFmt do def format_expr_type_error(expression, actual_type, expected_type, opts) do {inline_expr, fancy_expr} = case try_highlight_in_context(expression, opts) do - {:error, _e} -> {" " <> pp_expr(expression, opts), ""} + {:error, _e} -> {[" " | pp_expr(expression, opts)], ""} {:ok, fancy} -> {"", fancy} end @@ -145,26 +174,48 @@ defmodule Gradient.ElixirFmt do end end - def pp_expr(expression, opts) do - fmt = Keyword.get(opts, :fmt_expr_fun, &ElixirExpr.pp_expr/1) + def pp_expr_fun(opts) do + fmt = Keyword.get(opts, :ex_fmt_expr_fun, &ElixirExpr.pp_expr_format/1) + colors = get_colors_with_default(opts) + {:ok, use_colors} = Keyword.fetch(colors, :use_colors) + {:ok, expr_color} = Keyword.fetch(colors, :expression) - if Keyword.get(opts, :colors, true) do - IO.ANSI.blue() <> fmt.(expression) <> IO.ANSI.reset() - else - fmt.(expression) + fn expression -> + IO.ANSI.format([expr_color, fmt.(expression)], use_colors) end end - def pp_type(type, opts) do - fmt = Keyword.get(opts, :fmt_type_fun, &ElixirType.pretty_print/1) + def pp_type_fun(opts) do + fmt = Keyword.get(opts, :ex_fmt_type_fun, &ElixirType.pp_type_format/1) + colors = get_colors_with_default(opts) + {:ok, use_colors} = Keyword.fetch(colors, :use_colors) + {:ok, type_color} = Keyword.fetch(colors, :type) - if Keyword.get(opts, :colors, true) do - IO.ANSI.cyan() <> fmt.(type) <> IO.ANSI.reset() - else - fmt.(type) + fn type -> + IO.ANSI.format([type_color, fmt.(type)], use_colors) end end + def get_colors_with_default(opts) do + case Keyword.fetch(opts, :ex_colors) do + {:ok, colors} -> + colors ++ @default_colors + + _ -> + @default_colors + end + end + + def pp_expr(expression, opts) do + pp_expr_fun(opts).(expression) + end + + def pp_type(type, opts) do + pp_type_fun(opts).(type) + end + + @spec try_highlight_in_context(Types.abstract_expr(), options()) :: + {:ok, iodata()} | {:error, term()} def try_highlight_in_context(expression, opts) do forms = Keyword.get(opts, :forms) @@ -172,7 +223,7 @@ defmodule Gradient.ElixirFmt do {:ok, path} <- get_ex_file_path(forms), {:ok, code} <- File.read(path) do code_lines = String.split(code, ~r/\R/) - {:ok, highlight_in_context(expression, code_lines)} + {:ok, highlight_in_context(expression, code_lines, opts)} end end @@ -184,14 +235,14 @@ defmodule Gradient.ElixirFmt do end end - @spec highlight_in_context(tuple(), [String.t()]) :: String.t() - def highlight_in_context(expression, context) do + @spec highlight_in_context(tuple(), [String.t()], options()) :: iodata() + def highlight_in_context(expression, context, opts) do line = elem(expression, 1) context |> Enum.with_index(1) |> filter_context(line, 2) - |> underscore_line(line) + |> underscore_line(line, opts) |> Enum.join("\n") end @@ -202,10 +253,19 @@ defmodule Gradient.ElixirFmt do Enum.filter(lines, fn {_, number} -> number in range end) end - def underscore_line(lines, line) do + def underscore_line(lines, line, opts) do Enum.map(lines, fn {str, n} -> if(n == line) do - IO.ANSI.underline() <> IO.ANSI.red() <> to_string(n) <> " " <> str <> IO.ANSI.reset() + colors = get_colors_with_default(opts) + {:ok, use_colors} = Keyword.fetch(colors, :use_colors) + {:ok, color} = Keyword.fetch(colors, :underscored_line) + line_str = to_string(n) <> " " <> str + + [ + IO.ANSI.underline(), + IO.ANSI.format_fragment([color, line_str], use_colors), + IO.ANSI.reset() + ] else to_string(n) <> " " <> str end @@ -225,11 +285,6 @@ defmodule Gradient.ElixirFmt do end end - # defp warning_error_not_handled(error) do - # msg = "\nElixir formatter not exist for #{inspect(error, pretty: true)} using default \n" - # String.to_charlist(IO.ANSI.light_yellow() <> msg <> IO.ANSI.reset()) - # end - @spec describe_expr(:gradualizer_type.abstract_expr()) :: binary() def describe_expr({:atom, _, _}), do: "atom" def describe_expr({:bc, _, _, _}), do: "binary comprehension" diff --git a/lib/gradient/elixir_type.ex b/lib/gradient/elixir_type.ex index 3731a727..e1608bd1 100644 --- a/lib/gradient/elixir_type.ex +++ b/lib/gradient/elixir_type.ex @@ -1,17 +1,22 @@ defmodule Gradient.ElixirType do @moduledoc """ - Module to format types. - - Seems that: - - record type - - constrained function type - are not used by Elixir so the pp support has not been added. + Convert the Erlang abstract types to the Elixir code. """ alias Gradient.ElixirFmt @type abstract_type() :: Gradient.Types.abstract_type() + @doc """ + Convert abstract type to Elixir code and format output with formatter. + """ + @spec pp_type_format(abstract_type(), keyword()) :: iodata() + def pp_type_format(type, fmt_opts \\ []) do + type + |> pretty_print() + |> Code.format_string!(fmt_opts) + end + @doc """ Take type and prepare a pretty string representation. """ diff --git a/lib/gradient/types.ex b/lib/gradient/types.ex index caea73bf..c1348ad8 100644 --- a/lib/gradient/types.ex +++ b/lib/gradient/types.ex @@ -2,6 +2,7 @@ defmodule Gradient.Types do @type token :: tuple() @type tokens :: [tuple()] @type abstract_type :: :erl_parse.abstract_type() + @type abstract_expr :: :erl_parse.abstract_expr() @type form :: :erl_parse.abstract_clause() | :erl_parse.abstract_expr() From 2e6eea3ce2dc1c59fabf496fbfe58a200eebf600 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Przemys=C5=82aw=20Wojtasik?= Date: Fri, 18 Feb 2022 14:03:52 +0100 Subject: [PATCH 3/3] Adapt tests --- test/gradient/elixir_expr_test.exs | 30 ++++++++++---------- test/gradient/elixir_fmt_test.exs | 12 ++++---- test/support/expr_data.ex | 45 +++++++++++++++--------------- test/support/type_data.ex | 8 +++--- 4 files changed, 48 insertions(+), 47 deletions(-) diff --git a/test/gradient/elixir_expr_test.exs b/test/gradient/elixir_expr_test.exs index 619acf7b..fbb97c71 100644 --- a/test/gradient/elixir_expr_test.exs +++ b/test/gradient/elixir_expr_test.exs @@ -45,7 +45,7 @@ defmodule Gradient.ElixirExprTest do end |> ElixirExpr.pp_expr() - assert "fn {:ok, v} -> v; {:error, _} -> :error end" == actual + assert ~s(fn {:"ok", v} -> v; {:"error", _} -> :"error" end) == actual end test "binary comprehension" do @@ -79,7 +79,7 @@ defmodule Gradient.ElixirExprTest do end |> ElixirExpr.pp_expr() - assert "receive do {:hello, msg} -> msg end" == actual + assert ~s(receive do {:"hello", msg} -> msg end) == actual end test "receive after" do @@ -93,7 +93,7 @@ defmodule Gradient.ElixirExprTest do end |> ElixirExpr.pp_expr() - assert ~s(receive do {:hello, msg} -> msg after 1000 -> "nothing happened" end) == actual + assert ~s(receive do {:"hello", msg} -> msg after 1000 -> "nothing happened" end) == actual end test "call pipe" do @@ -123,7 +123,7 @@ defmodule Gradient.ElixirExprTest do end |> ElixirExpr.pp_expr() - assert "map = %{a: 12, b: 0}; case :maps.find(:a, map) do {:ok, a} -> case :maps.find(:b, map) do {:ok, b} -> a + b; _gen -> case _gen do :error -> 0; _gen -> raise {:with_clause, _gen} end end; _gen -> case _gen do :error -> 0; _gen -> raise {:with_clause, _gen} end end" == + assert ~s(map = %{"a": 12, "b": 0}; case :maps.find(:"a", map\) do {:"ok", a} -> case :maps.find(:"b", map\) do {:"ok", b} -> a + b; _gen -> case _gen do :"error" -> 0; _gen -> raise {:"with_clause", _gen} end end; _gen -> case _gen do :"error" -> 0; _gen -> raise {:"with_clause", _gen} end end) == actual end @@ -140,7 +140,7 @@ defmodule Gradient.ElixirExprTest do end |> ElixirExpr.pp_expr() - assert ~s(try do raise "ok"; catch :error, e -> IO.puts(Exception.format(:error, e, __STACKTRACE__\)\); reraise e, __STACKTRACE__ end) == + assert ~s(try do raise "ok"; catch :"error", e -> IO.puts(Exception.format(:"error", e, __STACKTRACE__\)\); reraise e, __STACKTRACE__ end) == actual end @@ -155,7 +155,7 @@ defmodule Gradient.ElixirExprTest do end |> ElixirExpr.pp_expr() - assert ~s(try do raise "oops"; catch :error, %RuntimeError{} = _ -> "Error!" end) == + assert ~s(try do raise "oops"; catch :"error", %RuntimeError{} = _ -> "Error!" end) == actual end @@ -170,7 +170,7 @@ defmodule Gradient.ElixirExprTest do end |> ElixirExpr.pp_expr() - assert "try do :ok; catch :error, _ -> :ok end" == actual + assert ~s(try do :"ok"; catch :"error", _ -> :"ok" end) == actual end test "simple after try" do @@ -184,7 +184,7 @@ defmodule Gradient.ElixirExprTest do end |> ElixirExpr.pp_expr() - assert "try do :ok; after :ok end" == actual + assert ~s(try do :"ok"; after :"ok" end) == actual end test "try guard" do @@ -215,7 +215,7 @@ defmodule Gradient.ElixirExprTest do end |> ElixirExpr.pp_expr() - assert ~s(try do throw "good"; :ok; else v when v == :ok -> :ok; v -> :nok; catch :error, %RuntimeError{} = e -> 11; e; :throw, val -> val; :throw, _ -> 0; after IO.puts("Cleaning!"\) end) == + assert ~s(try do throw "good"; :"ok"; else v when v == :"ok" -> :"ok"; v -> :"nok"; catch :"error", %RuntimeError{} = e -> 11; e; :"throw", val -> val; :"throw", _ -> 0; after IO.puts("Cleaning!"\) end) == actual end @@ -235,7 +235,7 @@ defmodule Gradient.ElixirExprTest do end |> ElixirExpr.pp_expr() - assert "case {:ok, 10} do {:ok, v} when v > 0 and v > 1 or v < - 1 -> :ok; t when :erlang.is_tuple(t) -> :nok; _ -> :err end" == + assert ~s(case {:"ok", 10} do {:"ok", v} when v > 0 and v > 1 or v < - 1 -> :"ok"; t when :erlang.is_tuple(t\) -> :"nok"; _ -> :"err" end) == actual end @@ -249,7 +249,7 @@ defmodule Gradient.ElixirExprTest do end |> ElixirExpr.pp_expr() - assert "case {:ok, 13} do {:ok, v} -> v; _err -> :error end" == actual + assert ~s(case {:"ok", 13} do {:"ok", v} -> v; _err -> :"error" end) == actual end test "if" do @@ -263,7 +263,7 @@ defmodule Gradient.ElixirExprTest do end |> ElixirExpr.pp_expr() - assert "if :math.floor(1.9) == 1.0 do :ok else :error end" == actual + assert ~s(if :math.floor(1.9\) == 1.0 do :"ok" else :"error" end) == actual end test "unless" do @@ -277,7 +277,7 @@ defmodule Gradient.ElixirExprTest do end |> ElixirExpr.pp_expr() - assert "if :math.floor(1.9) == 1.0 do :error else :ok end" == actual + assert ~s(if :math.floor(1.9\) == 1.0 do :"error" else :"ok" end) == actual end test "cond" do @@ -296,7 +296,7 @@ defmodule Gradient.ElixirExprTest do end |> ElixirExpr.pp_expr() - assert "cond do true == false -> :ok; :math.floor(1.9) == 1.0 -> :ok; true -> :error end" == + assert ~s(cond do true == false -> :"ok"; :math.floor\(1.9\) == 1.0 -> :"ok"; true -> :"error" end) == actual end @@ -322,7 +322,7 @@ defmodule Gradient.ElixirExprTest do |> ElixirExpr.pp_expr() assert ~s(try do if true do throw "good" else raise "oops" end;) <> - ~s( catch :error, %RuntimeError{} = e -> 11; e; :throw, val -> 12; val end) == + ~s( catch :"error", %RuntimeError{} = e -> 11; e; :"throw", val -> 12; val end) == actual end end diff --git a/test/gradient/elixir_fmt_test.exs b/test/gradient/elixir_fmt_test.exs index 78eafb14..c8e67001 100644 --- a/test/gradient/elixir_fmt_test.exs +++ b/test/gradient/elixir_fmt_test.exs @@ -209,7 +209,7 @@ defmodule Gradient.ElixirFmtTest do test "string", %{wrong_ret_errors: errors} do expr = expr_format_error_to_binary(errors.ret_wrong_boolean2) - assert String.contains?(expr, "\"1234\"") + assert String.contains?(expr, ~s("1234")) end test "char", %{wrong_ret_errors: errors} do @@ -225,7 +225,7 @@ defmodule Gradient.ElixirFmtTest do test "record", %{record_type_errors: errors} do expr = expr_format_error_to_binary(errors.ret_wrong_atom) - assert String.contains?(expr, "{:user, \"Kate\", 25}") + assert String.contains?(expr, ~s({:user, "Kate", 25})) end test "call", %{wrong_ret_errors: errors} do @@ -270,8 +270,8 @@ defmodule Gradient.ElixirFmtTest do end defp expr_format_error_to_binary(error, opts \\ []) do - opts = Keyword.put_new(opts, :fmt_type_fun, &mock_fmt/1) - opts = Keyword.put_new(opts, :colors, false) + opts = Keyword.put_new(opts, :ex_fmt_type_fun, &mock_fmt/1) + opts = Keyword.put_new(opts, :ex_colors, use_colors: false) error |> ElixirFmt.format_error(opts) @@ -281,8 +281,8 @@ defmodule Gradient.ElixirFmtTest do end defp type_format_error_to_binary(error, opts \\ []) do - opts = Keyword.put_new(opts, :fmt_expr_fun, &mock_fmt/1) - opts = Keyword.put_new(opts, :colors, false) + opts = Keyword.put_new(opts, :ex_fmt_expr_fun, &mock_fmt/1) + opts = Keyword.put_new(opts, :ex_colors, use_colors: false) error |> ElixirFmt.format_error(opts) diff --git a/test/support/expr_data.ex b/test/support/expr_data.ex index 7be58f73..57691569 100644 --- a/test/support/expr_data.ex +++ b/test/support/expr_data.ex @@ -20,7 +20,7 @@ defmodule Gradient.ExprData do def value_test_data() do [ - {"geric atom", {:atom, 0, :fjdksaose}, ":fjdksaose"}, + {"geric atom", {:atom, 0, :fjdksaose}, ~s(:"fjdksaose")}, {"module atom", {:atom, 0, Gradient.ElixirExpr}, "Gradient.ElixirExpr"}, {"nil atom", {:atom, 0, nil}, "nil"}, {"true atom", {:atom, 0, true}, "true"}, @@ -42,7 +42,7 @@ defmodule Gradient.ExprData do {:cons, 0, {:integer, 0, 1}, {:cons, 0, {:integer, 0, 2}, {nil, 0}}}}, "[0, 1, 2]"}, {"mixed list", {:cons, 0, {:integer, 0, 0}, - {:cons, 0, {:atom, 0, :ok}, {:cons, 0, {:integer, 0, 2}, {nil, 0}}}}, "[0, :ok, 2]"}, + {:cons, 0, {:atom, 0, :ok}, {:cons, 0, {:integer, 0, 2}, {nil, 0}}}}, ~s([0, :"ok", 2])}, {"var in list", {:cons, 0, {:integer, 0, 0}, {:cons, 0, {:var, 0, :a}, {nil, 0}}}, "[0, a]"}, {"list tail pm", elixir_to_ast([a | t] = [12, 13, 14]), "[a | t] = [12, 13, 14]"}, @@ -71,7 +71,7 @@ defmodule Gradient.ExprData do def exception_test_data() do [ - {"throw", elixir_to_ast(throw({:ok, 12})), "throw {:ok, 12}"}, + {"throw", elixir_to_ast(throw({:ok, 12})), ~s(throw {:"ok", 12})}, {"raise/1", elixir_to_ast(raise "test error"), ~s(raise "test error")}, {"raise/1 without msg", elixir_to_ast(raise RuntimeError), "raise RuntimeError"}, {"raise/2", elixir_to_ast(raise RuntimeError, "test error"), ~s(raise "test error")}, @@ -95,10 +95,10 @@ defmodule Gradient.ExprData do def map_test_data do [ {"string map", elixir_to_ast(%{"a" => 12}), ~s(%{"a" => 12})}, - {"map pm", elixir_to_ast(%{a: a} = %{a: 12}), "%{a: a} = %{a: 12}"}, - {"update map", elixir_to_ast(%{%{} | a: 1}), "%{%{} | a: 1}"}, + {"map pm", elixir_to_ast(%{a: a} = %{a: 12}), ~s(%{"a": a} = %{"a": 12})}, + {"update map", elixir_to_ast(%{%{} | a: 1}), ~s(%{%{} | "a": 1})}, {"struct expr", elixir_to_ast(%{__struct__: TestStruct, name: "John"}), - ~s(%TestStruct{name: "John"})} + ~s(%TestStruct{"name": "John"})} ] end @@ -118,16 +118,16 @@ defmodule Gradient.ExprData do "\"String without escape codes \\x26 without \#{interpolation}\""}, {"char lists", elixir_to_ast(~c(this is a char list containing 'single quotes')), "'this is a char list containing \\'single quotes\\''"}, - {"word list", elixir_to_ast(~w(foo bar bat)), "[\"foo\", \"bar\", \"bat\"]"}, - {"word list atom", elixir_to_ast(~w(foo bar bat)a), "[:foo, :bar, :bat]"}, + {"word list", elixir_to_ast(~w(foo bar bat)), ~s(["foo", "bar", "bat"])}, + {"word list atom", elixir_to_ast(~w(foo bar bat)a), ~s([:"foo", :"bar", :"bat"])}, {"date", elixir_to_ast(~D[2019-10-31]), - "%Date{calendar: Calendar.ISO, year: 2019, month: 10, day: 31}"}, + ~s(%Date{"calendar": Calendar.ISO, "year": 2019, "month": 10, "day": 31})}, {"time", elixir_to_ast(~T[23:00:07.0]), - "%Time{calendar: Calendar.ISO, hour: 23, minute: 0, second: 7, microsecond: {0, 1}}"}, + ~s(%Time{"calendar": Calendar.ISO, "hour": 23, "minute": 0, "second": 7, "microsecond": {0, 1}})}, {"naive date time", elixir_to_ast(~N[2019-10-31 23:00:07]), - "%NaiveDateTime{calendar: Calendar.ISO, year: 2019, month: 10, day: 31, hour: 23, minute: 0, second: 7, microsecond: {0, 0}}"}, + ~s(%NaiveDateTime{"calendar": Calendar.ISO, "year": 2019, "month": 10, "day": 31, "hour": 23, "minute": 0, "second": 7, "microsecond": {0, 0}})}, {"date time", elixir_to_ast(~U[2019-10-31 19:59:03Z]), - "%DateTime{calendar: Calendar.ISO, year: 2019, month: 10, day: 31, hour: 19, minute: 59, second: 3, microsecond: {0, 0}, time_zone: \"Etc/UTC\", zone_abbr: \"UTC\", utc_offset: 0, std_offset: 0}"} + ~s(%DateTime{"calendar": Calendar.ISO, "year": 2019, "month": 10, "day": 31, "hour": 19, "minute": 59, "second": 3, "microsecond": {0, 0}, "time_zone": "Etc/UTC", "zone_abbr": "UTC", "utc_offset": 0, "std_offset": 0})} ] end @@ -195,15 +195,16 @@ defmodule Gradient.ExprData do end defp regex_exp() do - <<37, 82, 101, 103, 101, 120, 123, 111, 112, 116, 115, 58, 32, 60, 60, 62, 62, 44, 32, 114, - 101, 95, 112, 97, 116, 116, 101, 114, 110, 58, 32, 123, 58, 114, 101, 95, 112, 97, 116, 116, - 101, 114, 110, 44, 32, 48, 44, 32, 48, 44, 32, 48, 44, 32, 34, 69, 82, 67, 80, 86, 0, 0, 0, - 0, 0, 0, 0, 1, 0, 0, 0, 195, 191, 195, 191, 195, 191, 195, 191, 195, 191, 195, 191, 195, - 191, 195, 191, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 194, 131, 0, 9, 29, 102, 29, 111, 29, 111, 119, - 0, 9, 29, 98, 29, 97, 29, 114, 120, 0, 18, 0, 34, 125, 44, 32, 114, 101, 95, 118, 101, 114, - 115, 105, 111, 110, 58, 32, 123, 34, 56, 46, 52, 52, 32, 50, 48, 50, 48, 45, 48, 50, 45, 49, - 50, 34, 44, 32, 58, 108, 105, 116, 116, 108, 101, 125, 44, 32, 115, 111, 117, 114, 99, 101, - 58, 32, 34, 102, 111, 111, 124, 98, 97, 114, 34, 125>> + <<37, 82, 101, 103, 101, 120, 123, 34, 111, 112, 116, 115, 34, 58, 32, 60, 60, 62, 62, 44, 32, + 34, 114, 101, 95, 112, 97, 116, 116, 101, 114, 110, 34, 58, 32, 123, 58, 34, 114, 101, 95, + 112, 97, 116, 116, 101, 114, 110, 34, 44, 32, 48, 44, 32, 48, 44, 32, 48, 44, 32, 34, 69, + 82, 67, 80, 86, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 195, 191, 195, 191, 195, 191, 195, 191, + 195, 191, 195, 191, 195, 191, 195, 191, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 64, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 194, 131, 0, 9, 29, + 102, 29, 111, 29, 111, 119, 0, 9, 29, 98, 29, 97, 29, 114, 120, 0, 18, 0, 34, 125, 44, 32, + 34, 114, 101, 95, 118, 101, 114, 115, 105, 111, 110, 34, 58, 32, 123, 34, 56, 46, 52, 52, + 32, 50, 48, 50, 48, 45, 48, 50, 45, 49, 50, 34, 44, 32, 58, 34, 108, 105, 116, 116, 108, + 101, 34, 125, 44, 32, 34, 115, 111, 117, 114, 99, 101, 34, 58, 32, 34, 102, 111, 111, 124, + 98, 97, 114, 34, 125>> end end diff --git a/test/support/type_data.ex b/test/support/type_data.ex index 754d190e..682f27d3 100644 --- a/test/support/type_data.ex +++ b/test/support/type_data.ex @@ -16,7 +16,7 @@ defmodule Gradient.TypeData do def value_test_data() do [ {"integer value", {:integer, 0, 12}, "12"}, - {"atom value", {:atom, 0, :ok}, ":ok"}, + {"atom value", {:atom, 0, :ok}, ~s(:"ok")}, {"boolean false", {:atom, 0, false}, "false"}, {"boolean true", {:atom, 0, true}, "true"}, {"nil", {:atom, 0, nil}, "nil"} @@ -49,7 +49,7 @@ defmodule Gradient.TypeData do [ {"any fun type", {:type, 0, :fun, []}, "fun()"}, {"fun with any args returning a specific type", - {:type, 0, :fun, [{:type, 0, :any}, {:atom, 0, :ok}]}, "(... -> :ok)"}, + {:type, 0, :fun, [{:type, 0, :any}, {:atom, 0, :ok}]}, ~s((... -> :"ok"\))}, {"fun with specific arg types returning a specific type", {:type, 0, :fun, [{:type, 0, :product, [{:type, 0, :atom, []}]}, {:type, 0, :atom, []}]}, "(atom() -> atom())"} @@ -64,14 +64,14 @@ defmodule Gradient.TypeData do [ {:type, 0, :map_field_assoc, [{:atom, 0, :value_a}, {:integer, 0, 5}]}, {:type, 0, :map_field_exact, [{:atom, 0, :value_b}, {:atom, 0, :neo}]} - ]}, "%{optional(:value_a) => 5, required(:value_b) => :neo}"} + ]}, ~s(%{optional(:"value_a"\) => 5, required(:"value_b"\) => :"neo"})} ] end def tuple_types_test_data() do [ {"any tuple type", {:type, 0, :tuple, :any}, "tuple()"}, - {"tuple {:ok, 8}", {:type, 0, :tuple, [{:atom, 0, :ok}, {:integer, 0, 8}]}, "{:ok, 8}"} + {"tuple {:ok, 8}", {:type, 0, :tuple, [{:atom, 0, :ok}, {:integer, 0, 8}]}, ~s({:"ok", 8})} ] end