Repository: mhanberg/temple (elixir)

Issue:
Component errors on missing @inner_content if additional options are given with do:
**Describe the bug**
Components doesn't render `@inner_content` if additional options are given when using `do:` syntax.

**Desktop:**
 - OS: Linux
 - Temple Version  {:temple, "~> 0.6.0-rc.0"}
 - elixir 1.11.3-otp-23
 - erlang 23.2.3

**Reproduction**

Define the component as:

```
defmodule App.Component.MyComponent do
  use Temple.Component

  render do
    div class: "some classes #{assigns[:class]}" do
      @inner_content
    end
  end
end
```

This works:

```
c App.Component.MyComponent, do: "Something"
```

This works:

```
c App.Component.MyComponent, class: "-ml-4" do
    "Something"
end
```

This does not work:

```
c App.Component.MyComponent, class: "-ml-4", do: "Something"
```

> assign @inner_content not available in eex template.
> 
> Please make sure all proper assigns have been set. If this
> is a child template, ensure assigns are given explicitly by
> the parent template as they are not automatically forwarded.
> 
> Available assigns: [:class, :do, :view_module, :view_template]
> 

Pull request:
Allow components to be used with inline blocks
Fixes #116 

Patch:
diff --git a/lib/temple/parser/components.ex b/lib/temple/parser/components.ex
index 4838dc5..c4a9e4b 100644
--- a/lib/temple/parser/components.ex
+++ b/lib/temple/parser/components.ex
@@ -13,26 +13,17 @@ defmodule Temple.Parser.Components do
 
   @impl Temple.Parser
   def run({:c, _meta, [component_module | args]}) do
-    {assigns, block} =
-      case args do
-        [assigns, [do: block]] ->
-          {assigns, block}
+    {do_and_else, args} =
+      args
+      |> Temple.Parser.Utils.split_args()
 
-        [[do: block]] ->
-          {[], block}
-
-        [assigns] ->
-          {assigns, nil}
-
-        _ ->
-          {[], nil}
-      end
+    {do_and_else, assigns} = Temple.Parser.Utils.consolidate_blocks(do_and_else, args)
 
     children =
-      if block == nil do
+      if do_and_else[:do] == nil do
         []
       else
-        Temple.Parser.parse(block)
+        Temple.Parser.parse(do_and_else[:do])
       end
 
     Temple.Ast.new(
diff --git a/lib/temple/parser/nonvoid_elements_aliases.ex b/lib/temple/parser/nonvoid_elements_aliases.ex
index 2ee3173..d883c25 100644
--- a/lib/temple/parser/nonvoid_elements_aliases.ex
+++ b/lib/temple/parser/nonvoid_elements_aliases.ex
@@ -21,18 +21,7 @@ defmodule Temple.Parser.NonvoidElementsAliases do
       args
       |> Temple.Parser.Utils.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
+    {do_and_else, args} = Temple.Parser.Utils.consolidate_blocks(do_and_else, args)
 
     children = Temple.Parser.parse(do_and_else[:do])
 
diff --git a/lib/temple/parser/private.ex b/lib/temple/parser/utils.ex
similarity index 90%
rename from lib/temple/parser/private.ex
rename to lib/temple/parser/utils.ex
index 8613ee4..bc34ce5 100644
--- a/lib/temple/parser/private.ex
+++ b/lib/temple/parser/utils.ex
@@ -60,6 +60,18 @@ defmodule Temple.Parser.Utils do
     {List.flatten(do_and_else), args}
   end
 
+  def consolidate_blocks(blocks, args) do
+    case args do
+      [args] when is_list(args) ->
+        {do_value, args} = Keyword.pop(args, :do)
+
+        {Keyword.put_new(blocks, :do, do_value), args}
+
+      _ ->
+        {blocks, args}
+    end
+  end
+
   def split_on_fn([{:fn, _, _} = func | rest], {args_before, _, args_after}) do
     split_on_fn(rest, {args_before, func, args_after})
   end


Test patch:
diff --git a/test/parser/components_test.exs b/test/parser/components_test.exs
index 37a7490..f5951cf 100644
--- a/test/parser/components_test.exs
+++ b/test/parser/components_test.exs
@@ -17,6 +17,15 @@ defmodule Temple.Parser.ComponentsTest do
       assert Components.applicable?(ast)
     end
 
+    test "runs when using the `c` ast with an inline block" do
+      ast =
+        quote do
+          c SomeModule, foo: :bar, do: "hello"
+        end
+
+      assert Components.applicable?(ast)
+    end
+
     test "runs when using the `c` ast without a block" do
       ast =
         quote do
@@ -47,6 +56,21 @@ defmodule Temple.Parser.ComponentsTest do
              } = ast
     end
 
+    test "runs when using the `c` ast with an inline block" do
+      ast =
+        quote do
+          c SomeModule, foo: :bar, do: "hello"
+        end
+
+      ast = Components.run(ast)
+
+      assert %Components{
+               content: SomeModule,
+               attrs: [foo: :bar],
+               children: _
+             } = ast
+    end
+
     test "adds a node to the buffer that takes args" do
       raw_ast =
         quote do