Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Refactor implementation pieces in prep for #230.

This splits each implementation piece into a separate object
so that it is easier to combine them.
  • Loading branch information...
commit c2c6b5593a6357dc46ece0ce700a2d7738cb9104 1 parent 7f644a9
@myronmarston myronmarston authored JonRowe committed
Showing with 52 additions and 27 deletions.
  1. +52 −27 lib/rspec/mocks/message_expectation.rb
View
79 lib/rspec/mocks/message_expectation.rb
@@ -25,7 +25,9 @@ def initialize(error_generator, expectation_ordering, expected_from, method_doub
@failed_fast = nil
@eval_context = nil
@implementation = implementation
- @values_to_return = nil
+
+ @initial_implementation_logic = nil
+ @terminal_implementation_logic = nil
end
# @private
@@ -78,8 +80,7 @@ def and_return(*values, &implementation)
# TODO: deprecate `and_return { value }`
@implementation = implementation
else
- @values_to_return = values
- @implementation = build_implementation
+ self.terminal_implementation_logic = AndReturnImplementation.new(values)
end
end
@@ -154,7 +155,7 @@ def and_throw(*args)
def and_yield(*args, &block)
yield @eval_context = Object.new.extend(RSpec::Mocks::InstanceExec) if block
@args_to_yield << args
- @implementation = build_implementation
+ self.initial_implementation_logic = AndYieldImplementation.new(@args_to_yield, @eval_context, @error_generator)
self
end
@@ -418,7 +419,7 @@ def increase_actual_received_count!
@actual_received_count += 1
end
- protected
+ private
def failed_fast?
@failed_fast
@@ -435,12 +436,20 @@ def set_expected_received_count(relativity, n)
end
end
- private
+ def initial_implementation_logic=(logic)
+ @initial_implementation_logic = logic
+ update_implementation
+ end
- def build_implementation
- Implementation.new(
- @values_to_return, @args_to_yield,
- @eval_context, @error_generator
+ def terminal_implementation_logic=(logic)
+ @terminal_implementation_logic = logic
+ update_implementation
+ end
+
+ def update_implementation
+ @implementation = Implementation.new(
+ @initial_implementation_logic,
+ @terminal_implementation_logic
).method(:call)
end
end
@@ -464,29 +473,16 @@ def negative_expectation_for?(message)
end
end
- # Represents a configured implementation. Takes into account
- # `and_return` and `and_yield` instructions.
+ # Handles the implementation of an `and_yield` declaration.
# @private
- class Implementation
- def initialize(values_to_return, args_to_yield, eval_context, error_generator)
- @values_to_return = values_to_return
+ class AndYieldImplementation
+ def initialize(args_to_yield, eval_context, error_generator)
@args_to_yield = args_to_yield
@eval_context = eval_context
@error_generator = error_generator
end
- def call(*args_to_ignore, &block)
- default_return_value = perform_yield(&block)
- return default_return_value unless @values_to_return
-
- if @values_to_return.size > 1
- @values_to_return.shift
- else
- @values_to_return.first
- end
- end
-
- def perform_yield(&block)
+ def call(*args_to_ignore, block)
return if @args_to_yield.empty? && @eval_context.nil?
@error_generator.raise_missing_block_error @args_to_yield unless block
@@ -500,5 +496,34 @@ def perform_yield(&block)
value
end
end
+
+ # Handles the implementation of an `and_return` implementation.
+ # @private
+ class AndReturnImplementation
+ def initialize(values_to_return)
+ @values_to_return = values_to_return
+ end
+
+ def call(*args_to_ignore, block)
+ if @values_to_return.size > 1
+ @values_to_return.shift
+ else
+ @values_to_return.first
+ end
+ end
+ end
+
+ # Represents a configured implementation. Takes into account
+ # any number of sub-implementations.
+ # @private
+ class Implementation
+ def initialize(*implementations)
+ @implementations = implementations.compact
+ end
+
+ def call(*args, &block)
+ @implementations.map { |i| i.call(*args, block) }.last
+ end
+ end
end
end
Please sign in to comment.
Something went wrong with that request. Please try again.