diff options
Diffstat (limited to 'test/lib/spec/matchers')
-rw-r--r-- | test/lib/spec/matchers/be.rb | 161 | ||||
-rw-r--r-- | test/lib/spec/matchers/be_close.rb | 37 | ||||
-rw-r--r-- | test/lib/spec/matchers/change.rb | 120 | ||||
-rw-r--r-- | test/lib/spec/matchers/eql.rb | 43 | ||||
-rw-r--r-- | test/lib/spec/matchers/equal.rb | 43 | ||||
-rw-r--r-- | test/lib/spec/matchers/has.rb | 44 | ||||
-rw-r--r-- | test/lib/spec/matchers/have.rb | 140 | ||||
-rw-r--r-- | test/lib/spec/matchers/include.rb | 50 | ||||
-rw-r--r-- | test/lib/spec/matchers/match.rb | 41 | ||||
-rw-r--r-- | test/lib/spec/matchers/raise_error.rb | 100 | ||||
-rw-r--r-- | test/lib/spec/matchers/respond_to.rb | 35 | ||||
-rw-r--r-- | test/lib/spec/matchers/satisfy.rb | 47 | ||||
-rw-r--r-- | test/lib/spec/matchers/throw_symbol.rb | 75 |
13 files changed, 936 insertions, 0 deletions
diff --git a/test/lib/spec/matchers/be.rb b/test/lib/spec/matchers/be.rb new file mode 100644 index 000000000..957f23de8 --- /dev/null +++ b/test/lib/spec/matchers/be.rb @@ -0,0 +1,161 @@ +module Spec + module Matchers + + class Be #:nodoc: + def initialize(expected=nil, *args) + @expected = parse_expected(expected) + @args = args + @comparison = "" + end + + def matches?(actual) + @actual = actual + return true if match_or_compare unless handling_predicate? + if handling_predicate? + begin + return @result = actual.__send__(predicate, *@args) + rescue => predicate_error + # This clause should be empty, but rcov will not report it as covered + # unless something (anything) is executed within the clause + rcov_error_report = "http://eigenclass.org/hiki.rb?rcov-0.8.0" + end + + # This supports should_exist > target.exists? in the old world. + # We should consider deprecating that ability as in the new world + # you can't write "should exist" unless you have your own custom matcher. + begin + return @result = actual.__send__(present_tense_predicate, *@args) + rescue + raise predicate_error + end + end + return false + end + + def failure_message + return "expected #{@comparison}#{expected}, got #{@actual.inspect}" unless handling_predicate? + return "expected #{predicate}#{args_to_s} to return true, got #{@result.inspect}" + end + + def negative_failure_message + return "expected not #{expected}, got #{@actual.inspect}" unless handling_predicate? + return "expected #{predicate}#{args_to_s} to return false, got #{@result.inspect}" + end + + def expected + return true if @expected == :true + return false if @expected == :false + return "nil" if @expected == :nil + return @expected.inspect + end + + def match_or_compare + return @actual == true if @expected == :true + return @actual == false if @expected == :false + return @actual.nil? if @expected == :nil + return @actual < @expected if @less_than + return @actual <= @expected if @less_than_or_equal + return @actual >= @expected if @greater_than_or_equal + return @actual > @expected if @greater_than + return @actual.equal?(@expected) + end + + def <(expected) + @less_than = true + @comparison = "< " + @expected = expected + self + end + + def <=(expected) + @less_than_or_equal = true + @comparison = "<= " + @expected = expected + self + end + + def >=(expected) + @greater_than_or_equal = true + @comparison = ">= " + @expected = expected + self + end + + def >(expected) + @greater_than = true + @comparison = "> " + @expected = expected + self + end + + def description + "be #{@comparison}#{@expected}" + end + + private + def parse_expected(expected) + if Symbol === expected + ["be_an_","be_a_","be_"].each do |prefix| + @handling_predicate = true + return "#{expected.to_s.sub(prefix,"")}".to_sym if expected.starts_with?(prefix) + end + end + return expected + end + + def predicate + "#{@expected.to_s}?".to_sym + end + + def present_tense_predicate + "#{@expected.to_s}s?".to_sym + end + + def args_to_s + return "" if @args.empty? + transformed_args = @args.collect{|a| a.inspect} + return "(#{transformed_args.join(', ')})" + end + + def handling_predicate? + return false if [:true, :false, :nil].include?(@expected) + return @handling_predicate + end + end + + # :call-seq: + # should be_true + # should be_false + # should be_nil + # should be_arbitrary_predicate(*args) + # should_not be_nil + # should_not be_arbitrary_predicate(*args) + # + # Given true, false, or nil, will pass if actual is + # true, false or nil (respectively). + # + # 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 + # 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. + # + # == Examples + # + # target.should be_true + # target.should be_false + # target.should be_nil + # target.should_not be_nil + # + # collection.should be_empty #passes if target.empty? + # "this string".should be_an_intance_of(String) + # + # 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) + end + end +end diff --git a/test/lib/spec/matchers/be_close.rb b/test/lib/spec/matchers/be_close.rb new file mode 100644 index 000000000..b09e3fd2f --- /dev/null +++ b/test/lib/spec/matchers/be_close.rb @@ -0,0 +1,37 @@ +module Spec + module Matchers + + class BeClose #:nodoc: + def initialize(expected, delta) + @expected = expected + @delta = delta + end + + def matches?(actual) + @actual = actual + (@actual - @expected).abs < @delta + end + + def failure_message + "expected #{@expected} +/- (<#{@delta}), got #{@actual}" + end + + def description + "be close to #{@expected} (+- #{@delta})" + end + end + + # :call-seq: + # should be_close(expected, delta) + # should_not be_close(expected, delta) + # + # Passes if actual == expected +/- delta + # + # == Example + # + # result.should be_close(3.0, 0.5) + def be_close(expected, delta) + Matchers::BeClose.new(expected, delta) + end + end +end
\ No newline at end of file diff --git a/test/lib/spec/matchers/change.rb b/test/lib/spec/matchers/change.rb new file mode 100644 index 000000000..41a718aca --- /dev/null +++ b/test/lib/spec/matchers/change.rb @@ -0,0 +1,120 @@ +module Spec + module Matchers + + #Based on patch from Wilson Bilkovich + class Change #:nodoc: + def initialize(receiver=nil, message=nil, &block) + @receiver = receiver + @message = message + @block = block + end + + def matches?(target, &block) + if block + raise MatcherError.new(<<-EOF +block passed to should or should_not change must use {} instead of do/end +EOF +) + end + @target = target + execute_change + return false if @from && (@from != @before) + return false if @to && (@to != @after) + return (@before + @amount == @after) if @amount + return @before != @after + end + + def execute_change + @before = @block.nil? ? @receiver.send(@message) : @block.call + @target.call + @after = @block.nil? ? @receiver.send(@message) : @block.call + end + + def failure_message + if @to + "#{result} should have been changed to #{@to.inspect}, but is now #{@after.inspect}" + elsif @from + "#{result} should have initially been #{@from.inspect}, but was #{@before.inspect}" + elsif @amount + "#{result} should have been changed by #{@amount.inspect}, but was changed by #{actual_delta.inspect}" + else + "#{result} should have changed, but is still #{@before.inspect}" + end + end + + def result + @message || "result" + end + + def actual_delta + @after - @before + end + + def negative_failure_message + "#{result} should not have changed, but did change from #{@before.inspect} to #{@after.inspect}" + end + + def by(amount) + @amount = amount + self + end + + def to(to) + @to = to + self + end + + def from (from) + @from = from + self + end + end + + # :call-seq: + # should change(receiver, message, &block) + # should change(receiver, message, &block).by(value) + # should change(receiver, message, &block).from(old).to(new) + # should_not change(receiver, message, &block) + # + # Allows you to specify that a Proc will cause some value to change. + # + # == Examples + # + # lambda { + # team.add_player(player) + # }.should change(roster, :count) + # + # lambda { + # team.add_player(player) + # }.should change(roster, :count).by(1) + # + # string = "string" + # lambda { + # string.reverse + # }.should change { string }.from("string").to("gnirts") + # + # lambda { + # person.happy_birthday + # }.should change(person, :birthday).from(32).to(33) + # + # lambda { + # employee.develop_great_new_social_networking_app + # }.should change(employee, :title).from("Mail Clerk").to("CEO") + # + # Evaluates +receiver.message+ or +block+ before and + # after it evaluates the c object (generated by the lambdas in the examples above). + # + # Then compares the values before and after the +receiver.message+ and + # evaluates the difference compared to the expected difference. + # + # == Warning + # +should_not+ +change+ only supports the form with no subsequent calls to + # +be+, +to+ or +from+. + # + # blocks passed to +should+ +change+ and +should_not+ +change+ + # must use the <tt>{}</tt> form (<tt>do/end</tt> is not supported) + def change(target=nil, message=nil, &block) + Matchers::Change.new(target, message, &block) + end + end +end diff --git a/test/lib/spec/matchers/eql.rb b/test/lib/spec/matchers/eql.rb new file mode 100644 index 000000000..caca1f7c6 --- /dev/null +++ b/test/lib/spec/matchers/eql.rb @@ -0,0 +1,43 @@ +module Spec + module Matchers + + class Eql #:nodoc: + def initialize(expected) + @expected = expected + end + + def matches?(actual) + @actual = actual + @actual.eql?(@expected) + end + + def failure_message + return "expected #{@expected.inspect}, got #{@actual.inspect} (using .eql?)", @expected, @actual + end + + def negative_failure_message + return "expected #{@actual.inspect} not to equal #{@expected.inspect} (using .eql?)", @expected, @actual + end + + def description + "eql #{@expected.inspect}" + end + end + + # :call-seq: + # should eql(expected) + # should_not eql(expected) + # + # Passes if actual and expected are of equal value, but not necessarily the same object. + # + # See http://www.ruby-doc.org/core/classes/Object.html#M001057 for more information about equality in Ruby. + # + # == Examples + # + # 5.should eql(5) + # 5.should_not eql(3) + def eql(expected) + Matchers::Eql.new(expected) + end + end +end
\ No newline at end of file diff --git a/test/lib/spec/matchers/equal.rb b/test/lib/spec/matchers/equal.rb new file mode 100644 index 000000000..e987e73cb --- /dev/null +++ b/test/lib/spec/matchers/equal.rb @@ -0,0 +1,43 @@ +module Spec + module Matchers + + class Equal #:nodoc: + def initialize(expected) + @expected = expected + end + + def matches?(actual) + @actual = actual + @actual.equal?(@expected) + end + + def failure_message + return "expected #{@expected.inspect}, got #{@actual.inspect} (using .equal?)", @expected, @actual + end + + def negative_failure_message + return "expected #{@actual.inspect} not to equal #{@expected.inspect} (using .equal?)", @expected, @actual + end + + def description + "equal #{@expected.inspect}" + end + end + + # :call-seq: + # should equal(expected) + # should_not equal(expected) + # + # Passes if actual and expected are the same object (object identity). + # + # See http://www.ruby-doc.org/core/classes/Object.html#M001057 for more information about equality in Ruby. + # + # == Examples + # + # 5.should equal(5) #Fixnums are equal + # "5".should_not equal("5") #Strings that look the same are not the same object + def equal(expected) + Matchers::Equal.new(expected) + end + end +end
\ No newline at end of file diff --git a/test/lib/spec/matchers/has.rb b/test/lib/spec/matchers/has.rb new file mode 100644 index 000000000..cc5a250b8 --- /dev/null +++ b/test/lib/spec/matchers/has.rb @@ -0,0 +1,44 @@ +module Spec + module Matchers + + class Has #:nodoc: + def initialize(sym, *args) + @sym = sym + @args = args + end + + def matches?(target) + @target = target + begin + return target.send(predicate, *@args) + rescue => @error + # This clause should be empty, but rcov will not report it as covered + # unless something (anything) is executed within the clause + rcov_error_report = "http://eigenclass.org/hiki.rb?rcov-0.8.0" + end + return false + end + + def failure_message + raise @error if @error + "expected ##{predicate}(#{@args[0].inspect}) to return true, got false" + end + + def negative_failure_message + raise @error if @error + "expected ##{predicate}(#{@args[0].inspect}) to return false, got true" + end + + def description + "have key #{@args[0].inspect}" + end + + private + def predicate + "#{@sym.to_s.sub("have_","has_")}?".to_sym + end + + end + + end +end diff --git a/test/lib/spec/matchers/have.rb b/test/lib/spec/matchers/have.rb new file mode 100644 index 000000000..81f9af3e3 --- /dev/null +++ b/test/lib/spec/matchers/have.rb @@ -0,0 +1,140 @@ +module Spec + module Matchers + + class Have #:nodoc: + def initialize(expected, relativity=:exactly) + @expected = (expected == :no ? 0 : expected) + @relativity = relativity + end + + def relativities + @relativities ||= { + :exactly => "", + :at_least => "at least ", + :at_most => "at most " + } + end + + def method_missing(sym, *args, &block) + @collection_name = sym + @args = args + @block = block + self + end + + def matches?(collection_owner) + if collection_owner.respond_to?(collection_name) + collection = collection_owner.send(collection_name, *@args, &@block) + elsif (collection_owner.respond_to?(:length) || collection_owner.respond_to?(:size)) + collection = collection_owner + else + collection_owner.send(collection_name, *@args, &@block) + end + @actual = collection.length if collection.respond_to?(:length) + @actual = collection.size if collection.respond_to?(:size) + return @actual >= @expected if @relativity == :at_least + return @actual <= @expected if @relativity == :at_most + return @actual == @expected + end + + def failure_message + "expected #{relative_expectation} #{collection_name}, got #{@actual}" + end + + def negative_failure_message + if @relativity == :exactly + return "expected target not to have #{@expected} #{collection_name}, got #{@actual}" + elsif @relativity == :at_most + return <<-EOF +Isn't life confusing enough? +Instead of having to figure out the meaning of this: + should_not have_at_most(#{@expected}).#{collection_name} +We recommend that you use this instead: + should have_at_least(#{@expected + 1}).#{collection_name} +EOF + elsif @relativity == :at_least + return <<-EOF +Isn't life confusing enough? +Instead of having to figure out the meaning of this: + should_not have_at_least(#{@expected}).#{collection_name} +We recommend that you use this instead: + should have_at_most(#{@expected - 1}).#{collection_name} +EOF + end + end + + def description + "have #{relative_expectation} #{collection_name}" + end + + private + def collection_name + @collection_name + end + + def relative_expectation + "#{relativities[@relativity]}#{@expected}" + end + end + + # :call-seq: + # should have(number).named_collection__or__sugar + # should_not have(number).named_collection__or__sugar + # + # Passes if receiver is a collection with the submitted + # number of items OR if the receiver OWNS a collection + # with the submitted number of items. + # + # If the receiver OWNS the collection, you must use the name + # of the collection. So if a <tt>Team</tt> instance has a + # collection named <tt>#players</tt>, you must use that name + # to set the expectation. + # + # If the receiver IS the collection, you can use any name + # you like for <tt>named_collection</tt>. We'd recommend using + # either "elements", "members", or "items" as these are all + # standard ways of describing the things IN a collection. + # + # This also works for Strings, letting you set an expectation + # about its length + # + # == Examples + # + # # Passes if team.players.size == 11 + # team.should have(11).players + # + # # Passes if [1,2,3].length == 3 + # [1,2,3].should have(3).items #"items" is pure sugar + # + # # Passes if "this string".length == 11 + # "this string".should have(11).characters #"characters" is pure sugar + def have(n) + Matchers::Have.new(n) + end + alias :have_exactly :have + + # :call-seq: + # should have_at_least(number).items + # + # Exactly like have() with >=. + # + # == Warning + # + # +should_not+ +have_at_least+ is not supported + def have_at_least(n) + Matchers::Have.new(n, :at_least) + end + + # :call-seq: + # should have_at_most(number).items + # + # Exactly like have() with <=. + # + # == Warning + # + # +should_not+ +have_at_most+ is not supported + def have_at_most(n) + Matchers::Have.new(n, :at_most) + end + end +end
\ No newline at end of file diff --git a/test/lib/spec/matchers/include.rb b/test/lib/spec/matchers/include.rb new file mode 100644 index 000000000..0d387f323 --- /dev/null +++ b/test/lib/spec/matchers/include.rb @@ -0,0 +1,50 @@ +module Spec + module Matchers + + class Include #:nodoc: + + def initialize(expected) + @expected = expected + end + + def matches?(actual) + @actual = actual + actual.include?(@expected) + end + + def failure_message + _message + end + + def negative_failure_message + _message("not ") + end + + def description + "include #{@expected.inspect}" + end + + private + def _message(maybe_not="") + "expected #{@actual.inspect} #{maybe_not}to include #{@expected.inspect}" + end + end + + # :call-seq: + # should include(expected) + # should_not include(expected) + # + # Passes if actual includes expected. This works for + # collections and Strings + # + # == Examples + # + # [1,2,3].should include(3) + # [1,2,3].should_not include(4) + # "spread".should include("read") + # "spread".should_not include("red") + def include(expected) + Matchers::Include.new(expected) + end + end +end diff --git a/test/lib/spec/matchers/match.rb b/test/lib/spec/matchers/match.rb new file mode 100644 index 000000000..61ab52429 --- /dev/null +++ b/test/lib/spec/matchers/match.rb @@ -0,0 +1,41 @@ +module Spec + module Matchers + + class Match #:nodoc: + def initialize(expected) + @expected = expected + end + + def matches?(actual) + @actual = actual + return true if actual =~ @expected + return false + end + + def failure_message + return "expected #{@actual.inspect} to match #{@expected.inspect}", @expected, @actual + end + + def negative_failure_message + return "expected #{@actual.inspect} not to match #{@expected.inspect}", @expected, @actual + end + + def description + "match #{@expected.inspect}" + end + end + + # :call-seq: + # should match(regexp) + # should_not match(regexp) + # + # Given a Regexp, passes if actual =~ regexp + # + # == Examples + # + # email.should match(/^([^@\s]+)@((?:[-a-z0-9]+\.)+[a-z]{2,})$/i) + def match(regexp) + Matchers::Match.new(regexp) + end + end +end diff --git a/test/lib/spec/matchers/raise_error.rb b/test/lib/spec/matchers/raise_error.rb new file mode 100644 index 000000000..95e82ad5e --- /dev/null +++ b/test/lib/spec/matchers/raise_error.rb @@ -0,0 +1,100 @@ +module Spec + module Matchers + + class RaiseError #:nodoc: + def initialize(exception=Exception, message=nil) + @expected_error = exception + @expected_message = message + end + + def matches?(proc) + @raised_expected_error = false + @raised_other = false + begin + proc.call + rescue @expected_error => @actual_error + if @expected_message.nil? + @raised_expected_error = true + else + case @expected_message + when Regexp + if @expected_message =~ @actual_error.message + @raised_expected_error = true + else + @raised_other = true + end + else + if @actual_error.message == @expected_message + @raised_expected_error = true + else + @raised_other = true + end + end + end + rescue => @actual_error + @raised_other = true + ensure + return @raised_expected_error + end + end + + def failure_message + return "expected #{expected_error}#{actual_error}" if @raised_other || !@raised_expected_error + end + + def negative_failure_message + "expected no #{expected_error}#{actual_error}" + end + + def description + "raise #{expected_error}" + end + + private + def expected_error + case @expected_message + when nil + @expected_error + when Regexp + "#{@expected_error} with message matching #{@expected_message.inspect}" + else + "#{@expected_error} with #{@expected_message.inspect}" + end + end + + def actual_error + @actual_error.nil? ? " but nothing was raised" : ", got #{@actual_error.inspect}" + end + end + + # :call-seq: + # should raise_error() + # should raise_error(NamedError) + # should raise_error(NamedError, String) + # should raise_error(NamedError, Regexp) + # should_not raise_error() + # should_not raise_error(NamedError) + # should_not raise_error(NamedError, String) + # should_not raise_error(NamedError, Regexp) + # + # With no args, matches if any error is raised. + # With a named error, matches only if that specific error is raised. + # With a named error and messsage specified as a String, matches only if both match. + # With a named error and messsage specified as a Regexp, matches only if both match. + # + # == Examples + # + # lambda { do_something_risky }.should raise_error + # lambda { do_something_risky }.should raise_error(PoorRiskDecisionError) + # lambda { do_something_risky }.should raise_error(PoorRiskDecisionError, "that was too risky") + # lambda { do_something_risky }.should raise_error(PoorRiskDecisionError, /oo ri/) + # + # lambda { do_something_risky }.should_not raise_error + # lambda { do_something_risky }.should_not raise_error(PoorRiskDecisionError) + # lambda { do_something_risky }.should_not raise_error(PoorRiskDecisionError, "that was too risky") + # lambda { do_something_risky }.should_not raise_error(PoorRiskDecisionError, /oo ri/) + def raise_error(error=Exception, message=nil) + Matchers::RaiseError.new(error, message) + end + end +end diff --git a/test/lib/spec/matchers/respond_to.rb b/test/lib/spec/matchers/respond_to.rb new file mode 100644 index 000000000..013a36f1d --- /dev/null +++ b/test/lib/spec/matchers/respond_to.rb @@ -0,0 +1,35 @@ +module Spec + module Matchers + + class RespondTo #:nodoc: + def initialize(sym) + @sym = sym + end + + def matches?(target) + return target.respond_to?(@sym) + end + + def failure_message + "expected target to respond to #{@sym.inspect}" + end + + def negative_failure_message + "expected target not to respond to #{@sym.inspect}" + end + + def description + "respond to ##{@sym.to_s}" + end + end + + # :call-seq: + # should respond_to(:sym) + # should_not respond_to(:sym) + # + # Matches if the target object responds to :sym + def respond_to(sym) + Matchers::RespondTo.new(sym) + end + end +end diff --git a/test/lib/spec/matchers/satisfy.rb b/test/lib/spec/matchers/satisfy.rb new file mode 100644 index 000000000..6c0ca95bc --- /dev/null +++ b/test/lib/spec/matchers/satisfy.rb @@ -0,0 +1,47 @@ +module Spec + module Matchers + + class Satisfy #:nodoc: + def initialize(&block) + @block = block + end + + def matches?(actual, &block) + @block = block if block + @actual = actual + @block.call(actual) + end + + def failure_message + "expected #{@actual} to satisfy block" + end + + def negative_failure_message + "expected #{@actual} not to satisfy block" + end + end + + # :call-seq: + # should satisfy {} + # should_not satisfy {} + # + # Passes if the submitted block returns true. Yields target to the + # block. + # + # Generally speaking, this should be thought of as a last resort when + # you can't find any other way to specify the behaviour you wish to + # specify. + # + # If you do find yourself in such a situation, you could always write + # a custom matcher, which would likely make your specs more expressive. + # + # == Examples + # + # 5.should satisfy { |n| + # n > 3 + # } + def satisfy(&block) + Matchers::Satisfy.new(&block) + end + end +end diff --git a/test/lib/spec/matchers/throw_symbol.rb b/test/lib/spec/matchers/throw_symbol.rb new file mode 100644 index 000000000..6732f6fed --- /dev/null +++ b/test/lib/spec/matchers/throw_symbol.rb @@ -0,0 +1,75 @@ +module Spec + module Matchers + + class ThrowSymbol #:nodoc: + def initialize(expected=nil) + @expected = expected + end + + def matches?(proc) + begin + proc.call + rescue NameError => e + @actual = extract_sym_from_name_error(e) + ensure + if @expected.nil? + return @actual.nil? ? false : true + else + return @actual == @expected + end + end + end + + def failure_message + if @actual + "expected #{expected}, got #{@actual.inspect}" + else + "expected #{expected} but nothing was thrown" + end + end + + def negative_failure_message + if @expected + "expected #{expected} not to be thrown" + else + "expected no Symbol, got :#{@actual}" + end + end + + def description + "throw #{expected}" + end + + private + + def expected + @expected.nil? ? "a Symbol" : @expected.inspect + end + + def extract_sym_from_name_error(error) + return "#{error.message.split("`").last.split("'").first}".to_sym + end + end + + # :call-seq: + # should throw_symbol() + # should throw_symbol(:sym) + # should_not throw_symbol() + # should_not throw_symbol(:sym) + # + # Given a Symbol argument, matches if a proc throws the specified Symbol. + # + # Given no argument, matches if a proc throws any Symbol. + # + # == Examples + # + # lambda { do_something_risky }.should throw_symbol + # lambda { do_something_risky }.should throw_symbol(:that_was_risky) + # + # lambda { do_something_risky }.should_not throw_symbol + # lambda { do_something_risky }.should_not throw_symbol(:that_was_risky) + def throw_symbol(sym=nil) + Matchers::ThrowSymbol.new(sym) + end + end +end |