tracks/vendor/plugins/rspec/lib/spec/matchers/simple_matcher.rb
Luke Melia 35ae5fc431 Next step in upgrading Tracks to Rails 2.2. Some highlights:
* Ran rake rails:update
* Added old actionwebservice framework
* Updated RSpec and RSpec-Rails
* Removed asset_packager plugin (not compatible, Scott no longer maintaining), and replaced with bundle_fu. See the bundle_fu README for more info.
* Hacks to UJS and ARTS plugins, which are no longer supported. Probably should move off both UJS and RJS.
* Hack to flashobject_helper plugin (upgrade to Rails 2.2-compatible version if/when it comes out.)
* Hack to skinny-spec plugin, for Rails 2.2 compatibility. Should check for official release.
* Hacks to resource_feeder plugin, for Rails 2.2 compatibility. Should check for official release (not likely) or move off it.
* Addressed some deprecation warnings. More to come.
* My mobile mime type hackery is no longer necessary with new Rails features. Yay!
* Updated environment.rb.tmpl with changes

TODO:
* Restore view specs marked pending
* Fix failing integration tests.
* Try selenium tests.
* Investigate OpenID support.
* Address deprecation warnings.
* Consider moving parts of environment.rb to initializers
* Address annoying config.gem warning about highline gem
2008-11-30 00:34:15 -05:00

132 lines
No EOL
4.7 KiB
Ruby

module Spec
module Matchers
class SimpleMatcher
attr_writer :failure_message, :negative_failure_message, :description
def initialize(description, &match_block)
@description = description
@match_block = match_block
end
def matches?(given)
@given = given
case @match_block.arity
when 2
@match_block.call(@given, self)
else
@match_block.call(@given)
end
end
def description
@description || explanation
end
def failure_message
@failure_message || (@description.nil? ? explanation : %[expected #{@description.inspect} but got #{@given.inspect}])
end
def negative_failure_message
@negative_failure_message || (@description.nil? ? explanation : %[expected not to get #{@description.inspect}, but got #{@given.inspect}])
end
def explanation
"No description provided. See RDoc for simple_matcher()"
end
end
# simple_matcher makes it easy for you to create your own custom matchers
# in just a few lines of code when you don't need all the power of a
# completely custom matcher object.
#
# The <tt>description</tt> argument will appear as part of any failure
# message, and is also the source for auto-generated descriptions.
#
# The <tt>match_block</tt> can have an arity of 1 or 2. The first block
# argument will be the given value. The second, if the block accepts it
# will be the matcher itself, giving you access to set custom failure
# messages in favor of the defaults.
#
# The <tt>match_block</tt> should return a boolean: <tt>true</tt>
# indicates a match, which will pass if you use <tt>should</tt> and fail
# if you use <tt>should_not</tt>. false (or nil) indicates no match,
# which will do the reverse: fail if you use <tt>should</tt> and pass if
# you use <tt>should_not</tt>.
#
# An error in the <tt>match_block</tt> will bubble up, resulting in a
# failure.
#
# == Example with default messages
#
# def be_even
# simple_matcher("an even number") { |given| given % 2 == 0 }
# end
#
# describe 2 do
# it "should be even" do
# 2.should be_even
# end
# end
#
# Given an odd number, this example would produce an error message stating:
# expected "an even number", got 3.
#
# Unfortunately, if you're a fan of auto-generated descriptions, this will
# produce "should an even number." Not the most desirable result. You can
# control that using custom messages:
#
# == Example with custom messages
#
# def rhyme_with(expected)
# simple_matcher("rhyme with #{expected.inspect}") do |given, matcher|
# matcher.failure_message = "expected #{given.inspect} to rhyme with #{expected.inspect}"
# matcher.negative_failure_message = "expected #{given.inspect} not to rhyme with #{expected.inspect}"
# given.rhymes_with? expected
# end
# end
#
# # OR
#
# def rhyme_with(expected)
# simple_matcher do |given, matcher|
# matcher.description = "rhyme with #{expected.inspect}"
# matcher.failure_message = "expected #{given.inspect} to rhyme with #{expected.inspect}"
# matcher.negative_failure_message = "expected #{given.inspect} not to rhyme with #{expected.inspect}"
# given.rhymes_with? expected
# end
# end
#
# describe "pecan" do
# it "should rhyme with 'be gone'" do
# nut = "pecan"
# nut.extend Rhymer
# nut.should rhyme_with("be gone")
# end
# end
#
# The resulting messages would be:
# description: rhyme with "be gone"
# failure_message: expected "pecan" to rhyme with "be gone"
# negative failure_message: expected "pecan" not to rhyme with "be gone"
#
# == Wrapped Expectations
#
# Because errors will bubble up, it is possible to wrap other expectations
# in a SimpleMatcher.
#
# def be_even
# simple_matcher("an even number") { |given| (given % 2).should == 0 }
# end
#
# BE VERY CAREFUL when you do this. Only use wrapped expectations for
# matchers that will always be used in only the positive
# (<tt>should</tt>) or negative (<tt>should_not</tt>), but not both.
# The reason is that is you wrap a <tt>should</tt> and call the wrapper
# with <tt>should_not</tt>, the correct result (the <tt>should</tt>
# failing), will fail when you want it to pass.
#
def simple_matcher(description=nil, &match_block)
SimpleMatcher.new(description, &match_block)
end
end
end