-
-
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 anonymous function calls
- Loading branch information
Showing
3 changed files
with
320 additions
and
1 deletion.
There are no files selected for viewing
196 changes: 196 additions & 0 deletions
196
test/features/app/pages/function_calls/anonymous_function_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,196 @@ | ||
defmodule HologramFeatureTests.FunctionCalls.AnonymousFunctionPage do | ||
use Hologram.Page | ||
|
||
import Hologram.Commons.KernelUtils, only: [inspect: 1] | ||
import Hologram.Commons.TestUtils, only: [wrap_term: 1] | ||
import Kernel, except: [inspect: 1] | ||
|
||
route "/function-calls/anonymous-function" | ||
|
||
layout HologramFeatureTests.Components.DefaultLayout | ||
|
||
def init(_params, component, _server) do | ||
put_state(component, :result, nil) | ||
end | ||
|
||
def template do | ||
~H""" | ||
<p> | ||
<button $click="reset"> Reset </button> | ||
</p> | ||
<p> | ||
<button $click="basic_case"> Basic case </button> | ||
<button $click="single_arg"> Single arg </button> | ||
<button $click="multiple_args"> Multiple args </button> | ||
<button $click="multiple_clauses"> Multiple clauses </button> | ||
<button $click="multiple_expression_body"> Multiple-expression body </button> | ||
<button $click="single_guard"> Single guard </button> | ||
<button $click="multiple_guards"> Multiple guards </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="no_matching_clause"> No matching clause </button> | ||
<button $click="error_in_body"> Error in body </button> | ||
</p> | ||
<p> | ||
Result: <strong id="result"><code>{inspect(@result)}</code></strong> | ||
</p> | ||
""" | ||
end | ||
|
||
# no args / single clause / single-expression body | ||
def action(:basic_case, _params, component) do | ||
fun = fn -> :a end | ||
result = fun.() | ||
|
||
put_state(component, :result, result) | ||
end | ||
|
||
def action(:single_arg, _params, component) do | ||
fun = fn x -> x end | ||
result = fun.(1) | ||
|
||
put_state(component, :result, result) | ||
end | ||
|
||
def action(:multiple_args, _params, component) do | ||
fun = fn x, y -> {x, y} end | ||
result = fun.(1, 2) | ||
|
||
put_state(component, :result, result) | ||
end | ||
|
||
def action(:multiple_clauses, _params, component) do | ||
fun = fn | ||
1, x -> {1, x} | ||
2, x -> {2, x} | ||
3, x -> {3, x} | ||
end | ||
|
||
result = | ||
2 | ||
|> wrap_term() | ||
|> fun.(3) | ||
|
||
put_state(component, :result, result) | ||
end | ||
|
||
def action(:multiple_expression_body, _params, component) do | ||
fun = fn -> | ||
:a | ||
:b | ||
end | ||
|
||
result = fun.() | ||
|
||
put_state(component, :result, result) | ||
end | ||
|
||
def action(:single_guard, _params, component) do | ||
fun = fn | ||
x when x == 1 -> :a | ||
x when x == 2 -> :b | ||
x when x == 3 -> :c | ||
end | ||
|
||
result = | ||
2 | ||
|> wrap_term() | ||
|> fun.() | ||
|
||
put_state(component, :result, result) | ||
end | ||
|
||
def action(:multiple_guards, _params, component) do | ||
fun = fn | ||
x when x > 0 and x < 10 -> :a | ||
x when x > 10 and x < 20 -> :b | ||
x when x > 10 and x < 30 -> :c | ||
x when x > 10 and x < 40 -> :d | ||
end | ||
|
||
result = | ||
25 | ||
|> wrap_term() | ||
|> fun.() | ||
|
||
put_state(component, :result, result) | ||
end | ||
|
||
def action(:vars_scoping, _params, component) do | ||
x = 1 | ||
y = 2 | ||
z = 3 | ||
|
||
fun = fn | ||
z, y = 4 -> | ||
{z, y} | ||
|
||
x = 5, y = 6 -> | ||
x = x + 10 | ||
{x, y, z} | ||
end | ||
|
||
result = fun.(5, wrap_term(6)) | ||
|
||
put_state(component, :result, {x, y, z, result}) | ||
end | ||
|
||
def action(:closure, _params, component) do | ||
x = 1 | ||
y = 2 | ||
|
||
anon_fun = fn -> {x, y} end | ||
|
||
result = local_fun(anon_fun) | ||
|
||
put_state(component, :result, result) | ||
end | ||
|
||
def action(:arity_invalid_called_with_no_args, _params, _component) do | ||
fun = fn x, y -> {x, y} end | ||
fun.() | ||
end | ||
|
||
def action(:arity_invalid_called_with_single_arg, _params, _component) do | ||
fun = fn x, y -> {x, y} end | ||
fun.(:a) | ||
end | ||
|
||
def action(:arity_invalid_called_with_multple_args, _params, _component) do | ||
fun = fn x -> x end | ||
fun.(:a, :b) | ||
end | ||
|
||
def action(:no_matching_clause, _params, component) do | ||
fun = fn | ||
1, 2 -> :a | ||
3, 4 -> :b | ||
end | ||
|
||
result = | ||
5 | ||
|> wrap_term() | ||
|> fun.(6) | ||
|
||
put_state(component, :result, result) | ||
end | ||
|
||
def action(:error_in_body, _params, _component) do | ||
fun = fn -> raise RuntimeError, "my message" end | ||
fun.() | ||
end | ||
|
||
def action(:reset, _params, component) do | ||
put_state(component, :result, nil) | ||
end | ||
|
||
defp local_fun(anon_fun) do | ||
x = 3 | ||
y = 4 | ||
|
||
{x, y, anon_fun.()} | ||
end | ||
end |
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
123 changes: 123 additions & 0 deletions
123
test/features/test/function_calls/anonymous_function_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,123 @@ | ||
defmodule HologramFeatureTests.FunctionCalls.AnonymousFunctionTest do | ||
use HologramFeatureTests.TestCase, async: true | ||
alias HologramFeatureTests.FunctionCalls.AnonymousFunctionPage | ||
|
||
# no args / single clause / single-expression body | ||
feature "basic case", %{session: session} do | ||
session | ||
|> visit(AnonymousFunctionPage) | ||
|> click(button("Basic case")) | ||
|> assert_text(css("#result"), ":a") | ||
end | ||
|
||
feature "single arg", %{session: session} do | ||
session | ||
|> visit(AnonymousFunctionPage) | ||
|> click(button("Single arg")) | ||
|> assert_text(css("#result"), "1") | ||
end | ||
|
||
feature "multiple args", %{session: session} do | ||
session | ||
|> visit(AnonymousFunctionPage) | ||
|> click(button("Multiple args")) | ||
|> assert_text(css("#result"), "{1, 2}") | ||
end | ||
|
||
feature "multiple clauses", %{session: session} do | ||
session | ||
|> visit(AnonymousFunctionPage) | ||
|> click(button("Multiple clauses")) | ||
|> assert_text(css("#result"), "{2, 3}") | ||
end | ||
|
||
feature "multiple-expression body", %{session: session} do | ||
session | ||
|> visit(AnonymousFunctionPage) | ||
|> click(button("Multiple-expression body")) | ||
|> assert_text(css("#result"), ":b") | ||
end | ||
|
||
feature "single guard", %{session: session} do | ||
session | ||
|> visit(AnonymousFunctionPage) | ||
|> click(button("Single guard")) | ||
|> assert_text(css("#result"), ":b") | ||
end | ||
|
||
feature "multiple guards", %{session: session} do | ||
session | ||
|> visit(AnonymousFunctionPage) | ||
|> click(button("Multiple guards")) | ||
|> assert_text(css("#result"), ":c") | ||
end | ||
|
||
feature "vars scoping", %{session: session} do | ||
session | ||
|> visit(AnonymousFunctionPage) | ||
|> click(button("Vars scoping")) | ||
|> assert_text(css("#result"), "{1, 2, 3, {15, 6, 3}}") | ||
end | ||
|
||
feature "closure", %{session: session} do | ||
session | ||
|> visit(AnonymousFunctionPage) | ||
|> click(button("Closure")) | ||
|> assert_text(css("#result"), "{3, 4, {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(AnonymousFunctionPage) | ||
|> 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(AnonymousFunctionPage) | ||
|> 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(AnonymousFunctionPage) | ||
|> click(button("Arity invalid, called with multiple args")) | ||
end | ||
end | ||
|
||
feature "no matching clause", %{session: session} do | ||
assert_client_error session, | ||
FunctionClauseError, | ||
build_function_clause_error_msg("anonymous fn/2", [5, 6]), | ||
fn -> | ||
session | ||
|> visit(AnonymousFunctionPage) | ||
|> click(button("No matching clause")) | ||
end | ||
end | ||
|
||
feature "Error in body", %{session: session} do | ||
assert_client_error session, | ||
RuntimeError, | ||
"my message", | ||
fn -> | ||
session | ||
|> visit(AnonymousFunctionPage) | ||
|> click(button("Error in body")) | ||
end | ||
end | ||
end |