Commit f78528a7 by Jon Yurek

Size validation matcher conversion

parent 9e73929c
require 'shoulda_macros/matchers/have_attached_file_matcher'
require 'shoulda_macros/matchers/validate_attachment_presence_matcher'
require 'shoulda_macros/matchers/validate_attachment_content_type_matcher'
require 'shoulda_macros/matchers/validate_attachment_size_matcher'
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
......@@ -54,54 +54,9 @@ module Paperclip
min = options[:greater_than] || (options[:in] && options[:in].first) || 0
max = options[:less_than] || (options[:in] && options[:in].last) || (1.0/0)
range = (min..max)
context "Class #{klass.name} validating file size on #{name}" do
context "with an attachment that is #{max+1} bytes" do
setup do
@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
matcher = validate_attachment_size(name).in(range)
should matcher.description do
assert_accepts(matcher, klass)
end
end
end
......
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
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment