Skip to content
Browse files

update be() from rspec-1

  • Loading branch information...
1 parent a8dec75 commit 537f3fdedeafc9e1c7dcfb2c4a6bdb70f093d5c4 @dchelimsky dchelimsky committed Jan 30, 2010
View
298 lib/rspec/matchers/be.rb
@@ -1,169 +1,206 @@
+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 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 run_predicate_on(actual)
+ 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 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
- def args_to_sentence
- to_sentence(@args)
- end
-
end
# :call-seq:
@@ -179,7 +216,7 @@ def args_to_sentence
# 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
@@ -197,7 +234,9 @@ def args_to_sentence
# 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)
@@ -208,3 +247,4 @@ def be_a(klass)
alias_method :be_an, :be_a
end
end
+
View
4 lib/rspec/matchers/method_missing.rb
@@ -1,8 +1,8 @@
module Rspec
module Matchers
def method_missing(sym, *args, &block) # :nodoc:
- return Matchers::Be.new(sym, *args) if sym.to_s =~ /^be_/
- return Matchers::Has.new(sym, *args) if sym.to_s =~ /^have_/
+ return Matchers::BePredicate.new(sym, *args, &block) if sym.to_s =~ /^be_/
+ return Matchers::Has.new(sym, *args, &block) if sym.to_s =~ /^have_/
super
end
end
View
172 spec/rspec/matchers/be_spec.rb
@@ -1,4 +1,4 @@
-require File.dirname(__FILE__) + '/../../spec_helper.rb'
+require 'spec_helper'
describe "should be_predicate" do
it "should pass when actual returns true for :predicate?" do
@@ -117,27 +117,143 @@
end
end
+describe "should be_predicate(&block)" do
+ it "should pass when actual returns true for :predicate?(&block)" do
+ actual = mock("actual")
+ delegate = mock("delegate")
+ actual.should_receive(:happy?).and_yield
+ delegate.should_receive(:check_happy).and_return(true)
+ actual.should be_happy { delegate.check_happy }
+ end
+
+ it "should fail when actual returns false for :predicate?(&block)" do
+ actual = mock("actual")
+ delegate = mock("delegate")
+ actual.should_receive(:happy?).and_yield
+ delegate.should_receive(:check_happy).and_return(false)
+ lambda {
+ actual.should be_happy { delegate.check_happy }
+ }.should fail_with("expected happy? to return true, got false")
+ end
+
+ it "should fail when actual does not respond to :predicate?" do
+ delegate = mock("delegate", :check_happy => true)
+ lambda {
+ Object.new.should be_happy { delegate.check_happy }
+ }.should raise_error(NameError)
+ end
+end
+
+describe "should_not be_predicate(&block)" do
+ it "should pass when actual returns false for :predicate?(&block)" do
+ actual = mock("actual")
+ delegate = mock("delegate")
+ actual.should_receive(:happy?).and_yield
+ delegate.should_receive(:check_happy).and_return(false)
+ actual.should_not be_happy { delegate.check_happy }
+ end
+
+ it "should fail when actual returns true for :predicate?(&block)" do
+ actual = mock("actual")
+ delegate = mock("delegate")
+ actual.should_receive(:happy?).and_yield
+ delegate.should_receive(:check_happy).and_return(true)
+ lambda {
+ actual.should_not be_happy { delegate.check_happy }
+ }.should fail_with("expected happy? to return false, got true")
+ end
+
+ it "should fail when actual does not respond to :predicate?" do
+ delegate = mock("delegate", :check_happy => true)
+ lambda {
+ Object.new.should_not be_happy { delegate.check_happy }
+ }.should raise_error(NameError)
+ end
+end
+
+describe "should be_predicate(*args, &block)" do
+ it "should pass when actual returns true for :predicate?(*args, &block)" do
+ actual = mock("actual")
+ delegate = mock("delegate")
+ actual.should_receive(:older_than?).with(3).and_yield(3)
+ delegate.should_receive(:check_older_than).with(3).and_return(true)
+ actual.should be_older_than(3) { |age| delegate.check_older_than(age) }
+ end
+
+ it "should fail when actual returns false for :predicate?(*args, &block)" do
+ actual = mock("actual")
+ delegate = mock("delegate")
+ actual.should_receive(:older_than?).with(3).and_yield(3)
+ delegate.should_receive(:check_older_than).with(3).and_return(false)
+ lambda {
+ actual.should be_older_than(3) { |age| delegate.check_older_than(age) }
+ }.should fail_with("expected older_than?(3) to return true, got false")
+ end
+
+ it "should fail when actual does not respond to :predicate?" do
+ delegate = mock("delegate", :check_older_than => true)
+ lambda {
+ Object.new.should be_older_than(3) { |age| delegate.check_older_than(age) }
+ }.should raise_error(NameError)
+ end
+end
+
+describe "should_not be_predicate(*args, &block)" do
+ it "should pass when actual returns false for :predicate?(*args, &block)" do
+ actual = mock("actual")
+ delegate = mock("delegate")
+ actual.should_receive(:older_than?).with(3).and_yield(3)
+ delegate.should_receive(:check_older_than).with(3).and_return(false)
+ actual.should_not be_older_than(3) { |age| delegate.check_older_than(age) }
+ end
+
+ it "should fail when actual returns true for :predicate?(*args, &block)" do
+ actual = mock("actual")
+ delegate = mock("delegate")
+ actual.should_receive(:older_than?).with(3).and_yield(3)
+ delegate.should_receive(:check_older_than).with(3).and_return(true)
+ lambda {
+ actual.should_not be_older_than(3) { |age| delegate.check_older_than(age) }
+ }.should fail_with("expected older_than?(3) to return false, got true")
+ end
+
+ it "should fail when actual does not respond to :predicate?" do
+ delegate = mock("delegate", :check_older_than => true)
+ lambda {
+ Object.new.should_not be_older_than(3) { |age| delegate.check_older_than(age) }
+ }.should raise_error(NameError)
+ end
+end
+
describe "should be_true" do
- it "should pass when actual equal(true)" do
+ it "should pass when actual equal?(true)" do
true.should be_true
end
- it "should fail when actual equal(false)" do
+ it "should pass when actual is 1" do
+ 1.should be_true
+ end
+
+ it "should fail when actual equal?(false)" do
lambda {
false.should be_true
- }.should fail_with("expected true, got false")
+ }.should fail_with("expected false to be true")
end
end
describe "should be_false" do
- it "should pass when actual equal(false)" do
+ it "should pass when actual equal?(false)" do
false.should be_false
end
- it "should fail when actual equal(true)" do
+ it "should pass when actual equal?(nil)" do
+ nil.should be_false
+ end
+
+ it "should fail when actual equal?(true)" do
lambda {
true.should be_false
- }.should fail_with("expected false, got true")
+ }.should fail_with("expected true to be false")
end
end
@@ -173,6 +289,10 @@
it "should fail when < operator returns false" do
lambda { 3.should be < 3 }.should fail_with("expected < 3, got 3")
end
+
+ it "should describe itself" do
+ be.<(4).description.should == "be < 4"
+ end
end
describe "should be <=" do
@@ -236,27 +356,56 @@
end
describe "should be" do
- it "should pass if actual is true or a set value" do
+ it "should pass if actual is truthy" do
true.should be
1.should be
end
it "should fail if actual is false" do
- lambda {false.should be}.should fail_with("expected true, got false")
+ lambda {false.should be}.should fail_with("expected false to evaluate to true")
end
it "should fail if actual is nil" do
- lambda {nil.should be}.should fail_with("expected true, got nil")
+ lambda {nil.should be}.should fail_with("expected nil to evaluate to true")
+ end
+
+ it "should describe itself" do
+ be.description.should == "be"
+ end
+end
+
+describe "should_not be" do
+ it "should pass if actual is falsy" do
+ false.should_not be
+ nil.should_not be
+ end
+
+ it "should fail on true" do
+ lambda {true.should_not be}.should fail_with("expected true to evaluate to false")
end
end
describe "should be(value)" do
it "should pass if actual.equal?(value)" do
5.should be(5)
end
+
it "should fail if !actual.equal?(value)" do
lambda { 5.should be(6) }.should fail_with("expected 6, got 5")
end
+
+ it "should describe itself" do
+ be(5).description.should == "be 5"
+ end
+end
+
+describe "should_not be(value)" do
+ it "should pass if !actual.equal?(value)" do
+ 5.should_not be(6)
+ end
+ it "should fail if !actual.equal?(value)" do
+ lambda { 5.should_not be(5) }.should fail_with("expected not 5, got 5")
+ end
end
describe "'should be' with operator" do
@@ -308,4 +457,5 @@ def large?
it "fails when class is higher up hierarchy" do
5.should_not be_an_instance_of(Numeric)
end
-end
+end
+
View
63 spec/rspec/matchers/matcher_methods_spec.rb
@@ -1,63 +0,0 @@
-require File.dirname(__FILE__) + '/../../spec_helper.rb'
-
-module Rspec
- module Matchers
- context %Q{The Rspec::Matchers module gets included in the execution context of every spec.
-This module should provide the following methods, each of which returns a Matcher object.} do
- it "be_true" do
- be_true.should be_an_instance_of(Be)
- end
- it "be_false" do
- be_false.should be_an_instance_of(Be)
- end
- it "be_nil" do
- be_nil.should be_an_instance_of(Be)
- end
- it "be_arbitrary_predicate" do
- be_arbitrary_predicate.should be_an_instance_of(Be)
- end
- it "change" do
- change("target", :message).should be_an_instance_of(Change)
- end
- it "have" do
- have(0).should be_an_instance_of(Have)
- end
- it "have_exactly" do
- have_exactly(0).should be_an_instance_of(Have)
- end
- it "have_at_least" do
- have_at_least(0).should be_an_instance_of(Have)
- end
- it "have_at_most" do
- have_at_most(0).should be_an_instance_of(Have)
- end
- it "raise_error" do
- raise_error.should be_an_instance_of(RaiseError)
- raise_error(NoMethodError).should be_an_instance_of(RaiseError)
- raise_error(NoMethodError, "message").should be_an_instance_of(RaiseError)
- end
- it "satisfy" do
- satisfy{}.should be_an_instance_of(Satisfy)
- end
- it "throw_symbol" do
- throw_symbol.should be_an_instance_of(ThrowSymbol)
- throw_symbol(:sym).should be_an_instance_of(ThrowSymbol)
- end
- it "respond_to" do
- respond_to(:sym).should be_an_instance_of(RespondTo)
- end
- end
-
- describe "Rspec::Matchers#method_missing" do
- it "should convert be_xyz to Be(:be_xyz)" do
- Be.should_receive(:new).with(:be_whatever)
- be_whatever
- end
-
- it "should convert have_xyz to Has(:have_xyz)" do
- Has.should_receive(:new).with(:have_whatever)
- have_whatever
- end
- end
- end
-end

0 comments on commit 537f3fd

Please sign in to comment.
Something went wrong with that request. Please try again.