rspec-expectations/upstream/lib/rspec/matchers/built_in/has.rb in opal-rspec-0.8.0 vs rspec-expectations/upstream/lib/rspec/matchers/built_in/has.rb in opal-rspec-1.0.0.alpha1
- old
+ new
@@ -1,15 +1,18 @@
module RSpec
module Matchers
module BuiltIn
# @api private
- # Provides the implementation for `has_<predicate>`.
- # Not intended to be instantiated directly.
- class Has < BaseMatcher
+ # Provides the implementation for dynamic predicate matchers.
+ # Not intended to be inherited directly.
+ class DynamicPredicate < BaseMatcher
+ include BeHelpers
+
def initialize(method_name, *args, &block)
@method_name, @args, @block = method_name, args, block
end
+ ruby2_keywords :initialize if respond_to?(:ruby2_keywords, true)
# @private
def matches?(actual, &block)
@actual = actual
@block ||= block
@@ -18,83 +21,146 @@
# @private
def does_not_match?(actual, &block)
@actual = actual
@block ||= block
- predicate_accessible? && !predicate_matches?
+ predicate_accessible? && predicate_matches?(false)
end
# @api private
# @return [String]
def failure_message
- validity_message || "expected ##{predicate}#{failure_message_args_description} to return true, got false"
+ failure_message_expecting(true)
end
# @api private
# @return [String]
def failure_message_when_negated
- validity_message || "expected ##{predicate}#{failure_message_args_description} to return false, got true"
+ failure_message_expecting(false)
end
# @api private
# @return [String]
def description
- [method_description, args_description].compact.join(' ')
+ "#{method_description}#{args_to_sentence}"
end
private
def predicate_accessible?
- !private_predicate? && predicate_exists?
+ @actual.respond_to? predicate
end
# support 1.8.7, evaluate once at load time for performance
if String === methods.first
+ # :nocov:
def private_predicate?
@actual.private_methods.include? predicate.to_s
end
+ # :nocov:
else
def private_predicate?
@actual.private_methods.include? predicate
end
end
- def predicate_exists?
- @actual.respond_to? predicate
+ def predicate_result
+ @predicate_result = actual.__send__(predicate_method_name, *@args, &@block)
end
- def predicate_matches?
- @actual.__send__(predicate, *@args, &@block)
+ def predicate_method_name
+ predicate
end
- def predicate
+ def predicate_matches?(value=true)
+ if RSpec::Expectations.configuration.strict_predicate_matchers?
+ value == predicate_result
+ else
+ value == !!predicate_result
+ end
+ end
+
+ def root
# On 1.9, there appears to be a bug where String#match can return `false`
# rather than the match data object. Changing to Regex#match appears to
# work around this bug. For an example of this bug, see:
# https://travis-ci.org/rspec/rspec-expectations/jobs/27549635
- @predicate ||= :"has_#{Matchers::HAS_REGEX.match(@method_name.to_s).captures.first}?"
+ self.class::REGEX.match(@method_name.to_s).captures.first
end
def method_description
- @method_name.to_s.gsub('_', ' ')
+ EnglishPhrasing.split_words(@method_name)
end
- def args_description
- return nil if @args.empty?
- @args.map { |arg| arg.inspect }.join(', ')
+ def failure_message_expecting(value)
+ validity_message ||
+ "expected `#{actual_formatted}.#{predicate}#{args_to_s}` to #{expectation_of value}, got #{description_of @predicate_result}"
end
- def failure_message_args_description
- desc = args_description
- "(#{desc})" if desc
+ def expectation_of(value)
+ if RSpec::Expectations.configuration.strict_predicate_matchers?
+ "return #{value}"
+ elsif value
+ "be truthy"
+ else
+ "be falsey"
+ end
end
def validity_message
+ return nil if predicate_accessible?
+
+ "expected #{actual_formatted} to respond to `#{predicate}`#{failure_to_respond_explanation}"
+ end
+
+ def failure_to_respond_explanation
if private_predicate?
- "expected #{@actual} to respond to `#{predicate}` but `#{predicate}` is a private method"
- elsif !predicate_exists?
- "expected #{@actual} to respond to `#{predicate}`"
+ " but `#{predicate}` is a private method"
end
+ end
+ end
+
+ # @api private
+ # Provides the implementation for `has_<predicate>`.
+ # Not intended to be instantiated directly.
+ class Has < DynamicPredicate
+ # :nodoc:
+ REGEX = Matchers::HAS_REGEX
+ private
+ def predicate
+ @predicate ||= :"has_#{root}?"
+ end
+ end
+
+ # @api private
+ # Provides the implementation of `be_<predicate>`.
+ # Not intended to be instantiated directly.
+ class BePredicate < DynamicPredicate
+ # :nodoc:
+ REGEX = Matchers::BE_PREDICATE_REGEX
+ private
+ def predicate
+ @predicate ||= :"#{root}?"
+ end
+
+ def predicate_method_name
+ actual.respond_to?(predicate) ? predicate : present_tense_predicate
+ end
+
+ def failure_to_respond_explanation
+ super || if predicate == :true?
+ " or perhaps you meant `be true` or `be_truthy`"
+ elsif predicate == :false?
+ " or perhaps you meant `be false` or `be_falsey`"
+ end
+ end
+
+ def predicate_accessible?
+ super || actual.respond_to?(present_tense_predicate)
+ end
+
+ def present_tense_predicate
+ :"#{root}s?"
end
end
end
end
end