Created
November 23, 2012 00:13
-
-
Save daronco/4133411 to your computer and use it in GitHub Desktop.
Shoulda matcher have_attr_accessor
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# Ensures the model has an attr_accessor, attr_reader or attr_writer | |
# Examples: | |
# it { should have_attr_accessor(:value) } | |
# it { should have_attr_accessor(:value).read_only } | |
# it { should have_attr_accessor(:value).write_only } | |
module Shoulda | |
module Matchers | |
module ActiveModel # :nodoc | |
def have_attr_accessor(attribute) | |
HaveAttrAccessorMatcher.new(attribute) | |
end | |
class HaveAttrAccessorMatcher < ValidationMatcher # :nodoc: | |
def initialize(attribute) | |
@attribute = attribute | |
@ro = false | |
@wo = false | |
end | |
def read_only | |
@ro = true | |
self | |
end | |
def write_only | |
@wo = true | |
self | |
end | |
def matches?(subject) | |
@subject = subject | |
reader = @subject.respond_to?(@attribute) | |
writer = @subject.respond_to?("#{@attribute.to_s}=") | |
v = true | |
v = v && !reader if @wo | |
v = v && reader unless @wo | |
v = v && !writer if @ro | |
v = v && writer unless @ro | |
v | |
end | |
def description | |
msg = "have " | |
if @ro | |
msg += "read only" | |
elsif @wo | |
msg += "write only" | |
else | |
msg += "read and write" | |
end | |
msg += " accessors for #{@attribute}" | |
end | |
def failure_message | |
if @ro | |
"Expected #{@subject.class.name} to respond only to '#{@attribute}'" | |
elsif @wo | |
"Expected #{@subject.class.name} to respond only to '#{@attribute}='" | |
else | |
"Expected #{@subject.class.name} to respond to both '#{@attribute}' and '#{@attribute}='" | |
end | |
end | |
def negative_failure_message | |
if @ro | |
"Expected #{@subject.class.name} not to respond only to '#{@attribute}'" | |
elsif @wo | |
"Expected #{@subject.class.name} not to respond only to '#{@attribute}'=" | |
else | |
"Expected #{@subject.class.name} not to respond to '#{@attribute}' and '#{@attribute}='" | |
end | |
end | |
end | |
end | |
end | |
end |
+1
I would expect, instead of read_only and write_only, to have separate matchers for have_attr_writer
and have_attr_reader
. Then you could, for example, use attr_reader
but create a more involved writer method that does not use attr_writer
:
it { is_expected.to have_attr_reader(:value) }
it { is_expected.to_not have_attr_writer(:value) }
Also, attr_accessors are not part of ActiveModel
, they are defined in ruby core Module
Any updates on this? I find it hard to believe that people out there aren't testing their attr_*, or else are repeating themselves constantly.
- 1, I see this is still not part of https://github.com/thoughtbot/shoulda-matchers
All I get from this is a (NameError)
:
uninitialized constant Shoulda::Matchers::ActiveRecord::ValidationMatcher (NameError)
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Nice one. Any way you can submit this to the Shoulda library for inclusion?