aboutsummaryrefslogtreecommitdiffstats
path: root/vendor/plugins/rspec/lib/spec/mocks
diff options
context:
space:
mode:
authorfrancis <francis>2008-09-04 06:10:25 +0000
committerfrancis <francis>2008-09-04 06:10:25 +0000
commit5bde1025dc4d43ea53f63107b88711ebf8942408 (patch)
tree962c8b1fb32186fbd1ab15050ede8e560d9a63f6 /vendor/plugins/rspec/lib/spec/mocks
parentce2cf5ed73d81180e9f88d590daaa23989ee9472 (diff)
rspec for rails 2.1
Diffstat (limited to 'vendor/plugins/rspec/lib/spec/mocks')
-rw-r--r--vendor/plugins/rspec/lib/spec/mocks/argument_constraint_matchers.rb6
-rw-r--r--vendor/plugins/rspec/lib/spec/mocks/argument_expectation.rb26
-rw-r--r--vendor/plugins/rspec/lib/spec/mocks/extensions.rb1
-rw-r--r--vendor/plugins/rspec/lib/spec/mocks/framework.rb15
-rw-r--r--vendor/plugins/rspec/lib/spec/mocks/message_expectation.rb34
-rw-r--r--vendor/plugins/rspec/lib/spec/mocks/mock.rb16
-rw-r--r--vendor/plugins/rspec/lib/spec/mocks/proxy.rb38
7 files changed, 111 insertions, 25 deletions
diff --git a/vendor/plugins/rspec/lib/spec/mocks/argument_constraint_matchers.rb b/vendor/plugins/rspec/lib/spec/mocks/argument_constraint_matchers.rb
index 0e4777082..96ccf0f4a 100644
--- a/vendor/plugins/rspec/lib/spec/mocks/argument_constraint_matchers.rb
+++ b/vendor/plugins/rspec/lib/spec/mocks/argument_constraint_matchers.rb
@@ -1,7 +1,7 @@
module Spec
module Mocks
module ArgumentConstraintMatchers
-
+
# Shortcut for creating an instance of Spec::Mocks::DuckTypeArgConstraint
def duck_type(*args)
DuckTypeArgConstraint.new(*args)
@@ -19,6 +19,10 @@ module Spec
BooleanArgConstraint.new(nil)
end
+ def hash_including(expected={})
+ HashIncludingConstraint.new(expected)
+ end
+
def no_args
NoArgsConstraint.new
end
diff --git a/vendor/plugins/rspec/lib/spec/mocks/argument_expectation.rb b/vendor/plugins/rspec/lib/spec/mocks/argument_expectation.rb
index 34a1d4d03..b3fdcc80d 100644
--- a/vendor/plugins/rspec/lib/spec/mocks/argument_expectation.rb
+++ b/vendor/plugins/rspec/lib/spec/mocks/argument_expectation.rb
@@ -108,6 +108,32 @@ module Spec
"duck_type"
end
end
+
+ class HashIncludingConstraint
+ def initialize(expected)
+ @expected = expected
+ end
+
+ def ==(actual)
+ @expected.each do | key, value |
+ # check key for case that value evaluates to nil
+ return false unless actual.has_key?(key) && actual[key] == value
+ end
+ true
+ rescue NoMethodError => ex
+ return false
+ end
+
+ def matches?(value)
+ self == value
+ end
+
+ def description
+ "hash_including(#{@expected.inspect.sub(/^\{/,"").sub(/\}$/,"")})"
+ end
+
+ end
+
class ArgumentExpectation
attr_reader :args
diff --git a/vendor/plugins/rspec/lib/spec/mocks/extensions.rb b/vendor/plugins/rspec/lib/spec/mocks/extensions.rb
new file mode 100644
index 000000000..6fd51a272
--- /dev/null
+++ b/vendor/plugins/rspec/lib/spec/mocks/extensions.rb
@@ -0,0 +1 @@
+require 'spec/mocks/extensions/object'
diff --git a/vendor/plugins/rspec/lib/spec/mocks/framework.rb b/vendor/plugins/rspec/lib/spec/mocks/framework.rb
new file mode 100644
index 000000000..92089673a
--- /dev/null
+++ b/vendor/plugins/rspec/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_constraint_matchers'
+require 'spec/mocks/spec_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/plugins/rspec/lib/spec/mocks/message_expectation.rb b/vendor/plugins/rspec/lib/spec/mocks/message_expectation.rb
index 6bd2f1c32..0b10290b3 100644
--- a/vendor/plugins/rspec/lib/spec/mocks/message_expectation.rb
+++ b/vendor/plugins/rspec/lib/spec/mocks/message_expectation.rb
@@ -72,12 +72,18 @@ module Spec
end
def invoke(args, block)
+ if @expected_received_count == 0
+ @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
@@ -112,12 +118,14 @@ module Spec
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
- block.call(*args_to_yield_this_time)
+ value = block.call(*args_to_yield_this_time)
end
+ value
end
def invoke_consecutive_return_block(args, block)
@@ -147,9 +155,8 @@ module Spec
@sym == sym and not @args_expectation.check_args(args)
end
- def verify_messages_received
- return if ignoring_args? || matches_exact_count? ||
- matches_at_least_count? || matches_at_most_count?
+ def verify_messages_received
+ return if expected_messages_received?
generate_error
rescue Spec::Mocks::MockExpectationError => error
@@ -157,6 +164,11 @@ module Spec
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
@@ -173,8 +185,20 @@ module Spec
@expected_received_count == @actual_received_count
end
+ def similar_messages
+ @similar_messages ||= []
+ end
+
+ def advise(args, block)
+ similar_messages << args
+ end
+
def generate_error
- @error_generator.raise_expectation_error(@sym, @expected_received_count, @actual_received_count, *@args_expectation.args)
+ 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.first)
+ end
end
def with(*args, &block)
diff --git a/vendor/plugins/rspec/lib/spec/mocks/mock.rb b/vendor/plugins/rspec/lib/spec/mocks/mock.rb
index f029b1b8f..d0b5f204d 100644
--- a/vendor/plugins/rspec/lib/spec/mocks/mock.rb
+++ b/vendor/plugins/rspec/lib/spec/mocks/mock.rb
@@ -3,19 +3,21 @@ module Spec
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.
+ # 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, stubs_and_options={})
@name = name
@options = parse_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
- # This is an unfortunate side effect from ActiveRecord, but this should be safe unless the RHS redefines == in a nonsensical manner
+ # 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
+ # This is an unfortunate side effect from ActiveRecord, but this should
+ # be safe unless the RHS redefines == in a nonsensical manner
def ==(other)
other == __mock_proxy
end
diff --git a/vendor/plugins/rspec/lib/spec/mocks/proxy.rb b/vendor/plugins/rspec/lib/spec/mocks/proxy.rb
index 03db3b113..45b96a30b 100644
--- a/vendor/plugins/rspec/lib/spec/mocks/proxy.rb
+++ b/vendor/plugins/rspec/lib/spec/mocks/proxy.rb
@@ -63,10 +63,14 @@ module Spec
def message_received(sym, *args, &block)
if expectation = find_matching_expectation(sym, *args)
expectation.invoke(args, block)
- elsif stub = find_matching_method_stub(sym, *args)
+ elsif (stub = find_matching_method_stub(sym, *args))
+ if expectation = find_almost_matching_expectation(sym, *args)
+ expectation.advise(args, block) unless expectation.expected_messages_received?
+ end
stub.invoke([], block)
elsif expectation = find_almost_matching_expectation(sym, *args)
- raise_unexpected_message_args_error(expectation, *args) unless has_negative_expectation?(sym) unless null_object?
+ expectation.advise(args, block) if null_object? unless expectation.expected_messages_received?
+ raise_unexpected_message_args_error(expectation, *args) unless (has_negative_expectation?(sym) or null_object?)
else
@target.send :method_missing, sym, *args, &block
end
@@ -88,18 +92,20 @@ module Spec
end
def define_expected_method(sym)
- if target_responds_to?(sym) && !metaclass.method_defined?(munge(sym))
+ visibility_string = "#{visibility(sym)} :#{sym}"
+ if target_responds_to?(sym) && !target_metaclass.method_defined?(munge(sym))
munged_sym = munge(sym)
- metaclass.instance_eval do
+ target_metaclass.instance_eval do
alias_method munged_sym, sym if method_defined?(sym.to_s)
end
@proxied_methods << sym
end
- metaclass_eval(<<-EOF, __FILE__, __LINE__)
+ target_metaclass.class_eval(<<-EOF, __FILE__, __LINE__)
def #{sym}(*args, &block)
__mock_proxy.message_received :#{sym}, *args, &block
end
+ #{visibility_string}
EOF
end
@@ -109,6 +115,18 @@ module Spec
return @target.respond_to?(sym)
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.to_s}".to_sym
end
@@ -125,12 +143,8 @@ module Spec
@proxied_methods.clear
end
- def metaclass_eval(str, filename, lineno)
- metaclass.class_eval(str, filename, lineno)
- end
-
- def metaclass
- (class << @target; self; end)
+ def target_metaclass
+ class << @target; self; end
end
def verify_expectations
@@ -142,7 +156,7 @@ module Spec
def reset_proxied_methods
@proxied_methods.each do |sym|
munged_sym = munge(sym)
- metaclass.instance_eval do
+ target_metaclass.instance_eval do
if method_defined?(munged_sym.to_s)
alias_method sym, munged_sym
undef_method munged_sym