So I tried to make my own generator like this:
def photo_meta_gen do
domain(
PhotoMeta,
fn (self, size) ->
{_, width} = pick(non_neg_integer, size)
{_, height} = pick(non_neg_integer, size)
{_, url} = pick(unicode_string, size)
{self, %{"width" => width, "height" => height, "url" => url}}
end,
fn (self, value) ->
(self, %{"width" => w} = value) when w > 0 -> {self, %{value | "width" => w - 1}}
(self, %{"height" => h} = value) when h > 0 -> {self, %{value | "height" => h - 1}}
(self, %{"url" => url} = value) when not(is_nil(url)) -> {self, %{value | "url" => String.slice(url, 0..-2)}}
(self, value) -> {self, value}
end
)
end
Then I changed my property to:
for_all unparsed_photo_meta in photo_meta_gen do
unparsed_photo_meta ==
unparsed_photo_meta
|> PhotoMeta.parse
|> Poison.encode!
|> Poison.decode!
end
Then I thought I could try to reuse the shrinkers defined by triq to simplify my custom generator. Example with the url key:
def photo_meta_gen do
domain(
PhotoMeta,
fn (self, size) ->
{_, width} = pick(non_neg_integer, size)
{_, height} = pick(non_neg_integer, size)
{_, url} = pick(unicode_string, size)
{self, %{"width" => width, "height" => height, "url" => url}}
end,
fn (self, value) ->
(self, %{"width" => w} = value) when w > 0 -> {self, %{value | "width" => w - 1}}
(self, %{"height" => h} = value) when h > 0 -> {self, %{value | "height" => h - 1}}
(self, %{"url" => url} = value) -> {self, %{value | "url" => shrink(unicode_string(), url)}}
(self, value) -> {self, value}
end
)
end
But it doesn’t work, and if I try it myself in iex I get this error:
iex(3)> :triq_dom.shrink(:triq_dom.unicode_string(), "lol")
** (ErlangError) erlang error: {:shrink, {:list, {:@, :unicode_char, #Function<83.73849349/2 in :triq_dom.unicode_char/0>, #Function<84.73849349/2 in :triq_dom.unicode_char/0>, true}}}
src/triq_dom.erl:163: :triq_dom.error_shrink/2