lib/rspec/matchers/be.rb in rspec-expectations-2.0.0.a2 vs lib/rspec/matchers/be.rb in rspec-expectations-2.0.0.a3
- old
+ new
@@ -1,171 +1,208 @@
+require 'rspec/matchers/dsl'
+
+Rspec::Matchers.define :be_true do
+ match do |actual|
+ !!actual
+ end
+end
+
+Rspec::Matchers.define :be_false do
+ match do |actual|
+ !actual
+ end
+end
+
+Rspec::Matchers.define :be_nil do
+ match do |actual|
+ actual.nil?
+ end
+
+ failure_message_for_should do |actual|
+ "expected nil, got #{actual.inspect}"
+ end
+
+ failure_message_for_should_not do
+ "expected not nil, got nil"
+ end
+end
+
module Rspec
module Matchers
-
+
class Be #:nodoc:
include Rspec::Matchers::Pretty
- def initialize(*args)
- @expected = args.empty? ? true : set_expected(args.shift)
+ def initialize(*args, &block)
@args = args
- @comparison_method = nil
end
def matches?(actual)
@actual = actual
- handling_predicate? ? run_predicate_on(actual) : match_or_compare(actual)
+ !!@actual
end
+
+ def failure_message_for_should
+ "expected #{@actual.inspect} to evaluate to true"
+ end
- def run_predicate_on(actual)
+ def failure_message_for_should_not
+ "expected #{@actual.inspect} to evaluate to false"
+ end
+
+ def description
+ "be"
+ end
+
+ [:==, :<, :<=, :>=, :>, :===].each do |operator|
+ define_method operator do |operand|
+ BeComparedTo.new(operand, operator)
+ end
+ end
+
+ private
+
+ def args_to_s
+ @args.empty? ? "" : parenthesize(inspected_args.join(', '))
+ end
+
+ def parenthesize(string)
+ return "(#{string})"
+ end
+
+ def inspected_args
+ @args.collect{|a| a.inspect}
+ end
+
+ def expected_to_sentence
+ split_words(@expected)
+ end
+
+ def args_to_sentence
+ to_sentence(@args)
+ end
+
+ end
+
+ class BeComparedTo < Be
+
+ def initialize(operand, operator)
+ @expected, @operator = operand, operator
+ @args = []
+ end
+
+ def matches?(actual)
+ @actual = actual
+ @actual.__send__(@operator, @expected)
+ end
+
+ def failure_message_for_should
+ "expected #{@operator} #{@expected}, got #{@actual.inspect}"
+ end
+
+ def failure_message_for_should_not
+ message = <<-MESSAGE
+'should_not be #{@operator} #{@expected}' not only FAILED,
+it is a bit confusing.
+ MESSAGE
+
+ raise message << ([:===,:==].include?(@operator) ?
+ "It might be more clearly expressed without the \"be\"?" :
+ "It might be more clearly expressed in the positive?")
+ end
+
+ def description
+ "be #{@operator} #{expected_to_sentence}#{args_to_sentence}"
+ end
+
+ end
+
+ class BePredicate < Be
+
+ def initialize(*args, &block)
+ @expected = parse_expected(args.shift)
+ @args = args
+ @block = block
+ end
+
+ def matches?(actual)
+ @actual = actual
begin
- return @result = actual.__send__(predicate, *@args)
+ return @result = actual.__send__(predicate, *@args, &@block)
rescue NameError => predicate_missing_error
"this needs to be here or rcov will not count this branch even though it's executed in a code example"
end
begin
- return @result = actual.__send__(present_tense_predicate, *@args)
+ return @result = actual.__send__(present_tense_predicate, *@args, &@block)
rescue NameError
raise predicate_missing_error
end
end
def failure_message_for_should
- if handling_predicate?
- if predicate == :nil?
- "expected nil, got #{@actual.inspect}"
- else
- "expected #{predicate}#{args_to_s} to return true, got #{@result.inspect}"
- end
- else
- "expected #{@comparison_method} #{expected}, got #{@actual.inspect}".gsub(' ',' ')
- end
+ "expected #{predicate}#{args_to_s} to return true, got #{@result.inspect}"
end
def failure_message_for_should_not
- if handling_predicate?
- if predicate == :nil?
- "expected not nil, got nil"
- else
- "expected #{predicate}#{args_to_s} to return false, got #{@result.inspect}"
- end
- else
- message = <<-MESSAGE
-'should_not be #{@comparison_method} #{expected}' not only FAILED,
-it is a bit confusing.
- MESSAGE
-
- raise message << ([:===,:==].include?(@comparison_method) ?
- "It might be more clearly expressed without the \"be\"?" :
- "It might be more clearly expressed in the positive?")
- end
+ "expected #{predicate}#{args_to_s} to return false, got #{@result.inspect}"
end
-
+
def description
- "#{prefix_to_sentence}#{comparison} #{expected_to_sentence}#{args_to_sentence}".gsub(/\s+/,' ')
+ "#{prefix_to_sentence}#{expected_to_sentence}#{args_to_sentence}"
end
- [:==, :<, :<=, :>=, :>, :===].each do |method|
- define_method method do |expected|
- compare_to(expected, :using => method)
- self
- end
- end
+ private
- private
- def match_or_compare(actual)
- TrueClass === @expected ? @actual : @actual.__send__(comparison_method, @expected)
- end
+ def predicate
+ "#{@expected}?".to_sym
+ end
- def comparison_method
- @comparison_method || :equal?
- end
+ def present_tense_predicate
+ "#{@expected}s?".to_sym
+ end
- def expected
- @expected
- end
+ def parse_expected(expected)
+ @prefix, expected = prefix_and_expected(expected)
+ expected
+ end
- def compare_to(expected, opts)
- @expected, @comparison_method = expected, opts[:using]
- end
+ def prefix_and_expected(symbol)
+ symbol.to_s =~ /^(be_(an?_)?)(.*)/
+ return $1, $3
+ end
- def set_expected(expected)
- Symbol === expected ? parse_expected(expected) : expected
- end
-
- def parse_expected(expected)
- ["be_an_","be_a_","be_"].each do |prefix|
- handling_predicate!
- if expected.to_s =~ /^#{prefix}/
- set_prefix(prefix)
- expected = expected.to_s.sub(prefix,"")
- [true, false, nil].each do |val|
- return val if val.to_s == expected
- end
- return expected.to_sym
- end
- end
- end
-
- def set_prefix(prefix)
- @prefix = prefix
- end
-
- def prefix
- # FIXME - this is a bit goofy - but we get failures
- # if just defining @prefix = nil in initialize
- @prefix = nil unless defined?(@prefix)
- @prefix
- end
+ def prefix_to_sentence
+ split_words(@prefix)
+ end
- def handling_predicate!
- @handling_predicate = true
- end
-
- def handling_predicate?
- return false if [true, false, nil].include?(expected)
- # FIXME - this is a bit goofy - but we get failures
- # if just defining @handling_predicate = nil or false in initialize
- return defined?(@handling_predicate) ? @handling_predicate : nil
- end
+ end
- def predicate
- "#{@expected.to_s}?".to_sym
- end
-
- def present_tense_predicate
- "#{@expected.to_s}s?".to_sym
- end
-
- def args_to_s
- @args.empty? ? "" : parenthesize(inspected_args.join(', '))
- end
-
- def parenthesize(string)
- return "(#{string})"
- end
-
- def inspected_args
- @args.collect{|a| a.inspect}
- end
-
- def comparison
- @comparison_method.nil? ? " " : "be #{@comparison_method.to_s} "
- end
-
- def expected_to_sentence
- split_words(expected)
- end
-
- def prefix_to_sentence
- split_words(prefix)
- end
+ class BeSameAs < Be
+
+ def initialize(*args, &block)
+ @expected = args.shift
+ @args = args
+ end
+
+ def matches?(actual)
+ @actual = actual
+ @actual.equal?(@expected)
+ end
- def args_to_sentence
- to_sentence(@args)
- end
-
+ def failure_message_for_should
+ "expected #{@expected}, got #{@actual.inspect}"
+ end
+
+ def failure_message_for_should_not
+ "expected not #{@expected}, got #{@actual.inspect}"
+ end
+
+ def description
+ "be #{expected_to_sentence}#{args_to_sentence}"
+ end
+
end
# :call-seq:
# should be_true
# should be_false
@@ -177,11 +214,11 @@
# Given true, false, or nil, will pass if actual value is
# true, false or nil (respectively). Given no args means
# the caller should satisfy an if condition (to be or not to be).
#
# Predicates are any Ruby method that ends in a "?" and returns true or false.
- # Given be_ followed by arbitrary_predicate (without the "?"), RSpec will match
+ # Given be_ followed by arbitrary_predicate (without the "?"), Rspec will match
# convert that into a query against the target object.
#
# The arbitrary_predicate feature will handle any predicate
# prefixed with "be_an_" (e.g. be_an_instance_of), "be_a_" (e.g. be_a_kind_of)
# or "be_" (e.g. be_empty), letting you choose the prefix that best suits the predicate.
@@ -195,16 +232,19 @@
#
# collection.should be_empty #passes if target.empty?
# target.should_not be_empty #passes unless target.empty?
# target.should_not be_old_enough(16) #passes unless target.old_enough?(16)
def be(*args)
- Matchers::Be.new(*args)
+ args.empty? ?
+ Matchers::Be.new :
+ Matchers::BeSameAs.new(*args)
end
# passes if target.kind_of?(klass)
def be_a(klass)
be_a_kind_of(klass)
end
alias_method :be_an, :be_a
end
end
+