rspec-mocks 2.0.0.beta.4 → 2.0.0.beta.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (43) hide show
  1. data/.autotest +3 -2
  2. data/VERSION +1 -1
  3. data/features/mocks/block_local_expectations.feature +0 -14
  4. data/features/mocks/mix_stubs_and_mocks.feature +2 -2
  5. data/features/mocks/warn_when_expectation_is_set_on_nil.feature +50 -0
  6. data/lib/rspec/mocks.rb +9 -9
  7. data/lib/rspec/mocks/argument_matchers.rb +1 -1
  8. data/lib/rspec/mocks/error_generator.rb +24 -8
  9. data/lib/rspec/mocks/framework.rb +1 -0
  10. data/lib/rspec/mocks/message_expectation.rb +1 -1
  11. data/lib/rspec/mocks/method_double.rb +156 -0
  12. data/lib/rspec/mocks/methods.rb +2 -2
  13. data/lib/rspec/mocks/mock.rb +17 -10
  14. data/lib/rspec/mocks/proxy.rb +71 -158
  15. data/lib/rspec/mocks/spec_methods.rb +19 -3
  16. data/rspec-mocks.gemspec +14 -10
  17. data/spec/rspec/mocks/any_number_of_times_spec.rb +1 -1
  18. data/spec/rspec/mocks/argument_expectation_spec.rb +2 -2
  19. data/spec/rspec/mocks/bug_report_10260_spec.rb +1 -1
  20. data/spec/rspec/mocks/bug_report_10263_spec.rb +8 -8
  21. data/spec/rspec/mocks/bug_report_15719_spec.rb +12 -12
  22. data/spec/rspec/mocks/bug_report_7611_spec.rb +1 -1
  23. data/spec/rspec/mocks/bug_report_7805_spec.rb +1 -1
  24. data/spec/rspec/mocks/bug_report_8165_spec.rb +1 -1
  25. data/spec/rspec/mocks/bug_report_957_spec.rb +1 -1
  26. data/spec/rspec/mocks/double_spec.rb +12 -0
  27. data/spec/rspec/mocks/failing_argument_matchers_spec.rb +7 -6
  28. data/spec/rspec/mocks/mock_ordering_spec.rb +54 -54
  29. data/spec/rspec/mocks/mock_space_spec.rb +4 -4
  30. data/spec/rspec/mocks/mock_spec.rb +55 -51
  31. data/spec/rspec/mocks/multiple_return_value_spec.rb +29 -7
  32. data/spec/rspec/mocks/nil_expectation_warning_spec.rb +8 -8
  33. data/spec/rspec/mocks/null_object_mock_spec.rb +2 -2
  34. data/spec/rspec/mocks/once_counts_spec.rb +1 -1
  35. data/spec/rspec/mocks/options_hash_spec.rb +1 -1
  36. data/spec/rspec/mocks/partial_mock_spec.rb +13 -7
  37. data/spec/rspec/mocks/passing_argument_matchers_spec.rb +1 -1
  38. data/spec/rspec/mocks/precise_counts_spec.rb +1 -1
  39. data/spec/rspec/mocks/record_messages_spec.rb +1 -1
  40. data/spec/rspec/mocks/stub_spec.rb +22 -22
  41. data/spec/rspec/mocks/stubbed_message_expectations_spec.rb +12 -12
  42. data/spec/rspec/mocks/twice_counts_spec.rb +1 -1
  43. metadata +13 -9
@@ -1,29 +1,36 @@
1
1
  module Rspec
2
2
  module Mocks
3
3
  class Proxy
4
- DEFAULT_OPTIONS = {
5
- :null_object => false,
6
- }
4
+ DEFAULT_OPTIONS = { :null_object => false }
5
+
6
+ class << self
7
+ def warn_about_expectations_on_nil
8
+ defined?(@warn_about_expectations_on_nil) ? @warn_about_expectations_on_nil : true
9
+ end
7
10
 
8
- @@warn_about_expectations_on_nil = true
11
+ def warn_about_expectations_on_nil=(new_value)
12
+ @warn_about_expectations_on_nil = new_value
13
+ end
9
14
 
10
- def self.allow_message_expectations_on_nil
11
- @@warn_about_expectations_on_nil = false
12
-
13
- # ensure nil.rspec_verify is called even if an expectation is not set in the example
14
- # otherwise the allowance would effect subsequent examples
15
- $rspec_mocks.add(nil) unless $rspec_mocks.nil?
15
+ def allow_message_expectations_on_nil
16
+ @warn_about_expectations_on_nil = false
17
+
18
+ # ensure nil.rspec_verify is called even if an expectation is not set in the example
19
+ # otherwise the allowance would effect subsequent examples
20
+ $rspec_mocks.add(nil) unless $rspec_mocks.nil?
21
+ end
22
+
23
+ def allow_message_expectations_on_nil?
24
+ !warn_about_expectations_on_nil
25
+ end
16
26
  end
17
27
 
18
- def initialize(target, name=nil, options={})
19
- @target = target
28
+ def initialize(object, name=nil, options={})
29
+ @object = object
20
30
  @name = name
21
- @error_generator = ErrorGenerator.new target, name
31
+ @error_generator = ErrorGenerator.new object, name, options
22
32
  @expectation_ordering = OrderGroup.new @error_generator
23
- @expectations = []
24
33
  @messages_received = []
25
- @stubs = []
26
- @proxied_methods = []
27
34
  @options = options ? DEFAULT_OPTIONS.dup.merge(options) : DEFAULT_OPTIONS
28
35
  @already_proxied_respond_to = false
29
36
  end
@@ -34,197 +41,103 @@ module Rspec
34
41
 
35
42
  def as_null_object
36
43
  @options[:null_object] = true
37
- @target
44
+ @object
38
45
  end
39
46
 
40
- def add_message_expectation(expected_from, sym, opts={}, &block)
41
- __add sym
42
- warn_if_nil_class sym
43
- if existing_stub = @stubs.detect {|s| s.sym == sym }
44
- expectation = existing_stub.build_child(expected_from, block_given?? block : nil, 1, opts)
45
- else
46
- expectation = MessageExpectation.new(@error_generator, @expectation_ordering, expected_from, sym, block_given? ? block : nil, 1, opts)
47
- end
48
- @expectations << expectation
49
- @expectations.last
47
+ def already_proxied_respond_to
48
+ @already_proxied_respond_to = true
49
+ end
50
+
51
+ def already_proxied_respond_to?
52
+ @already_proxied_respond_to
53
+ end
54
+
55
+ def add_message_expectation(location, method_name, opts={}, &block)
56
+ method_double[method_name].add_expectation @error_generator, @expectation_ordering, location, opts, &block
50
57
  end
51
58
 
52
- def add_negative_message_expectation(expected_from, sym, &block)
53
- __add sym
54
- warn_if_nil_class sym
55
- @expectations << NegativeMessageExpectation.new(@error_generator, @expectation_ordering, expected_from, sym, block_given? ? block : nil)
56
- @expectations.last
59
+ def add_negative_message_expectation(location, method_name, &implementation)
60
+ method_double[method_name].add_negative_expectation @error_generator, @expectation_ordering, location, &implementation
57
61
  end
58
62
 
59
- def add_stub(expected_from, sym, opts={}, &implementation)
60
- __add sym
61
- @stubs.unshift MessageExpectation.new(@error_generator, @expectation_ordering, expected_from, sym, nil, :any, opts, &implementation)
62
- @stubs.first
63
+ def add_stub(location, method_name, opts={}, &implementation)
64
+ method_double[method_name].add_stub @error_generator, @expectation_ordering, location, opts, &implementation
63
65
  end
64
66
 
65
67
  def verify #:nodoc:
66
- verify_expectations
68
+ method_doubles.each {|d| d.verify}
67
69
  ensure
68
70
  reset
69
71
  end
70
72
 
71
73
  def reset
72
- clear_expectations
73
- clear_stubs
74
- reset_proxied_methods
75
- clear_proxied_methods
76
- reset_nil_expectations_warning
74
+ method_doubles.each {|d| d.reset}
77
75
  end
78
76
 
79
- def received_message?(sym, *args, &block)
80
- @messages_received.any? {|array| array == [sym, args, block]}
77
+ def received_message?(method_name, *args, &block)
78
+ @messages_received.any? {|array| array == [method_name, args, block]}
81
79
  end
82
80
 
83
- def has_negative_expectation?(sym)
84
- @expectations.detect {|expectation| expectation.negative_expectation_for?(sym)}
81
+ def has_negative_expectation?(method_name)
82
+ method_double[method_name].expectations.detect {|expectation| expectation.negative_expectation_for?(method_name)}
85
83
  end
86
84
 
87
- def record_message_received(sym, args, block)
88
- @messages_received << [sym, args, block]
85
+ def record_message_received(method_name, args, block)
86
+ @messages_received << [method_name, args, block]
89
87
  end
90
88
 
91
- def message_received(sym, *args, &block)
92
- expectation = find_matching_expectation(sym, *args)
93
- stub = find_matching_method_stub(sym, *args)
89
+ def message_received(method_name, *args, &block)
90
+ expectation = find_matching_expectation(method_name, *args)
91
+ stub = find_matching_method_stub(method_name, *args)
94
92
 
95
93
  if (stub && expectation && expectation.called_max_times?) || (stub && !expectation)
96
- if expectation = find_almost_matching_expectation(sym, *args)
94
+ if expectation = find_almost_matching_expectation(method_name, *args)
97
95
  expectation.advise(args, block) unless expectation.expected_messages_received?
98
96
  end
99
97
  stub.invoke(args, block)
100
98
  elsif expectation
101
99
  expectation.invoke(args, block)
102
- elsif expectation = find_almost_matching_expectation(sym, *args)
100
+ elsif expectation = find_almost_matching_expectation(method_name, *args)
103
101
  expectation.advise(args, block) if null_object? unless expectation.expected_messages_received?
104
- raise_unexpected_message_args_error(expectation, *args) unless (has_negative_expectation?(sym) or null_object?)
105
- elsif @target.is_a?(Class)
106
- @target.superclass.send(sym, *args, &block)
102
+ raise_unexpected_message_args_error(expectation, *args) unless (has_negative_expectation?(method_name) or null_object?)
103
+ elsif @object.is_a?(Class)
104
+ @object.superclass.send(method_name, *args, &block)
107
105
  else
108
- @target.__send__ :method_missing, sym, *args, &block
106
+ @object.__send__ :method_missing, method_name, *args, &block
109
107
  end
110
108
  end
111
109
 
112
110
  def raise_unexpected_message_args_error(expectation, *args)
113
- @error_generator.raise_unexpected_message_args_error expectation, *args
111
+ @error_generator.raise_unexpected_message_args_error(expectation, *args)
114
112
  end
115
113
 
116
- def raise_unexpected_message_error(sym, *args)
117
- @error_generator.raise_unexpected_message_error sym, *args
114
+ def raise_unexpected_message_error(method_name, *args)
115
+ @error_generator.raise_unexpected_message_error method_name, *args
118
116
  end
119
117
 
120
118
  private
121
119
 
122
- def __add(sym)
123
- $rspec_mocks.add(@target) unless $rspec_mocks.nil?
124
- define_expected_method(sym)
125
- end
126
-
127
- def warn_if_nil_class(sym)
128
- if proxy_for_nil_class? & @@warn_about_expectations_on_nil
129
- Kernel.warn("An expectation of :#{sym} was set on nil. Called from #{caller[2]}. Use allow_message_expectations_on_nil to disable warnings.")
130
- end
131
- end
132
-
133
- def define_expected_method(sym)
134
- unless @proxied_methods.include?(sym)
135
- visibility_string = "#{visibility(sym)} :#{sym}"
136
- if target_responds_to?(sym)
137
- munged_sym = munge(sym)
138
- target_metaclass.instance_eval do
139
- alias_method munged_sym, sym if method_defined?(sym)
140
- end
141
- @proxied_methods << sym
142
- end
143
- target_metaclass.class_eval(<<-EOF, __FILE__, __LINE__)
144
- def #{sym}(*args, &block)
145
- __mock_proxy.message_received :#{sym}, *args, &block
146
- end
147
- #{visibility_string}
148
- EOF
149
- end
150
- end
151
-
152
- def target_responds_to?(sym)
153
- return @target.__send__(munge(:respond_to?),sym) if @already_proxied_respond_to
154
- return @already_proxied_respond_to = true if sym == :respond_to?
155
- return @target.respond_to?(sym, true)
156
- end
157
-
158
- def visibility(sym)
159
- if Mock === @target
160
- 'public'
161
- elsif target_metaclass.private_method_defined?(sym)
162
- 'private'
163
- elsif target_metaclass.protected_method_defined?(sym)
164
- 'protected'
165
- else
166
- 'public'
167
- end
168
- end
169
-
170
- def munge(sym)
171
- "proxied_by_rspec__#{sym}"
172
- end
173
-
174
- def clear_expectations
175
- @expectations.clear
176
- end
177
-
178
- def clear_stubs
179
- @stubs.clear
180
- end
181
-
182
- def clear_proxied_methods
183
- @proxied_methods.clear
120
+ def method_double
121
+ @method_double ||= Hash.new {|h,k|
122
+ h[k] = MethodDouble.new(@object, k, self)
123
+ }
184
124
  end
185
125
 
186
- def target_metaclass
187
- class << @target; self; end
188
- end
189
-
190
- def verify_expectations
191
- @expectations.each do |expectation|
192
- expectation.verify_messages_received
193
- end
194
- end
195
-
196
- def reset_proxied_methods
197
- @proxied_methods.each do |sym|
198
- munged_sym = munge(sym)
199
- target_metaclass.instance_eval do
200
- remove_method sym
201
- if method_defined?(munged_sym)
202
- alias_method sym, munged_sym
203
- remove_method munged_sym
204
- end
205
- end
206
- end
207
- end
208
-
209
- def proxy_for_nil_class?
210
- @target.nil?
126
+ def method_doubles
127
+ method_double.values
211
128
  end
212
129
 
213
- def reset_nil_expectations_warning
214
- @@warn_about_expectations_on_nil = true if proxy_for_nil_class?
215
- end
216
-
217
- def find_matching_expectation(sym, *args)
218
- @expectations.find {|expectation| expectation.matches(sym, args) && !expectation.called_max_times?} ||
219
- @expectations.find {|expectation| expectation.matches(sym, args)}
130
+ def find_matching_expectation(method_name, *args)
131
+ method_double[method_name].expectations.find {|expectation| expectation.matches(method_name, args) && !expectation.called_max_times?} ||
132
+ method_double[method_name].expectations.find {|expectation| expectation.matches(method_name, args)}
220
133
  end
221
134
 
222
- def find_almost_matching_expectation(sym, *args)
223
- @expectations.find {|expectation| expectation.matches_name_but_not_args(sym, args)}
135
+ def find_almost_matching_expectation(method_name, *args)
136
+ method_double[method_name].expectations.find {|expectation| expectation.matches_name_but_not_args(method_name, args)}
224
137
  end
225
138
 
226
- def find_matching_method_stub(sym, *args)
227
- @stubs.find {|stub| stub.matches(sym, args)}
139
+ def find_matching_method_stub(method_name, *args)
140
+ method_double[method_name].stubs.find {|stub| stub.matches(method_name, args)}
228
141
  end
229
142
 
230
143
  end
@@ -14,17 +14,25 @@ module Rspec
14
14
  #
15
15
  # == Examples
16
16
  #
17
- # stub_thing = mock("thing", :a => "A")
17
+ # stub_thing = double("thing", :a => "A")
18
18
  # stub_thing.a == "A" => true
19
19
  #
20
20
  # stub_person = stub("thing", :name => "Joe", :email => "joe@domain.com")
21
21
  # stub_person.name => "Joe"
22
22
  # stub_person.email => "joe@domain.com"
23
+ def double(*args)
24
+ declare_double('Double', *args)
25
+ end
26
+
27
+ # Just like double, but use double
23
28
  def mock(*args)
24
- Rspec::Mocks::Mock.new(*args)
29
+ declare_double('Mock', *args)
25
30
  end
26
31
 
27
- alias :stub :mock
32
+ # Just like double, but use double
33
+ def stub(*args)
34
+ declare_double('Stub', *args)
35
+ end
28
36
 
29
37
  # Disables warning messages about expectations being set on nil.
30
38
  #
@@ -34,6 +42,14 @@ module Rspec
34
42
  Proxy.allow_message_expectations_on_nil
35
43
  end
36
44
 
45
+ private
46
+
47
+ def declare_double(declared_as, *args) # :nodoc:
48
+ args << {} unless Hash === args.last
49
+ args.last[:__declared_as] = declared_as
50
+ Rspec::Mocks::Mock.new(*args)
51
+ end
52
+
37
53
  end
38
54
  end
39
55
  end
@@ -5,11 +5,11 @@
5
5
 
6
6
  Gem::Specification.new do |s|
7
7
  s.name = %q{rspec-mocks}
8
- s.version = "2.0.0.beta.4"
8
+ s.version = "2.0.0.beta.5"
9
9
 
10
10
  s.required_rubygems_version = Gem::Requirement.new("> 1.3.1") if s.respond_to? :required_rubygems_version=
11
11
  s.authors = ["David Chelimsky", "Chad Humphries"]
12
- s.date = %q{2010-03-15}
12
+ s.date = %q{2010-04-04}
13
13
  s.description = %q{Rspec's 'test double' framework, with support for stubbing and mocking}
14
14
  s.email = %q{dchelimsky@gmail.com;chad.humphries@gmail.com}
15
15
  s.extra_rdoc_files = [
@@ -27,6 +27,7 @@ Gem::Specification.new do |s|
27
27
  "cucumber.yml",
28
28
  "features/mocks/block_local_expectations.feature",
29
29
  "features/mocks/mix_stubs_and_mocks.feature",
30
+ "features/mocks/warn_when_expectation_is_set_on_nil.feature",
30
31
  "features/stubs/stub_implementation.feature",
31
32
  "features/support/env.rb",
32
33
  "lib/rspec/mocks.rb",
@@ -39,6 +40,7 @@ Gem::Specification.new do |s|
39
40
  "lib/rspec/mocks/extensions/object.rb",
40
41
  "lib/rspec/mocks/framework.rb",
41
42
  "lib/rspec/mocks/message_expectation.rb",
43
+ "lib/rspec/mocks/method_double.rb",
42
44
  "lib/rspec/mocks/methods.rb",
43
45
  "lib/rspec/mocks/mock.rb",
44
46
  "lib/rspec/mocks/order_group.rb",
@@ -66,6 +68,7 @@ Gem::Specification.new do |s|
66
68
  "spec/rspec/mocks/bug_report_8302_spec.rb",
67
69
  "spec/rspec/mocks/bug_report_830_spec.rb",
68
70
  "spec/rspec/mocks/bug_report_957_spec.rb",
71
+ "spec/rspec/mocks/double_spec.rb",
69
72
  "spec/rspec/mocks/failing_argument_matchers_spec.rb",
70
73
  "spec/rspec/mocks/hash_including_matcher_spec.rb",
71
74
  "spec/rspec/mocks/hash_not_including_matcher_spec.rb",
@@ -94,7 +97,7 @@ Gem::Specification.new do |s|
94
97
  s.homepage = %q{http://github.com/rspec/mocks}
95
98
  s.post_install_message = %q{**************************************************
96
99
 
97
- Thank you for installing rspec-mocks-2.0.0.beta.4
100
+ Thank you for installing rspec-mocks-2.0.0.beta.5
98
101
 
99
102
  This is beta software. If you are looking
100
103
  for a supported production release, please
@@ -106,7 +109,7 @@ Gem::Specification.new do |s|
106
109
  s.require_paths = ["lib"]
107
110
  s.rubyforge_project = %q{rspec}
108
111
  s.rubygems_version = %q{1.3.6}
109
- s.summary = %q{rspec-mocks-2.0.0.beta.4}
112
+ s.summary = %q{rspec-mocks-2.0.0.beta.5}
110
113
  s.test_files = [
111
114
  "spec/rspec/mocks/and_yield_spec.rb",
112
115
  "spec/rspec/mocks/any_number_of_times_spec.rb",
@@ -126,6 +129,7 @@ Gem::Specification.new do |s|
126
129
  "spec/rspec/mocks/bug_report_8302_spec.rb",
127
130
  "spec/rspec/mocks/bug_report_830_spec.rb",
128
131
  "spec/rspec/mocks/bug_report_957_spec.rb",
132
+ "spec/rspec/mocks/double_spec.rb",
129
133
  "spec/rspec/mocks/failing_argument_matchers_spec.rb",
130
134
  "spec/rspec/mocks/hash_including_matcher_spec.rb",
131
135
  "spec/rspec/mocks/hash_not_including_matcher_spec.rb",
@@ -156,15 +160,15 @@ Gem::Specification.new do |s|
156
160
  s.specification_version = 3
157
161
 
158
162
  if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
159
- s.add_development_dependency(%q<rspec-core>, ["= 2.0.0.beta.4"])
160
- s.add_development_dependency(%q<rspec-expectations>, ["= 2.0.0.beta.4"])
163
+ s.add_development_dependency(%q<rspec-core>, ["= 2.0.0.beta.5"])
164
+ s.add_development_dependency(%q<rspec-expectations>, ["= 2.0.0.beta.5"])
161
165
  else
162
- s.add_dependency(%q<rspec-core>, ["= 2.0.0.beta.4"])
163
- s.add_dependency(%q<rspec-expectations>, ["= 2.0.0.beta.4"])
166
+ s.add_dependency(%q<rspec-core>, ["= 2.0.0.beta.5"])
167
+ s.add_dependency(%q<rspec-expectations>, ["= 2.0.0.beta.5"])
164
168
  end
165
169
  else
166
- s.add_dependency(%q<rspec-core>, ["= 2.0.0.beta.4"])
167
- s.add_dependency(%q<rspec-expectations>, ["= 2.0.0.beta.4"])
170
+ s.add_dependency(%q<rspec-core>, ["= 2.0.0.beta.5"])
171
+ s.add_dependency(%q<rspec-expectations>, ["= 2.0.0.beta.5"])
168
172
  end
169
173
  end
170
174
 
@@ -25,7 +25,7 @@ module Rspec
25
25
  end
26
26
 
27
27
  it "should return the mocked value when called after a similar stub" do
28
- @mock.stub!(:message).and_return :stub_value
28
+ @mock.stub(:message).and_return :stub_value
29
29
  @mock.should_receive(:message).any_number_of_times.and_return(:mock_value)
30
30
  @mock.message.should == :mock_value
31
31
  @mock.message.should == :mock_value
@@ -5,7 +5,7 @@ module Rspec
5
5
  describe ArgumentExpectation do
6
6
  it "should consider an object that responds to #matches? and #description to be a matcher" do
7
7
  argument_expecatation = Rspec::Mocks::ArgumentExpectation.new([])
8
- obj = mock("matcher")
8
+ obj = double("matcher")
9
9
  obj.should_receive(:respond_to?).with(:matches?).and_return(true)
10
10
  obj.should_receive(:respond_to?).with(:description).and_return(true)
11
11
  argument_expecatation.is_matcher?(obj).should be_true
@@ -13,7 +13,7 @@ module Rspec
13
13
 
14
14
  it "should NOT consider an object that only responds to #matches? to be a matcher" do
15
15
  argument_expecatation = Rspec::Mocks::ArgumentExpectation.new([])
16
- obj = mock("matcher")
16
+ obj = double("matcher")
17
17
  obj.should_receive(:respond_to?).with(:matches?).and_return(true)
18
18
  obj.should_receive(:respond_to?).with(:description).and_return(false)
19
19
  argument_expecatation.is_matcher?(obj).should be_false