Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Keep a stack of continuations when shrinking #98

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
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.
Jump to
Jump to file
Failed to load files.
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