Description
In case they help others, here are a couple of "helper" functions that I've found useful.
maybe()
I often want specs or schemas that also accept a nil
value. Rather than littering my specs with spec(is_nil() or (...))
, I have a maybe()
helper function:
def maybe(spec), do: one_of([spec(is_nil()), spec])
Example:
def order(), do: spec(is_integer() and (&(&1 >= 0)))
@contract get_order() :: maybe(order())
def get_order(), do: Enum.random([nil, 0, 1, 2, 3])
Perhaps it's something that could be included in the library as a bit of syntactic sugar.
regex()
When using Regex.match?
in specs, it's important to also check for is_binary()
. Otherwise, when you send, say, a nil
value you'll get a no function clause matching in Regex.match?/2
error with a stacktrace that only points to Norm's own code. (It will still crash when wrapped in my maybe()
helper function.)
So that I don't forget any is_binary()
clauses, I use my own regex()
helper function(s).
def flip(p2, p1, func), do: apply(func, [p1, p2])
def regex(regex), do: spec(is_binary() and flip(regex, &Regex.match?/2))
Example:
def date(), do: regex(~r/^20\d\d-\d\d-\d\d$/)
Perhaps match()
or match?()
would be better naming than regex()
.