rspec-virtus
rspec-virtus copied to clipboard
Model with boolean attribute
With the current version it is not possible to test attribute type if attribute type is boolean.
The current implementation uses method Attribute#primitive
to fetch and compare types, which in case of Boolean returns BasicObject (because ruby does not have a corresponding type) and thus fails.
class Authorization
include Virtus.model
attribute :status, String
attribute :approved, Boolean
attribute :pending
end
it { expect(described_class).to have_attribute(:approved).of_type(described_class::Boolean) } # fails
it { expect(described_class).to have_attribute(:approved).of_type(Virtus::Attribute::Boolean) } # fails
it { expect(described_class).to have_attribute(:approved).of_type(Axiom::Types::Boolean) } #fails
Authorization.attribute_set['status'] #=> #<Virtus::Attribute type=Axiom::Types::String (String)
Authorization.attribute_set['status'].primitive #=> String
Authorization.attribute_set['approved'] #=> #<Virtus::Attribute::Boolean type=Axiom::Types::Boolean (BasicObject) ...
Authorization.attribute_set['approved'].primitive #=> BasicObject
Authorization.attribute_set['pending'] #=> #<Virtus::Attribute type=Axiom::Types::Object (BasicObject)
Authorization.attribute_set['pending'].primitive #=> BasicObject
As a solution I suggest to update method type_correct?
to check if attribute is instance of given type.
module RSpec
module Virtus
class Matcher
def type_correct?
if @options[:member_type]
member_type == @options[:member_type] && (attribute_type == @options[:type] || attribute.is_a?(@options[:type]))
elsif @options[:type]
attribute_type == @options[:type] || attribute.is_a?(@options[:type])
else
true
end
end
end
end
end