Skip to content

Commit

Permalink
[Matcher] Add duration validator matcher
Browse files Browse the repository at this point in the history
  • Loading branch information
Mth0158 committed Dec 29, 2024
1 parent b1c2ce2 commit 8673a02
Show file tree
Hide file tree
Showing 15 changed files with 352 additions and 37 deletions.
5 changes: 3 additions & 2 deletions lib/active_storage_validations/matchers.rb
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
require 'active_storage_validations/matchers/limit_validator_matcher'
require 'active_storage_validations/matchers/content_type_validator_matcher'
require 'active_storage_validations/matchers/dimension_validator_matcher'
require 'active_storage_validations/matchers/duration_validator_matcher'
require 'active_storage_validations/matchers/size_validator_matcher'
require 'active_storage_validations/matchers/total_size_validator_matcher'

Expand All @@ -25,8 +26,8 @@ def self.stub_method(object, method, result)
end
end

def self.mock_metadata(attachment, width, height)
mock = Struct.new(:metadata).new({ width: width, height: height })
def self.mock_metadata(attachment, metadata = {})
mock = Struct.new(:metadata).new(metadata)

stub_method(ActiveStorageValidations::Analyzer, :new, mock) do
yield
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,7 @@ def is_custom_message_valid?
end

def mock_dimensions_for(attachment, width, height)
Matchers.mock_metadata(attachment, width, height) do
Matchers.mock_metadata(attachment, { width: width, height: height }) do
yield
end
end
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,23 +33,23 @@ def initialize(attribute_name)
@min = @max = nil
end

def less_than(size)
@max = size - 1.byte
def less_than(value)
@max = value - smallest_measurement
self
end

def less_than_or_equal_to(size)
@max = size
def less_than_or_equal_to(value)
@max = value
self
end

def greater_than(size)
@min = size + 1.byte
def greater_than(value)
@min = value + smallest_measurement
self
end

def greater_than_or_equal_to(size)
@min = size
def greater_than_or_equal_to(value)
@min = value
self
end

Expand Down Expand Up @@ -78,56 +78,62 @@ def build_failure_message(message)

message << " but there seem to have issues with the matcher methods you used, since:"
@failure_message_artefacts.each do |error_case|
message << " validation failed when provided with a #{error_case[:size]} bytes test file"
message << " validation failed when provided with a #{error_case[:value]} #{failure_message_unit} test file"
end
message << " whereas it should have passed"
end

def failure_message_unit
raise NotImplementedError
end

def not_lower_than_min?
@min.nil? || !passes_validation_with_size(@min - 1)
@min.nil? || !passes_validation_with_value(@min - 1)
end

def higher_than_min?
@min.nil? || passes_validation_with_size(@min + 1)
@min.nil? || passes_validation_with_value(@min + 1)
end

def lower_than_max?
@max.nil? || @max == Float::INFINITY || passes_validation_with_size(@max - 1)
@max.nil? || @max == Float::INFINITY || passes_validation_with_value(@max - 1)
end

def not_higher_than_max?
@max.nil? || @max == Float::INFINITY || !passes_validation_with_size(@max + 1)
@max.nil? || @max == Float::INFINITY || !passes_validation_with_value(@max + 1)
end

def passes_validation_with_size(size)
mock_size_for(io, size) do
def smallest_measurement
raise NotImplementedError
end

def passes_validation_with_value(value)
mock_value_for(io, value) do
attach_file
validate
detach_file
is_valid? || add_failure_message_artefact(size)
is_valid? || add_failure_message_artefact(value)
end
end

def add_failure_message_artefact(size)
@failure_message_artefacts << { size: size }
def add_failure_message_artefact(value)
@failure_message_artefacts << { value: value }
false
end

def is_custom_message_valid?
return true unless @custom_message

mock_size_for(io, -1.kilobytes) do
mock_value_for(io, -smallest_measurement) do
attach_file
validate
detach_file
has_an_error_message_which_is_custom_message?
end
end

def mock_size_for(io, size)
Matchers.stub_method(io, :size, size) do
yield
end
def mock_value_for(io, size)
raise NotImplementedError
end
end
end
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -185,7 +185,7 @@ def is_custom_message_valid?
end

def mock_dimensions_for(attachment, width, height)
Matchers.mock_metadata(attachment, width, height) do
Matchers.mock_metadata(attachment, { width: width, height: height }) do
yield
end
end
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
# frozen_string_literal: true

require_relative 'base_comparison_validator_matcher'

module ActiveStorageValidations
module Matchers
def validate_duration_of(attribute_name)
DurationValidatorMatcher.new(attribute_name)
end

class DurationValidatorMatcher < BaseComparisonValidatorMatcher
def description
"validate file duration of :#{@attribute_name}"
end

def failure_message
message = ["is expected to validate file duration of :#{@attribute_name}"]
build_failure_message(message)
message.join("\n")
end

private

def failure_message_unit
"seconds"
end

def smallest_measurement
1.second
end

def mock_value_for(io, duration)
Matchers.mock_metadata(io, { duration: duration }) do
yield
end
end
end
end
end
16 changes: 16 additions & 0 deletions lib/active_storage_validations/matchers/size_validator_matcher.rb
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,22 @@ def failure_message
build_failure_message(message)
message.join("\n")
end

private

def failure_message_unit
"bytes"
end

def smallest_measurement
1.byte
end

def mock_value_for(io, size)
Matchers.stub_method(io, :size, size) do
yield
end
end
end
end
end
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,22 @@ def attach_file
@subject.public_send(@attribute_name).attach([dummy_blob])
@subject.public_send(@attribute_name)
end

private

def failure_message_unit
"bytes"
end

def smallest_measurement
1.byte
end

def mock_value_for(io, size)
Matchers.stub_method(io, :size, size) do
yield
end
end
end
end
end
8 changes: 4 additions & 4 deletions test/dummy/app/models/duration/matcher.rb
Original file line number Diff line number Diff line change
Expand Up @@ -74,9 +74,9 @@ class Duration::Matcher < ApplicationRecord
has_one_attached :greater_than_with_message
has_one_attached :greater_than_or_equal_to_with_message
has_one_attached :between_with_message
validates :less_than_with_message, duration: { less_than: 2.seconds, message: 'File is too big.' }
validates :less_than_or_equal_to_with_message, duration: { less_than_or_equal_to: 2.seconds, message: 'File is too big.' }
validates :greater_than_with_message, duration: { greater_than: 7.seconds, message: 'File is too small.' }
validates :greater_than_or_equal_to_with_message, duration: { greater_than_or_equal_to: 7.seconds, message: 'File is too small.' }
validates :less_than_with_message, duration: { less_than: 2.seconds, message: 'File is too long.' }
validates :less_than_or_equal_to_with_message, duration: { less_than_or_equal_to: 2.seconds, message: 'File is too long.' }
validates :greater_than_with_message, duration: { greater_than: 7.seconds, message: 'File is too short.' }
validates :greater_than_or_equal_to_with_message, duration: { greater_than_or_equal_to: 7.seconds, message: 'File is too short.' }
validates :between_with_message, duration: { between: 2.seconds..7.seconds, message: 'File is not in accepted duration range.' }
end
Loading

0 comments on commit 8673a02

Please sign in to comment.