aboutsummaryrefslogtreecommitdiffstats
path: root/vendor/gems/rspec-1.3.1/lib/spec/mocks
diff options
context:
space:
mode:
authorLouise Crow <louise.crow@gmail.com>2011-02-24 15:10:14 +0000
committerLouise Crow <louise.crow@gmail.com>2011-02-24 15:10:14 +0000
commit08a64f9e3139851fd65c7ba6969ee590b4afea6a (patch)
tree20c77e796002dfa95b2af3ba00ebd2f691c02fc7 /vendor/gems/rspec-1.3.1/lib/spec/mocks
parent3757bb52c0aa86b779b00428d7ebe35b30cea1ee (diff)
Adding rspec gem.
Diffstat (limited to 'vendor/gems/rspec-1.3.1/lib/spec/mocks')
-rw-r--r--vendor/gems/rspec-1.3.1/lib/spec/mocks/argument_expectation.rb51
-rw-r--r--vendor/gems/rspec-1.3.1/lib/spec/mocks/argument_matchers.rb237
-rw-r--r--vendor/gems/rspec-1.3.1/lib/spec/mocks/error_generator.rb92
-rw-r--r--vendor/gems/rspec-1.3.1/lib/spec/mocks/errors.rb10
-rw-r--r--vendor/gems/rspec-1.3.1/lib/spec/mocks/example_methods.rb69
-rw-r--r--vendor/gems/rspec-1.3.1/lib/spec/mocks/extensions.rb1
-rw-r--r--vendor/gems/rspec-1.3.1/lib/spec/mocks/extensions/object.rb3
-rw-r--r--vendor/gems/rspec-1.3.1/lib/spec/mocks/framework.rb15
-rw-r--r--vendor/gems/rspec-1.3.1/lib/spec/mocks/message_expectation.rb344
-rw-r--r--vendor/gems/rspec-1.3.1/lib/spec/mocks/methods.rb94
-rw-r--r--vendor/gems/rspec-1.3.1/lib/spec/mocks/mock.rb71
-rw-r--r--vendor/gems/rspec-1.3.1/lib/spec/mocks/order_group.rb29
-rw-r--r--vendor/gems/rspec-1.3.1/lib/spec/mocks/proxy.rb268
-rw-r--r--vendor/gems/rspec-1.3.1/lib/spec/mocks/space.rb28
14 files changed, 1312 insertions, 0 deletions
diff --git a/vendor/gems/rspec-1.3.1/lib/spec/mocks/argument_expectation.rb b/vendor/gems/rspec-1.3.1/lib/spec/mocks/argument_expectation.rb
new file mode 100644
index 000000000..b51b7bae5
--- /dev/null
+++ b/vendor/gems/rspec-1.3.1/lib/spec/mocks/argument_expectation.rb
@@ -0,0 +1,51 @@
+module Spec
+ module Mocks
+
+ class ArgumentExpectation
+ attr_reader :args
+
+ def initialize(args, &block)
+ @args = args
+ @matchers_block = block
+ @match_any_args = false
+ @matchers = nil
+
+ if ArgumentMatchers::AnyArgsMatcher === args.first
+ @match_any_args = true
+ elsif ArgumentMatchers::NoArgsMatcher === args.first
+ @matchers = []
+ else
+ @matchers = args.collect {|arg| matcher_for(arg)}
+ end
+ end
+
+ def matcher_for(arg)
+ return ArgumentMatchers::MatcherMatcher.new(arg) if is_matcher?(arg)
+ return ArgumentMatchers::RegexpMatcher.new(arg) if arg.is_a?(Regexp)
+ return ArgumentMatchers::EqualityProxy.new(arg)
+ end
+
+ def is_matcher?(obj)
+ return obj.respond_to?(:matches?) & obj.respond_to?(:description)
+ end
+
+ def args_match?(given_args)
+ match_any_args? || matchers_block_matches?(given_args) || matchers_match?(given_args)
+ end
+
+ def matchers_block_matches?(given_args)
+ @matchers_block ? @matchers_block.call(*given_args) : nil
+ end
+
+ def matchers_match?(given_args)
+ @matchers == given_args
+ end
+
+ def match_any_args?
+ @match_any_args
+ end
+
+ end
+
+ end
+end
diff --git a/vendor/gems/rspec-1.3.1/lib/spec/mocks/argument_matchers.rb b/vendor/gems/rspec-1.3.1/lib/spec/mocks/argument_matchers.rb
new file mode 100644
index 000000000..f56551f21
--- /dev/null
+++ b/vendor/gems/rspec-1.3.1/lib/spec/mocks/argument_matchers.rb
@@ -0,0 +1,237 @@
+module Spec
+ module Mocks
+
+ # ArgumentMatchers are messages that you can include in message
+ # expectations to match arguments against a broader check than simple
+ # equality.
+ #
+ # With the exception of any_args() and no_args(), the matchers
+ # are all positional - they match against the arg in the given position.
+ module ArgumentMatchers
+
+ class AnyArgsMatcher
+ def description
+ "any args"
+ end
+ end
+
+ class NoArgsMatcher
+ def description
+ "no args"
+ end
+ end
+
+ class AnyArgMatcher
+ def initialize(ignore)
+ end
+
+ def ==(other)
+ true
+ end
+
+ def description
+ "anything"
+ end
+ end
+
+ class RegexpMatcher
+ def initialize(regexp)
+ @regexp = regexp
+ end
+
+ def ==(value)
+ return value =~ @regexp unless value.is_a?(Regexp)
+ value == @regexp
+ end
+ end
+
+ class BooleanMatcher
+ def initialize(ignore)
+ end
+
+ def ==(value)
+ TrueClass === value || FalseClass === value
+ end
+ end
+
+ class HashIncludingMatcher
+ def initialize(expected)
+ @expected = expected
+ end
+
+ def ==(actual)
+ @expected.each do | key, value |
+ return false unless actual.has_key?(key) && value == actual[key]
+ end
+ true
+ rescue NoMethodError => ex
+ return false
+ end
+
+ def description
+ "hash_including(#{@expected.inspect.sub(/^\{/,"").sub(/\}$/,"")})"
+ end
+ end
+
+ class HashNotIncludingMatcher
+ def initialize(expected)
+ @expected = expected
+ end
+
+ def ==(actual)
+ @expected.each do | key, value |
+ return false if actual.has_key?(key) && value == actual[key]
+ end
+ true
+ rescue NoMethodError => ex
+ return false
+ end
+
+ def description
+ "hash_not_including(#{@expected.inspect.sub(/^\{/,"").sub(/\}$/,"")})"
+ end
+ end
+
+ class DuckTypeMatcher
+ def initialize(*methods_to_respond_to)
+ @methods_to_respond_to = methods_to_respond_to
+ end
+
+ def ==(value)
+ @methods_to_respond_to.all? { |sym| value.respond_to?(sym) }
+ end
+ end
+
+ class MatcherMatcher
+ def initialize(matcher)
+ @matcher = matcher
+ end
+
+ def ==(value)
+ @matcher.matches?(value)
+ end
+ end
+
+ class EqualityProxy
+ def initialize(given)
+ @given = given
+ end
+
+ def ==(expected)
+ @given == expected
+ end
+ end
+
+ class InstanceOf
+ def initialize(klass)
+ @klass = klass
+ end
+
+ def ==(actual)
+ actual.instance_of?(@klass)
+ end
+ end
+
+ class KindOf
+ def initialize(klass)
+ @klass = klass
+ end
+
+ def ==(actual)
+ actual.kind_of?(@klass)
+ end
+ end
+
+ # :call-seq:
+ # object.should_receive(:message).with(no_args())
+ #
+ # Passes if no arguments are passed along with the message
+ def no_args
+ NoArgsMatcher.new
+ end
+
+ # :call-seq:
+ # object.should_receive(:message).with(any_args())
+ #
+ # Passes if object receives :message with any args at all. This is
+ # really a more explicit variation of object.should_receive(:message)
+ def any_args
+ AnyArgsMatcher.new
+ end
+
+ # :call-seq:
+ # object.should_receive(:message).with(anything())
+ #
+ # Passes as long as there is an argument.
+ def anything
+ AnyArgMatcher.new(nil)
+ end
+
+ # :call-seq:
+ # object.should_receive(:message).with(duck_type(:hello))
+ # object.should_receive(:message).with(duck_type(:hello, :goodbye))
+ #
+ # Passes if the argument responds to the specified messages.
+ #
+ # == Examples
+ #
+ # array = []
+ # display = mock('display')
+ # display.should_receive(:present_names).with(duck_type(:length, :each))
+ # => passes
+ def duck_type(*args)
+ DuckTypeMatcher.new(*args)
+ end
+
+ # :call-seq:
+ # object.should_receive(:message).with(boolean())
+ #
+ # Passes if the argument is boolean.
+ def boolean
+ BooleanMatcher.new(nil)
+ end
+
+ # :call-seq:
+ # object.should_receive(:message).with(hash_including(:key => val))
+ # object.should_receive(:message).with(hash_including(:key))
+ # object.should_receive(:message).with(hash_including(:key, :key2 => val2))
+ # Passes if the argument is a hash that includes the specified key(s) or key/value
+ # pairs. If the hash includes other keys, it will still pass.
+ def hash_including(*args)
+ HashIncludingMatcher.new(anythingize_lonely_keys(*args))
+ end
+
+ # :call-seq:
+ # object.should_receive(:message).with(hash_not_including(:key => val))
+ # object.should_receive(:message).with(hash_not_including(:key))
+ # object.should_receive(:message).with(hash_not_including(:key, :key2 => :val2))
+ #
+ # Passes if the argument is a hash that doesn't include the specified key(s) or key/value
+ def hash_not_including(*args)
+ HashNotIncludingMatcher.new(anythingize_lonely_keys(*args))
+ end
+
+ # Passes if arg.instance_of?(klass)
+ def instance_of(klass)
+ InstanceOf.new(klass)
+ end
+
+ alias_method :an_instance_of, :instance_of
+
+ # Passes if arg.kind_of?(klass)
+ def kind_of(klass)
+ KindOf.new(klass)
+ end
+
+ alias_method :a_kind_of, :kind_of
+
+ private
+
+ def anythingize_lonely_keys(*args)
+ hash = args.last.class == Hash ? args.delete_at(-1) : {}
+ args.each { | arg | hash[arg] = anything }
+ hash
+ end
+ end
+ end
+end
diff --git a/vendor/gems/rspec-1.3.1/lib/spec/mocks/error_generator.rb b/vendor/gems/rspec-1.3.1/lib/spec/mocks/error_generator.rb
new file mode 100644
index 000000000..f63811fed
--- /dev/null
+++ b/vendor/gems/rspec-1.3.1/lib/spec/mocks/error_generator.rb
@@ -0,0 +1,92 @@
+module Spec
+ module Mocks
+ class ErrorGenerator
+ attr_writer :opts
+
+ def initialize(target, name, options={})
+ @declared_as = options[:__declared_as] || 'Mock'
+ @target = target
+ @name = name
+ end
+
+ def opts
+ @opts ||= {}
+ end
+
+ def raise_unexpected_message_error(sym, *args)
+ __raise "#{intro} received unexpected message :#{sym}#{arg_message(*args)}"
+ end
+
+ def raise_unexpected_message_args_error(expectation, *args)
+ expected_args = format_args(*expectation.expected_args)
+ actual_args = args.empty? ? "(no args)" : format_args(*args)
+ __raise "#{intro} received #{expectation.sym.inspect} with unexpected arguments\n expected: #{expected_args}\n got: #{actual_args}"
+ end
+
+ def raise_expectation_error(sym, expected_received_count, actual_received_count, *args)
+ __raise "#{intro} expected :#{sym}#{arg_message(*args)} #{count_message(expected_received_count)}, but received it #{count_message(actual_received_count)}"
+ end
+
+ def raise_out_of_order_error(sym)
+ __raise "#{intro} received :#{sym} out of order"
+ end
+
+ def raise_block_failed_error(sym, detail)
+ __raise "#{intro} received :#{sym} but passed block failed with: #{detail}"
+ end
+
+ def raise_missing_block_error(args_to_yield)
+ __raise "#{intro} asked to yield |#{arg_list(*args_to_yield)}| but no block was passed"
+ end
+
+ def raise_wrong_arity_error(args_to_yield, arity)
+ __raise "#{intro} yielded |#{arg_list(*args_to_yield)}| to block with arity of #{arity}"
+ end
+
+ private
+
+ def intro
+ if @name
+ "#{@declared_as} #{@name.inspect}"
+ elsif Mock === @target
+ @declared_as
+ elsif Class === @target
+ "<#{@target.inspect} (class)>"
+ elsif @target
+ @target
+ else
+ "nil"
+ end
+ end
+
+ def __raise(message)
+ message = opts[:message] unless opts[:message].nil?
+ Kernel::raise(Spec::Mocks::MockExpectationError, message)
+ end
+
+ def arg_message(*args)
+ " with " + format_args(*args)
+ end
+
+ def format_args(*args)
+ args.empty? ? "(no args)" : "(" + arg_list(*args) + ")"
+ end
+
+ def arg_list(*args)
+ args.collect {|arg| arg.respond_to?(:description) ? arg.description : arg.inspect}.join(", ")
+ end
+
+ def count_message(count)
+ return "at least #{pretty_print(count.abs)}" if count < 0
+ return pretty_print(count)
+ end
+
+ def pretty_print(count)
+ return "once" if count == 1
+ return "twice" if count == 2
+ return "#{count} times"
+ end
+
+ end
+ end
+end
diff --git a/vendor/gems/rspec-1.3.1/lib/spec/mocks/errors.rb b/vendor/gems/rspec-1.3.1/lib/spec/mocks/errors.rb
new file mode 100644
index 000000000..560b66a93
--- /dev/null
+++ b/vendor/gems/rspec-1.3.1/lib/spec/mocks/errors.rb
@@ -0,0 +1,10 @@
+module Spec
+ module Mocks
+ class MockExpectationError < Exception
+ end
+
+ class AmbiguousReturnError < StandardError
+ end
+ end
+end
+
diff --git a/vendor/gems/rspec-1.3.1/lib/spec/mocks/example_methods.rb b/vendor/gems/rspec-1.3.1/lib/spec/mocks/example_methods.rb
new file mode 100644
index 000000000..f6c68ab6a
--- /dev/null
+++ b/vendor/gems/rspec-1.3.1/lib/spec/mocks/example_methods.rb
@@ -0,0 +1,69 @@
+module Spec
+ module Mocks
+ module ExampleMethods
+ include Spec::Mocks::ArgumentMatchers
+
+ # Shortcut for creating an instance of Spec::Mocks::Mock.
+ #
+ # +name+ is used for failure reporting, so you should use the
+ # role that the double is playing in the example.
+ #
+ # +stubs_and_options+ lets you assign options and stub values
+ # at the same time. The only option available is :null_object.
+ # Anything else is treated as a stub value.
+ #
+ # == Examples
+ #
+ # thing = double("thing", :a => "A")
+ # thing.a == "A" => true
+ #
+ # person = double("thing", :name => "Joe", :email => "joe@domain.com")
+ # person.name => "Joe"
+ # person.email => "joe@domain.com"
+ def double(*args)
+ __declare_double('Double', *args)
+ end
+
+ # Alias for double
+ def mock(*args)
+ __declare_double('Mock', *args)
+ end
+
+ # Alias for double
+ def stub(*args)
+ __declare_double('Stub', *args)
+ end
+
+ def __declare_double(declared_as, *args) # :nodoc:
+ args << {} unless Hash === args.last
+ args.last[:__declared_as] = declared_as
+ Spec::Mocks::Mock.new(*args)
+ end
+
+ # DEPRECATED - use double('name').as_null_object instead
+ #
+ # Shortcut for creating a mock object that will return itself in response
+ # to any message it receives that it hasn't been explicitly instructed
+ # to respond to.
+ def stub_everything(name = 'stub')
+ Spec.warn(<<-WARNING)
+
+DEPRECATION: stub_everything('#{name}') is deprecated and will be removed
+from a future version of rspec. Please use double('#{name}').as_null_object
+(or stub('#{name}').as_null_object or mock('#{name}').as_null_object instead.
+
+WARNING
+ mock(name, :null_object => true)
+ end
+
+ # Disables warning messages about expectations being set on nil.
+ #
+ # By default warning messages are issued when expectations are set on nil. This is to
+ # prevent false-positives and to catch potential bugs early on.
+ def allow_message_expectations_on_nil
+ Proxy.allow_message_expectations_on_nil
+ end
+
+ end
+ end
+end
diff --git a/vendor/gems/rspec-1.3.1/lib/spec/mocks/extensions.rb b/vendor/gems/rspec-1.3.1/lib/spec/mocks/extensions.rb
new file mode 100644
index 000000000..6fd51a272
--- /dev/null
+++ b/vendor/gems/rspec-1.3.1/lib/spec/mocks/extensions.rb
@@ -0,0 +1 @@
+require 'spec/mocks/extensions/object'
diff --git a/vendor/gems/rspec-1.3.1/lib/spec/mocks/extensions/object.rb b/vendor/gems/rspec-1.3.1/lib/spec/mocks/extensions/object.rb
new file mode 100644
index 000000000..4b7531066
--- /dev/null
+++ b/vendor/gems/rspec-1.3.1/lib/spec/mocks/extensions/object.rb
@@ -0,0 +1,3 @@
+class Object
+ include Spec::Mocks::Methods
+end
diff --git a/vendor/gems/rspec-1.3.1/lib/spec/mocks/framework.rb b/vendor/gems/rspec-1.3.1/lib/spec/mocks/framework.rb
new file mode 100644
index 000000000..e25778655
--- /dev/null
+++ b/vendor/gems/rspec-1.3.1/lib/spec/mocks/framework.rb
@@ -0,0 +1,15 @@
+# Require everything except the global extensions of class and object. This
+# supports wrapping rspec's mocking functionality without invading every
+# object in the system.
+
+require 'spec/mocks/methods'
+require 'spec/mocks/argument_matchers'
+require 'spec/mocks/example_methods'
+require 'spec/mocks/proxy'
+require 'spec/mocks/mock'
+require 'spec/mocks/argument_expectation'
+require 'spec/mocks/message_expectation'
+require 'spec/mocks/order_group'
+require 'spec/mocks/errors'
+require 'spec/mocks/error_generator'
+require 'spec/mocks/space'
diff --git a/vendor/gems/rspec-1.3.1/lib/spec/mocks/message_expectation.rb b/vendor/gems/rspec-1.3.1/lib/spec/mocks/message_expectation.rb
new file mode 100644
index 000000000..cd8dc0f97
--- /dev/null
+++ b/vendor/gems/rspec-1.3.1/lib/spec/mocks/message_expectation.rb
@@ -0,0 +1,344 @@
+module Spec
+ module Mocks
+
+ class BaseExpectation
+ attr_reader :sym
+ attr_writer :expected_received_count, :method_block, :expected_from
+ protected :expected_received_count=, :method_block=, :expected_from=
+ attr_accessor :error_generator
+ protected :error_generator, :error_generator=
+
+ def initialize(error_generator, expectation_ordering, expected_from, sym, method_block, expected_received_count=1, opts={}, &implementation)
+ @error_generator = error_generator
+ @error_generator.opts = opts
+ @expected_from = expected_from
+ @sym = sym
+ @method_block = method_block
+ @actual_received_count = 0
+ @expected_received_count = expected_received_count
+ @args_expectation = ArgumentExpectation.new([ArgumentMatchers::AnyArgsMatcher.new])
+ @consecutive = false
+ @exception_to_raise = nil
+ @symbol_to_throw = nil
+ @order_group = expectation_ordering
+ @at_least = nil
+ @at_most = nil
+ @args_to_yield = []
+ @failed_fast = nil
+ @args_to_yield_were_cloned = false
+ @return_block = implementation
+ @eval_context = nil
+ end
+
+ def build_child(expected_from, method_block, expected_received_count, opts={})
+ child = clone
+ child.expected_from = expected_from
+ child.method_block = method_block
+ child.expected_received_count = expected_received_count
+ child.clear_actual_received_count!
+ new_gen = error_generator.clone
+ new_gen.opts = opts
+ child.error_generator = new_gen
+ child.clone_args_to_yield @args_to_yield
+ child
+ end
+
+ def expected_args
+ @args_expectation.args
+ end
+
+ def and_return(*values, &return_block)
+ Kernel::raise AmbiguousReturnError unless @method_block.nil?
+ case values.size
+ when 0 then value = nil
+ when 1 then value = values[0]
+ else
+ value = values
+ @consecutive = true
+ @expected_received_count = values.size if !ignoring_args? &&
+ @expected_received_count < values.size
+ end
+ @return_block = block_given? ? return_block : lambda { value }
+ end
+
+ # :call-seq:
+ # and_raise()
+ # and_raise(Exception) #any exception class
+ # and_raise(exception) #any exception object
+ #
+ # == Warning
+ #
+ # When you pass an exception class, the MessageExpectation will
+ # raise an instance of it, creating it with +new+. If the exception
+ # class initializer requires any parameters, you must pass in an
+ # instance and not the class.
+ def and_raise(exception=Exception)
+ @exception_to_raise = exception
+ end
+
+ def and_throw(symbol)
+ @symbol_to_throw = symbol
+ end
+
+ def and_yield(*args, &block)
+ if @args_to_yield_were_cloned
+ @args_to_yield.clear
+ @args_to_yield_were_cloned = false
+ end
+
+ if block
+ require 'spec/extensions/instance_exec'
+ @eval_context = Object.new
+ @eval_context.extend Spec::Matchers::InstanceExec
+ yield @eval_context
+ end
+ @args_to_yield << args
+ self
+ end
+
+ def matches(sym, args)
+ @sym == sym and @args_expectation.args_match?(args)
+ end
+
+ def invoke(*args, &block)
+ if @expected_received_count == 0
+ @failed_fast = true
+ @actual_received_count += 1
+ @error_generator.raise_expectation_error @sym, @expected_received_count, @actual_received_count, *args
+ end
+
+ @order_group.handle_order_constraint self
+
+ begin
+ Kernel::raise @exception_to_raise unless @exception_to_raise.nil?
+ Kernel::throw @symbol_to_throw unless @symbol_to_throw.nil?
+
+
+ if !@method_block.nil?
+ default_return_val = invoke_method_block(*args)
+ elsif @args_to_yield.size > 0 || @eval_context
+ default_return_val = invoke_with_yield(&block)
+ else
+ default_return_val = nil
+ end
+
+ if @consecutive
+ return invoke_consecutive_return_block(*args, &block)
+ elsif @return_block
+ return invoke_return_block(*args, &block)
+ else
+ return default_return_val
+ end
+ ensure
+ @actual_received_count += 1
+ end
+ end
+
+ def called_max_times?
+ @expected_received_count != :any && @expected_received_count > 0 &&
+ @actual_received_count >= @expected_received_count
+ end
+
+ def invoke_return_block(*args, &block)
+ args << block unless block.nil?
+ # Ruby 1.9 - when we set @return_block to return values
+ # regardless of arguments, any arguments will result in
+ # a "wrong number of arguments" error
+ @return_block.arity == 0 ? @return_block.call : @return_block.call(*args)
+ end
+
+ protected
+
+ def invoke_method_block(*args)
+ begin
+ @method_block.call(*args)
+ rescue => detail
+ @error_generator.raise_block_failed_error @sym, detail.message
+ end
+ end
+
+ def invoke_with_yield(&block)
+ if block.nil?
+ @error_generator.raise_missing_block_error @args_to_yield
+ end
+ value = nil
+ @args_to_yield.each do |args_to_yield_this_time|
+ if block.arity > -1 && args_to_yield_this_time.length != block.arity
+ @error_generator.raise_wrong_arity_error args_to_yield_this_time, block.arity
+ end
+ value = eval_block(*args_to_yield_this_time, &block)
+ end
+ value
+ end
+
+ def eval_block(*args, &block)
+ if @eval_context
+ @eval_context.instance_exec(*args, &block)
+ else
+ block.call(*args)
+ end
+ end
+
+ def invoke_consecutive_return_block(*args, &block)
+ value = invoke_return_block(*args, &block)
+ index = [@actual_received_count, value.size-1].min
+ value[index]
+ end
+
+ def clone_args_to_yield(args)
+ @args_to_yield = args.clone
+ @args_to_yield_were_cloned = true
+ end
+
+ def failed_fast?
+ @failed_fast
+ end
+ end
+
+ class MessageExpectation < BaseExpectation
+
+ def matches_name?(sym)
+ @sym == sym
+ end
+
+ def matches_name_but_not_args(sym, args)
+ matches_name?(sym) and not @args_expectation.args_match?(args)
+ end
+
+ def verify_messages_received
+ return if expected_messages_received? || failed_fast?
+
+ generate_error
+ rescue Spec::Mocks::MockExpectationError => error
+ error.backtrace.insert(0, @expected_from)
+ Kernel::raise error
+ end
+
+ def expected_messages_received?
+ ignoring_args? || matches_exact_count? ||
+ matches_at_least_count? || matches_at_most_count?
+ end
+
+ def ignoring_args?
+ @expected_received_count == :any
+ end
+
+ def matches_at_least_count?
+ @at_least && @actual_received_count >= @expected_received_count
+ end
+
+ def matches_at_most_count?
+ @at_most && @actual_received_count <= @expected_received_count
+ end
+
+ def matches_exact_count?
+ @expected_received_count == @actual_received_count
+ end
+
+ def similar_messages
+ @similar_messages ||= []
+ end
+
+ def advise(args, block)
+ similar_messages << args
+ end
+
+ def generate_error
+ if similar_messages.empty?
+ @error_generator.raise_expectation_error(@sym, @expected_received_count, @actual_received_count, *@args_expectation.args)
+ else
+ @error_generator.raise_unexpected_message_args_error(self, *@similar_messages)
+ end
+ end
+
+ def with(*args, &block)
+ @args_expectation = ArgumentExpectation.new(args, &block)
+ self
+ end
+
+ def exactly(n)
+ set_expected_received_count :exactly, n
+ self
+ end
+
+ def at_least(n)
+ set_expected_received_count :at_least, n
+ self
+ end
+
+ def at_most(n)
+ set_expected_received_count :at_most, n
+ self
+ end
+
+ def times(&block)
+ @method_block = block if block
+ self
+ end
+
+ def any_number_of_times(&block)
+ @method_block = block if block
+ @expected_received_count = :any
+ self
+ end
+
+ def never
+ @expected_received_count = 0
+ self
+ end
+
+ def once(&block)
+ @method_block = block if block
+ @expected_received_count = 1
+ self
+ end
+
+ def twice(&block)
+ @method_block = block if block
+ @expected_received_count = 2
+ self
+ end
+
+ def ordered(&block)
+ @method_block = block if block
+ @order_group.register(self)
+ @ordered = true
+ self
+ end
+
+ def negative_expectation_for?(sym)
+ return false
+ end
+
+ protected
+ def set_expected_received_count(relativity, n)
+ @at_least = (relativity == :at_least)
+ @at_most = (relativity == :at_most)
+ @expected_received_count = case n
+ when Numeric
+ n
+ when :once
+ 1
+ when :twice
+ 2
+ end
+ end
+
+ def clear_actual_received_count!
+ @actual_received_count = 0
+ end
+
+ end
+
+ class NegativeMessageExpectation < MessageExpectation
+ def initialize(message, expectation_ordering, expected_from, sym, method_block)
+ super(message, expectation_ordering, expected_from, sym, method_block, 0)
+ end
+
+ def negative_expectation_for?(sym)
+ return @sym == sym
+ end
+ end
+
+ end
+end
diff --git a/vendor/gems/rspec-1.3.1/lib/spec/mocks/methods.rb b/vendor/gems/rspec-1.3.1/lib/spec/mocks/methods.rb
new file mode 100644
index 000000000..5d94cac37
--- /dev/null
+++ b/vendor/gems/rspec-1.3.1/lib/spec/mocks/methods.rb
@@ -0,0 +1,94 @@
+module Spec
+ module Mocks
+ module Methods
+ def should_receive(sym, opts={}, &block)
+ __mock_proxy.add_message_expectation(opts[:expected_from] || caller(1)[0], sym.to_sym, opts, &block)
+ end
+
+ def should_not_receive(sym, &block)
+ __mock_proxy.add_negative_message_expectation(caller(1)[0], sym.to_sym, &block)
+ end
+
+ def stub!(sym_or_hash, opts={}, &block)
+ if Hash === sym_or_hash
+ sym_or_hash.each {|method, value| stub!(method).and_return value }
+ else
+ __mock_proxy.add_stub(caller(1)[0], sym_or_hash.to_sym, opts, &block)
+ end
+ end
+
+ alias_method :stub, :stub!
+
+ def unstub!(message)
+ __mock_proxy.remove_stub(message)
+ end
+
+ alias_method :unstub, :unstub!
+
+ # :call-seq:
+ # object.stub_chain(:first, :second, :third).and_return(:this)
+ #
+ # Supports stubbing a chain of methods. Each argument represents
+ # a method name to stub, and each one returns a proxy object that
+ # can accept more stubs, until the last, which returns whatever
+ # is passed to +and_return_.
+ #
+ # == Examples
+ #
+ # # with this in an example ...
+ # article = double('article')
+ # Article.stub_chain(:authored_by, :published, :recent).and_return([article])
+ # # then this will return an Array with the article double in it:
+ # Article.authored_by(params[:author_id]).published.recent
+ def stub_chain(*methods)
+ if methods.length > 1
+ if matching_stub = __mock_proxy.find_matching_method_stub(methods[0])
+ methods.shift
+ matching_stub.invoke_return_block.stub_chain(*methods)
+ else
+ next_in_chain = Object.new
+ stub!(methods.shift) {next_in_chain}
+ next_in_chain.stub_chain(*methods)
+ end
+ else
+ stub!(methods.shift)
+ end
+ end
+
+ # Record and otherwise ignore all messages that aren't specified,
+ # with +stub+, +stub!+, or +should_receive+.
+ #
+ # == Returns
+ # self
+ def as_null_object
+ __mock_proxy.as_null_object
+ end
+
+ def null_object?
+ __mock_proxy.null_object?
+ end
+
+ def received_message?(sym, *args, &block) #:nodoc:
+ __mock_proxy.received_message?(sym.to_sym, *args, &block)
+ end
+
+ def rspec_verify #:nodoc:
+ __mock_proxy.verify
+ end
+
+ def rspec_reset #:nodoc:
+ __mock_proxy.reset
+ end
+
+ private
+
+ def __mock_proxy
+ if Mock === self
+ @mock_proxy ||= Proxy.new(self, @name, @options)
+ else
+ @mock_proxy ||= Proxy.new(self)
+ end
+ end
+ end
+ end
+end
diff --git a/vendor/gems/rspec-1.3.1/lib/spec/mocks/mock.rb b/vendor/gems/rspec-1.3.1/lib/spec/mocks/mock.rb
new file mode 100644
index 000000000..35a6c798e
--- /dev/null
+++ b/vendor/gems/rspec-1.3.1/lib/spec/mocks/mock.rb
@@ -0,0 +1,71 @@
+module Spec
+ module Mocks
+ class Mock
+ include Methods
+
+ # Creates a new mock with a +name+ (that will be used in error messages
+ # only) == Options:
+ # * <tt>:null_object</tt> - if true, the mock object acts as a forgiving
+ # null object allowing any message to be sent to it.
+ def initialize(name=nil, stubs_and_options={})
+ if name.is_a?(Hash) && stubs_and_options.empty?
+ stubs_and_options = name
+ @name = nil
+ else
+ @name = name
+ end
+ @options = extract_options(stubs_and_options)
+ assign_stubs(stubs_and_options)
+ end
+
+ # This allows for comparing the mock to other objects that proxy such as
+ # ActiveRecords belongs_to proxy objects. By making the other object run
+ # the comparison, we're sure the call gets delegated to the proxy
+ # target.
+ def ==(other)
+ other == __mock_proxy
+ end
+
+ def inspect
+ "#<#{self.class}:#{sprintf '0x%x', self.object_id} @name=#{@name.inspect}>"
+ end
+
+ def to_s
+ inspect.gsub('<','[').gsub('>',']')
+ end
+
+ private
+
+ def method_missing(sym, *args, &block)
+ __mock_proxy.record_message_received(sym, args, block)
+ begin
+ return self if __mock_proxy.null_object?
+ super(sym, *args, &block)
+ rescue NameError
+ __mock_proxy.raise_unexpected_message_error sym, *args
+ end
+ end
+
+ def extract_options(stubs_and_options)
+ options = {}
+ extract_option(stubs_and_options, options, :null_object)
+ extract_option(stubs_and_options, options, :__declared_as, 'Mock')
+ options
+ end
+
+ def extract_option(source, target, key, default=nil)
+ if source[key]
+ target[key] = source.delete(key)
+ elsif default
+ target[key] = default
+ end
+ end
+
+ def assign_stubs(stubs)
+ stubs.each_pair do |message, response|
+ stub!(message).and_return(response)
+ end
+ end
+ end
+ end
+end
diff --git a/vendor/gems/rspec-1.3.1/lib/spec/mocks/order_group.rb b/vendor/gems/rspec-1.3.1/lib/spec/mocks/order_group.rb
new file mode 100644
index 000000000..9983207eb
--- /dev/null
+++ b/vendor/gems/rspec-1.3.1/lib/spec/mocks/order_group.rb
@@ -0,0 +1,29 @@
+module Spec
+ module Mocks
+ class OrderGroup
+ def initialize error_generator
+ @error_generator = error_generator
+ @ordering = Array.new
+ end
+
+ def register(expectation)
+ @ordering << expectation
+ end
+
+ def ready_for?(expectation)
+ return @ordering.first == expectation
+ end
+
+ def consume
+ @ordering.shift
+ end
+
+ def handle_order_constraint expectation
+ return unless @ordering.include? expectation
+ return consume if ready_for?(expectation)
+ @error_generator.raise_out_of_order_error expectation.sym
+ end
+
+ end
+ end
+end
diff --git a/vendor/gems/rspec-1.3.1/lib/spec/mocks/proxy.rb b/vendor/gems/rspec-1.3.1/lib/spec/mocks/proxy.rb
new file mode 100644
index 000000000..6c29a9cdd
--- /dev/null
+++ b/vendor/gems/rspec-1.3.1/lib/spec/mocks/proxy.rb
@@ -0,0 +1,268 @@
+module Spec
+ module Mocks
+ class Proxy
+ DEFAULT_OPTIONS = {
+ :null_object => false,
+ }
+
+ @@warn_about_expectations_on_nil = true
+
+ def self.allow_message_expectations_on_nil
+ @@warn_about_expectations_on_nil = false
+
+ # ensure nil.rspec_verify is called even if an expectation is not set in the example
+ # otherwise the allowance would effect subsequent examples
+ $rspec_mocks.add(nil) unless $rspec_mocks.nil?
+ end
+
+ def initialize(target, name=nil, options={})
+ @target = target
+ @name = name
+ @error_generator = ErrorGenerator.new target, name, options
+ @expectation_ordering = OrderGroup.new @error_generator
+ @expectations = []
+ @messages_received = []
+ @stubs = []
+ @proxied_methods = []
+ @options = options ? DEFAULT_OPTIONS.dup.merge(options) : DEFAULT_OPTIONS
+ @already_proxied_respond_to = false
+ end
+
+ def null_object?
+ @options[:null_object]
+ end
+
+ def as_null_object
+ @options[:null_object] = true
+ @target
+ end
+
+ def add_message_expectation(expected_from, sym, opts={}, &block)
+ __add sym
+ warn_if_nil_class sym
+ @expectations << build_expectation(expected_from, sym, opts, &block)
+ @expectations.last
+ end
+
+ def build_expectation(expected_from, sym, opts, &block)
+ if stub = find_matching_method_stub(sym)
+ stub.build_child(expected_from, block_given?? block : nil, 1, opts)
+ else
+ MessageExpectation.new(@error_generator, @expectation_ordering, expected_from, sym, block_given? ? block : nil, 1, opts)
+ end
+ end
+
+ def add_negative_message_expectation(expected_from, sym, &block)
+ __add sym
+ warn_if_nil_class sym
+ @expectations << NegativeMessageExpectation.new(@error_generator, @expectation_ordering, expected_from, sym, block_given? ? block : nil)
+ @expectations.last
+ end
+
+ def add_stub(expected_from, sym, opts={}, &implementation)
+ __add sym
+ @stubs.unshift MessageExpectation.new(@error_generator, @expectation_ordering, expected_from, sym, nil, :any, opts, &implementation)
+ @stubs.first
+ end
+
+ def remove_stub(message)
+ message = message.to_sym
+ if stub_to_remove = @stubs.detect { |s| s.matches_name?(message) }
+ reset_proxied_method(message)
+ @stubs.delete(stub_to_remove)
+ else
+ raise MockExpectationError, "The method `#{message}` was not stubbed or was already unstubbed"
+ end
+ end
+
+ def verify #:nodoc:
+ verify_expectations
+ ensure
+ reset
+ end
+
+ def reset
+ clear_expectations
+ clear_stubs
+ reset_proxied_methods
+ clear_proxied_methods
+ reset_nil_expectations_warning
+ end
+
+ def received_message?(sym, *args, &block)
+ @messages_received.any? {|array| array == [sym, args, block]}
+ end
+
+ def has_negative_expectation?(sym)
+ @expectations.any? {|expectation| expectation.negative_expectation_for?(sym)}
+ end
+
+ def record_message_received(sym, args, block)
+ @messages_received << [sym, args, block]
+ end
+
+ def message_received(sym, *args, &block)
+ expectation = find_matching_expectation(sym, *args)
+ stub = find_matching_method_stub(sym, *args)
+
+ if ok_to_invoke_stub?(stub, expectation)
+ record_stub(stub, sym, args, &block)
+ elsif expectation
+ invoke_expectation(expectation, *args, &block)
+ elsif expectation = find_almost_matching_expectation(sym, *args)
+ record_almost_matching_expectation(expectation, sym, *args, &block)
+ elsif @target.is_a?(Class)
+ @target.superclass.send(sym, *args, &block)
+ else
+ @target.__send__ :method_missing, sym, *args, &block
+ end
+ end
+
+ def record_stub(stub, sym, args, &block)
+ almost_matching_expectation(sym, *args) do |e|
+ e.advise(args, block)
+ end
+ stub.invoke(*args, &block)
+ end
+
+ def invoke_expectation(expectation, *args, &block)
+ expectation.invoke(*args, &block)
+ end
+
+ def record_almost_matching_expectation(expectation, sym, *args, &block)
+ expectation.advise(args, block)
+ unless (null_object? or has_negative_expectation?(sym))
+ raise_unexpected_message_args_error(expectation, *args)
+ end
+ end
+
+ def ok_to_invoke_stub?(stub, expectation)
+ stub && (!expectation || expectation.called_max_times?)
+ end
+
+ def raise_unexpected_message_args_error(expectation, *args)
+ @error_generator.raise_unexpected_message_args_error expectation, *args
+ end
+
+ def raise_unexpected_message_error(sym, *args)
+ @error_generator.raise_unexpected_message_error sym, *args
+ end
+
+ def find_matching_method_stub(sym, *args)
+ @stubs.find {|stub| stub.matches(sym, args)}
+ end
+
+ private
+
+ def __add(sym)
+ $rspec_mocks.add(@target) unless $rspec_mocks.nil?
+ define_expected_method(sym)
+ end
+
+ def warn_if_nil_class(sym)
+ if proxy_for_nil_class? & @@warn_about_expectations_on_nil
+ Kernel.warn("An expectation of :#{sym} was set on nil. Called from #{caller[2]}. Use allow_message_expectations_on_nil to disable warnings.")
+ end
+ end
+
+ def define_expected_method(sym)
+ unless @proxied_methods.include?(sym)
+ visibility_string = "#{visibility(sym)} :#{sym}"
+ if target_responds_to?(sym)
+ munged_sym = munge(sym)
+ target_metaclass.instance_eval do
+ alias_method munged_sym, sym if method_defined?(sym)
+ end
+ @proxied_methods << sym
+ end
+ target_metaclass.class_eval(<<-EOF, __FILE__, __LINE__)
+ def #{sym}(*args, &block)
+ __mock_proxy.message_received :#{sym}, *args, &block
+ end
+ #{visibility_string}
+ EOF
+ end
+ end
+
+ def target_responds_to?(sym)
+ return @target.__send__(munge(:respond_to?),sym) if @already_proxied_respond_to
+ return @already_proxied_respond_to = true if sym == :respond_to?
+ return @target.respond_to?(sym, true)
+ end
+
+ def visibility(sym)
+ if Mock === @target
+ 'public'
+ elsif target_metaclass.private_method_defined?(sym)
+ 'private'
+ elsif target_metaclass.protected_method_defined?(sym)
+ 'protected'
+ else
+ 'public'
+ end
+ end
+
+ def munge(sym)
+ "proxied_by_rspec__#{sym}"
+ end
+
+ def clear_expectations
+ @expectations.clear
+ end
+
+ def clear_stubs
+ @stubs.clear
+ end
+
+ def clear_proxied_methods
+ @proxied_methods.clear
+ end
+
+ def target_metaclass
+ class << @target; self; end
+ end
+
+ def verify_expectations
+ @expectations.map {|e| e.verify_messages_received}
+ end
+
+ def reset_proxied_methods
+ @proxied_methods.map {|sym| reset_proxied_method(sym)}
+ end
+
+ def reset_proxied_method(sym)
+ munged_sym = munge(sym)
+ target_metaclass.instance_eval do
+ remove_method sym
+ if method_defined?(munged_sym)
+ alias_method sym, munged_sym
+ remove_method munged_sym
+ end
+ end
+ end
+
+ def proxy_for_nil_class?
+ @target.nil?
+ end
+
+ def reset_nil_expectations_warning
+ @@warn_about_expectations_on_nil = true if proxy_for_nil_class?
+ end
+
+ def find_matching_expectation(sym, *args)
+ @expectations.find {|expectation| expectation.matches(sym, args) && !expectation.called_max_times?} ||
+ @expectations.find {|expectation| expectation.matches(sym, args)}
+ end
+
+ def almost_matching_expectation(sym, *args, &block)
+ if e = find_almost_matching_expectation(sym, *args)
+ yield e
+ end
+ end
+
+ def find_almost_matching_expectation(sym, *args)
+ @expectations.find {|expectation| expectation.matches_name_but_not_args(sym, args)}
+ end
+ end
+ end
+end
diff --git a/vendor/gems/rspec-1.3.1/lib/spec/mocks/space.rb b/vendor/gems/rspec-1.3.1/lib/spec/mocks/space.rb
new file mode 100644
index 000000000..3e13224c7
--- /dev/null
+++ b/vendor/gems/rspec-1.3.1/lib/spec/mocks/space.rb
@@ -0,0 +1,28 @@
+module Spec
+ module Mocks
+ class Space
+ def add(obj)
+ mocks << obj unless mocks.detect {|m| m.equal? obj}
+ end
+
+ def verify_all
+ mocks.each do |mock|
+ mock.rspec_verify
+ end
+ end
+
+ def reset_all
+ mocks.each do |mock|
+ mock.rspec_reset
+ end
+ mocks.clear
+ end
+
+ private
+
+ def mocks
+ @mocks ||= []
+ end
+ end
+ end
+end