class Tokyo::Expectation
Attributes
expected_message[R]
received_messages[R]
Public Class Methods
new(object, expected_message, assert, caller)
click to toggle source
# File lib/tokyo/expectations.rb, line 17 def initialize object, expected_message, assert, caller @object = object @expected_message = expected_message.to_sym @assert = assert @caller = caller proxify(@object, @expected_message) end
restore_object_status(obj)
click to toggle source
# File lib/tokyo/expectations.rb, line 4 def self.restore_object_status obj return unless obj.instance_variable_get(:@__tokyo__original_methods__) obj.instance_variable_get(:@__tokyo__original_methods__).each_pair do |n,m| obj.define_singleton_method(n, &m) end obj.instance_variable_set(:@__tokyo__original_methods__, {}) obj.instance_variable_set(:@__tokyo__received_messages__, {}) end
Public Instance Methods
and_raise(type = nil, message = nil, &block)
click to toggle source
ensure received message raises as expected
@note if block given it will have precedence over arguments
@example
x = mock(X.new) expect(x).to_receive(:y).and_raise(NoMethodError) # call `x.y` for test to pass
# File lib/tokyo/expectations/raise.rb, line 13 def and_raise type = nil, message = nil, &block @raise = block || [type, message] end
and_return(value = nil, &block)
click to toggle source
ensure received message returns expected value
@note if block given it will have precedence over arguments
@example
n = mock(1) expect(n).to_receive(:+).with(1).and_return(2)
# File lib/tokyo/expectations/return.rb, line 12 def and_return value = nil, &block @return = block || value end
and_throw(symbol = nil, &block)
click to toggle source
ensure received message throws as expected
@note if block given it will have precedence over arguments
@example
x = mock(X.new) expect(x).to_receive(:y).and_throw(:z)
# File lib/tokyo/expectations/throw.rb, line 12 def and_throw symbol = nil, &block @throw = [symbol, block] end
assert_message_raised_as_expected()
click to toggle source
# File lib/tokyo/expectations/raise.rb, line 17 def assert_message_raised_as_expected return unless @raise if @raise.is_a?(Proc) received_messages.find {|log| @raise.call(log[:raised])} || Tokyo.fail([ 'Looks like :%s message never raised as expected' % expected_message, 'See validation block' ], @caller) else received_messages.each do |log| next unless f = Tokyo.assert_raised_as_expected(log, *@raise) Tokyo.fail(f, log[:caller]) end end end
assert_message_thrown_as_expected()
click to toggle source
# File lib/tokyo/expectations/throw.rb, line 16 def assert_message_thrown_as_expected return unless @throw received_messages.each do |log| next unless f = Tokyo.assert_thrown_as_expected(log, *@throw) Tokyo.fail(f, log[:caller]) end end
validate()
click to toggle source
# File lib/tokyo/expectations.rb, line 25 def validate @received_messages = @object.__tokyo__received_messages__[expected_message] || [] return refute_message_received unless @assert assert_message_received assert_message_received_with_correct_arguments assert_message_returned_correct_value assert_message_raised_as_expected assert_message_thrown_as_expected end
with(*args, &block)
click to toggle source
ensure expected message received with correct arguments
@note if block given it will have precedence over arguments
@example
test :some_test do some_object = mock(SomeObject.new) expect(some_object).to_receive(:some_method).with(:some, :args) # call `some_object.some_method(:some, :args)` for test to pass end
# File lib/tokyo/expectations/with.rb, line 15 def with *args, &block @with = block || args self end
Private Instance Methods
assert_message_received()
click to toggle source
# File lib/tokyo/expectations.rb, line 84 def assert_message_received Tokyo.fail('Expected %s to receive %s message' % [ Tokyo.pp(@object), Tokyo.pp(expected_message) ], @caller) if received_messages.empty? end
assert_message_received_with_correct_arguments()
click to toggle source
# File lib/tokyo/expectations/with.rb, line 21 def assert_message_received_with_correct_arguments return unless @with if @with.is_a?(Proc) received_messages.find {|log| @with.call(log[:arguments])} || Tokyo.fail([ 'Looks like :%s message never was called with expected arguments' % expected_message, 'See validation block' ], @caller) else received_messages.find {|log| log[:arguments] == @with} || Tokyo.fail([ 'Looks like :%s message never was called with expected arguments:' % expected_message, Array(@with).map {|x| Tokyo.pp(x)}.join(', ') ], @caller) end end
assert_message_returned_correct_value()
click to toggle source
# File lib/tokyo/expectations/return.rb, line 17 def assert_message_returned_correct_value return unless @return if @return.is_a?(Proc) received_messages.find {|log| @return.call(log[:returned])} || Tokyo.fail([ 'Looks like :%s message never returned expected value' % expected_message, 'See validation block' ], @caller) else received_messages.find {|log| log[:returned] == @return} || Tokyo.fail([ 'Looks like :%s message never returned expected value:' % expected_message, Array(@return).map {|x| Tokyo.pp(x)}.join(', ') ], @caller) end end
mount_original_methods_depot(object)
click to toggle source
# File lib/tokyo/expectations.rb, line 69 def mount_original_methods_depot object return if object.respond_to?(:__tokyo__original_methods__) def object.__tokyo__original_methods__; @__tokyo__original_methods__ ||= {} end end
mount_received_messages_depot(object)
click to toggle source
# File lib/tokyo/expectations.rb, line 74 def mount_received_messages_depot object return if object.respond_to?(:__tokyo__received_messages__) def object.__tokyo__received_messages__; @__tokyo__received_messages__ ||= {} end end
proxify(object, method)
click to toggle source
# File lib/tokyo/expectations.rb, line 36 def proxify object, method mount_original_methods_depot(object) mount_received_messages_depot(object) store_original_method(object, method) object.define_singleton_method method do |*a,&b| log = {arguments: a, block: b, caller: Tokyo.relative_location(caller[0])} (__tokyo__received_messages__[method] ||= []).push(log) if __tokyo__original_methods__[method] return begin log[:returned] = __tokyo__original_methods__[method].call(*a, &b) rescue UncaughtThrowError => e log[:thrown] = Tokyo.extract_thrown_symbol(e) rescue Exception => e log[:raised] = e end end if respond_to?(:method_missing) return begin log[:returned] = __send__(:method_missing, method, *a, &b) rescue UncaughtThrowError => e log[:thrown] = Tokyo.extract_thrown_symbol(e) rescue Exception => e log[:raised] = e end end log[:raised] = NoMethodError.new("undefined method `%s' for %s:%s" % [method, self.inspect, self.class]) end end
refute_message_received()
click to toggle source
# File lib/tokyo/expectations.rb, line 91 def refute_message_received Tokyo.fail('Not Expected %s to receive %s message' % [ Tokyo.pp(@object), Tokyo.pp(expected_message) ], @caller) if received_messages.any? end
store_original_method(object, method)
click to toggle source
# File lib/tokyo/expectations.rb, line 79 def store_original_method object, method return unless object.respond_to?(method) object.__tokyo__original_methods__[method] ||= object.method(method) end