whatyouhide / stream_data

Data generation and property-based testing for Elixir. šŸ”®
https://hexdocs.pm/stream_data
864 stars 66 forks source link

Simple generator for random/constant/unshrinkable things #172

Closed zachdaniel closed 2 years ago

zachdaniel commented 2 years ago

I can't seem to find a way to make a simple generator for something like &Ecto.UUID.generate/0. Per #38, bind/2 works I think because the inner generator is recreated each time, so my best guess on implementing that generator is currently

# Just picking any generator here
StreamData.integer()
|> StreamData.bind(fn _i -> StreamData.constant(Ecto.UUID.generate()) end)
|> StreamData.unshrinkable()

It seems strange to have to build off of another generator for no good reason there.

StreamData.constant(Ecto.UUID.generate()) |> Enum.take(10)

This doesn't work, as naturally the list simply repeats the generated uuid.

whatyouhide commented 2 years ago

@zachdaniel yep, that's a valid point!

The easiest way is probably something like this:

map(boolean(), fn _ ā†’ Ecto.UUID.generate() end)

which is very similar to what you show above. Iā€™m open to having something like StreamData.from_stream/1 though? It would be an unshrinkable generator that takes any stream and converts it to a StreamData generator. With that, you could implement the UUID as:

&Ecto.UUID.generate/0
|> Stream.repeatedly()
|> StreamData.from_stream()

Thoughts?

zachdaniel commented 2 years ago

I think StreamData.from_stream/1 being unshrinkable may be a bit of a footgun, and that perhaps we should add something smaller like StreamData.repeatedly/1?

whatyouhide commented 2 years ago

@zachdaniel Iā€™m ok to start with StreamData.repeatedly/1. Wanna go for a PR? šŸ™ƒ

zachdaniel commented 2 years ago

Absolutely :)