Class: RSpec::Mocks::MethodDouble

Inherits:
Hash
  • Object
show all
Defined in:
lib/rspec/mocks/method_double.rb

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(object, method_name, proxy) ⇒ MethodDouble

Returns a new instance of MethodDouble.



6
7
8
9
10
11
12
13
# File 'lib/rspec/mocks/method_double.rb', line 6

def initialize(object, method_name, proxy)
  @method_name = method_name
  @object = object
  @proxy = proxy
  @stashed = false
  store(:expectations, [])
  store(:stubs, [])
end

Instance Attribute Details

#method_nameObject (readonly)

Returns the value of attribute method_name.



4
5
6
# File 'lib/rspec/mocks/method_double.rb', line 4

def method_name
  @method_name
end

Instance Method Details

#add_expectation(error_generator, expectation_ordering, expected_from, opts, &block) ⇒ Object



116
117
118
119
120
121
122
123
124
125
# File 'lib/rspec/mocks/method_double.rb', line 116

def add_expectation(error_generator, expectation_ordering, expected_from, opts, &block)
  configure_method
  expectation = if existing_stub = stubs.first
    existing_stub.build_child(expected_from, block, 1, opts)
  else
    MessageExpectation.new(error_generator, expectation_ordering, expected_from, @method_name, block, 1, opts)
  end
  expectations << expectation
  expectation
end

#add_negative_expectation(error_generator, expectation_ordering, expected_from, &implementation) ⇒ Object



127
128
129
130
131
132
# File 'lib/rspec/mocks/method_double.rb', line 127

def add_negative_expectation(error_generator, expectation_ordering, expected_from, &implementation)
  configure_method
  expectation = NegativeMessageExpectation.new(error_generator, expectation_ordering, expected_from, @method_name, implementation)
  expectations.unshift expectation
  expectation
end

#add_stub(error_generator, expectation_ordering, expected_from, opts = {}, &implementation) ⇒ Object



134
135
136
137
138
139
# File 'lib/rspec/mocks/method_double.rb', line 134

def add_stub(error_generator, expectation_ordering, expected_from, opts={}, &implementation)
  configure_method
  stub = MessageExpectation.new(error_generator, expectation_ordering, expected_from, @method_name, nil, :any, opts, &implementation)
  stubs.unshift stub
  stub
end

#clearObject



111
112
113
114
# File 'lib/rspec/mocks/method_double.rb', line 111

def clear
  expectations.clear
  stubs.clear
end

#configure_methodObject



57
58
59
60
61
62
63
64
# File 'lib/rspec/mocks/method_double.rb', line 57

def configure_method
  RSpec::Mocks::space.add(@object) if RSpec::Mocks::space
  warn_if_nil_class
  unless @stashed
    stash_original_method
    define_proxy_method
  end
end

#define_proxy_methodObject



75
76
77
78
79
80
81
82
83
84
# File 'lib/rspec/mocks/method_double.rb', line 75

def define_proxy_method
  method_name = @method_name
  visibility_for_method = "#{visibility} :#{method_name}"
  object_singleton_class.class_eval(<<-EOF, __FILE__, __LINE__)
    def #{method_name}(*args, &block)
      __mock_proxy.message_received :#{method_name}, *args, &block
    end
    #{visibility_for_method}
  EOF
end

#expectationsObject



15
16
17
# File 'lib/rspec/mocks/method_double.rb', line 15

def expectations
  self[:expectations]
end

#obfuscate(method_name) ⇒ Object



39
40
41
# File 'lib/rspec/mocks/method_double.rb', line 39

def obfuscate(method_name)
  "obfuscated_by_rspec_mocks__#{method_name}"
end

#object_responds_to?(method_name) ⇒ Boolean

Returns:

  • (Boolean)


47
48
49
50
51
52
53
54
55
# File 'lib/rspec/mocks/method_double.rb', line 47

def object_responds_to?(method_name)
  if @proxy.already_proxied_respond_to?
    @object.__send__(obfuscate(:respond_to?), method_name)
  elsif method_name == :respond_to?
    @proxy.already_proxied_respond_to
  else
    @object.respond_to?(method_name, true)
  end
end

#object_singleton_classObject



35
36
37
# File 'lib/rspec/mocks/method_double.rb', line 35

def object_singleton_class
  class << @object; self; end
end

#proxy_for_nil_class?Boolean

Returns:

  • (Boolean)


146
147
148
# File 'lib/rspec/mocks/method_double.rb', line 146

def proxy_for_nil_class?
  @object.nil?
end

#raise_method_not_stubbed_errorObject



156
157
158
# File 'lib/rspec/mocks/method_double.rb', line 156

def raise_method_not_stubbed_error
  raise MockExpectationError, "The method `#{method_name}` was not stubbed or was already unstubbed" 
end

#remove_stubObject



141
142
143
144
# File 'lib/rspec/mocks/method_double.rb', line 141

def remove_stub
  raise_method_not_stubbed_error if stubs.empty?
  expectations.empty? ? reset : stubs.clear
end

#resetObject



105
106
107
108
109
# File 'lib/rspec/mocks/method_double.rb', line 105

def reset
  reset_nil_expectations_warning
  restore_original_method
  clear
end

#reset_nil_expectations_warningObject



160
161
162
# File 'lib/rspec/mocks/method_double.rb', line 160

def reset_nil_expectations_warning
  RSpec::Mocks::Proxy.warn_about_expectations_on_nil = true if proxy_for_nil_class?
end

#restore_original_methodObject



86
87
88
89
90
91
92
93
94
95
96
97
98
99
# File 'lib/rspec/mocks/method_double.rb', line 86

def restore_original_method
  if @stashed
    method_name = @method_name
    stashed_method_name = self.stashed_method_name
    object_singleton_class.instance_eval do
      remove_method method_name
      if method_defined?(stashed_method_name) || private_method_defined?(stashed_method_name)
        alias_method method_name, stashed_method_name
        remove_method stashed_method_name
      end
    end
    @stashed = false
  end
end

#stash_original_methodObject



66
67
68
69
70
71
72
73
# File 'lib/rspec/mocks/method_double.rb', line 66

def stash_original_method
  stashed = stashed_method_name
  orig = @method_name
  object_singleton_class.class_eval do
    alias_method(stashed, orig) if method_defined?(orig) || private_method_defined?(orig)
  end
  @stashed = true
end

#stashed_method_nameObject



43
44
45
# File 'lib/rspec/mocks/method_double.rb', line 43

def stashed_method_name
  obfuscate(method_name)
end

#stubsObject



19
20
21
# File 'lib/rspec/mocks/method_double.rb', line 19

def stubs
  self[:stubs]
end

#verifyObject



101
102
103
# File 'lib/rspec/mocks/method_double.rb', line 101

def verify
  expectations.each {|e| e.verify_messages_received}
end

#visibilityObject



23
24
25
26
27
28
29
30
31
32
33
# File 'lib/rspec/mocks/method_double.rb', line 23

def visibility
  if Mock === @object
    'public'
  elsif object_singleton_class.private_method_defined?(@method_name)
    'private'
  elsif object_singleton_class.protected_method_defined?(@method_name)
    'protected'
  else
    'public'
  end
end

#warn_if_nil_classObject



150
151
152
153
154
# File 'lib/rspec/mocks/method_double.rb', line 150

def warn_if_nil_class
  if proxy_for_nil_class? & RSpec::Mocks::Proxy.warn_about_expectations_on_nil
    Kernel.warn("An expectation of :#{@method_name} was set on nil. Called from #{caller[4]}. Use allow_message_expectations_on_nil to disable warnings.")
  end
end