Skip to content

Commit

Permalink
Size validation matcher conversion
Browse files Browse the repository at this point in the history
  • Loading branch information
Jon Yurek committed Feb 8, 2009
1 parent 9e73929 commit f78528a
Show file tree
Hide file tree
Showing 4 changed files with 137 additions and 48 deletions.
1 change: 1 addition & 0 deletions shoulda_macros/matchers.rb
Original file line number Original file line Diff line number Diff line change
@@ -1,3 +1,4 @@
require 'shoulda_macros/matchers/have_attached_file_matcher' require 'shoulda_macros/matchers/have_attached_file_matcher'
require 'shoulda_macros/matchers/validate_attachment_presence_matcher' require 'shoulda_macros/matchers/validate_attachment_presence_matcher'
require 'shoulda_macros/matchers/validate_attachment_content_type_matcher' require 'shoulda_macros/matchers/validate_attachment_content_type_matcher'
require 'shoulda_macros/matchers/validate_attachment_size_matcher'
83 changes: 83 additions & 0 deletions shoulda_macros/matchers/validate_attachment_size_matcher.rb
Original file line number Original file line Diff line number Diff line change
@@ -0,0 +1,83 @@
module Paperclip
module Shoulda
module Matchers
def validate_attachment_size name
ValidateAttachmentSizeMatcher.new(name)
end

class ValidateAttachmentSizeMatcher
def initialize attachment_name
@attachment_name = attachment_name
@low, @high = 0, (1.0/0)
end

def less_than size
@high = size
self
end

def greater_than size
@low = size
self
end

def in range
@low, @high = range.first, range.last
self
end

def matches? subject
@subject = subject
lower_than_low? && higher_than_low? && lower_than_high? && higher_than_high?
end

def failure_message
"Attachment #{@attachment_name} must be between #{@low} and #{@high} bytes"
end

def negative_failure_message
"Attachment #{@attachment_name} cannot be between #{@low} and #{@high} bytes"
end

def description
"validate the size of attachment #{@attachment_name}"
end

protected

def override_method object, method, &replacement
(class << object; self; end).class_eval do
define_method(method, &replacement)
end
end

def passes_validation_with_size(new_size)
file = StringIO.new(".")
override_method(file, :size){ new_size }
attachment = @subject.new.attachment_for(@attachment_name)
attachment.assign(file)
attachment.errors[:size].nil?
end

def lower_than_low?
not passes_validation_with_size(@low - 1)
end

def higher_than_low?
passes_validation_with_size(@low + 1)
end

def lower_than_high?
return true if @high == (1.0/0)
passes_validation_with_size(@high - 1)
end

def higher_than_high?
return true if @high == (1.0/0)
not passes_validation_with_size(@high + 1)
end
end
end
end
end

51 changes: 3 additions & 48 deletions shoulda_macros/paperclip.rb
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -54,54 +54,9 @@ def should_validate_attachment_size name, options = {}
min = options[:greater_than] || (options[:in] && options[:in].first) || 0 min = options[:greater_than] || (options[:in] && options[:in].first) || 0
max = options[:less_than] || (options[:in] && options[:in].last) || (1.0/0) max = options[:less_than] || (options[:in] && options[:in].last) || (1.0/0)
range = (min..max) range = (min..max)
context "Class #{klass.name} validating file size on #{name}" do matcher = validate_attachment_size(name).in(range)
context "with an attachment that is #{max+1} bytes" do should matcher.description do
setup do assert_accepts(matcher, klass)
@file = StringIO.new("." * (max+1))
@attachment = klass.new.send(name)
@attachment.assign(@file)
end

should "have a :size validation error" do
assert @attachment.errors[:size]
end
end
context "with an attachment that us #{max-1} bytes" do
setup do
@file = StringIO.new("." * (max-1))
@attachment = klass.new.send(name)
@attachment.assign(@file)
end

should "not have a :size validation error" do
assert ! @attachment.errors[:size]
end
end

if min > 0
context "with an attachment that is #{min-1} bytes" do
setup do
@file = StringIO.new("." * (min-1))
@attachment = klass.new.send(name)
@attachment.assign(@file)
end

should "have a :size validation error" do
assert @attachment.errors[:size]
end
end
context "with an attachment that us #{min+1} bytes" do
setup do
@file = StringIO.new("." * (min+1))
@attachment = klass.new.send(name)
@attachment.assign(@file)
end

should "not have a :size validation error" do
assert ! @attachment.errors[:size]
end
end
end
end end
end end
end end
Expand Down
50 changes: 50 additions & 0 deletions test/matchers/validate_attachment_size_matcher_test.rb
Original file line number Original file line Diff line number Diff line change
@@ -0,0 +1,50 @@
require 'test/helper'

class ValidateAttachmentSizeMatcherTest < Test::Unit::TestCase
context "validate_attachment_size" do
setup do
reset_table("dummies") do |d|
d.string :avatar_file_name
end
@dummy_class = reset_class "Dummy"
@dummy_class.has_attached_file :avatar
end

context "of limited size" do
setup{ @matcher = validate_attachment_size(:avatar).in(256..1024) }

should "reject a class with no validation" do
assert_rejects @matcher, @dummy_class
end

should "reject a class with a validation that's too high" do
@dummy_class.validates_attachment_size :avatar, :in => 256..2048
assert_rejects @matcher, @dummy_class
end

should "reject a class with a validation that's too low" do
@dummy_class.validates_attachment_size :avatar, :in => 0..1024
assert_rejects @matcher, @dummy_class
end

should "accept a class with a validation that matches" do
@dummy_class.validates_attachment_size :avatar, :in => 256..1024
assert_accepts @matcher, @dummy_class
end
end

context "validates_attachment_size with infinite range" do
setup{ @matcher = validate_attachment_size(:avatar) }

should "accept a class with an upper limit" do
@dummy_class.validates_attachment_size :avatar, :less_than => 1
assert_accepts @matcher, @dummy_class
end

should "accept a class with no upper limit" do
@dummy_class.validates_attachment_size :avatar, :greater_than => 1
assert_accepts @matcher, @dummy_class
end
end
end
end

0 comments on commit f78528a

Please sign in to comment.