rspec-mocks 2.11.1 → 2.11.2

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.
@@ -1,3 +1,15 @@
1
+ ### 2.11.2 / 2012-08-11
2
+ [full changelog](http://github.com/rspec/rspec-mocks/compare/v2.11.1...v2.11.2)
3
+
4
+ Bug fixes
5
+
6
+ * Don't modify `dup` on classes that don't support `dup` (David Chelimsky)
7
+ * Fix `any_instance` so that it works properly with methods defined on
8
+ a superclass. (Daniel Eguzkiza)
9
+ * Fix `stub_const` so that it works properly for nested constants that
10
+ share a name with a top-level constant (e.g. "MyGem::Hash"). (Myron
11
+ Marston)
12
+
1
13
  ### 2.11.1 / 2012-07-09
2
14
  [full changelog](http://github.com/rspec/rspec-mocks/compare/v2.11.0...v2.11.1)
3
15
 
@@ -13,7 +25,7 @@ Bug fixes
13
25
 
14
26
  Enhancements
15
27
 
16
- * expose ArgumentListMatcher as a formal API
28
+ * Expose ArgumentListMatcher as a formal API
17
29
  * supports use by 3rd party mock frameworks like Surrogate
18
30
  * Add `stub_const` API to stub constants for the duration of an
19
31
  example (Myron Marston).
data/README.md CHANGED
@@ -152,8 +152,8 @@ specify certain kinds of arguments:
152
152
  ```ruby
153
153
  double.should_receive(:msg).with(no_args())
154
154
  double.should_receive(:msg).with(any_args())
155
- double.should_receive(:msg).with(1, kind_of(Numeric), "b") #2nd argument can any kind of Numeric
156
- double.should_receive(:msg).with(1, boolean(), "b") #2nd argument can true or false
155
+ double.should_receive(:msg).with(1, kind_of(Numeric), "b") #2nd argument can be any kind of Numeric
156
+ double.should_receive(:msg).with(1, boolean(), "b") #2nd argument can be true or false
157
157
  double.should_receive(:msg).with(1, /abc/, "b") #2nd argument can be any String matching the submitted Regexp
158
158
  double.should_receive(:msg).with(1, anything(), "b") #2nd argument can be anything at all
159
159
  double.should_receive(:msg).with(1, duck_type(:abs, :div), "b")
@@ -4,20 +4,20 @@ Argument matchers can be used:
4
4
 
5
5
  * In stubs to constrain the scope of the stubbed method
6
6
 
7
- obj.stub(:foo).with(:bar) do |arg|
8
- #do something for :bar
9
- end
10
- obj.stub(:foo).with(:baz) do |arg|
11
- #do something for :baz
12
- end
7
+ obj.stub(:foo).with(:bar) do |arg|
8
+ #do something for :bar
9
+ end
10
+ obj.stub(:foo).with(:baz) do |arg|
11
+ #do something for :baz
12
+ end
13
13
 
14
14
  * In expectations to validate the arguments that should be received in a method call
15
15
 
16
- #create a double
17
- obj = double()
16
+ #create a double
17
+ obj = double()
18
18
 
19
- #expect a message with given args
20
- obj.should_receive(:message).with('an argument')
19
+ #expect a message with given args
20
+ obj.should_receive(:message).with('an argument')
21
21
 
22
22
  If more control is needed, one can use a block
23
23
 
@@ -1,6 +1,8 @@
1
1
  Feature: stub with argument constraints
2
2
 
3
- You can further specify the behavior by constraining the type, format and/or number of arguments with the #with() method chained off of #stub()
3
+ You can further specify the behavior by constraining the type,
4
+ format and/or number of arguments with the `#with()` method
5
+ chained off of `#stub()`
4
6
 
5
7
  Scenario: an_instance_of argument matcher
6
8
  Given a file named "stub_an_instance_of_args_spec.rb" with:
@@ -7,7 +7,30 @@
7
7
  obj.should_receive(:message)
8
8
 
9
9
  # specify a return value
10
- obj.should_receive(:message) { 'this is the value to return' }
10
+ obj.should_receive(:message) { :value }
11
+ obj.should_receive(:message => :value)
12
+ obj.should_receive(:message).and_return(:value)
13
+
14
+ These forms are somewhat interchangeable. The difference is that the
15
+ block contents are evaluated lazily when the `obj` receives the
16
+ `message` message, whereas the others are evaluated as they are read.
17
+
18
+ ### Fake implementation
19
+
20
+ obj.should_receive(:message) do |arg1, arg2|
21
+ # set expectations about the args in this block
22
+ # and set a return value
23
+ end
24
+
25
+ ### Raising/Throwing
26
+
27
+ obj.should_receive(:message).and_raise("this error")
28
+ obj.should_receive(:message).and_throw(:this_symbol)
29
+
30
+ You can also use the block format:
31
+
32
+ obj.should_receive(:message) { raise "this error" }
33
+ obj.should_receive(:message) { throw :this_symbol }
11
34
 
12
35
  ### Argument constraints
13
36
 
@@ -40,19 +63,7 @@
40
63
  obj.should_receive(:message).at_most(:twice)
41
64
  obj.should_receive(:message).at_most(n).times
42
65
 
43
- ### Raising/Throwing
44
-
45
- obj.should_receive(:message) { raise "this error" }
46
- obj.should_receive(:message) { throw :this_symbol }
47
-
48
66
  ### Ordering
49
67
 
50
68
  obj.should_receive(:one).ordered
51
69
  obj.should_receive(:two).ordered
52
-
53
- ### Arbitrary handling
54
-
55
- obj.should_receive(:message) do |arg1, arg2|
56
- # set expectations about the args in this block
57
- # and set a return value
58
- end
@@ -1,12 +1,16 @@
1
1
  ### Stub return values
2
2
 
3
+ # create a double
4
+ obj = double()
5
+
6
+ # specify a return value
3
7
  obj.stub(:message) { :value }
4
8
  obj.stub(:message => :value)
5
9
  obj.stub(:message).and_return(:value)
6
10
 
7
- These forms are somewhat interchangeable. The difference is that the block
8
- contents are evaluated lazily when the `obj` receives the `message` message,
9
- whereas the others are evaluated as they are read.
11
+ These forms are somewhat interchangeable. The difference is that the
12
+ block contents are evaluated lazily when the `obj` receives the
13
+ `message` message, whereas the others are evaluated as they are read.
10
14
 
11
15
  ### Fake implementation
12
16
 
@@ -20,7 +24,7 @@ whereas the others are evaluated as they are read.
20
24
  obj.stub(:message).and_raise("this error")
21
25
  obj.stub(:message).and_throw(:this_symbol)
22
26
 
23
- You can also use the block format, for consistency with other stubs:
27
+ You can also use the block format:
24
28
 
25
29
  obj.stub(:message) { raise "this error" }
26
30
  obj.stub(:message) { throw :this_symbol }
@@ -54,7 +54,7 @@ module RSpec
54
54
 
55
55
  private
56
56
  def modify_dup_to_remove_mock_proxy_when_invoked
57
- unless self.method_defined?(:__rspec_original_dup)
57
+ if self.method_defined?(:dup) and !self.method_defined?(:__rspec_original_dup)
58
58
  self.class_eval do
59
59
  def __rspec_dup
60
60
  __remove_mock_proxy
@@ -175,7 +175,8 @@ module RSpec
175
175
  backup_method!(method_name)
176
176
  @klass.class_eval(<<-EOM, __FILE__, __LINE__)
177
177
  def #{method_name}(*args, &blk)
178
- self.class.__recorder.playback!(self, :#{method_name})
178
+ klass = self.method(:#{method_name}).owner
179
+ klass.__recorder.playback!(self, :#{method_name})
179
180
  self.__send__(:#{method_name}, *args, &blk)
180
181
  end
181
182
  EOM
@@ -186,7 +187,8 @@ module RSpec
186
187
  @klass.class_eval(<<-EOM, __FILE__, __LINE__)
187
188
  def #{method_name}(*args, &blk)
188
189
  method_name = :#{method_name}
189
- invoked_instance = self.class.__recorder.instance_that_received(method_name)
190
+ klass = self.method(:#{method_name}).owner
191
+ invoked_instance = klass.__recorder.instance_that_received(method_name)
190
192
  raise RSpec::Mocks::MockExpectationError, "The message '#{method_name}' was received by \#{self.inspect} but has already been received by \#{invoked_instance}"
191
193
  end
192
194
  EOM
@@ -31,7 +31,7 @@ module RSpec
31
31
  def raise_missing_default_stub_error(expectation,*args)
32
32
  expected_args = format_args(*expectation.expected_args)
33
33
  actual_args = args.collect {|a| format_args(*a)}.join(", ")
34
- __raise "#{intro} received #{expectation.message.inspect} with unexpected arguments\n Please stub a default value first if message might be received with other args as well. \n"
34
+ __raise "#{intro} received #{expectation.message.inspect} with unexpected arguments\n expected: #{expected_args}\n got: #{actual_args}\n Please stub a default value first if message might be received with other args as well. \n"
35
35
  end
36
36
 
37
37
  # @private
@@ -4,15 +4,54 @@ module RSpec
4
4
  # constant stubbing.
5
5
  # @api private
6
6
  module RecursiveConstMethods
7
- def recursive_const_get(name)
8
- name.split('::').inject(Object) { |mod, name| mod.const_get name }
7
+ # We only want to consider constants that are defined directly on a
8
+ # particular module, and not include top-level/inherited constants.
9
+ # Unfortunately, the constant API changed between 1.8 and 1.9, so
10
+ # we need to conditionally define methods to ignore the top-level/inherited
11
+ # constants.
12
+ #
13
+ # Given `class A; end`:
14
+ #
15
+ # On 1.8:
16
+ # - A.const_get("Hash") # => ::Hash
17
+ # - A.const_defined?("Hash") # => false
18
+ # - Neither method accepts the extra `inherit` argument
19
+ # On 1.9:
20
+ # - A.const_get("Hash") # => ::Hash
21
+ # - A.const_defined?("Hash") # => true
22
+ # - A.const_get("Hash", false) # => raises NameError
23
+ # - A.const_defined?("Hash", false) # => false
24
+ if Module.method(:const_defined?).arity == 1
25
+ def const_defined_on?(mod, const_name)
26
+ mod.const_defined?(const_name)
27
+ end
28
+
29
+ def get_const_defined_on(mod, const_name)
30
+ if const_defined_on?(mod, const_name)
31
+ return mod.const_get(const_name)
32
+ end
33
+
34
+ raise NameError, "uninitialized constant #{mod.name}::#{const_name}"
35
+ end
36
+ else
37
+ def const_defined_on?(mod, const_name)
38
+ mod.const_defined?(const_name, false)
39
+ end
40
+
41
+ def get_const_defined_on(mod, const_name)
42
+ mod.const_get(const_name, false)
43
+ end
44
+ end
45
+
46
+ def recursive_const_get(const_name)
47
+ const_name.split('::').inject(Object) { |mod, name| get_const_defined_on(mod, name) }
9
48
  end
10
49
 
11
- def recursive_const_defined?(name)
12
- name.split('::').inject([Object, '']) do |(mod, full_name), name|
50
+ def recursive_const_defined?(const_name)
51
+ const_name.split('::').inject([Object, '']) do |(mod, full_name), name|
13
52
  yield(full_name, name) if block_given? && !mod.is_a?(Module)
14
- return false unless mod.const_defined?(name)
15
- [mod.const_get(name), [mod, name].join('::')]
53
+ return false unless const_defined_on?(mod, name)
54
+ [get_const_defined_on(mod, name), [mod, name].join('::')]
16
55
  end
17
56
  end
18
57
  end
@@ -139,7 +178,7 @@ module RSpec
139
178
  class DefinedConstantReplacer < BaseStubber
140
179
  def stub
141
180
  @context = recursive_const_get(@context_parts.join('::'))
142
- @original_value = @context.const_get(@const_name)
181
+ @original_value = get_const_defined_on(@context, @const_name)
143
182
 
144
183
  constants_to_transfer = verify_constants_to_transfer!
145
184
 
@@ -160,7 +199,7 @@ module RSpec
160
199
 
161
200
  def transfer_nested_constants(constants)
162
201
  constants.each do |const|
163
- @stubbed_value.const_set(const, original_value.const_get(const))
202
+ @stubbed_value.const_set(const, get_const_defined_on(original_value, const))
164
203
  end
165
204
  end
166
205
 
@@ -202,9 +241,9 @@ module RSpec
202
241
  def stub
203
242
  remaining_parts = @context_parts.dup
204
243
  @deepest_defined_const = @context_parts.inject(Object) do |klass, name|
205
- break klass unless klass.const_defined?(name)
244
+ break klass unless const_defined_on?(klass, name)
206
245
  remaining_parts.shift
207
- klass.const_get(name)
246
+ get_const_defined_on(klass, name)
208
247
  end
209
248
 
210
249
  context = remaining_parts.inject(@deepest_defined_const) do |klass, name|
@@ -230,7 +269,7 @@ module RSpec
230
269
  #
231
270
  # @api private
232
271
  def self.ensure_registered_with_mocks_space
233
- return if @registered_with_mocks_space
272
+ return if defined?(@registered_with_mocks_space) && @registered_with_mocks_space
234
273
  ::RSpec::Mocks.space.add(self)
235
274
  @registered_with_mocks_space = true
236
275
  end
@@ -1,7 +1,7 @@
1
1
  module RSpec
2
2
  module Mocks
3
3
  module Version
4
- STRING = '2.11.1'
4
+ STRING = '2.11.2'
5
5
  end
6
6
  end
7
7
  end
@@ -818,8 +818,33 @@ module RSpec
818
818
  o.some_method
819
819
  lambda { o.dup.some_method }.should_not raise_error(SystemStackError)
820
820
  end
821
+
822
+ it "doesn't bomb if the object doesn't support `dup`" do
823
+ klass = Class.new do
824
+ undef_method :dup
825
+ end
826
+ klass.any_instance
827
+ end
821
828
  end
822
829
 
830
+ context "when directed at a method defined on a superclass" do
831
+ let(:sub_klass) { Class.new(klass) }
832
+
833
+ it "stubs the method correctly" do
834
+ klass.any_instance.stub(:existing_method).and_return("foo")
835
+ sub_klass.new.existing_method.should == "foo"
836
+ end
837
+
838
+ it "mocks the method correctly" do
839
+ instance_one = sub_klass.new
840
+ instance_two = sub_klass.new
841
+ expect do
842
+ klass.any_instance.should_receive(:existing_method)
843
+ instance_one.existing_method
844
+ instance_two.existing_method
845
+ end.to raise_error(RSpec::Mocks::MockExpectationError, "The message 'existing_method' was received by #{instance_two.inspect} but has already been received by #{instance_one.inspect}")
846
+ end
847
+ end
823
848
  end
824
849
  end
825
850
  end
@@ -57,7 +57,6 @@ module RSpec
57
57
  end
58
58
 
59
59
  it 'returns the stubbed value' do
60
- orig_value = const
61
60
  stub_const(const_name, 7).should eq(7)
62
61
  end
63
62
  end
@@ -178,6 +177,10 @@ module RSpec
178
177
  it_behaves_like "loaded constant stubbing", "TestClass::Nested"
179
178
  end
180
179
 
180
+ context 'for an unloaded constant with nested name that matches a top-level constant' do
181
+ it_behaves_like "unloaded constant stubbing", "TestClass::Hash"
182
+ end
183
+
181
184
  context 'for a loaded deeply nested constant' do
182
185
  it_behaves_like "loaded constant stubbing", "TestClass::Nested::NestedEvenMore"
183
186
  end
metadata CHANGED
@@ -1,80 +1,71 @@
1
- --- !ruby/object:Gem::Specification
1
+ --- !ruby/object:Gem::Specification
2
2
  name: rspec-mocks
3
- version: !ruby/object:Gem::Version
4
- hash: 33
3
+ version: !ruby/object:Gem::Version
4
+ version: 2.11.2
5
5
  prerelease:
6
- segments:
7
- - 2
8
- - 11
9
- - 1
10
- version: 2.11.1
11
6
  platform: ruby
12
- authors:
7
+ authors:
13
8
  - Steven Baker
14
9
  - David Chelimsky
15
10
  autorequire:
16
11
  bindir: bin
17
12
  cert_chain: []
18
-
19
- date: 2012-07-10 00:00:00 Z
20
- dependencies:
21
- - !ruby/object:Gem::Dependency
13
+ date: 2012-08-12 00:00:00.000000000 Z
14
+ dependencies:
15
+ - !ruby/object:Gem::Dependency
22
16
  name: rake
17
+ requirement: !ruby/object:Gem::Requirement
18
+ none: false
19
+ requirements:
20
+ - - ~>
21
+ - !ruby/object:Gem::Version
22
+ version: 0.9.2
23
23
  type: :development
24
24
  prerelease: false
25
- version_requirements: &id001 !ruby/object:Gem::Requirement
25
+ version_requirements: !ruby/object:Gem::Requirement
26
26
  none: false
27
- requirements:
27
+ requirements:
28
28
  - - ~>
29
- - !ruby/object:Gem::Version
30
- hash: 63
31
- segments:
32
- - 0
33
- - 9
34
- - 2
29
+ - !ruby/object:Gem::Version
35
30
  version: 0.9.2
36
- requirement: *id001
37
- - !ruby/object:Gem::Dependency
31
+ - !ruby/object:Gem::Dependency
38
32
  name: cucumber
33
+ requirement: !ruby/object:Gem::Requirement
34
+ none: false
35
+ requirements:
36
+ - - ~>
37
+ - !ruby/object:Gem::Version
38
+ version: 1.1.9
39
39
  type: :development
40
40
  prerelease: false
41
- version_requirements: &id002 !ruby/object:Gem::Requirement
41
+ version_requirements: !ruby/object:Gem::Requirement
42
42
  none: false
43
- requirements:
43
+ requirements:
44
44
  - - ~>
45
- - !ruby/object:Gem::Version
46
- hash: 1
47
- segments:
48
- - 1
49
- - 1
50
- - 9
45
+ - !ruby/object:Gem::Version
51
46
  version: 1.1.9
52
- requirement: *id002
53
- - !ruby/object:Gem::Dependency
47
+ - !ruby/object:Gem::Dependency
54
48
  name: aruba
49
+ requirement: !ruby/object:Gem::Requirement
50
+ none: false
51
+ requirements:
52
+ - - ~>
53
+ - !ruby/object:Gem::Version
54
+ version: 0.4.11
55
55
  type: :development
56
56
  prerelease: false
57
- version_requirements: &id003 !ruby/object:Gem::Requirement
57
+ version_requirements: !ruby/object:Gem::Requirement
58
58
  none: false
59
- requirements:
59
+ requirements:
60
60
  - - ~>
61
- - !ruby/object:Gem::Version
62
- hash: 25
63
- segments:
64
- - 0
65
- - 4
66
- - 11
61
+ - !ruby/object:Gem::Version
67
62
  version: 0.4.11
68
- requirement: *id003
69
63
  description: RSpec's 'test double' framework, with support for stubbing and mocking
70
64
  email: rspec-users@rubyforge.org
71
65
  executables: []
72
-
73
66
  extensions: []
74
-
75
67
  extra_rdoc_files: []
76
-
77
- files:
68
+ files:
78
69
  - lib/rspec/mocks.rb
79
70
  - lib/rspec/mocks/any_instance.rb
80
71
  - lib/rspec/mocks/any_instance/chain.rb
@@ -184,39 +175,38 @@ files:
184
175
  - spec/rspec/mocks_spec.rb
185
176
  - spec/spec_helper.rb
186
177
  homepage: http://github.com/rspec/rspec-mocks
187
- licenses:
178
+ licenses:
188
179
  - MIT
189
180
  post_install_message:
190
- rdoc_options:
181
+ rdoc_options:
191
182
  - --charset=UTF-8
192
- require_paths:
183
+ require_paths:
193
184
  - lib
194
- required_ruby_version: !ruby/object:Gem::Requirement
185
+ required_ruby_version: !ruby/object:Gem::Requirement
195
186
  none: false
196
- requirements:
197
- - - ">="
198
- - !ruby/object:Gem::Version
199
- hash: 3
200
- segments:
187
+ requirements:
188
+ - - ! '>='
189
+ - !ruby/object:Gem::Version
190
+ version: '0'
191
+ segments:
201
192
  - 0
202
- version: "0"
203
- required_rubygems_version: !ruby/object:Gem::Requirement
193
+ hash: -769108312098701241
194
+ required_rubygems_version: !ruby/object:Gem::Requirement
204
195
  none: false
205
- requirements:
206
- - - ">="
207
- - !ruby/object:Gem::Version
208
- hash: 3
209
- segments:
196
+ requirements:
197
+ - - ! '>='
198
+ - !ruby/object:Gem::Version
199
+ version: '0'
200
+ segments:
210
201
  - 0
211
- version: "0"
202
+ hash: -769108312098701241
212
203
  requirements: []
213
-
214
204
  rubyforge_project: rspec
215
- rubygems_version: 1.8.6
205
+ rubygems_version: 1.8.24
216
206
  signing_key:
217
207
  specification_version: 3
218
- summary: rspec-mocks-2.11.1
219
- test_files:
208
+ summary: rspec-mocks-2.11.2
209
+ test_files:
220
210
  - features/README.md
221
211
  - features/Scope.md
222
212
  - features/Upgrade.md