-
-
Notifications
You must be signed in to change notification settings - Fork 11
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Implement feature tests for function capture calls
- Loading branch information
Showing
3 changed files
with
328 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
defmodule HologramFeatureTests.ModuleFixture do | ||
defp private_fun(x, y) do | ||
{x, y} | ||
end | ||
|
||
def public_fun(x, y) do | ||
private_fun(x, y) | ||
end | ||
end |
183 changes: 183 additions & 0 deletions
183
test/features/app/pages/function_calls/function_capture_page.ex
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,183 @@ | ||
defmodule HologramFeatureTests.FunctionCalls.FunctionCapturePage do | ||
use Hologram.Page | ||
|
||
import Hologram.Commons.KernelUtils, only: [inspect: 1] | ||
import Hologram.Commons.TestUtils, only: [wrap_term: 1] | ||
import Kernel, except: [inspect: 1] | ||
|
||
alias HologramFeatureTests.ModuleFixture | ||
|
||
route "/function-calls/function-capture" | ||
|
||
layout HologramFeatureTests.Components.DefaultLayout | ||
|
||
def init(_params, component, _server) do | ||
put_state(component, :result, nil) | ||
end | ||
|
||
def template do | ||
~H""" | ||
<p> | ||
<button $click="single_arg"> Single arg </button> | ||
<button $click="multiple_args"> Multiple args </button> | ||
<button $click="local_private_function_capture"> Local private function capture </button> | ||
<button $click="local_public_function_capture"> Local public function capture </button> | ||
<button $click="remote_private_elixir_function_capture"> Remote private Elixir function capture </button> | ||
<button $click="remote_public_elixir_function_capture"> Remote public Elixir function capture </button> | ||
<button $click="remote_erlang_function_capture"> Remote Erlang function capture </button> | ||
<button $click="partially_applied_local_function_capture"> Partially applied local function capture </button> | ||
<button $click="partially_applied_remote_elixir_function_capture"> Partially applied remote Elixir function capture </button> | ||
<button $click="partially_applied_remote_erlang_function_capture"> Partially applied remote Erlang function capture </button> | ||
<button $click="vars_scoping"> Vars scoping </button> | ||
<button $click="closure"> Closure </button> | ||
<button $click="arity_invalid_called_with_no_args"> Arity invalid, called with no args </button> | ||
<button $click="arity_invalid_called_with_single_arg"> Arity invalid, called with single arg </button> | ||
<button $click="arity_invalid_called_with_multple_args"> Arity invalid, called with multiple args </button> | ||
<button $click="error_in_body"> Error in body </button> | ||
</p> | ||
<p> | ||
Result: <strong id="result"><code>{inspect(@result)}</code></strong> | ||
</p> | ||
<p> | ||
<button $click="reset"> Reset </button> | ||
</p> | ||
""" | ||
end | ||
|
||
def action(:single_arg, _params, component) do | ||
fun = & &1 | ||
result = fun.(:a) | ||
|
||
put_state(component, :result, result) | ||
end | ||
|
||
def action(:multiple_args, _params, component) do | ||
fun = &{&1, &2} | ||
result = fun.(:a, :b) | ||
|
||
put_state(component, :result, result) | ||
end | ||
|
||
def action(:local_private_function_capture, _params, component) do | ||
fun = &local_private_fun/2 | ||
result = fun.(:a, :b) | ||
|
||
put_state(component, :result, result) | ||
end | ||
|
||
def action(:local_public_function_capture, _params, component) do | ||
fun = &local_public_fun/2 | ||
result = fun.(:a, :b) | ||
|
||
put_state(component, :result, result) | ||
end | ||
|
||
def action(:remote_private_elixir_function_capture, _params, component) do | ||
module = wrap_term(ModuleFixture) | ||
fun = &module.private_fun/2 | ||
result = fun.(:a, :b) | ||
|
||
put_state(component, :result, result) | ||
end | ||
|
||
def action(:remote_public_elixir_function_capture, _params, component) do | ||
fun = &ModuleFixture.public_fun/2 | ||
result = fun.(:a, :b) | ||
|
||
put_state(component, :result, result) | ||
end | ||
|
||
def action(:remote_erlang_function_capture, _params, component) do | ||
fun = &:lists.member/2 | ||
result = fun.(:b, [:a, :b]) | ||
|
||
put_state(component, :result, result) | ||
end | ||
|
||
def action(:partially_applied_local_function_capture, _params, component) do | ||
fun = &local_public_fun(&1, :b) | ||
result = fun.(:a) | ||
|
||
put_state(component, :result, result) | ||
end | ||
|
||
def action(:partially_applied_remote_elixir_function_capture, _params, component) do | ||
fun = &ModuleFixture.public_fun(&1, :b) | ||
result = fun.(:a) | ||
|
||
put_state(component, :result, result) | ||
end | ||
|
||
def action(:partially_applied_remote_erlang_function_capture, _params, component) do | ||
fun = &:lists.member(&1, [:a, :b]) | ||
result = fun.(:b) | ||
|
||
put_state(component, :result, result) | ||
end | ||
|
||
def action(:vars_scoping, _params, component) do | ||
x = 1 | ||
y = 2 | ||
|
||
fun = | ||
&{&1, | ||
( | ||
x = 4 | ||
x | ||
), y} | ||
|
||
result = fun.(3) | ||
|
||
put_state(component, :result, {x, y, result}) | ||
end | ||
|
||
def action(:closure, _params, component) do | ||
x = 1 | ||
y = 2 | ||
|
||
fun_capture = &{&1, x, y} | ||
|
||
result = local_fun_2(fun_capture) | ||
|
||
put_state(component, :result, result) | ||
end | ||
|
||
def action(:arity_invalid_called_with_no_args, _params, _component) do | ||
fun = &{&1, &2} | ||
fun.() | ||
end | ||
|
||
def action(:arity_invalid_called_with_single_arg, _params, _component) do | ||
fun = &{&1, &2} | ||
fun.(:a) | ||
end | ||
|
||
def action(:arity_invalid_called_with_multple_args, _params, _component) do | ||
fun = & &1 | ||
fun.(:a, :b) | ||
end | ||
|
||
def action(:error_in_body, _params, _component) do | ||
fun = &{&1, raise(RuntimeError, "my message")} | ||
fun.(:a) | ||
end | ||
|
||
def action(:reset, _params, component) do | ||
put_state(component, :result, nil) | ||
end | ||
|
||
def local_public_fun(x, y) do | ||
{x, y} | ||
end | ||
|
||
def local_fun_2(fun_capture) do | ||
x = 3 | ||
y = 4 | ||
|
||
{x, y, fun_capture.(5)} | ||
end | ||
|
||
defp local_private_fun(x, y) do | ||
{x, y} | ||
end | ||
end |
136 changes: 136 additions & 0 deletions
136
test/features/test/function_calls/function_capture_test.exs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,136 @@ | ||
defmodule HologramFeatureTests.FunctionCalls.FunctionCaptureTest do | ||
use HologramFeatureTests.TestCase, async: true | ||
alias HologramFeatureTests.FunctionCalls.FunctionCapturePage | ||
|
||
feature "single arg", %{session: session} do | ||
session | ||
|> visit(FunctionCapturePage) | ||
|> click(button("Single arg")) | ||
|> assert_text(css("#result"), ":a") | ||
end | ||
|
||
feature "multiple args", %{session: session} do | ||
session | ||
|> visit(FunctionCapturePage) | ||
|> click(button("Multiple args")) | ||
|> assert_text(css("#result"), "{:a, :b}") | ||
end | ||
|
||
feature "local private function capture", %{session: session} do | ||
session | ||
|> visit(FunctionCapturePage) | ||
|> click(button("Local private function capture")) | ||
|> assert_text(css("#result"), "{:a, :b}") | ||
end | ||
|
||
feature "local public function capture", %{session: session} do | ||
session | ||
|> visit(FunctionCapturePage) | ||
|> click(button("Local public function capture")) | ||
|> assert_text(css("#result"), "{:a, :b}") | ||
end | ||
|
||
feature "remote private Elixir function capture", %{session: session} do | ||
assert_client_error session, | ||
UndefinedFunctionError, | ||
"function HologramFeatureTests.ModuleFixture.private_fun/2 is undefined or private", | ||
fn -> | ||
session | ||
|> visit(FunctionCapturePage) | ||
|> click(button("Remote private Elixir function capture")) | ||
end | ||
end | ||
|
||
feature "remote public Elixir function capture", %{session: session} do | ||
session | ||
|> visit(FunctionCapturePage) | ||
|> click(button("Remote public Elixir function capture")) | ||
|> assert_text(css("#result"), "{:a, :b}") | ||
end | ||
|
||
feature "remote Erlang function capture", %{session: session} do | ||
session | ||
|> visit(FunctionCapturePage) | ||
|> click(button("Remote Erlang function capture")) | ||
|> assert_text(css("#result"), "true") | ||
end | ||
|
||
feature "partially applied local function capture", %{session: session} do | ||
session | ||
|> visit(FunctionCapturePage) | ||
|> click(button("Partially applied local function capture")) | ||
|> assert_text(css("#result"), "{:a, :b}") | ||
end | ||
|
||
feature "partially applied remote Elixir function capture", %{session: session} do | ||
session | ||
|> visit(FunctionCapturePage) | ||
|> click(button("Partially applied remote Elixir function capture")) | ||
|> assert_text(css("#result"), "{:a, :b}") | ||
end | ||
|
||
feature "partially applied remote Erlang function capture", %{session: session} do | ||
session | ||
|> visit(FunctionCapturePage) | ||
|> click(button("Partially applied remote Erlang function capture")) | ||
|> assert_text(css("#result"), "true") | ||
end | ||
|
||
feature "vars scoping", %{session: session} do | ||
session | ||
|> visit(FunctionCapturePage) | ||
|> click(button("Vars scoping")) | ||
|> assert_text(css("#result"), "{1, 2, {3, 4, 2}}") | ||
end | ||
|
||
feature "closure", %{session: session} do | ||
session | ||
|> visit(FunctionCapturePage) | ||
|> click(button("Closure")) | ||
|> assert_text(css("#result"), "{3, 4, {5, 1, 2}}") | ||
end | ||
|
||
feature "arity invalid, called with no args", %{session: session} do | ||
assert_client_error session, | ||
BadArityError, | ||
"anonymous function with arity 2 called with no arguments", | ||
fn -> | ||
session | ||
|> visit(FunctionCapturePage) | ||
|> click(button("Arity invalid, called with no args")) | ||
end | ||
end | ||
|
||
feature "arity invalid, called with single arg", %{session: session} do | ||
assert_client_error session, | ||
BadArityError, | ||
"anonymous function with arity 2 called with 1 argument (:a)", | ||
fn -> | ||
session | ||
|> visit(FunctionCapturePage) | ||
|> click(button("Arity invalid, called with single arg")) | ||
end | ||
end | ||
|
||
feature "arity invalid, called with multiple args", %{session: session} do | ||
assert_client_error session, | ||
BadArityError, | ||
"anonymous function with arity 1 called with 2 arguments (:a, :b)", | ||
fn -> | ||
session | ||
|> visit(FunctionCapturePage) | ||
|> click(button("Arity invalid, called with multiple args")) | ||
end | ||
end | ||
|
||
feature "Error in body", %{session: session} do | ||
assert_client_error session, | ||
RuntimeError, | ||
"my message", | ||
fn -> | ||
session | ||
|> visit(FunctionCapturePage) | ||
|> click(button("Error in body")) | ||
end | ||
end | ||
end |