Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
44 changes: 44 additions & 0 deletions lib/stream_data_types.ex
Original file line number Diff line number Diff line change
Expand Up @@ -113,4 +113,48 @@ defmodule StreamDataTypes do
defp generate({:type, _, :float, _}) do
float()
end

defp generate({:type, _line, :fun, [{:type, _, :any}, ret_type]}) do
ret_type = generate(ret_type)

create_fun(ret_type)
end

defp generate({:type, _line, :fun, [{:type, _, :product, args}, ret_type]}) do
arity = length(args)
ret_type = generate(ret_type)

create_fun(arity, ret_type)
end

@fn_arity_cap 20
defp create_fun(arity \\ nil, %StreamData{generator: generator}) do
f = fn seed, size ->
arity =
if arity do
arity
else
{int, _next_seed} = :rand.uniform_s(@fn_arity_cap, seed)
int
end

vars = Macro.generate_arguments(arity, Elixir)

ast = quote do
fn unquote_splicing(vars) ->
int = :erlang.phash2([unquote_splicing(vars)])
new_seed = :rand.seed_s(:exsp, {int, 0, 0})
var!(generator).(new_seed, var!(size)).root
end
end

{root, _} = Code.eval_quoted(ast, [generator: generator, size: size])
lazy_tree(root)
end
%StreamData{generator: f}
end

defp lazy_tree(root, children \\ []) do
%StreamData.LazyTree{root: root, children: children}
end
end
5 changes: 5 additions & 0 deletions test/stream_data/types_list.ex
Original file line number Diff line number Diff line change
Expand Up @@ -7,4 +7,9 @@ defmodule StreamDataTest.TypesList do
@type basic_neg_integer() :: neg_integer()
@type basic_non_neg_integer() :: non_neg_integer()
@type basic_pos_integer() :: pos_integer()

@type literal_function_arity_any :: (... -> float())
@type literal_function_arity_0 :: (() -> neg_integer())
@type literal_function_arity_1 :: (any() -> integer())
@type literal_function_arity_2 :: (integer(), atom() -> integer())
end
50 changes: 50 additions & 0 deletions test/stream_data/types_test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,56 @@ defmodule StreamData.TypesTest do
end
end

describe "literals" do
test "function with any arity" do
data = generate_data(:literal_function_arity_any)

check all f <- data, i <- integer() do
assert is_function(f)

{:arity, arity} = :erlang.fun_info(f, :arity)
args = List.duplicate(i, arity)

ast = quote do
var!(f).(unquote_splicing(args))
end
{int, _} = Code.eval_quoted(ast, f: f)

assert is_float(int)
end
end

test "function literal with 0 arguments" do
data = generate_data(:literal_function_arity_0)

check all f <- data do
assert is_function(f, 0)
assert f.() == f.() # The function is pure
int = f.()
assert is_integer(int)
assert int < 0
end
end

test "function literal with 1 argument" do
data = generate_data(:literal_function_arity_1)

check all f <- data, i <- integer() do
assert is_function(f, 1)
assert is_integer(f.(i))
end
end

test "function literal with 2 arguments" do
data = generate_data(:literal_function_arity_2)

check all f <- data, a <- integer(), b <- integer() do
assert is_function(f, 2)
assert is_integer(f.(a, b))
end
end
end

defp generate_data(name, args \\ []) do
Types.from_type(StreamDataTest.TypesList, name, args)
end
Expand Down