Skip to content

Commit

Permalink
[Matcher] Add #allow_blank option on matchers (#224)
Browse files Browse the repository at this point in the history
  • Loading branch information
Mth0158 committed Dec 8, 2023
1 parent 6b8f4f1 commit 5a08068
Show file tree
Hide file tree
Showing 17 changed files with 123 additions and 18 deletions.
6 changes: 5 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -331,13 +331,17 @@ end
```
(Note that matcher methods are chainable)

All matchers can currently be customized with 2 Rails validation options:
All matchers can currently be customized with Rails validation options:

```ruby
describe User do
# allow_blank
it { is_expected.to validate_attached_of(:avatar).allow_blank }
# :on
it { is_expected.to validate_attached_of(:avatar).on(:update) }
it { is_expected.to validate_attached_of(:avatar).on(%i[update custom]) }
# :message
it { is_expected.to validate_dimensions_of(:avatar).width(250).with_message('Invalid dimensions.') }
end
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
# frozen_string_literal: true

require_relative 'concerns/active_storageable.rb'
require_relative 'concerns/allow_blankable.rb'
require_relative 'concerns/contextable.rb'
require_relative 'concerns/messageable.rb'
require_relative 'concerns/validatable.rb'
Expand All @@ -13,6 +14,7 @@ def validate_aspect_ratio_of(name, expected_aspect_ratio)

class AspectRatioValidatorMatcher
include ActiveStorageable
include AllowBlankable
include Contextable
include Messageable
include Validatable
Expand Down Expand Up @@ -41,9 +43,10 @@ def matches?(subject)

is_a_valid_active_storage_attribute? &&
is_context_valid? &&
is_allowing_blank? &&
is_custom_message_valid? &&
all_allowed_aspect_ratios_allowed? &&
all_rejected_aspect_ratios_rejected? &&
is_custom_message_valid?
all_rejected_aspect_ratios_rejected?
end

def failure_message
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,9 +30,9 @@ def matches?(subject)

is_a_valid_active_storage_attribute? &&
is_context_valid? &&
is_custom_message_valid? &&
is_valid_when_file_attached? &&
is_invalid_when_file_not_attached? &&
is_custom_message_valid?
is_invalid_when_file_not_attached?
end

def failure_message
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
require "active_support/concern"

module ActiveStorageValidations
module Matchers
module AllowBlankable
extend ActiveSupport::Concern

def initialize(attribute_name)
super
@allow_blank = nil
end

def allow_blank
@allow_blank = true
self
end

private

def is_allowing_blank?
return true unless @allow_blank

validate
end
end
end
end
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
# https://github.com/thoughtbot/paperclip/blob/v6.1.0/lib/paperclip/matchers/validate_attachment_content_type_matcher.rb

require_relative 'concerns/active_storageable.rb'
require_relative 'concerns/allow_blankable.rb'
require_relative 'concerns/contextable.rb'
require_relative 'concerns/messageable.rb'
require_relative 'concerns/validatable.rb'
Expand All @@ -16,6 +17,7 @@ def validate_content_type_of(name)

class ContentTypeValidatorMatcher
include ActiveStorageable
include AllowBlankable
include Contextable
include Messageable
include Validatable
Expand Down Expand Up @@ -44,9 +46,10 @@ def matches?(subject)

is_a_valid_active_storage_attribute? &&
is_context_valid? &&
is_allowing_blank? &&
is_custom_message_valid? &&
all_allowed_types_allowed? &&
all_rejected_types_rejected? &&
is_custom_message_valid?
all_rejected_types_rejected?
end

def failure_message
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
# frozen_string_literal: true

require_relative 'concerns/active_storageable.rb'
require_relative 'concerns/allow_blankable.rb'
require_relative 'concerns/contextable.rb'
require_relative 'concerns/messageable.rb'
require_relative 'concerns/validatable.rb'
Expand All @@ -13,6 +14,7 @@ def validate_dimensions_of(name)

class DimensionValidatorMatcher
include ActiveStorageable
include AllowBlankable
include Contextable
include Messageable
include Validatable
Expand Down Expand Up @@ -71,6 +73,8 @@ def matches?(subject)

is_a_valid_active_storage_attribute? &&
is_context_valid? &&
is_allowing_blank? &&
is_custom_message_valid? &&
width_not_smaller_than_min? &&
width_larger_than_min? &&
width_smaller_than_max? &&
Expand All @@ -80,8 +84,7 @@ def matches?(subject)
height_larger_than_min? &&
height_smaller_than_max? &&
height_not_larger_than_max? &&
height_equals? &&
is_custom_message_valid?
height_equals?
end

def failure_message
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
# https://github.com/thoughtbot/paperclip/blob/v6.1.0/lib/paperclip/matchers/validate_attachment_size_matcher.rb

require_relative 'concerns/active_storageable.rb'
require_relative 'concerns/allow_blankable.rb'
require_relative 'concerns/contextable.rb'
require_relative 'concerns/messageable.rb'
require_relative 'concerns/validatable.rb'
Expand All @@ -16,6 +17,7 @@ def validate_size_of(name)

class SizeValidatorMatcher
include ActiveStorageable
include AllowBlankable
include Contextable
include Messageable
include Validatable
Expand Down Expand Up @@ -59,11 +61,12 @@ def matches?(subject)

is_a_valid_active_storage_attribute? &&
is_context_valid? &&
is_allowing_blank? &&
is_custom_message_valid? &&
not_lower_than_min? &&
higher_than_min? &&
lower_than_max? &&
not_higher_than_max? &&
is_custom_message_valid?
not_higher_than_max?
end

def failure_message
Expand Down
3 changes: 3 additions & 0 deletions test/dummy/app/models/aspect_ratio/matcher.rb
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,9 @@ class AspectRatio::Matcher < ApplicationRecord
has_one_attached :allowing_one_is_x_y
validates :allowing_one_is_x_y, aspect_ratio: :is_16_9

has_one_attached :allow_blank
validates :allow_blank, aspect_ratio: :square, allow_blank: true

has_one_attached :with_message
validates :with_message, aspect_ratio: { with: :square, message: 'Custom message' }

Expand Down
3 changes: 3 additions & 0 deletions test/dummy/app/models/content_type/matcher.rb
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,9 @@ class ContentType::Matcher < ApplicationRecord
has_one_attached :allowing_several_through_regex
validates :allowing_several_through_regex, content_type: [/\Aimage\/.*\z/]

has_one_attached :allow_blank
validates :allow_blank, content_type: ['image/png'], allow_blank: true

has_one_attached :with_message
validates :with_message, content_type: { in: ['image/png'], message: 'Custom message' }

Expand Down
3 changes: 3 additions & 0 deletions test/dummy/app/models/dimension/matcher.rb
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,9 @@ class Dimension::Matcher < ApplicationRecord
validates :"#{bound}_with_message", dimension: { "#{bound}": 800..600, message: 'Invalid dimensions.' }
end

has_one_attached :allow_blank
validates :allow_blank, dimension: { width: 150, height: 150 }, allow_blank: true

has_one_attached :with_message
has_one_attached :without_message
validates :with_message, dimension: { width: 150, height: 150, message: 'Custom message' }
Expand Down
3 changes: 3 additions & 0 deletions test/dummy/app/models/size/matcher.rb
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,9 @@ class Size::Matcher < ApplicationRecord
validates :proc_greater_than_or_equal_to, size: { greater_than_or_equal_to: -> (record) { 7.kilobytes } }
validates :proc_between, size: { between: -> { 2.kilobytes..7.kilobytes } }

has_one_attached :allow_blank
validates :allow_blank, size: { less_than_or_equal_to: 5.megabytes }, allow_blank: true

has_one_attached :with_message
validates :with_message, size: { less_than_or_equal_to: 5.megabytes, message: 'Custom message' }

Expand Down
7 changes: 6 additions & 1 deletion test/matchers/aspect_ratio_validator_matcher_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,9 @@

require 'test_helper'
require 'matchers/shared_examples/checks_if_is_a_valid_active_storage_attribute'
require 'matchers/shared_examples/works_with_context'
require 'matchers/shared_examples/works_with_allow_blank'
require 'matchers/shared_examples/works_with_both_instance_and_class'
require 'matchers/shared_examples/works_with_context'
require 'matchers/shared_examples/works_with_custom_message'

describe ActiveStorageValidations::Matchers::AspectRatioValidatorMatcher do
Expand Down Expand Up @@ -234,6 +235,10 @@
end
end

describe "#allow_blank" do
include WorksWithAllowBlank
end

describe '#with_message' do
include WorksWithCustomMessage
end
Expand Down
2 changes: 1 addition & 1 deletion test/matchers/attached_validator_matcher_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@

require 'test_helper'
require 'matchers/shared_examples/checks_if_is_a_valid_active_storage_attribute'
require 'matchers/shared_examples/works_with_context'
require 'matchers/shared_examples/works_with_both_instance_and_class'
require 'matchers/shared_examples/works_with_context'
require 'matchers/shared_examples/works_with_custom_message'

describe ActiveStorageValidations::Matchers::AttachedValidatorMatcher do
Expand Down
5 changes: 5 additions & 0 deletions test/matchers/content_type_validator_matcher_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

require 'test_helper'
require 'matchers/shared_examples/checks_if_is_a_valid_active_storage_attribute'
require 'matchers/shared_examples/works_with_allow_blank'
require 'matchers/shared_examples/works_with_both_instance_and_class'
require 'matchers/shared_examples/works_with_context'
require 'matchers/shared_examples/works_with_custom_message'
Expand Down Expand Up @@ -154,6 +155,10 @@
end
end

describe "#allow_blank" do
include WorksWithAllowBlank
end

describe '#with_message' do
include WorksWithCustomMessage
end
Expand Down
5 changes: 5 additions & 0 deletions test/matchers/dimension_validator_matcher_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

require 'test_helper'
require 'matchers/shared_examples/checks_if_is_a_valid_active_storage_attribute'
require 'matchers/shared_examples/works_with_allow_blank'
require 'matchers/shared_examples/works_with_both_instance_and_class'
require 'matchers/shared_examples/works_with_context'
require 'matchers/shared_examples/works_with_custom_message'
Expand Down Expand Up @@ -321,6 +322,10 @@ module OnlyMatchWhenExactValues
end
end

describe "#allow_blank" do
include WorksWithAllowBlank
end

describe '#with_message' do
include WorksWithCustomMessage
end
Expand Down
30 changes: 30 additions & 0 deletions test/matchers/shared_examples/works_with_allow_blank.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
module WorksWithAllowBlank
extend ActiveSupport::Concern

included do
let(:model_attribute) { :allow_blank }

describe 'when provided with the other validator requirements' do
before do
case validator_sym
when :aspect_ratio then matcher.allowing(:square)
when :content_type then matcher.allowing('image/png')
when :dimension then matcher.width(150).height(150)
when :size then matcher.less_than_or_equal_to(5.megabytes)
end
end

describe 'and when provided with #allow_blank method' do
subject { matcher.allow_blank }

it { is_expected_to_match_for(klass) }
end

describe 'and when not provided with #allow_blank method' do
subject { matcher }

it { is_expected_to_match_for(klass) }
end
end
end
end
15 changes: 10 additions & 5 deletions test/matchers/size_validator_matcher_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

require 'test_helper'
require 'matchers/shared_examples/checks_if_is_a_valid_active_storage_attribute'
require 'matchers/shared_examples/works_with_allow_blank'
require 'matchers/shared_examples/works_with_both_instance_and_class'
require 'matchers/shared_examples/works_with_context'
require 'matchers/shared_examples/works_with_custom_message'
Expand All @@ -14,19 +15,19 @@ module OnlyMatchWhenExactValue
describe 'standard validator' do
describe 'when provided with a lower size than the size specified in the model validations' do
subject { matcher.public_send(matcher_method, 0.5.kilobyte) }

it { is_expected_not_to_match_for(klass) }
end

describe 'when provided with the exact size specified in the model validations' do
subject { matcher.public_send(matcher_method, validator_value) }

it { is_expected_to_match_for(klass) }
end

describe 'when provided with a higher size than the size specified in the model validations' do
subject { matcher.public_send(matcher_method, 99.kilobytes) }

it { is_expected_not_to_match_for(klass) }
end
end
Expand Down Expand Up @@ -141,6 +142,10 @@ module OnlyMatchWhenExactValue
end
end

describe "#allow_blank" do
include WorksWithAllowBlank
end

describe '#with_message' do
include WorksWithCustomMessage
end
Expand Down

0 comments on commit 5a08068

Please sign in to comment.