Class: Spec::Mocks::Proxy

Inherits:
Object show all
Defined in:
lib/spec/mocks/proxy.rb

Constant Summary collapse

DEFAULT_OPTIONS =
{
  :null_object => false,
}
@@warn_about_expectations_on_nil =
true

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(target, name = nil, options = {}) ⇒ Proxy

Returns a new instance of Proxy.



18
19
20
21
22
23
24
25
26
27
28
29
# File 'lib/spec/mocks/proxy.rb', line 18

def initialize(target, name=nil, options={})
  @target = target
  @name = name
  @error_generator = ErrorGenerator.new target, name, options
  @expectation_ordering = OrderGroup.new @error_generator
  @expectations = []
  @messages_received = []
  @stubs = []
  @proxied_methods = []
  @options = options ? DEFAULT_OPTIONS.dup.merge(options) : DEFAULT_OPTIONS
  @already_proxied_respond_to = false
end

Class Method Details

.allow_message_expectations_on_nilObject



10
11
12
13
14
15
16
# File 'lib/spec/mocks/proxy.rb', line 10

def self.allow_message_expectations_on_nil
  @@warn_about_expectations_on_nil = false
  
  # ensure nil.rspec_verify is called even if an expectation is not set in the example
  # otherwise the allowance would effect subsequent examples
  $rspec_mocks.add(nil) unless $rspec_mocks.nil?
end

Instance Method Details

#add_message_expectation(expected_from, sym, opts = {}, &block) ⇒ Object



40
41
42
43
44
45
46
47
48
49
50
# File 'lib/spec/mocks/proxy.rb', line 40

def add_message_expectation(expected_from, sym, opts={}, &block)        
  __add sym
  warn_if_nil_class sym
  if existing_stub = @stubs.detect {|s| s.sym == sym }
    expectation = existing_stub.build_child(expected_from, block_given?? block : nil, 1, opts)
  else
    expectation = MessageExpectation.new(@error_generator, @expectation_ordering, expected_from, sym, block_given? ? block : nil, 1, opts)
  end
  @expectations << expectation
  @expectations.last
end

#add_negative_message_expectation(expected_from, sym, &block) ⇒ Object



52
53
54
55
56
57
# File 'lib/spec/mocks/proxy.rb', line 52

def add_negative_message_expectation(expected_from, sym, &block)
  __add sym
  warn_if_nil_class sym
  @expectations << NegativeMessageExpectation.new(@error_generator, @expectation_ordering, expected_from, sym, block_given? ? block : nil)
  @expectations.last
end

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



59
60
61
62
63
# File 'lib/spec/mocks/proxy.rb', line 59

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

#as_null_objectObject



35
36
37
38
# File 'lib/spec/mocks/proxy.rb', line 35

def as_null_object
  @options[:null_object] = true
  @target
end

#find_matching_method_stub(sym, *args) ⇒ Object



134
135
136
# File 'lib/spec/mocks/proxy.rb', line 134

def find_matching_method_stub(sym, *args)
  @stubs.find {|stub| stub.matches(sym, args)}
end

#has_negative_expectation?(sym) ⇒ Boolean

Returns:

  • (Boolean)


94
95
96
# File 'lib/spec/mocks/proxy.rb', line 94

def has_negative_expectation?(sym)
  @expectations.detect {|expectation| expectation.negative_expectation_for?(sym)}
end

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



102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
# File 'lib/spec/mocks/proxy.rb', line 102

def message_received(sym, *args, &block)
  expectation = find_matching_expectation(sym, *args)
  stub = find_matching_method_stub(sym, *args)

  if (stub && expectation && expectation.called_max_times?) || (stub && !expectation)
    if expectation = find_almost_matching_expectation(sym, *args)
      expectation.advise(*args) unless expectation.expected_messages_received?
    end
    stub.invoke(*args, &block)
  elsif expectation
    expectation.invoke(*args, &block)
  elsif expectation = find_almost_matching_expectation(sym, *args)
    expectation.advise(*args) if null_object? unless expectation.expected_messages_received?
    raise_unexpected_message_args_error(expectation, *args) unless (has_negative_expectation?(sym) or null_object?)
  elsif stub = find_almost_matching_stub(sym, *args)
    stub.advise(*args)
    raise_unexpected_message_args_error(stub, *args)
  elsif @target.is_a?(Class) && @target.superclass.respond_to?(sym, true)
    @target.superclass.send(sym, *args, &block)
  else
    @target.__send__ :method_missing, sym, *args, &block
  end
end

#null_object?Boolean

Returns:

  • (Boolean)


31
32
33
# File 'lib/spec/mocks/proxy.rb', line 31

def null_object?
  @options[:null_object]
end

#raise_unexpected_message_args_error(expectation, *args) ⇒ Object



126
127
128
# File 'lib/spec/mocks/proxy.rb', line 126

def raise_unexpected_message_args_error(expectation, *args)
  @error_generator.raise_unexpected_message_args_error expectation, *args
end

#raise_unexpected_message_error(sym, *args) ⇒ Object



130
131
132
# File 'lib/spec/mocks/proxy.rb', line 130

def raise_unexpected_message_error(sym, *args)
  @error_generator.raise_unexpected_message_error sym, *args
end

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

Returns:

  • (Boolean)


90
91
92
# File 'lib/spec/mocks/proxy.rb', line 90

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

#record_message_received(sym, args, block) ⇒ Object



98
99
100
# File 'lib/spec/mocks/proxy.rb', line 98

def record_message_received(sym, args, block)
  @messages_received << [sym, args, block]
end

#remove_stub(message) ⇒ Object



65
66
67
68
69
70
71
72
73
74
# File 'lib/spec/mocks/proxy.rb', line 65

def remove_stub(message)
  message = message.to_sym
  
  if stub_to_remove = @stubs.detect { |s| s.matches_name?(message) }
    reset_proxied_method(message)
    @stubs.delete(stub_to_remove)
  else
    raise MockExpectationError, "The method `#{message}` was not stubbed or was already unstubbed"
  end
end

#resetObject



82
83
84
85
86
87
88
# File 'lib/spec/mocks/proxy.rb', line 82

def reset
  clear_expectations
  clear_stubs
  reset_proxied_methods
  clear_proxied_methods
  reset_nil_expectations_warning
end

#verifyObject

:nodoc:



76
77
78
79
80
# File 'lib/spec/mocks/proxy.rb', line 76

def verify #:nodoc:
  verify_expectations
ensure
  reset
end