Class: Muack::Mock
- Inherits:
- BasicObject
- Defined in:
- lib/muack/mock.rb
Instance Attribute Summary collapse
-
#object ⇒ Object
readonly
Returns the value of attribute object.
Instance Method Summary collapse
-
#__mock_class ⇒ Object
used for Muack::Modifier#times to determine if it’s a mock or not.
-
#__mock_defis_pop(defi) ⇒ Object
used for Muack::Modifier#times.
-
#__mock_defis_push(defi) ⇒ Object
used for Muack::Modifier#times.
-
#__mock_dispatch(msg, actual_args) ⇒ Object
used for mocked object to dispatch mocked method.
-
#__mock_dispatch_call(disp, actual_args, actual_block) ⇒ Object
used for mocked object to dispatch mocked method.
-
#__mock_reset ⇒ Object
used for Muack::Session#reset.
-
#__mock_verify ⇒ Object
used for Muack::Session#verify.
-
#initialize(object) ⇒ Mock
constructor
A new instance of Mock.
-
#inspect ⇒ Object
Public API: Bacon needs this, or we often ended up with stack overflow.
-
#method_missing(msg, *args, &block) ⇒ Object
Public API: Define mocked method.
Constructor Details
#initialize(object) ⇒ Mock
Returns a new instance of Mock.
10 11 12 13 14 15 16 |
# File 'lib/muack/mock.rb', line 10 def initialize object @object = object @__mock_injected = {} [:__mock_defis=, :__mock_disps=].each do |m| __send__(m, ::Hash.new{ |h, k| h[k] = [] }) end end |
Dynamic Method Handling
This class handles dynamic methods through the method_missing method
#method_missing(msg, *args, &block) ⇒ Object
Public API: Define mocked method
24 25 26 27 28 29 30 31 32 33 |
# File 'lib/muack/mock.rb', line 24 def method_missing msg, *args, &block defi = Definition.new(msg, args, block) if injected = __mock_injected[defi.msg] defi.original_method = injected.original_method else __mock_inject_method(defi) end __mock_defis_push(defi) Modifier.new(self, defi) end |
Instance Attribute Details
#object ⇒ Object (readonly)
Returns the value of attribute object.
9 10 11 |
# File 'lib/muack/mock.rb', line 9 def object @object end |
Instance Method Details
#__mock_class ⇒ Object
used for Muack::Modifier#times to determine if it’s a mock or not
46 47 48 |
# File 'lib/muack/mock.rb', line 46 def __mock_class (class << self; self; end).superclass end |
#__mock_defis_pop(defi) ⇒ Object
used for Muack::Modifier#times
41 42 43 |
# File 'lib/muack/mock.rb', line 41 def __mock_defis_pop defi __mock_defis[defi.msg].pop end |
#__mock_defis_push(defi) ⇒ Object
used for Muack::Modifier#times
36 37 38 |
# File 'lib/muack/mock.rb', line 36 def __mock_defis_push defi __mock_defis[defi.msg] << defi end |
#__mock_dispatch(msg, actual_args) ⇒ Object
used for mocked object to dispatch mocked method
51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 |
# File 'lib/muack/mock.rb', line 51 def __mock_dispatch msg, actual_args if defi = __mock_defis[msg].shift __mock_disps_push(defi) if __mock_check_args(defi.args, actual_args) defi else Mock.__send__(:raise, # Wrong argument Unexpected.new(object, [defi], msg, actual_args)) end else defis = __mock_disps[msg] if expected = defis.find{ |d| __mock_check_args(d.args, actual_args) } Mock.__send__(:raise, # Too many times Expected.new(object, expected, defis.size, defis.size+1)) else Mock.__send__(:raise, # Wrong argument Unexpected.new(object, defis, msg, actual_args)) end end end |
#__mock_dispatch_call(disp, actual_args, actual_block) ⇒ Object
used for mocked object to dispatch mocked method
73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 |
# File 'lib/muack/mock.rb', line 73 def __mock_dispatch_call disp, actual_args, actual_block if disp.proxy value = yield # need the original context for proxy or AnyInstanceOf if disp.block disp.block.call(value) else value end elsif block = disp.block arity = block.arity if arity < 0 block.call(*actual_args , &actual_block) else block.call(*actual_args.first(arity), &actual_block) end end end |
#__mock_reset ⇒ Object
used for Muack::Session#reset
103 104 105 106 107 108 109 110 111 112 113 114 |
# File 'lib/muack/mock.rb', line 103 def __mock_reset __mock_injected.each_value do |defi| object.singleton_class.module_eval do remove_method(defi.msg) # restore original method if instance_methods(false).include?(defi.original_method) alias_method defi.msg, defi.original_method remove_method defi.original_method end end end end |
#__mock_verify ⇒ Object
used for Muack::Session#verify
92 93 94 95 96 97 98 99 100 |
# File 'lib/muack/mock.rb', line 92 def __mock_verify __mock_defis.values.all?(&:empty?) || begin msg, defis_with_same_msg = __mock_defis.find{ |_, v| v.size > 0 } args, defis = defis_with_same_msg.group_by(&:args).first dsize = __mock_disps[msg].select{ |d| d.args == args }.size Mock.__send__(:raise, # Too little times Expected.new(object, defis.first, defis.size + dsize, dsize)) end end |
#inspect ⇒ Object
Public API: Bacon needs this, or we often ended up with stack overflow
19 20 21 |
# File 'lib/muack/mock.rb', line 19 def inspect "Muack::API.#{__mock_class.name[/\w+$/].downcase}(#{object.inspect})" end |