Skip to content

Commit

Permalink
Refactored specs for HaveAttachedMatcher (thoughtbot#1102)
Browse files Browse the repository at this point in the history
  • Loading branch information
StefSchenkelaars committed Jul 6, 2020
1 parent a963475 commit f7c5481
Show file tree
Hide file tree
Showing 3 changed files with 299 additions and 112 deletions.
103 changes: 59 additions & 44 deletions lib/shoulda/matchers/active_record/have_attached_matcher.rb
Expand Up @@ -18,20 +18,25 @@ def initialize(macro, name)
@name = name
end

def description
"has_#{macro}_attached #{name}"
def description
"have a has_#{macro}_attached called #{name}"
end

def failure_message
"Expected #{expectation} (#{@failure})"
<<-MESSAGE
Expected #{expectation}, but this could not be proved.
#{@failure}
MESSAGE
end

def failure_message_when_negated
"Did not expect #{expectation}"
<<-MESSAGE
Did not expect #{expectation}, but it does.
MESSAGE
end

def expectation
"#{model_class.name} to have a has_#{macro} attached called #{name}"
"#{model_class.name} to #{description}"
end

def matches?(subject)
Expand All @@ -47,83 +52,93 @@ def matches?(subject)

attr_reader :subject, :macro

def reader_attribute_exists?
if subject.respond_to?(name)
true
else
@failure = "#{model_class.name} does not have a :#{name} method."
false
end
end

def writer_attribute_exists?
if subject.respond_to?("#{name}=")
true
else
@failure = "#{model_class.name} does not have a :#{name}= method."
false
end
end

def attachments_association_exists?
if attachments_association_matcher.matches?(subject)
true
else
@failure = "no valid association called #{attachments_association_name}"
@failure = attachments_association_matcher.failure_message
false
end
end

def attachments_association_matcher
@attachments_association_matcher ||=
AssociationMatcher.new(:"has_#{macro}", attachments_association_name).
@_attachments_association_matcher ||=
AssociationMatcher.new(
:"has_#{macro}",
attachments_association_name,
).
conditions(name: name).
class_name('ActiveStorage::Attachment').
inverse_of(:record).
dependent(false)
end

def attachments_association_name
case macro
when :one then
"#{name}_attachment"
when :many then
"#{name}_attachments"
end
end

def blobs_association_exists?
if blobs_association_matcher.matches?(subject)
true
else
@failure = "no valid association called #{blobs_association_name}"
@failure = blobs_association_matcher.failure_message
false
end
end

def blobs_association_matcher
@blobs_association_matcher ||=
AssociationMatcher.new(:"has_#{macro}", blobs_association_name).
@_blobs_association_matcher ||=
AssociationMatcher.new(
:"has_#{macro}",
blobs_association_name,
).
through(attachments_association_name).
class_name('ActiveStorage::Blob').
source(:blob)
end

def blobs_association_name
case macro
when :one then
"#{name}_blob"
when :many then
"#{name}_blobs"
end
end

def eager_loading_scope_exists?
if model_class.respond_to?("with_attached_#{name}")
true
else
@failure = "no scope with_attached_#{name} found"
@failure = "#{model_class.name} does not have a " \
":with_attached_#{name} scope."
false
end
end

def reader_attribute_exists?
if !subject.respond_to?(name)
@failure = "no association #{name} found"
false
else
true
end
end

def writer_attribute_exists?
if !subject.respond_to?("#{name}=")
@failure = "no method #{name}= found"
false
else
true
end
end

def attachments_association_name
case macro
when :one then "#{name}_attachment"
when :many then "#{name}_attachments"
end
end

def blobs_association_name
case macro
when :one then "#{name}_blob"
when :many then "#{name}_blobs"
end
end

def model_class
subject.class
end
Expand Down
4 changes: 4 additions & 0 deletions spec/support/unit/helpers/active_record_versions.rb
Expand Up @@ -47,6 +47,10 @@ def active_record_supports_expression_indexes?
active_record_version >= 5
end

def active_record_supports_active_storage?
active_record_version >= 5.2
end

def active_record_supports_validate_presence_on_active_storage?
active_record_version >= '6.0.0.beta1'
end
Expand Down

0 comments on commit f7c5481

Please sign in to comment.