diff --git a/test/elixir/hologram/ex_js_consistency/interpreter_test.exs b/test/elixir/hologram/ex_js_consistency/interpreter_test.exs index c0626cd85..d02773db7 100644 --- a/test/elixir/hologram/ex_js_consistency/interpreter_test.exs +++ b/test/elixir/hologram/ex_js_consistency/interpreter_test.exs @@ -82,6 +82,12 @@ defmodule Hologram.ExJsConsistency.InterpreterTest do # TODO: implement # describe "call function capture" + # IMPORTANT! + # Keep consistent with feature tests in: + # * test/features/test/function_calls/local_function_test.exs + # * test/features/test/function_calls/remote_function_test.exs + # TODO: split into "call local function" and "call remote function" + # TODO: reimplement to be consistent with aforementioned feature tests describe "call named function" do test "remote private function call" do expected_msg = diff --git a/test/features/app/pages/function_calls/local_function_page.ex b/test/features/app/pages/function_calls/local_function_page.ex new file mode 100644 index 000000000..b7fd82251 --- /dev/null +++ b/test/features/app/pages/function_calls/local_function_page.ex @@ -0,0 +1,182 @@ +defmodule HologramFeatureTests.FunctionCalls.LocalFunctionPage do + use Hologram.Page + + import Hologram.Commons.KernelUtils, only: [inspect: 1] + import Kernel, except: [inspect: 1] + + route "/function-calls/local-function" + + layout HologramFeatureTests.Components.DefaultLayout + + def init(_params, component, _server) do + put_state(component, :result, nil) + end + + def template do + ~H""" +
+ + + + + + + + + + + +
+
+ Result: {inspect(@result)}
+
+ +
+ """ + end + + # public funciton / no args / single clause / single-expression body + def action(:basic_case, _params, component) do + result = local_fun_1() + + put_state(component, :result, result) + end + + def action(:private_function, _params, component) do + result = local_fun_10() + + put_state(component, :result, result) + end + + def action(:single_arg, _params, component) do + result = local_fun_2(:a) + + put_state(component, :result, result) + end + + def action(:multiple_args, _params, component) do + result = local_fun_3(:a, :b) + + put_state(component, :result, result) + end + + def action(:multiple_clauses, _params, component) do + result = local_fun_4(2, :a) + + put_state(component, :result, result) + end + + def action(:multiple_expression_body, _params, component) do + result = local_fun_5() + + put_state(component, :result, result) + end + + def action(:single_guard, _params, component) do + result = local_fun_6(2) + + put_state(component, :result, result) + end + + def action(:multiple_guards, _params, component) do + result = local_fun_7(25) + + put_state(component, :result, result) + end + + def action(:vars_scoping, _params, component) do + x = 1 + y = 2 + + result = local_fun_8(x, 5) + + put_state(component, :result, {x, y, result}) + end + + def action(:no_matching_clause, _params, _component) do + local_fun_4(4, 5) + end + + def action(:error_in_body, _params, _component) do + local_fun_9() + end + + def action(:reset, _params, component) do + put_state(component, :result, nil) + end + + def local_fun_1 do + :a + end + + def local_fun_2(x) do + x + end + + def local_fun_3(x, y) do + {x, y} + end + + def local_fun_4(1, x) do + {1, x} + end + + def local_fun_4(2, x) do + {2, x} + end + + def local_fun_4(3, x) do + {3, x} + end + + def local_fun_5 do + :a + :b + end + + def local_fun_6(x) when x == 1 do + :a + end + + def local_fun_6(x) when x == 2 do + :b + end + + def local_fun_6(x) when x == 3 do + :c + end + + def local_fun_7(x) when x > 0 and x < 10 do + :a + end + + def local_fun_7(x) when x > 10 and x < 20 do + :b + end + + def local_fun_7(x) when x > 10 and x < 30 do + :c + end + + def local_fun_7(x) when x > 10 and x < 40 do + :d + end + + def local_fun_8(x = 3, y = 4) do + {x, y} + end + + def local_fun_8(x, y) do + x = x + 10 + {x, y} + end + + def local_fun_9 do + raise RuntimeError, "my message" + end + + defp local_fun_10 do + :a + end +end diff --git a/test/features/test/function_calls/local_function_test.exs b/test/features/test/function_calls/local_function_test.exs new file mode 100644 index 000000000..8f5df874e --- /dev/null +++ b/test/features/test/function_calls/local_function_test.exs @@ -0,0 +1,98 @@ +defmodule HologramFeatureTests.FunctionCalls.LocalFunctionTest do + use HologramFeatureTests.TestCase, async: true + alias HologramFeatureTests.FunctionCalls.LocalFunctionPage + + # IMPORTANT! + # Keep consistent with Elixir/JavaScript consistency tests + # in test/elixir/hologram/ex_js_consistency/interpreter_test.exs (call local function section). + + # no args / single clause / single-expression body + feature "basic case", %{session: session} do + session + |> visit(LocalFunctionPage) + |> click(button("Basic case")) + |> assert_text(css("#result"), ":a") + end + + feature "private function", %{session: session} do + session + |> visit(LocalFunctionPage) + |> click(button("Private function")) + |> assert_text(css("#result"), ":a") + end + + feature "single arg", %{session: session} do + session + |> visit(LocalFunctionPage) + |> click(button("Single arg")) + |> assert_text(css("#result"), ":a") + end + + feature "multiple args", %{session: session} do + session + |> visit(LocalFunctionPage) + |> click(button("Multiple args")) + |> assert_text(css("#result"), "{:a, :b}") + end + + feature "multiple clauses", %{session: session} do + session + |> visit(LocalFunctionPage) + |> click(button("Multiple clauses")) + |> assert_text(css("#result"), "{2, :a}") + end + + feature "multiple-expression body", %{session: session} do + session + |> visit(LocalFunctionPage) + |> click(button("Multiple-expression body")) + |> assert_text(css("#result"), ":b") + end + + feature "single guard", %{session: session} do + session + |> visit(LocalFunctionPage) + |> click(button("Single guard")) + |> assert_text(css("#result"), ":b") + end + + feature "multiple guards", %{session: session} do + session + |> visit(LocalFunctionPage) + |> click(button("Multiple guards")) + |> assert_text(css("#result"), ":c") + end + + feature "vars scoping", %{session: session} do + session + |> visit(LocalFunctionPage) + |> click(button("Vars scoping")) + |> assert_text(css("#result"), "{1, 2, {11, 5}}") + end + + # # TODO: client error message for this case is inconsistent with server error message + feature "no matching clause", %{session: session} do + assert_client_error session, + FunctionClauseError, + build_function_clause_error_msg( + "HologramFeatureTests.FunctionCalls.LocalFunctionPage.local_fun_4/2", + [4, 5] + ), + fn -> + session + |> visit(LocalFunctionPage) + |> click(button("No matching clause")) + end + end + + feature "Error in body", %{session: session} do + assert_client_error session, + RuntimeError, + "my message", + fn -> + session + |> visit(LocalFunctionPage) + |> click(button("Error in body")) + end + end +end