WIP
This commit is contained in:
parent
14d2d73da9
commit
6ebcce6ce0
|
@ -244,6 +244,10 @@ module Shoulda
|
|||
:context, :value, :matched_error, :after_setting_value_callback
|
||||
|
||||
def set_value(value)
|
||||
if attribute_to_set.nil?
|
||||
raise "No attribute has been set!"
|
||||
end
|
||||
|
||||
instance.__send__("#{attribute_to_set}=", value)
|
||||
after_setting_value_callback.call
|
||||
end
|
||||
|
|
|
@ -288,38 +288,35 @@ module Shoulda
|
|||
|
||||
delegate :failure_message, :failure_message_when_negated,
|
||||
:failure_message_for_should, :failure_message_for_should_not,
|
||||
to: :submatchers
|
||||
to: :matcher_collection
|
||||
|
||||
def initialize(attribute)
|
||||
@attribute = attribute
|
||||
@submatchers = MatcherCollection.new
|
||||
@matcher_collection = MatcherCollection.new
|
||||
@diff_to_compare = DEFAULT_DIFF_TO_COMPARE
|
||||
add_disallow_value_matcher
|
||||
|
||||
submatchers.configure do |matcher|
|
||||
matcher.for(attribute)
|
||||
end
|
||||
end
|
||||
|
||||
def only_integer
|
||||
add_submatcher(Numericality::OnlyIntegerMatcher)
|
||||
add_submatcher(Numericality::OnlyIntegerMatcher, attribute)
|
||||
self
|
||||
end
|
||||
|
||||
def allow_nil
|
||||
add_submatcher(AllowValueMatcher, nil) do |matcher|
|
||||
matcher.for(attribute)
|
||||
matcher.with_message(:not_a_number)
|
||||
end
|
||||
self
|
||||
end
|
||||
|
||||
def odd
|
||||
add_submatcher(Numericality::OddNumberMatcher)
|
||||
add_submatcher(Numericality::OddNumberMatcher, attribute)
|
||||
self
|
||||
end
|
||||
|
||||
def even
|
||||
add_submatcher(Numericality::EvenNumberMatcher)
|
||||
add_submatcher(Numericality::EvenNumberMatcher, attribute)
|
||||
self
|
||||
end
|
||||
|
||||
|
@ -349,13 +346,13 @@ module Shoulda
|
|||
end
|
||||
|
||||
def with_message(message)
|
||||
submatchers.configure { |matcher| matcher.with_message(message) }
|
||||
matcher_collection.configure(:with_message, message)
|
||||
self
|
||||
end
|
||||
|
||||
def matches?(subject)
|
||||
@subject = subject
|
||||
submatchers.matches?(subject)
|
||||
matcher_collection.matches?(subject)
|
||||
end
|
||||
|
||||
def description
|
||||
|
@ -364,22 +361,25 @@ module Shoulda
|
|||
|
||||
protected
|
||||
|
||||
attr_reader :attribute
|
||||
attr_reader :attribute, :matcher_collection
|
||||
|
||||
private
|
||||
|
||||
def add_submatcher(klass, *args, &block)
|
||||
submatchers.add(klass, *args, &block)
|
||||
matcher_collection.add(klass, *args, &block)
|
||||
end
|
||||
|
||||
def add_disallow_value_matcher
|
||||
add_submatcher(DisallowValueMatcher, NON_NUMERIC_VALUE) do |matcher|
|
||||
matcher.for(attribute)
|
||||
matcher.with_message(:not_a_number)
|
||||
end
|
||||
end
|
||||
|
||||
def add_comparison_submatcher(value, operator)
|
||||
add_submatcher(Numericality::ComparisonMatcher, self, value, operator)
|
||||
add_submatcher(Numericality::ComparisonMatcher, self, value, operator) do |matcher|
|
||||
matcher.for(attribute)
|
||||
end
|
||||
end
|
||||
|
||||
def diff_to_compare
|
||||
|
@ -387,7 +387,7 @@ module Shoulda
|
|||
end
|
||||
|
||||
def possible_diff_to_compares
|
||||
[DEFAULT_DIFF_TO_COMPARE] + submatchers.invoke(:diff_to_compare)
|
||||
[DEFAULT_DIFF_TO_COMPARE] + matcher_collection.invoke(:diff_to_compare)
|
||||
end
|
||||
|
||||
def allowed_types
|
||||
|
@ -399,7 +399,7 @@ module Shoulda
|
|||
end
|
||||
|
||||
def submatcher_allowed_types
|
||||
submatchers.invoke(:allowed_type)
|
||||
matcher_collection.invoke(:allowed_type)
|
||||
end
|
||||
|
||||
def comparison_descriptions
|
||||
|
@ -411,7 +411,7 @@ module Shoulda
|
|||
end
|
||||
|
||||
def submatcher_comparison_descriptions
|
||||
submatchers.invoke(:comparison_description)
|
||||
matcher_collection.invoke(:comparison_description)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
module Shoulda
|
||||
module Matchers
|
||||
module MatcherCollection
|
||||
class MatcherCollection
|
||||
attr_reader :failure_message, :failure_message_when_negated
|
||||
alias_method :failure_message_for_should,
|
||||
:failure_message
|
||||
|
@ -16,8 +16,18 @@ module Shoulda
|
|||
matchers_to_create << [klass, args, block]
|
||||
end
|
||||
|
||||
def configure(&block)
|
||||
matcher_configurations << block
|
||||
def configure(*args, &block)
|
||||
puts 'configure'
|
||||
# if block
|
||||
# matcher_configurations << block
|
||||
# else
|
||||
# # configure do |matcher|
|
||||
# # matcher.__send__(*args)
|
||||
# # end
|
||||
# matcher_configurations << proc do |matcher|
|
||||
# matcher.__send__(*args)
|
||||
# end
|
||||
# end
|
||||
end
|
||||
|
||||
def invoke(method_name)
|
||||
|
@ -28,37 +38,52 @@ module Shoulda
|
|||
|
||||
def matches?(subject)
|
||||
@subject = subject
|
||||
@failure_message = first_failing_matcher.failure_message
|
||||
|
||||
if first_failing_matcher
|
||||
@failure_message = first_failing_matcher.failure_message
|
||||
false
|
||||
else
|
||||
true
|
||||
end
|
||||
end
|
||||
|
||||
def does_not_match?(subject)
|
||||
@subject = subject
|
||||
@failure_message_when_negated =
|
||||
first_passing_matcher.failure_message_when_negated
|
||||
|
||||
if first_passing_matcher
|
||||
@failure_message_when_negated =
|
||||
first_passing_matcher.failure_message_when_negated
|
||||
false
|
||||
else
|
||||
true
|
||||
end
|
||||
end
|
||||
|
||||
protected
|
||||
|
||||
attr_reader :matchers_to_create, :matcher_configurations, :subject
|
||||
|
||||
private
|
||||
|
||||
def matchers
|
||||
@_matchers ||= matchers_to_create.map do |klass, args, block|
|
||||
klass.new(*args).tap do |matcher|
|
||||
matcher.call(block) if block
|
||||
|
||||
matcher_configurations.each do |block|
|
||||
block.call(matcher)
|
||||
end
|
||||
# block.call(matcher) if block
|
||||
# matcher_configurations.each do |block|
|
||||
# block.call(matcher)
|
||||
# end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def first_failing_matcher
|
||||
matchers.detect do |matcher|
|
||||
@_first_failing_matcher ||= matchers.detect do |matcher|
|
||||
!matcher.matches?(subject)
|
||||
end
|
||||
end
|
||||
|
||||
def first_passing_matcher
|
||||
matchers.detect do |matcher|
|
||||
@_first_passing_matcher ||= matchers.detect do |matcher|
|
||||
matcher.matches?(subject)
|
||||
end
|
||||
end
|
||||
|
|
|
@ -0,0 +1,48 @@
|
|||
module UnitTests
|
||||
module Matchers
|
||||
def alias_instance_method(old_method_name)
|
||||
AliasInstanceMethodMatcher.new(old_method_name)
|
||||
end
|
||||
|
||||
class AliasInstanceMethodMatcher
|
||||
def initialize(old_method_name)
|
||||
@old_method_name = old_method_name
|
||||
end
|
||||
|
||||
def to(new_method_name)
|
||||
@new_method_name = new_method_name
|
||||
self
|
||||
end
|
||||
|
||||
def matches?(klass)
|
||||
@klass = klass
|
||||
instance_method(old_method_name) == instance_method(new_method_name)
|
||||
end
|
||||
|
||||
def description
|
||||
"should #{expectation}"
|
||||
end
|
||||
|
||||
def failure_message
|
||||
"Expected #{klass} to #{expectation}"
|
||||
end
|
||||
alias_method :failure_message_for_should, :failure_message
|
||||
|
||||
def failure_message_when_negated
|
||||
"Expected #{klass} not to #{expectation}"
|
||||
end
|
||||
alias_method :failure_message_for_should_not,
|
||||
:failure_message_when_negated
|
||||
|
||||
protected
|
||||
|
||||
attr_reader :old_method_name, :new_method_name, :klass
|
||||
|
||||
private
|
||||
|
||||
def expectation
|
||||
"alias instance method ##{old_method_name} to ##{new_method_name}"
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -0,0 +1,71 @@
|
|||
module UnitTests
|
||||
module Matchers
|
||||
def have_instance_method(method_name)
|
||||
HaveInstanceMethodMatcher.new(method_name)
|
||||
end
|
||||
|
||||
class HaveInstanceMethodMatcher
|
||||
def initialize(method_name)
|
||||
@method_name = method_name
|
||||
end
|
||||
|
||||
def with_arity(arity)
|
||||
@arity = arity
|
||||
self
|
||||
end
|
||||
|
||||
def matches?(klass)
|
||||
@klass = klass
|
||||
instance_method_defined? && instance_method_has_arity?
|
||||
end
|
||||
|
||||
def description
|
||||
"should #{expectation}"
|
||||
end
|
||||
|
||||
def failure_message
|
||||
"Expected #{klass} to #{expectation}"
|
||||
end
|
||||
alias_method :failure_message_for_should, :failure_message
|
||||
|
||||
def failure_message_when_negated
|
||||
"Expected #{klass} not to #{expectation}"
|
||||
end
|
||||
alias_method :failure_message_for_should_not,
|
||||
:failure_message_when_negated
|
||||
|
||||
protected
|
||||
|
||||
attr_reader :method_name, :arity, :klass
|
||||
|
||||
private
|
||||
|
||||
def arity_specified?
|
||||
defined?(@arity)
|
||||
end
|
||||
|
||||
def instance_method_defined?
|
||||
method_name == :initialize ||
|
||||
klass.instance_methods.include?(method_name)
|
||||
end
|
||||
|
||||
def instance_method_has_arity?
|
||||
!arity_specified? || instance_method.arity == arity
|
||||
end
|
||||
|
||||
def instance_method
|
||||
klass.instance_method(method_name)
|
||||
end
|
||||
|
||||
def expectation
|
||||
string = "have instance method ##{method_name}"
|
||||
|
||||
if arity_specified?
|
||||
string << " with arity of #{arity}"
|
||||
end
|
||||
|
||||
string
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -0,0 +1,18 @@
|
|||
shared_examples_for 'a matcher' do
|
||||
subject { described_class }
|
||||
|
||||
it { should have_instance_method(:description).with_arity(0) }
|
||||
it { should have_instance_method(:matches?).with_arity(1) }
|
||||
it { should have_instance_method(:failure_message).with_arity(0) }
|
||||
it { should have_instance_method(:failure_message).with_arity(0) }
|
||||
|
||||
it do
|
||||
should alias_instance_method(:failure_message).
|
||||
to(:failure_message_for_should)
|
||||
end
|
||||
|
||||
it do
|
||||
should alias_instance_method(:failure_message_when_negated).
|
||||
to(:failure_message_for_should_not)
|
||||
end
|
||||
end
|
|
@ -0,0 +1,8 @@
|
|||
shared_examples_for 'a validation matcher' do
|
||||
subject { described_class }
|
||||
|
||||
it { should have_instance_method(:initialize).with_arity(1) }
|
||||
it { should have_instance_method(:with_message).with_arity(1) }
|
||||
# it { should have_instance_method(:on).with_arity(1) }
|
||||
# it { should have_instance_method(:strict).with_arity(0) }
|
||||
end
|
|
@ -1,6 +1,10 @@
|
|||
require 'unit_spec_helper'
|
||||
|
||||
describe Shoulda::Matchers::ActiveModel::ValidateNumericalityOfMatcher do
|
||||
subject { described_class.new(:attribute) }
|
||||
|
||||
it_behaves_like 'a matcher'
|
||||
it_behaves_like 'a validation matcher'
|
||||
|
||||
context 'with a model with a numericality validation' do
|
||||
it 'accepts' do
|
||||
|
|
Loading…
Reference in New Issue