I’m working on a Ruby gem. Especially its specs.
We have custom
Dry::Types types. And we’re getting parsed API types for specs.
Attributes of our Ruby types have internal defaults, which external API has no.
How can I remove defaults from them?
class ReplyKeyboardRemove < Base
attribute? :selective, Types::Bool.default(false)
expected: #<Dry::Types[Sum<Constrained<Nominal<TrueClass> rule=[type?(TrueClass)]> | Constrained<Nominal<FalseClass> rule=[type?(FalseClass)]>>]>
got: #<Dry::Types[Default<Sum<Constrained<Nominal<TrueClass> rule=[type?(TrueClass)]> | Constrained<Nominal<FalseClass> rule=[type?(FalseClass)]>> value=false>]>
(compared using ==)
So I haven’t had to do this myself before, but one thing that’s with noting here is that a type with a default is just a wrapper over the original type, which you can still get to via
So something like this becomes possible:
Undefined = Dry::Core::Constants::Undefined
t = Types::Bool.default(true)
# Show the default in action
# => true
# Get the raw (non-defaulting) type
tt = t.type
# Show it no longer has a default
# This errors as expected!
# => Undefined violates constraints (type?(FalseClass, Undefined) failed) (Dry::Types::ConstraintError)
# And of course it still accepts a valid value
# => false
You’ll probably want to be careful with how you construct your types to make sure it’s actually the
Default wrapper that you’re unwrapping, but hopefully this can set you off in a good direction.
Yeah, thanks, I’ve already found this work-around yesterday.
attribute.type.type seems weird, but works. I thought maybe there is a more elegant way. OK.
About safety — yeah, just
if type.default? enough.