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
13 changes: 7 additions & 6 deletions lib/stream_data.ex
Original file line number Diff line number Diff line change
Expand Up @@ -2032,7 +2032,7 @@ defmodule StreamData do

{:error, reason} ->
shrinking_result =
shrink_failure(shrink_initial_cont(children), nil, reason, fun, 1, config)
shrink_failure(shrink_initial_cont(children), [], reason, fun, 1, config)
|> Map.put(:original_failure, reason)
|> Map.put(:successful_runs, runs)

Expand All @@ -2059,23 +2059,24 @@ defmodule StreamData do
# node but only if it has children, otherwise we move to the siblings. If it
# doesn't fail, we move to the siblings.

defp shrink_failure(cont, parent_cont, smallest, fun, nodes_visited, config) do
defp shrink_failure(cont, parent_conts, smallest, fun, nodes_visited, config) do
case cont.({:cont, []}) do
{state, _} when state in [:halted, :done] and is_function(parent_cont) ->
shrink_failure(parent_cont, nil, smallest, fun, nodes_visited, config)
{state, _} when state in [:halted, :done] and length(parent_conts) > 0 ->
[parent_cont | parent_conts] = parent_conts
shrink_failure(parent_cont, parent_conts, smallest, fun, nodes_visited, config)

{state, _} when state in [:halted, :done] ->
%{shrunk_failure: smallest, nodes_visited: nodes_visited}

{:suspended, [child], cont} ->
case fun.(child.root) do
{:ok, _term} ->
shrink_failure(cont, nil, smallest, fun, nodes_visited + 1, config)
shrink_failure(cont, [], smallest, fun, nodes_visited + 1, config)

{:error, reason} ->
shrink_failure(
shrink_initial_cont(child.children),
cont,
[cont | parent_conts],
reason,
fun,
nodes_visited + 1,
Expand Down
22 changes: 19 additions & 3 deletions test/stream_data_test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -189,9 +189,25 @@ defmodule StreamDataTest do
assert Enum.count(values, &(&1 == :small_chance)) < Enum.count(values, &(&1 == :big_chance))
end

property "one_of/1" do
check all int <- one_of([integer(1..5), integer(-1..-5)]) do
assert int in 1..5 or int in -1..-5
describe "one_of/1" do
property "picks one of the supplied generators" do
check all int <- one_of([integer(1..5), integer(-1..-5)]) do
assert int in 1..5 or int in -1..-5
end
end

property "shrinks towards earlier generators" do
check all size <- positive_integer(),
seed <- {integer(), integer(), integer()} do
{:error, result} =
one_of([:foo, {:bar, integer()}])
|> check_all(
[max_shrinking_steps: 100, initial_size: size, initial_seed: seed],
fn example -> {:error, example} end
)

assert result.shrunk_failure == :foo or result.nodes_visited >= 100
end
end
end

Expand Down