Class: RSpec::Mocks::Proxy

Inherits:
Object show all
Defined in:
lib/rubypitaya/app-template/vendor/bundle/ruby/3.1.0/gems/rspec-mocks-3.12.2/lib/rspec/mocks/proxy.rb

Direct Known Subclasses

PartialDoubleProxy, TestDoubleProxy

Defined Under Namespace

Classes: SpecificMessage

Constant Summary collapse

DEFAULT_MESSAGE_EXPECTATION_OPTS =
{}.freeze

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(object, order_group, options = {}) ⇒ Proxy

Returns a new instance of Proxy.



23
24
25
26
27
28
29
30
31
32
33
34
# File 'lib/rubypitaya/app-template/vendor/bundle/ruby/3.1.0/gems/rspec-mocks-3.12.2/lib/rspec/mocks/proxy.rb', line 23

def initialize(object, order_group, options={})
  ensure_can_be_proxied!(object)

  @object = object
  @order_group = order_group
  @error_generator = ErrorGenerator.new(object)
  @messages_received = []
  @messages_received_mutex = Mutex.new
  @options = options
  @null_object = false
  @method_doubles = Hash.new { |h, k| h[k] = MethodDouble.new(@object, k, self) }
end

Instance Attribute Details

#objectObject (readonly)



45
46
47
# File 'lib/rubypitaya/app-template/vendor/bundle/ruby/3.1.0/gems/rspec-mocks-3.12.2/lib/rspec/mocks/proxy.rb', line 45

def object
  @object
end

Class Method Details

.prepended_modules_of(klass) ⇒ Object



247
248
249
250
251
252
253
254
255
# File 'lib/rubypitaya/app-template/vendor/bundle/ruby/3.1.0/gems/rspec-mocks-3.12.2/lib/rspec/mocks/proxy.rb', line 247

def self.prepended_modules_of(klass)
  ancestors = klass.ancestors

  # `|| 0` is necessary for Ruby 2.0, where the singleton class
  # is only in the ancestor list when there are prepended modules.
  singleton_index = ancestors.index(klass) || 0

  ancestors[0, singleton_index]
end

Instance Method Details

#add_message_expectation(method_name, opts = DEFAULT_MESSAGE_EXPECTATION_OPTS, &block) ⇒ Object



68
69
70
71
72
73
74
75
76
77
78
79
# File 'lib/rubypitaya/app-template/vendor/bundle/ruby/3.1.0/gems/rspec-mocks-3.12.2/lib/rspec/mocks/proxy.rb', line 68

def add_message_expectation(method_name, opts=DEFAULT_MESSAGE_EXPECTATION_OPTS, &block)
  location = opts.fetch(:expected_from) { CallerFilter.first_non_rspec_line }
  meth_double = method_double_for(method_name)

  if null_object? && !block
    meth_double.add_default_stub(@error_generator, @order_group, location, opts) do
      @object
    end
  end

  meth_double.add_expectation @error_generator, @order_group, location, opts, &block
end

#add_simple_expectation(method_name, response, location) ⇒ Object



82
83
84
# File 'lib/rubypitaya/app-template/vendor/bundle/ruby/3.1.0/gems/rspec-mocks-3.12.2/lib/rspec/mocks/proxy.rb', line 82

def add_simple_expectation(method_name, response, location)
  method_double_for(method_name).add_simple_expectation method_name, response, @error_generator, location
end

#add_simple_stub(method_name, response) ⇒ Object



143
144
145
# File 'lib/rubypitaya/app-template/vendor/bundle/ruby/3.1.0/gems/rspec-mocks-3.12.2/lib/rspec/mocks/proxy.rb', line 143

def add_simple_stub(method_name, response)
  method_double_for(method_name).add_simple_stub method_name, response
end

#add_stub(method_name, opts = {}, &implementation) ⇒ Object



137
138
139
140
# File 'lib/rubypitaya/app-template/vendor/bundle/ruby/3.1.0/gems/rspec-mocks-3.12.2/lib/rspec/mocks/proxy.rb', line 137

def add_stub(method_name, opts={}, &implementation)
  location = opts.fetch(:expected_from) { CallerFilter.first_non_rspec_line }
  method_double_for(method_name).add_stub @error_generator, @order_group, location, opts, &implementation
end

#as_null_objectObject

Tells the object to ignore any messages that aren’t explicitly set as stubs or message expectations.



55
56
57
58
# File 'lib/rubypitaya/app-template/vendor/bundle/ruby/3.1.0/gems/rspec-mocks-3.12.2/lib/rspec/mocks/proxy.rb', line 55

def as_null_object
  @null_object = true
  @object
end

#build_expectation(method_name) ⇒ Object



87
88
89
90
91
92
93
94
# File 'lib/rubypitaya/app-template/vendor/bundle/ruby/3.1.0/gems/rspec-mocks-3.12.2/lib/rspec/mocks/proxy.rb', line 87

def build_expectation(method_name)
  meth_double = method_double_for(method_name)

  meth_double.build_expectation(
    @error_generator,
    @order_group
  )
end

#check_for_unexpected_arguments(expectation) ⇒ Object



120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
# File 'lib/rubypitaya/app-template/vendor/bundle/ruby/3.1.0/gems/rspec-mocks-3.12.2/lib/rspec/mocks/proxy.rb', line 120

def check_for_unexpected_arguments(expectation)
  @messages_received_mutex.synchronize do
    return if @messages_received.empty?

    return if @messages_received.any? { |method_name, args, _| expectation.matches?(method_name, *args) }

    name_but_not_args, others = @messages_received.partition do |(method_name, args, _)|
      expectation.matches_name_but_not_args(method_name, *args)
    end

    return if name_but_not_args.empty? && !others.empty?

    expectation.raise_unexpected_message_args_error(name_but_not_args.map { |args| args[1] })
  end
end

#ensure_can_be_proxied!(object) ⇒ Object

Raises:

  • (ArgumentError)


37
38
39
40
41
42
# File 'lib/rubypitaya/app-template/vendor/bundle/ruby/3.1.0/gems/rspec-mocks-3.12.2/lib/rspec/mocks/proxy.rb', line 37

def ensure_can_be_proxied!(object)
  return unless object.is_a?(Symbol)

  msg = "Cannot proxy frozen objects. Symbols such as #{object} cannot be mocked or stubbed."
  raise ArgumentError, msg
end

#ensure_implemented(*_args) ⇒ Object



18
19
20
# File 'lib/rubypitaya/app-template/vendor/bundle/ruby/3.1.0/gems/rspec-mocks-3.12.2/lib/rspec/mocks/proxy.rb', line 18

def ensure_implemented(*_args)
  # noop for basic proxies, see VerifyingProxy for behaviour.
end

#has_negative_expectation?(message) ⇒ Boolean

Returns:

  • (Boolean)


184
185
186
# File 'lib/rubypitaya/app-template/vendor/bundle/ruby/3.1.0/gems/rspec-mocks-3.12.2/lib/rspec/mocks/proxy.rb', line 184

def has_negative_expectation?(message)
  method_double_for(message).expectations.find { |expectation| expectation.negative_expectation_for?(message) }
end

#message_received(message, *args, &block) ⇒ Object



198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
# File 'lib/rubypitaya/app-template/vendor/bundle/ruby/3.1.0/gems/rspec-mocks-3.12.2/lib/rspec/mocks/proxy.rb', line 198

def message_received(message, *args, &block)
  record_message_received message, *args, &block

  expectation = find_matching_expectation(message, *args)
  stub = find_matching_method_stub(message, *args)

  if (stub && expectation && expectation.called_max_times?) || (stub && !expectation)
    expectation.increase_actual_received_count! if expectation && expectation.actual_received_count_matters?
    if (expectation = find_almost_matching_expectation(message, *args))
      expectation.advise(*args) unless expectation.expected_messages_received?
    end
    stub.invoke(nil, *args, &block)
  elsif expectation
    expectation.unadvise(messages_arg_list)
    expectation.invoke(stub, *args, &block)
  elsif (expectation = find_almost_matching_expectation(message, *args))
    expectation.advise(*args) if null_object? unless expectation.expected_messages_received?

    if null_object? || !has_negative_expectation?(message)
      expectation.raise_unexpected_message_args_error([args])
    end
  elsif (stub = find_almost_matching_stub(message, *args))
    stub.advise(*args)
    raise_missing_default_stub_error(stub, [args])
  elsif Class === @object
    @object.superclass.__send__(message, *args, &block)
  else
    @object.__send__(:method_missing, message, *args, &block)
  end
end

#messages_arg_listObject



177
178
179
180
181
# File 'lib/rubypitaya/app-template/vendor/bundle/ruby/3.1.0/gems/rspec-mocks-3.12.2/lib/rspec/mocks/proxy.rb', line 177

def messages_arg_list
  @messages_received_mutex.synchronize do
    @messages_received.map { |_, args, _| args }
  end
end

#method_double_if_exists_for_message(message) ⇒ Object



263
264
265
# File 'lib/rubypitaya/app-template/vendor/bundle/ruby/3.1.0/gems/rspec-mocks-3.12.2/lib/rspec/mocks/proxy.rb', line 263

def method_double_if_exists_for_message(message)
  method_double_for(message) if @method_doubles.key?(message.to_sym)
end

#null_object?Boolean

Returns:

  • (Boolean)


48
49
50
# File 'lib/rubypitaya/app-template/vendor/bundle/ruby/3.1.0/gems/rspec-mocks-3.12.2/lib/rspec/mocks/proxy.rb', line 48

def null_object?
  @null_object
end

#original_method_handle_for(_message) ⇒ Object



61
62
63
# File 'lib/rubypitaya/app-template/vendor/bundle/ruby/3.1.0/gems/rspec-mocks-3.12.2/lib/rspec/mocks/proxy.rb', line 61

def original_method_handle_for(_message)
  nil
end

#prepended_modules_of_singleton_classObject



257
258
259
# File 'lib/rubypitaya/app-template/vendor/bundle/ruby/3.1.0/gems/rspec-mocks-3.12.2/lib/rspec/mocks/proxy.rb', line 257

def prepended_modules_of_singleton_class
  @prepended_modules_of_singleton_class ||= RSpec::Mocks::Proxy.prepended_modules_of(@object.singleton_class)
end

#raise_missing_default_stub_error(expectation, args_for_multiple_calls) ⇒ Object



236
237
238
# File 'lib/rubypitaya/app-template/vendor/bundle/ruby/3.1.0/gems/rspec-mocks-3.12.2/lib/rspec/mocks/proxy.rb', line 236

def raise_missing_default_stub_error(expectation, args_for_multiple_calls)
  @error_generator.raise_missing_default_stub_error(expectation, args_for_multiple_calls)
end

#raise_unexpected_message_error(method_name, args) ⇒ Object



231
232
233
# File 'lib/rubypitaya/app-template/vendor/bundle/ruby/3.1.0/gems/rspec-mocks-3.12.2/lib/rspec/mocks/proxy.rb', line 231

def raise_unexpected_message_error(method_name, args)
  @error_generator.raise_unexpected_message_error method_name, args
end

#received_message?(method_name, *args, &block) ⇒ Boolean

Returns:

  • (Boolean)


170
171
172
173
174
# File 'lib/rubypitaya/app-template/vendor/bundle/ruby/3.1.0/gems/rspec-mocks-3.12.2/lib/rspec/mocks/proxy.rb', line 170

def received_message?(method_name, *args, &block)
  @messages_received_mutex.synchronize do
    @messages_received.any? { |array| array == [method_name, args, block] }
  end
end

#record_message_received(message, *args, &block) ⇒ Object



189
190
191
192
193
194
# File 'lib/rubypitaya/app-template/vendor/bundle/ruby/3.1.0/gems/rspec-mocks-3.12.2/lib/rspec/mocks/proxy.rb', line 189

def record_message_received(message, *args, &block)
  @order_group.invoked SpecificMessage.new(object, message, args)
  @messages_received_mutex.synchronize do
    @messages_received << [message, args, block]
  end
end

#remove_stub(method_name) ⇒ Object



148
149
150
# File 'lib/rubypitaya/app-template/vendor/bundle/ruby/3.1.0/gems/rspec-mocks-3.12.2/lib/rspec/mocks/proxy.rb', line 148

def remove_stub(method_name)
  method_double_for(method_name).remove_stub
end

#remove_stub_if_present(method_name) ⇒ Object



153
154
155
# File 'lib/rubypitaya/app-template/vendor/bundle/ruby/3.1.0/gems/rspec-mocks-3.12.2/lib/rspec/mocks/proxy.rb', line 153

def remove_stub_if_present(method_name)
  method_double_for(method_name).remove_stub_if_present
end

#replay_received_message_on(expectation, &block) ⇒ Object



97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
# File 'lib/rubypitaya/app-template/vendor/bundle/ruby/3.1.0/gems/rspec-mocks-3.12.2/lib/rspec/mocks/proxy.rb', line 97

def replay_received_message_on(expectation, &block)
  expected_method_name = expectation.message
  meth_double = method_double_for(expected_method_name)

  if meth_double.expectations.any?
    @error_generator.raise_expectation_on_mocked_method(expected_method_name)
  end

  unless null_object? || meth_double.stubs.any?
    @error_generator.raise_expectation_on_unstubbed_method(expected_method_name)
  end

  @messages_received_mutex.synchronize do
    @messages_received.each do |(actual_method_name, args, received_block)|
      next unless expectation.matches?(actual_method_name, *args)

      expectation.safe_invoke(nil)
      block.call(*args, &received_block) if block
    end
  end
end

#resetObject



163
164
165
166
167
# File 'lib/rubypitaya/app-template/vendor/bundle/ruby/3.1.0/gems/rspec-mocks-3.12.2/lib/rspec/mocks/proxy.rb', line 163

def reset
  @messages_received_mutex.synchronize do
    @messages_received.clear
  end
end

#verifyObject



158
159
160
# File 'lib/rubypitaya/app-template/vendor/bundle/ruby/3.1.0/gems/rspec-mocks-3.12.2/lib/rspec/mocks/proxy.rb', line 158

def verify
  @method_doubles.each_value { |d| d.verify }
end

#visibility_for(_method_name) ⇒ Object



241
242
243
244
# File 'lib/rubypitaya/app-template/vendor/bundle/ruby/3.1.0/gems/rspec-mocks-3.12.2/lib/rspec/mocks/proxy.rb', line 241

def visibility_for(_method_name)
  # This is the default (for test doubles). Subclasses override this.
  :public
end