From 8bb424576112f81f41aac26c363e770bbdd2a082 Mon Sep 17 00:00:00 2001 From: Mitchell Hanberg Date: Thu, 8 Apr 2021 23:04:26 -0400 Subject: [PATCH] Output AST to EEx --- lib/temple/ast.ex | 6 +- lib/temple/eex.ex | 3 + lib/temple/parsers/anonymous_functions.ex | 41 +++++++++++- lib/temple/parsers/components.ex | 66 +++++++++++++++++-- lib/temple/parsers/default.ex | 9 +++ lib/temple/parsers/do_expressions.ex | 28 +++++++- lib/temple/parsers/empty.ex | 13 +++- lib/temple/parsers/match.ex | 9 +++ .../parsers/nonvoid_elements_aliases.ex | 18 +++++ lib/temple/parsers/right_arrow.ex | 14 ++++ .../parsers/temple_namespace_nonvoid.ex | 32 ++------- lib/temple/parsers/temple_namespace_void.ex | 12 ++-- lib/temple/parsers/text.ex | 14 +++- lib/temple/parsers/void_elements_aliases.ex | 14 ++++ test/parser/anonymous_functions_test.exs | 26 ++++++-- test/parser/components_test.exs | 55 ++++++++++++++-- test/parser/default_test.exs | 16 ++++- test/parser/do_expressions_test.exs | 50 +++++++++----- test/parser/empty_test.exs | 19 +++++- test/parser/match_test.exs | 36 +++++++++- test/parser/nonvoid_elements_aliases_test.exs | 29 ++++++-- test/parser/right_arrow_test.exs | 22 +++++-- test/parser/temple_namespace_nonvoid_test.exs | 22 ++++++- test/parser/temple_namespace_void_test.exs | 19 +++++- test/parser/text_test.exs | 14 +++- test/parser/void_elements_aliases_test.exs | 16 ++++- 26 files changed, 504 insertions(+), 99 deletions(-) create mode 100644 lib/temple/eex.ex diff --git a/lib/temple/ast.ex b/lib/temple/ast.ex index 8ffd1cd..1873bb0 100644 --- a/lib/temple/ast.ex +++ b/lib/temple/ast.ex @@ -1,7 +1,5 @@ defmodule Temple.Ast do - defstruct content: nil, attrs: [], children: [], meta: %{} - - def new(opts \\ []) do - struct(__MODULE__, opts) + def new(module, opts \\ []) do + struct(module, opts) end end diff --git a/lib/temple/eex.ex b/lib/temple/eex.ex new file mode 100644 index 0000000..37a3d4a --- /dev/null +++ b/lib/temple/eex.ex @@ -0,0 +1,3 @@ +defprotocol Temple.EEx do + def to_eex(ast) +end diff --git a/lib/temple/parsers/anonymous_functions.ex b/lib/temple/parsers/anonymous_functions.ex index 51a747e..4317946 100644 --- a/lib/temple/parsers/anonymous_functions.ex +++ b/lib/temple/parsers/anonymous_functions.ex @@ -2,6 +2,8 @@ defmodule Temple.Parser.AnonymousFunctions do @moduledoc false @behaviour Temple.Parser + defstruct content: nil, attrs: [], children: [] + alias Temple.Parser alias Temple.Buffer @@ -20,19 +22,56 @@ defmodule Temple.Parser.AnonymousFunctions do def run({_name, _, args} = expression) do {_do_and_else, args} = Temple.Parser.Private.split_args(args) - {_args, func_arg, _args2} = Temple.Parser.Private.split_on_fn(args, {[], nil, []}) + {_args, func_arg, _args2} = + Temple.Parser.Private.split_on_fn(args, {[], nil, []}) {_func, _, [{_arrow, _, [[{_arg, _, _}], block]}]} = func_arg children = Temple.Parser.parse(block) Temple.Ast.new( + __MODULE__, meta: %{type: :anonymous_functions}, content: expression, children: children ) end + defimpl Temple.EEx do + def to_eex(%{content: {name, _, args}, children: children}) do + {_do_and_else, args} = Temple.Parser.Private.split_args(args) + + {args, {func, _, [{arrow, _, [[{arg, _, _}], _block]}]}, args2} = + Temple.Parser.Private.split_on_fn(args, {[], nil, []}) + + [ + "<%= ", + to_string(name), + " ", + Enum.map(args, &Macro.to_string(&1)) |> Enum.join(", "), + ", ", + to_string(func), + " ", + to_string(arg), + " ", + to_string(arrow), + " %>", + "\n", + for(child <- children, do: Temple.EEx.to_eex(child)), + if Enum.any?(args2) do + [ + "<% end, ", + Enum.map(args2, fn arg -> Macro.to_string(arg) end) + |> Enum.join(", "), + " %>" + ] + else + ["<% end %>", "\n"] + end + ] + end + end + @impl Parser def run({name, _, args}, buffer) do import Temple.Parser.Private diff --git a/lib/temple/parsers/components.ex b/lib/temple/parsers/components.ex index 8bb5e33..98682f9 100644 --- a/lib/temple/parsers/components.ex +++ b/lib/temple/parsers/components.ex @@ -2,6 +2,8 @@ defmodule Temple.Parser.Components do @moduledoc false @behaviour Temple.Parser + defstruct content: nil, attrs: [], children: [] + alias Temple.Buffer def applicable?({:c, _, _}) do @@ -10,19 +12,71 @@ defmodule Temple.Parser.Components do def applicable?(_), do: false - def run({:c, meta, [component_module, [do: _] = block]}) do - run({:c, meta, [component_module, [], block]}) - end + def run({:c, _meta, [component_module | args]}) do + {assigns, block} = + case args do + [assigns, [do: block]] -> + {assigns, block} + + [[do: block]] -> + {[], block} + + [assigns] -> + {assigns, nil} + + _ -> + {[], nil} + end + + children = + if block == nil do + [] + else + Temple.Parser.parse(block) + end - def run({:c, _meta, [component_module, args, [do: block]]}) do Temple.Ast.new( + __MODULE__, meta: %{type: :component}, content: Macro.expand_once(component_module, __ENV__), - attrs: args, - children: block + attrs: assigns, + children: children ) end + defimpl Temple.EEx do + def to_eex(%{content: component_module, attrs: assigns, children: []}) do + [ + "<%= Phoenix.View.render", + " ", + Macro.to_string(component_module), + ", ", + ":self,", + " ", + Macro.to_string(assigns), + " ", + "%>" + ] + end + + def to_eex(%{content: component_module, attrs: assigns, children: children}) do + [ + "<%= Phoenix.View.render_layout ", + Macro.to_string(component_module), + ", ", + ":self", + ", ", + Macro.to_string(assigns), + " ", + "do %>", + "\n", + for(child <- children, do: Temple.EEx.to_eex(child)), + "\n", + "<% end %>" + ] + end + end + def run({:c, _meta, [component_module | args]}, buffer) do import Temple.Parser.Private diff --git a/lib/temple/parsers/default.ex b/lib/temple/parsers/default.ex index 00bf9cd..f1ef653 100644 --- a/lib/temple/parsers/default.ex +++ b/lib/temple/parsers/default.ex @@ -2,6 +2,8 @@ defmodule Temple.Parser.Default do @moduledoc false @behaviour Temple.Parser + defstruct content: nil, attrs: [], children: [] + alias Temple.Parser alias Temple.Buffer @@ -10,6 +12,7 @@ defmodule Temple.Parser.Default do def run(ast) do Temple.Ast.new( + __MODULE__, meta: %{type: :default}, content: ast ) @@ -29,4 +32,10 @@ defmodule Temple.Parser.Default do :ok end + + defimpl Temple.EEx do + def to_eex(%{content: expression}) do + ["<%= ", Macro.to_string(expression), " %>"] + end + end end diff --git a/lib/temple/parsers/do_expressions.ex b/lib/temple/parsers/do_expressions.ex index 1fe5df6..0ee9a16 100644 --- a/lib/temple/parsers/do_expressions.ex +++ b/lib/temple/parsers/do_expressions.ex @@ -2,6 +2,8 @@ defmodule Temple.Parser.DoExpressions do @moduledoc false @behaviour Temple.Parser + defstruct content: nil, attrs: [], children: [] + alias Temple.Parser alias Temple.Buffer @@ -17,15 +19,39 @@ defmodule Temple.Parser.DoExpressions do do_body = Temple.Parser.parse(do_and_else[:do]) - else_body = Temple.Parser.parse(do_and_else[:else]) + else_body = + if do_and_else[:else] == nil do + nil + else + Temple.Parser.parse(do_and_else[:else]) + end Temple.Ast.new( + __MODULE__, meta: %{type: :do_expression}, children: [do_body, else_body], content: {name, meta, args} ) end + defimpl Temple.EEx do + def to_eex(%{content: expression, children: [do_body, else_body]}) do + [ + "<%= ", + Macro.to_string(expression), + " do %>", + "\n", + for(child <- do_body, do: Temple.EEx.to_eex(child)), + if(else_body != nil, + do: ["\n<% else %>\n", for(child <- else_body, do: Temple.EEx.to_eex(child))], + else: "" + ), + "\n", + "<% end %>" + ] + end + end + @impl Parser def run({name, meta, args}, buffer) do import Temple.Parser.Private diff --git a/lib/temple/parsers/empty.ex b/lib/temple/parsers/empty.ex index 43ea9f5..7d2f5c3 100644 --- a/lib/temple/parsers/empty.ex +++ b/lib/temple/parsers/empty.ex @@ -2,6 +2,8 @@ defmodule Temple.Parser.Empty do @moduledoc false @behaviour Temple.Parser + defstruct content: nil, attrs: [], children: [] + alias Temple.Parser alias Temple.Ast @@ -10,11 +12,20 @@ defmodule Temple.Parser.Empty do def applicable?(_), do: false def run(_ast) do - Ast.new(meta: %{type: :empty}) + Ast.new( + __MODULE__, + meta: %{type: :empty} + ) end @impl Parser def run(_ast, _buffer) do :ok end + + defimpl Temple.EEx do + def to_eex(_) do + [] + end + end end diff --git a/lib/temple/parsers/match.ex b/lib/temple/parsers/match.ex index 2ec4084..8c57472 100644 --- a/lib/temple/parsers/match.ex +++ b/lib/temple/parsers/match.ex @@ -2,6 +2,8 @@ defmodule Temple.Parser.Match do @moduledoc false @behaviour Temple.Parser + defstruct content: nil, attrs: [], children: [] + alias Temple.Parser alias Temple.Buffer @@ -14,11 +16,18 @@ defmodule Temple.Parser.Match do def run(macro) do Temple.Ast.new( + __MODULE__, meta: %{type: :match}, content: macro ) end + defimpl Temple.EEx do + def to_eex(%{content: content}) do + ["<% ", Macro.to_string(content), " %>"] + end + end + @impl Parser def run({_, _, args} = macro, buffer) do import Temple.Parser.Private diff --git a/lib/temple/parsers/nonvoid_elements_aliases.ex b/lib/temple/parsers/nonvoid_elements_aliases.ex index f549141..cb021f8 100644 --- a/lib/temple/parsers/nonvoid_elements_aliases.ex +++ b/lib/temple/parsers/nonvoid_elements_aliases.ex @@ -2,6 +2,8 @@ defmodule Temple.Parser.NonvoidElementsAliases do @moduledoc false @behaviour Temple.Parser + defstruct content: nil, attrs: [], children: [] + alias Temple.Parser alias Temple.Buffer @@ -35,6 +37,7 @@ defmodule Temple.Parser.NonvoidElementsAliases do children = Temple.Parser.parse(do_and_else[:do]) Temple.Ast.new( + __MODULE__, content: to_string(name), meta: %{type: :nonvoid_alias}, attrs: args, @@ -42,6 +45,21 @@ defmodule Temple.Parser.NonvoidElementsAliases do ) end + defimpl Temple.EEx do + def to_eex(%{content: content, attrs: attrs, children: children}) do + [ + "<", + content, + Temple.Parser.Private.compile_attrs(attrs), + ">\n", + for(child <- children, do: Temple.EEx.to_eex(child)), + "\n" + ] + end + end + @impl Parser def run({name, _, args}, buffer) do import Temple.Parser.Private diff --git a/lib/temple/parsers/right_arrow.ex b/lib/temple/parsers/right_arrow.ex index cf8ff5e..e2b85d2 100644 --- a/lib/temple/parsers/right_arrow.ex +++ b/lib/temple/parsers/right_arrow.ex @@ -2,6 +2,8 @@ defmodule Temple.Parser.RightArrow do @moduledoc false @behaviour Temple.Parser + defstruct content: nil, attrs: [], children: [] + alias Temple.Parser alias Temple.Buffer @@ -13,12 +15,24 @@ defmodule Temple.Parser.RightArrow do children = Temple.Parser.parse(args) Temple.Ast.new( + __MODULE__, meta: %{type: :right_arrow}, content: pattern, children: children ) end + defimpl Temple.EEx do + def to_eex(%{content: content, children: children}) do + [ + "<% ", + Macro.to_string(content), + " -> %>\n", + for(child <- children, do: Temple.EEx.to_eex(child)) + ] + end + end + @impl Parser def run({_, _, [[pattern], args]}, buffer) do import Temple.Parser.Private diff --git a/lib/temple/parsers/temple_namespace_nonvoid.ex b/lib/temple/parsers/temple_namespace_nonvoid.ex index f98e303..9319963 100644 --- a/lib/temple/parsers/temple_namespace_nonvoid.ex +++ b/lib/temple/parsers/temple_namespace_nonvoid.ex @@ -2,6 +2,8 @@ defmodule Temple.Parser.TempleNamespaceNonvoid do @moduledoc false @behaviour Temple.Parser + defstruct content: nil, attrs: [], children: [] + alias Temple.Parser alias Temple.Buffer @@ -12,35 +14,9 @@ defmodule Temple.Parser.TempleNamespaceNonvoid do def applicable?(_), do: false - def run({name, _, args}) do + def run({name, meta, args}) do {:., _, [{:__aliases__, _, [:Temple]}, name]} = name - name = Parser.nonvoid_elements_lookup()[name] - - {do_and_else, args} = - args - |> Temple.Parser.Private.split_args() - - {do_and_else, args} = - case args do - [args] when is_list(args) -> - {do_value, args} = Keyword.pop(args, :do) - - do_and_else = Keyword.put_new(do_and_else, :do, do_value) - - {do_and_else, args} - - _ -> - {do_and_else, args} - end - - children = Temple.Parser.parse(do_and_else[:do]) - - Temple.Ast.new( - content: to_string(name), - meta: %{type: :temple_nonvoid}, - attrs: args, - children: children - ) + Temple.Parser.NonvoidElementsAliases.run({name, meta, args}) end @impl Parser diff --git a/lib/temple/parsers/temple_namespace_void.ex b/lib/temple/parsers/temple_namespace_void.ex index 43cca99..0cf1e00 100644 --- a/lib/temple/parsers/temple_namespace_void.ex +++ b/lib/temple/parsers/temple_namespace_void.ex @@ -2,6 +2,8 @@ defmodule Temple.Parser.TempleNamespaceVoid do @moduledoc false @behaviour Temple.Parser + defstruct content: nil, attrs: [], children: [] + alias Temple.Parser alias Temple.Buffer @@ -12,16 +14,10 @@ defmodule Temple.Parser.TempleNamespaceVoid do def applicable?(_), do: false - def run({name, _, [args]}) do + def run({name, meta, args}) do {:., _, [{:__aliases__, _, [:Temple]}, name]} = name - name = Parser.void_elements_lookup()[name] - - Temple.Ast.new( - content: to_string(name), - meta: %{type: :temple_void}, - attrs: args - ) + Temple.Parser.VoidElementsAliases.run({name, meta, args}) end @impl Parser diff --git a/lib/temple/parsers/text.ex b/lib/temple/parsers/text.ex index 38cf3b3..a96ceb4 100644 --- a/lib/temple/parsers/text.ex +++ b/lib/temple/parsers/text.ex @@ -2,6 +2,8 @@ defmodule Temple.Parser.Text do @moduledoc false @behaviour Temple.Parser + defstruct content: nil, attrs: [], children: [] + alias Temple.Buffer alias Temple.Parser alias Temple.Ast @@ -11,7 +13,11 @@ defmodule Temple.Parser.Text do def applicable?(_), do: false def run(text) do - Ast.new(content: text, meta: %{type: :text}) + Ast.new( + __MODULE__, + content: text, + meta: %{type: :text} + ) end @impl Parser @@ -21,4 +27,10 @@ defmodule Temple.Parser.Text do :ok end + + defimpl Temple.EEx do + def to_eex(%{content: text}) do + [text] + end + end end diff --git a/lib/temple/parsers/void_elements_aliases.ex b/lib/temple/parsers/void_elements_aliases.ex index 2ecc5d9..bff8f3b 100644 --- a/lib/temple/parsers/void_elements_aliases.ex +++ b/lib/temple/parsers/void_elements_aliases.ex @@ -2,6 +2,8 @@ defmodule Temple.Parser.VoidElementsAliases do @moduledoc false @behaviour Temple.Parser + defstruct content: nil, attrs: [], children: [] + alias Temple.Parser alias Temple.Buffer @@ -18,12 +20,24 @@ defmodule Temple.Parser.VoidElementsAliases do name = Parser.void_elements_lookup()[name] Temple.Ast.new( + __MODULE__, content: name, meta: %{type: :void_alias}, attrs: args ) end + defimpl Temple.EEx do + def to_eex(%{content: content, attrs: attrs}) do + [ + "<", + to_string(content), + Temple.Parser.Private.compile_attrs(attrs), + ">\n" + ] + end + end + @impl Parser def run({name, _, args}, buffer) do import Temple.Parser.Private diff --git a/test/parser/anonymous_functions_test.exs b/test/parser/anonymous_functions_test.exs index 55fc2be..c53e6d1 100644 --- a/test/parser/anonymous_functions_test.exs +++ b/test/parser/anonymous_functions_test.exs @@ -54,12 +54,10 @@ defmodule Temple.Parser.AnonymousFunctionsTest do ast = AnonymousFunctions.run(raw_ast) - assert %Temple.Ast{ - meta: %{type: :anonymous_functions}, + assert %AnonymousFunctions{ content: _, children: [ - %Temple.Ast{ - meta: %{type: :default}, + %Temple.Parser.Default{ content: ^expected_child, children: [] } @@ -67,4 +65,24 @@ defmodule Temple.Parser.AnonymousFunctionsTest do } = ast end end + + describe "Temple.EEx.to_eex/1" do + test "emits eex" do + raw_ast = + quote do + form_for changeset, Routes.foo_path(conn, :create), fn form -> + Does.something!(form) + end + end + + result = + raw_ast + |> AnonymousFunctions.run() + |> struct(children: []) + |> Temple.EEx.to_eex() + + assert result |> :erlang.iolist_to_binary() == + ~s|<%= form_for changeset, Routes.foo_path(conn, :create), fn form -> %>\n<% end %>\n| + end + end end diff --git a/test/parser/components_test.exs b/test/parser/components_test.exs index 490bd4d..37a7490 100644 --- a/test/parser/components_test.exs +++ b/test/parser/components_test.exs @@ -40,8 +40,7 @@ defmodule Temple.Parser.ComponentsTest do ast = Components.run(raw_ast) - assert %Temple.Ast{ - meta: %{type: :component}, + assert %Components{ content: SomeModule, attrs: [], children: _ @@ -60,12 +59,60 @@ defmodule Temple.Parser.ComponentsTest do ast = Components.run(raw_ast) - assert %Temple.Ast{ - meta: %{type: :component}, + assert %Components{ content: SomeModule, attrs: [foo: :bar], children: _ } = ast end + + test "adds a node to the buffer that without a block" do + raw_ast = + quote do + c SomeModule, foo: :bar + end + + ast = Components.run(raw_ast) + + assert %Components{ + content: SomeModule, + attrs: [foo: :bar], + children: [] + } = ast + end + end + + describe "Temple.EEx.to_eex/1" do + test "emits eex for non void component" do + raw_ast = + quote do + c SomeModule, foo: :bar do + "I'm a component!" + end + end + + result = + raw_ast + |> Components.run() + |> Temple.EEx.to_eex() + + assert result |> :erlang.iolist_to_binary() == + ~s|<%= Phoenix.View.render_layout SomeModule, :self, [foo: :bar] do %>\nI'm a component!\n<% end %>| + end + + test "emits eex for void component" do + raw_ast = + quote do + c SomeModule, foo: :bar + end + + result = + raw_ast + |> Components.run() + |> Temple.EEx.to_eex() + + assert result |> :erlang.iolist_to_binary() == + ~s|<%= Phoenix.View.render SomeModule, :self, [foo: :bar] %>| + end end end diff --git a/test/parser/default_test.exs b/test/parser/default_test.exs index 342ca48..53a8111 100644 --- a/test/parser/default_test.exs +++ b/test/parser/default_test.exs @@ -23,11 +23,23 @@ defmodule Temple.Parser.DefaultTest do ast = Default.run(expression) - assert %Temple.Ast{ - meta: %{type: :default}, + assert %Default{ content: expression, children: [] } == ast end end + + describe "to_eex/1" do + test "emits eex" do + result = + quote do + Foo.bar!(baz) + end + |> Default.run() + |> Temple.EEx.to_eex() + + assert result |> :erlang.iolist_to_binary() == ~s|<%= Foo.bar!(baz) %>| + end + end end diff --git a/test/parser/do_expressions_test.exs b/test/parser/do_expressions_test.exs index 52badf7..da47b2e 100644 --- a/test/parser/do_expressions_test.exs +++ b/test/parser/do_expressions_test.exs @@ -27,26 +27,44 @@ defmodule Temple.Parser.DoExpressionsTest do ast = DoExpressions.run(raw_ast) - assert %Temple.Ast{ - meta: %{type: :do_expression}, + assert %DoExpressions{ content: _, children: [ - [ - %Temple.Ast{ - meta: %{type: :text}, - content: "bob", - children: [] - } - ], - [ - %Temple.Ast{ - meta: %{type: :empty}, - content: nil, - children: [] - } - ] + [%Temple.Parser.Text{content: "bob", children: []}], nil ] } = ast end end + + describe "to_eex/1" do + test "emits eex" do + result = + quote do + for big <- boys do + "bob" + end + end + |> DoExpressions.run() + |> Temple.EEx.to_eex() + + assert result |> :erlang.iolist_to_binary() == + ~s|<%= for(big <- boys) do %>\nbob\n<% end %>| + end + + test "emits eex for that includes in else clause" do + result = + quote do + if foo? do + "bob" + else + "carol" + end + end + |> DoExpressions.run() + |> Temple.EEx.to_eex() + + assert result |> :erlang.iolist_to_binary() == + ~s|<%= if(foo?) do %>\nbob\n<% else %>\ncarol\n<% end %>| + end + end end diff --git a/test/parser/empty_test.exs b/test/parser/empty_test.exs index e784511..cf68f0a 100644 --- a/test/parser/empty_test.exs +++ b/test/parser/empty_test.exs @@ -26,12 +26,27 @@ defmodule Temple.Parser.EmptyTest do for _ <- [nil, []] do ast = Empty.run(nil) - assert %Temple.Ast{ - meta: %{type: :empty}, + assert %Empty{ content: nil, children: [] } == ast end end end + + describe "Temple.EEx.to_eex/1" do + test "emits eex for non void component" do + raw_ast = + quote do + nil + end + + result = + raw_ast + |> Empty.run() + |> Temple.EEx.to_eex() + + assert result |> :erlang.iolist_to_binary() == "" + end + end end diff --git a/test/parser/match_test.exs b/test/parser/match_test.exs index f6132d3..c610bf6 100644 --- a/test/parser/match_test.exs +++ b/test/parser/match_test.exs @@ -33,11 +33,43 @@ defmodule Temple.Parser.MatchTest do ast = Match.run(expression) - assert %Temple.Ast{ - meta: %{type: :match}, + assert %Match{ content: expression, children: [] } == ast end end + + describe "Temple.EEx.to_eex/1" do + test "emits eex" do + raw_ast = + quote do + yolo = :synergy + end + + result = + raw_ast + |> Match.run() + |> Temple.EEx.to_eex() + + assert result |> :erlang.iolist_to_binary() == ~s|<% yolo = :synergy %>| + end + + test "emits eex big boy" do + raw_ast = + quote do + yolo = + if true do + :synergy + end + end + + result = + raw_ast + |> Match.run() + |> Temple.EEx.to_eex() + + assert result |> :erlang.iolist_to_binary() == ~s|<% yolo = if(true) do\n :synergy\nend %>| + end + end end diff --git a/test/parser/nonvoid_elements_aliases_test.exs b/test/parser/nonvoid_elements_aliases_test.exs index 55f1d60..94f6748 100644 --- a/test/parser/nonvoid_elements_aliases_test.exs +++ b/test/parser/nonvoid_elements_aliases_test.exs @@ -60,18 +60,17 @@ defmodule Temple.Parser.NonvoidElementsAliasesTest do ast = NonvoidElementsAliases.run(raw_ast) - assert %Temple.Ast{ - meta: %{type: :nonvoid_alias}, + assert %NonvoidElementsAliases{ content: "div", attrs: [class: "foo", id: {:var, [], _}], children: [ - %Temple.Ast{ + %NonvoidElementsAliases{ content: "select", children: [ - %Temple.Ast{ + %NonvoidElementsAliases{ content: "option", children: [ - %Temple.Ast{content: "foo"} + %Temple.Parser.Text{content: "foo"} ] } ] @@ -80,4 +79,24 @@ defmodule Temple.Parser.NonvoidElementsAliasesTest do } = ast end end + + describe "to_eex/1" do + test "emits eex" do + result = + quote do + div class: "foo", id: var do + select__ do + option do + "foo" + end + end + end + end + |> NonvoidElementsAliases.run() + |> Temple.EEx.to_eex() + + assert result |> :erlang.iolist_to_binary() == + ~s|
\n\n
| + end + end end diff --git a/test/parser/right_arrow_test.exs b/test/parser/right_arrow_test.exs index d349c7d..9e25a4a 100644 --- a/test/parser/right_arrow_test.exs +++ b/test/parser/right_arrow_test.exs @@ -49,12 +49,10 @@ defmodule Temple.Parser.RightArrowTest do ast = RightArrow.run(raw_ast) - assert %Temple.Ast{ - meta: %{type: :right_arrow}, + assert %RightArrow{ content: :bing, children: [ - %Temple.Ast{ - meta: %{type: :default}, + %Temple.Parser.Default{ content: ^bong, children: [] } @@ -62,4 +60,20 @@ defmodule Temple.Parser.RightArrowTest do } = ast end end + + describe "to_eex/1" do + test "emits eex" do + result = + quote do + :bing -> + :bong + end + |> List.first() + |> RightArrow.run() + |> Temple.EEx.to_eex() + + assert result |> :erlang.iolist_to_binary() == + ~s|<% :bing -> %>\n<%= :bong %>| + end + end end diff --git a/test/parser/temple_namespace_nonvoid_test.exs b/test/parser/temple_namespace_nonvoid_test.exs index 66fccfd..bfabf22 100644 --- a/test/parser/temple_namespace_nonvoid_test.exs +++ b/test/parser/temple_namespace_nonvoid_test.exs @@ -1,6 +1,7 @@ defmodule Temple.Parser.TempleNamespaceNonvoidTest do use ExUnit.Case, async: true + alias Temple.Parser.NonvoidElementsAliases alias Temple.Parser.TempleNamespaceNonvoid describe "applicable?/1" do @@ -46,12 +47,27 @@ defmodule Temple.Parser.TempleNamespaceNonvoidTest do ast = TempleNamespaceNonvoid.run(raw_ast) - assert %Temple.Ast{ - meta: %{type: :temple_nonvoid}, + assert %NonvoidElementsAliases{ content: "div", attrs: [class: "foo", id: {:var, [], _}], - children: [%Temple.Ast{content: "foo"}] + children: [%Temple.Parser.Text{content: "foo"}] } = ast end end + + describe "to_eex/1" do + test "emits eex" do + result = + quote do + Temple.div class: "foo", id: var do + "foo" + end + end + |> TempleNamespaceNonvoid.run() + |> Temple.EEx.to_eex() + + assert result |> :erlang.iolist_to_binary() == + ~s|
\nfoo\n
| + end + end end diff --git a/test/parser/temple_namespace_void_test.exs b/test/parser/temple_namespace_void_test.exs index 3034c02..9e88ef8 100644 --- a/test/parser/temple_namespace_void_test.exs +++ b/test/parser/temple_namespace_void_test.exs @@ -2,6 +2,7 @@ defmodule Temple.Parser.TempleNamespaceVoidTest do use ExUnit.Case, async: true alias Temple.Parser.TempleNamespaceVoid + alias Temple.Parser.VoidElementsAliases describe "applicable?/1" do test "returns true when the node is a Temple aliased nonvoid element" do @@ -42,12 +43,24 @@ defmodule Temple.Parser.TempleNamespaceVoidTest do ast = TempleNamespaceVoid.run(raw_ast) - assert %Temple.Ast{ - meta: %{type: :temple_void}, - content: "meta", + assert %VoidElementsAliases{ + content: :meta, attrs: [class: "foo", id: {:var, [], _}], children: [] } = ast end end + + describe "to_eex/1" do + test "emits eex" do + result = + quote do + Temple.meta(content: "foo") + end + |> TempleNamespaceVoid.run() + |> Temple.EEx.to_eex() + + assert result |> :erlang.iolist_to_binary() == ~s|\n| + end + end end diff --git a/test/parser/text_test.exs b/test/parser/text_test.exs index ca0a44f..ddc8940 100644 --- a/test/parser/text_test.exs +++ b/test/parser/text_test.exs @@ -25,11 +25,21 @@ defmodule Temple.Parser.TextTest do text = "string literal" ast = Text.run(text) - assert %Temple.Ast{ - meta: %{type: :text}, + assert %Text{ content: text, children: [] } == ast end end + + describe "Temple.EEx.to_eex/1" do + test "emits eex" do + result = + "string literal" + |> Text.run() + |> Temple.EEx.to_eex() + + assert result |> :erlang.iolist_to_binary() == ~s|string literal| + end + end end diff --git a/test/parser/void_elements_aliases_test.exs b/test/parser/void_elements_aliases_test.exs index 707aa14..4c37524 100644 --- a/test/parser/void_elements_aliases_test.exs +++ b/test/parser/void_elements_aliases_test.exs @@ -48,12 +48,24 @@ defmodule Temple.Parser.VoidElementsAliasesTest do ast = VoidElementsAliases.run(raw_ast) - assert %Temple.Ast{ - meta: %{type: :void_alias}, + assert %VoidElementsAliases{ content: :meta, attrs: [content: "foo"], children: [] } = ast end end + + describe "to_eex/1" do + test "emits eex" do + result = + quote do + meta content: "foo" + end + |> VoidElementsAliases.run() + |> Temple.EEx.to_eex() + + assert result |> :erlang.iolist_to_binary() == ~s|\n| + end + end end