rspec-mocks 2.99.0.beta1 → 2.99.0.beta2

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 (36) hide show
  1. data/Changelog.md +26 -1
  2. data/features/spies/spy_pure_mock_method.feature +1 -1
  3. data/lib/rspec/mocks.rb +17 -4
  4. data/lib/rspec/mocks/caller_filter.rb +50 -45
  5. data/lib/rspec/mocks/example_methods.rb +1 -1
  6. data/lib/rspec/mocks/matchers/have_received.rb +5 -3
  7. data/lib/rspec/mocks/message_expectation.rb +33 -9
  8. data/lib/rspec/mocks/mock.rb +8 -1
  9. data/lib/rspec/mocks/mutate_const.rb +6 -0
  10. data/lib/rspec/mocks/proxy.rb +7 -0
  11. data/lib/rspec/mocks/space.rb +9 -1
  12. data/lib/rspec/mocks/stub_chain.rb +1 -1
  13. data/lib/rspec/mocks/test_double.rb +15 -7
  14. data/lib/rspec/mocks/version.rb +1 -1
  15. data/spec/rspec/mocks/and_return_spec.rb +17 -0
  16. data/spec/rspec/mocks/and_yield_spec.rb +1 -1
  17. data/spec/rspec/mocks/any_instance_spec.rb +2 -0
  18. data/spec/rspec/mocks/any_number_of_times_spec.rb +1 -1
  19. data/spec/rspec/mocks/before_all_spec.rb +74 -0
  20. data/spec/rspec/mocks/block_return_value_spec.rb +54 -1
  21. data/spec/rspec/mocks/bug_report_10260_spec.rb +1 -1
  22. data/spec/rspec/mocks/combining_implementation_instructions_spec.rb +2 -0
  23. data/spec/rspec/mocks/double_spec.rb +38 -1
  24. data/spec/rspec/mocks/matchers/receive_spec.rb +4 -0
  25. data/spec/rspec/mocks/mock_space_spec.rb +1 -0
  26. data/spec/rspec/mocks/mock_spec.rb +24 -4
  27. data/spec/rspec/mocks/multiple_return_value_spec.rb +1 -1
  28. data/spec/rspec/mocks/null_object_mock_spec.rb +1 -6
  29. data/spec/rspec/mocks/options_hash_spec.rb +3 -3
  30. data/spec/rspec/mocks/space_spec.rb +1 -0
  31. data/spec/rspec/mocks/stub_chain_spec.rb +12 -0
  32. data/spec/rspec/mocks/stub_spec.rb +1 -0
  33. data/spec/rspec/mocks_spec.rb +26 -16
  34. data/spec/spec_helper.rb +14 -3
  35. metadata +21 -6
  36. checksums.yaml +0 -15
@@ -1,7 +1,22 @@
1
+ ### 2.99.0.beta2 / 2014-02-17
2
+ [full changelog](http://github.com/rspec/rspec-mocks/compare/v2.99.0.beta1...v2.99.0.beta2)
3
+
4
+ Deprecations:
5
+
6
+ * Deprecate `RSpec::Mocks::Mock` in favor of `RSpec::Mocks::Double`.
7
+ (Myron Marston)
8
+ * Deprecate the `host` argument of `RSpec::Mocks.setup`. Instead
9
+ `RSpec::Mocks::ExampleMethods` should be included directly in the scope where
10
+ RSpec's mocking capabilities are used. (Sam Phippen)
11
+ * Deprecate using any of rspec-mocks' features outside the per-test
12
+ lifecycle (e.g. from a `before(:all)` hook). (Myron Marston)
13
+ * Deprecate re-using a test double in another example. (Myron Marston)
14
+ * Deprecate `and_return { value }` and `and_return` without arguments. (Yuji Nakayama)
15
+
1
16
  ### 2.99.0.beta1 / 2013-11-07
2
17
  [full changelog](http://github.com/rspec/rspec-mocks/compare/v2.14.4...v2.99.0.beta1)
3
18
 
4
- Deprecations
19
+ Deprecations:
5
20
 
6
21
  * Expecting to use lambdas or other strong arity implementations for stub
7
22
  methods with mis-matched arity is deprecated and support for them will be
@@ -23,6 +38,16 @@ Enhancements:
23
38
  * Add a config option to yield the receiver to `any_instance` implementation
24
39
  blocks. (Sam Phippen)
25
40
 
41
+ ### 2.14.5 / 2014-02-01
42
+ [full changelog](http://github.com/rspec/rspec-mocks/compare/v2.14.4...v2.14.5)
43
+
44
+ Bug Fixes:
45
+
46
+ * Fix regression that caused block implementations to not receive all
47
+ args on 1.8.7 if the block also receives a block, due to Proc#arity
48
+ reporting `1` no matter how many args the block receives if it
49
+ receives a block, too. (Myron Marston)
50
+
26
51
  ### 2.14.4 / 2013-10-15
27
52
  [full changelog](http://github.com/rspec/rspec-mocks/compare/v2.14.3...v2.14.4)
28
53
 
@@ -66,7 +66,7 @@ Feature: Spy on a stubbed method on a pure mock
66
66
  Given a file named "spy_message_spec.rb" with:
67
67
  """ruby
68
68
  describe "have_received" do
69
- subject(:invitation) { double('invitation', :deliver => true) }
69
+ subject(:invitation) { double('invitation', :deliver => true) }
70
70
  before { invitation.deliver }
71
71
 
72
72
  it { should have_received(:deliver) }
@@ -7,11 +7,21 @@ module RSpec
7
7
  class << self
8
8
  attr_accessor :space
9
9
 
10
- def setup(host)
11
- (class << host; self; end).class_eval do
12
- include RSpec::Mocks::ExampleMethods
10
+ def setup(host=nil)
11
+ host_is_from_rspec_core = defined?(::RSpec::Core::ExampleGroup) && host.is_a?(::RSpec::Core::ExampleGroup)
12
+ if host
13
+ unless host_is_from_rspec_core
14
+ RSpec.deprecate(
15
+ "The host argument to `RSpec::Mocks.setup`",
16
+ :replacement => "`include RSpec::Mocks::ExampleMethods` in #{host.inspect}"
17
+ )
18
+ end
19
+
20
+ (class << host; self; end).class_eval do
21
+ include RSpec::Mocks::ExampleMethods
22
+ end
13
23
  end
14
- self.space ||= RSpec::Mocks::Space.new
24
+ space.outside_example = false
15
25
  end
16
26
 
17
27
  def verify
@@ -20,6 +30,7 @@ module RSpec
20
30
 
21
31
  def teardown
22
32
  space.reset_all
33
+ space.outside_example = true
23
34
  end
24
35
 
25
36
  def proxy_for(object)
@@ -95,6 +106,8 @@ module RSpec
95
106
 
96
107
  # @private
97
108
  IGNORED_BACKTRACE_LINE = 'this backtrace line is ignored'
109
+
110
+ self.space = RSpec::Mocks::Space.new
98
111
  end
99
112
  end
100
113
 
@@ -3,53 +3,58 @@ module RSpec
3
3
  # non-rspec lines. This enables errors to be reported at the call site in
4
4
  # the code using the library, which is far more useful than the particular
5
5
  # internal method that raised an error.
6
- class CallerFilter
7
-
8
- RSPEC_LIBS = %w[
9
- core
10
- mocks
11
- expectations
12
- matchers
13
- rails
14
- ]
15
-
16
- ADDITIONAL_TOP_LEVEL_FILES = %w[ autorun ]
17
-
18
- LIB_REGEX = %r{/lib/rspec/(#{(RSPEC_LIBS + ADDITIONAL_TOP_LEVEL_FILES).join('|')})(\.rb|/)}
19
-
20
- if RUBY_VERSION >= '2.0.0'
21
- def self.first_non_rspec_line
22
- # `caller` is an expensive method that scales linearly with the size of
23
- # the stack. The performance hit for fetching it in chunks is small,
24
- # and since the target line is probably near the top of the stack, the
25
- # overall improvement of a chunked search like this is significant.
26
- #
27
- # See benchmarks/caller.rb for measurements.
28
-
29
- # Initial value here is mostly arbitrary, but is chosen to give good
30
- # performance on the common case of creating a double.
31
- increment = 5
32
- i = 1
33
- line = nil
34
-
35
- while !line
36
- stack = caller(i, increment)
37
- raise "No non-lib lines in stack" unless stack
38
-
39
- line = stack.find { |l| l !~ LIB_REGEX }
40
-
41
- i += increment
42
- increment *= 2 # The choice of two here is arbitrary.
43
- end
44
6
 
45
- line
46
- end
47
- else
48
- # Earlier rubies do not support the two argument form of `caller`. This
49
- # fallback is logically the same, but slower.
50
- def self.first_non_rspec_line
51
- caller.find { |line| line !~ LIB_REGEX }
7
+ unless defined?(CallerFilter)
8
+
9
+ class CallerFilter
10
+
11
+ RSPEC_LIBS = %w[
12
+ core
13
+ mocks
14
+ expectations
15
+ matchers
16
+ rails
17
+ ]
18
+
19
+ ADDITIONAL_TOP_LEVEL_FILES = %w[ autorun ]
20
+
21
+ LIB_REGEX = %r{/lib/rspec/(#{(RSPEC_LIBS + ADDITIONAL_TOP_LEVEL_FILES).join('|')})(\.rb|/)}
22
+
23
+ if RUBY_VERSION >= '2.0.0'
24
+ def self.first_non_rspec_line
25
+ # `caller` is an expensive method that scales linearly with the size of
26
+ # the stack. The performance hit for fetching it in chunks is small,
27
+ # and since the target line is probably near the top of the stack, the
28
+ # overall improvement of a chunked search like this is significant.
29
+ #
30
+ # See benchmarks/caller.rb for measurements.
31
+
32
+ # Initial value here is mostly arbitrary, but is chosen to give good
33
+ # performance on the common case of creating a double.
34
+ increment = 5
35
+ i = 1
36
+ line = nil
37
+
38
+ while !line
39
+ stack = caller(i, increment)
40
+ return nil unless stack
41
+
42
+ line = stack.find { |l| l !~ LIB_REGEX }
43
+
44
+ i += increment
45
+ increment *= 2 # The choice of two here is arbitrary.
46
+ end
47
+
48
+ line
49
+ end
50
+ else
51
+ # Earlier rubies do not support the two argument form of `caller`. This
52
+ # fallback is logically the same, but slower.
53
+ def self.first_non_rspec_line
54
+ caller.find { |line| line !~ LIB_REGEX }
55
+ end
52
56
  end
53
57
  end
58
+
54
59
  end
55
60
  end
@@ -144,7 +144,7 @@ module RSpec
144
144
  def declare_double(declared_as, *args)
145
145
  args << {} unless Hash === args.last
146
146
  args.last[:__declared_as] = declared_as
147
- RSpec::Mocks::Mock.new(*args)
147
+ RSpec::Mocks::Double.new(*args)
148
148
  end
149
149
 
150
150
  # This module exists to host the `expect` method for cases where
@@ -47,9 +47,11 @@ module RSpec
47
47
  private
48
48
 
49
49
  def expect
50
- expectation = mock_proxy.build_expectation(@method_name)
51
- apply_constraints_to expectation
52
- expectation
50
+ @expect ||= begin
51
+ expectation = mock_proxy.build_expectation(@method_name)
52
+ apply_constraints_to expectation
53
+ expectation
54
+ end
53
55
  end
54
56
 
55
57
  def apply_constraints_to(expectation)
@@ -52,8 +52,8 @@ module RSpec
52
52
  # If the message is received more times than there are values, the last
53
53
  # value is received for every subsequent call.
54
54
  #
55
- # The block format is still supported, but is unofficially deprecated in
56
- # favor of just passing a block to the stub method.
55
+ # The block format is deprecated in favor of just passing a block to the
56
+ # stub method.
57
57
  #
58
58
  # @example
59
59
  #
@@ -69,11 +69,11 @@ module RSpec
69
69
  # counter.count # => 3
70
70
  # # etc
71
71
  #
72
- # # Supported, but ...
72
+ # # Deprecated ...
73
73
  # counter.stub(:count).and_return { 1 }
74
74
  # counter.count # => 1
75
75
  #
76
- # # ... this is prefered
76
+ # # ... use this instead
77
77
  # counter.stub(:count) { 1 }
78
78
  # counter.count # => 1
79
79
  def and_return(*values, &implementation)
@@ -84,9 +84,16 @@ module RSpec
84
84
  @expected_received_count = [@expected_received_count, values.size].max unless ignoring_args? || (@expected_received_count == 0 and @at_least)
85
85
 
86
86
  if implementation
87
- # TODO: deprecate `and_return { value }`
87
+ RSpec.deprecate('`and_return { value }`',
88
+ :replacement => '`and_return(value)` or an implementation block without `and_return`')
88
89
  self.inner_implementation_action = implementation
89
90
  else
91
+ if values.empty?
92
+ RSpec.warn_deprecation('`and_return` without arguments is deprecated. ' +
93
+ 'Remove the `and_return`. ' +
94
+ "Called from #{CallerFilter.first_non_rspec_line}.")
95
+ end
96
+
90
97
  self.terminal_implementation_action = AndReturnImplementation.new(values)
91
98
  end
92
99
 
@@ -607,10 +614,27 @@ MSG
607
614
  end.last
608
615
  end
609
616
 
610
- def arg_slice_for(args, arity)
611
- if arity >= 0
612
- args.slice(0, arity)
613
- else
617
+ if RUBY_VERSION.to_f > 1.8
618
+ def arg_slice_for(args, arity)
619
+ if arity >= 0
620
+ args.slice(0, arity)
621
+ else
622
+ args
623
+ end
624
+ end
625
+ else
626
+ # 1.8.7's `arity` lies somtimes:
627
+ # Given:
628
+ # def print_arity(&b) puts b.arity; end
629
+ #
630
+ # This prints 1:
631
+ # print_arity { |a, b, c, &bl| }
632
+ #
633
+ # But this prints 3:
634
+ # print_arity { |a, b, c| }
635
+ #
636
+ # Given that it lies, we can't trust it and we don't slice the args.
637
+ def arg_slice_for(args, arity)
614
638
  args
615
639
  end
616
640
  end
@@ -1,7 +1,14 @@
1
1
  module RSpec
2
2
  module Mocks
3
- class Mock
3
+ class Double
4
4
  include TestDouble
5
5
  end
6
+
7
+ def self.const_missing(name)
8
+ return super unless name == :Mock
9
+ RSpec.deprecate("RSpec::Mocks::Mock", :replacement => "RSpec::Mocks::Double")
10
+ Double
11
+ end
6
12
  end
7
13
  end
14
+
@@ -167,6 +167,9 @@ module RSpec
167
167
  # so you can stub constants in other contexts (e.g. helper
168
168
  # classes).
169
169
  def self.stub(constant_name, value, options = {})
170
+ space = RSpec::Mocks.space
171
+ space.print_out_of_example_deprecation if space.outside_example
172
+
170
173
  mutator = if recursive_const_defined?(constant_name, &raise_on_invalid_const)
171
174
  DefinedConstantReplacer
172
175
  else
@@ -187,6 +190,9 @@ module RSpec
187
190
  # so you can hide constants in other contexts (e.g. helper
188
191
  # classes).
189
192
  def self.hide(constant_name)
193
+ space = RSpec::Mocks.space
194
+ space.print_out_of_example_deprecation if space.outside_example
195
+
190
196
  return unless recursive_const_defined?(constant_name)
191
197
 
192
198
  mutate(ConstantHider.new(constant_name, nil, { }))
@@ -219,5 +219,12 @@ module RSpec
219
219
  method_double[method_name].stubs.find {|stub| stub.matches_name_but_not_args(method_name, *args)}
220
220
  end
221
221
  end
222
+
223
+ class TestDoubleProxy < Proxy
224
+ def reset
225
+ object.__warn_if_used_further!
226
+ super
227
+ end
228
+ end
222
229
  end
223
230
  end
@@ -2,11 +2,13 @@ module RSpec
2
2
  module Mocks
3
3
  # @api private
4
4
  class Space
5
- attr_reader :proxies, :any_instance_recorders
5
+ attr_reader :proxies, :any_instance_recorders
6
+ attr_accessor :outside_example
6
7
 
7
8
  def initialize
8
9
  @proxies = {}
9
10
  @any_instance_recorders = {}
11
+ self.outside_example = true
10
12
  end
11
13
 
12
14
  def verify_all
@@ -36,6 +38,7 @@ module RSpec
36
38
  end
37
39
 
38
40
  def any_instance_recorder_for(klass)
41
+ print_out_of_example_deprecation if outside_example
39
42
  id = klass.__id__
40
43
  any_instance_recorders.fetch(id) do
41
44
  any_instance_recorders[id] = AnyInstance::Recorder.new(klass)
@@ -51,6 +54,7 @@ module RSpec
51
54
  end
52
55
 
53
56
  def proxy_for(object)
57
+ print_out_of_example_deprecation if outside_example
54
58
  id = id_for(object)
55
59
  proxies.fetch(id) do
56
60
  proxies[id] = case object
@@ -68,6 +72,10 @@ module RSpec
68
72
  proxies.has_key?(id_for object)
69
73
  end
70
74
 
75
+ def print_out_of_example_deprecation
76
+ RSpec.deprecate("Using rspec-mocks doubles or partial doubles outside the per-test lifecycle (such as in a `before(:all)` hook)")
77
+ end
78
+
71
79
  if defined?(::BasicObject) && !::BasicObject.method_defined?(:__id__) # for 1.9.2
72
80
  require 'securerandom'
73
81
 
@@ -19,7 +19,7 @@ module RSpec
19
19
  chain.shift
20
20
  matching_stub.invoke(nil).stub_chain(*chain, &block)
21
21
  else
22
- next_in_chain = Mock.new
22
+ next_in_chain = Double.new
23
23
  object.stub(chain.shift) { next_in_chain }
24
24
  StubChain.stub_chain_on(next_in_chain, *chain, &block)
25
25
  end
@@ -34,6 +34,7 @@ module RSpec
34
34
 
35
35
  # Returns true if this object has received `as_null_object`
36
36
  def null_object?
37
+ __warn_of_expired_use_if_expired
37
38
  @__null_object
38
39
  end
39
40
 
@@ -64,20 +65,21 @@ module RSpec
64
65
 
65
66
  # @private
66
67
  def __build_mock_proxy
67
- proxy = Proxy.new(self, @name, @options || {})
68
-
69
- if null_object?
70
- proxy.as_null_object
71
- RSpec.deprecate "Relying on a test double's null-ness to persist between examples"
72
- end
73
-
68
+ proxy = TestDoubleProxy.new(self, @name, @options || {})
69
+ __warn_of_expired_use_if_expired
70
+ proxy.as_null_object if @__null_object
74
71
  proxy
75
72
  end
76
73
 
74
+ def __warn_if_used_further!
75
+ @__expired = true
76
+ end
77
+
77
78
  private
78
79
 
79
80
  def __initialize_as_test_double(name=nil, stubs_and_options={})
80
81
  @__null_object = false
82
+ @__expired = false
81
83
 
82
84
  if name.is_a?(Hash) && stubs_and_options.empty?
83
85
  stubs_and_options = name
@@ -131,6 +133,12 @@ module RSpec
131
133
  end
132
134
  end
133
135
 
136
+ def __warn_of_expired_use_if_expired
137
+ if @__expired
138
+ RSpec.deprecate "Continuing to use a test double after it has been reset (e.g. in a subsequent example)"
139
+ end
140
+ end
141
+
134
142
  private
135
143
 
136
144
  def __mock_proxy
@@ -1,7 +1,7 @@
1
1
  module RSpec
2
2
  module Mocks
3
3
  module Version
4
- STRING = '2.99.0.beta1'
4
+ STRING = '2.99.0.beta2'
5
5
  end
6
6
  end
7
7
  end
@@ -0,0 +1,17 @@
1
+ require 'spec_helper'
2
+
3
+ module RSpec
4
+ module Mocks
5
+ describe 'and_return' do
6
+ let(:obj) { double('obj') }
7
+
8
+ context 'when no argument is passed' do
9
+ it 'warns of deprection' do
10
+ expect_warn_deprecation_with_call_site(__FILE__, __LINE__ + 1, '`and_return` without arguments')
11
+ obj.stub(:foo).and_return
12
+ expect(obj.foo).to be_nil
13
+ end
14
+ end
15
+ end
16
+ end
17
+ end
@@ -1,6 +1,6 @@
1
1
  require 'spec_helper'
2
2
 
3
- describe RSpec::Mocks::Mock do
3
+ describe RSpec::Mocks::Double do
4
4
 
5
5
  let(:obj) { double }
6
6
 
@@ -214,6 +214,8 @@ module RSpec
214
214
  end
215
215
 
216
216
  context "with a block" do
217
+ before { allow_unavoidable_1_8_deprecation }
218
+
217
219
  it "stubs a method" do
218
220
  klass.any_instance.stub(:foo) { 1 }
219
221
  expect(klass.new.foo).to eq(1)
@@ -2,7 +2,7 @@ require 'spec_helper'
2
2
 
3
3
  describe "AnyNumberOfTimes" do
4
4
  before(:each) do
5
- @mock = RSpec::Mocks::Mock.new("test mock")
5
+ @mock = RSpec::Mocks::Double.new("test mock")
6
6
  allow(RSpec).to receive(:deprecate)
7
7
  end
8
8
 
@@ -0,0 +1,74 @@
1
+ require 'spec_helper'
2
+
3
+ describe "using rspec-mocks constructs in before(:all)" do
4
+ deprecations = []
5
+
6
+ def in_rspec_singleton_class(&block)
7
+ klass = class << ::RSpec; self; end
8
+ klass.class_eval(&block)
9
+ end
10
+
11
+ before(:all) do
12
+ in_rspec_singleton_class do
13
+ alias old_deprecate deprecate
14
+ undef deprecate
15
+ define_method(:deprecate) { |*args| deprecations << args.first }
16
+ end
17
+ end
18
+
19
+ after(:all) do
20
+ in_rspec_singleton_class do
21
+ undef deprecate
22
+ alias deprecate old_deprecate
23
+ undef old_deprecate
24
+ end
25
+ end
26
+
27
+ describe "a method stub" do
28
+ before(:all) do
29
+ deprecations.clear
30
+ Object.stub(:foo) { 13 }
31
+ end
32
+
33
+ it 'works in examples and prints a deprecation' do
34
+ expect(Object.foo).to eq(13)
35
+ expect(deprecations).to include(match(/outside the per-test lifecycle/))
36
+ end
37
+ end
38
+
39
+ describe "an any_instance stub" do
40
+ before(:all) do
41
+ deprecations.clear
42
+ Object.any_instance.stub(:foo => 13)
43
+ end
44
+
45
+ it 'works in examples and prints a deprecation' do
46
+ expect(Object.new.foo).to eq(13)
47
+ expect(deprecations).to include(match(/outside the per-test lifecycle/))
48
+ end
49
+ end
50
+
51
+ describe "constant stubbing" do
52
+ before(:all) do
53
+ deprecations.clear
54
+ RSpec::Mocks::ConstantMutator.stub("Foo23", 23)
55
+ end
56
+
57
+ it 'works in examples and prints a deprecation' do
58
+ expect(Foo23).to eq(23)
59
+ expect(deprecations).to include(match(/outside the per-test lifecycle/))
60
+ end
61
+ end
62
+
63
+ describe "constant hiding" do
64
+ before(:all) do
65
+ deprecations.clear
66
+ RSpec::Mocks::ConstantMutator.hide("SomeClass")
67
+ end
68
+
69
+ it 'works in examples and prints a deprecation' do
70
+ expect(deprecations).to include(match(/outside the per-test lifecycle/))
71
+ end
72
+ end
73
+ end
74
+
@@ -1,6 +1,17 @@
1
1
  require "spec_helper"
2
2
 
3
3
  describe "a double declaration with a block handed to:" do
4
+ # The "receives a block" part is important: 1.8.7 has a bug that reports the
5
+ # wrong arity when a block receives a block.
6
+ it 'forwards all given args to the block, even when it receives a block', :unless => RUBY_VERSION.to_s == '1.8.6' do
7
+ obj = Object.new
8
+ yielded_args = []
9
+ eval("obj.stub(:foo) { |*args, &bl| yielded_args << args }")
10
+ obj.foo(1, 2, 3)
11
+
12
+ expect(yielded_args).to eq([[1, 2, 3]])
13
+ end
14
+
4
15
  describe "should_receive" do
5
16
  it "returns the value of executing the block" do
6
17
  obj = Object.new
@@ -83,7 +94,7 @@ describe "a double declaration with a block handed to:" do
83
94
  end
84
95
  end
85
96
 
86
- %w[once twice ordered and_return].each do |method|
97
+ %w[once twice ordered].each do |method|
87
98
  describe method do
88
99
  it "returns the value of executing the block" do
89
100
  obj = Object.new
@@ -110,6 +121,48 @@ describe "a double declaration with a block handed to:" do
110
121
  end
111
122
  end
112
123
 
124
+ describe 'and_return' do
125
+ before do
126
+ allow_deprecation
127
+ end
128
+
129
+ it "returns the value of executing the block" do
130
+ obj = Object.new
131
+ obj.stub(:foo).and_return { 'bar' }
132
+ expect(obj.foo).to eq('bar')
133
+ end
134
+
135
+ it "does not complain if a lambda block and mismatched arguments are passed" do
136
+ obj = Object.new
137
+ obj.stub(:foo).and_return(&lambda { 'bar' })
138
+ expect(obj.foo(1, 2)).to eq('bar')
139
+ end
140
+
141
+ it 'warns of deprecation of `and_return { value }`' do
142
+ expect_deprecation_with_call_site(__FILE__, __LINE__ + 3, '`and_return { value }`')
143
+
144
+ obj = Object.new
145
+ obj.stub(:foo).and_return { 'bar' }
146
+ expect(obj.foo(1, 2)).to eq('bar')
147
+ end
148
+
149
+ it 'warns of deprection if argument counts dont match' do
150
+ warned = false
151
+
152
+ expect(RSpec).to receive(:deprecate).at_least(1) do |message, opts|
153
+ next unless message == "stubbing implementations with mismatched arity"
154
+ expect(opts[:call_site]).to match %r%/spec/rspec/mocks/block_return_value_spec.rb%
155
+ warned = true
156
+ end
157
+
158
+ obj = Object.new
159
+ obj.stub(:foo).and_return(&lambda { 'bar' })
160
+ expect(obj.foo(1, 2)).to eq('bar')
161
+
162
+ expect(warned).to be true
163
+ end
164
+ end
165
+
113
166
  describe 'any_number_of_times' do
114
167
  before do
115
168
  RSpec.stub(:deprecate)
@@ -3,6 +3,6 @@ require 'spec_helper'
3
3
  describe "An RSpec Mock" do
4
4
  it "hides internals in its inspect representation" do
5
5
  m = double('cup')
6
- expect(m.inspect).to match(/#<RSpec::Mocks::Mock:0x[a-f0-9.]+ @name="cup">/)
6
+ expect(m.inspect).to match(/#<RSpec::Mocks::Double:0x[a-f0-9.]+ @name="cup">/)
7
7
  end
8
8
  end
@@ -91,6 +91,8 @@ module RSpec
91
91
  end
92
92
 
93
93
  it 'can combine and_yield and and_return with a block' do
94
+ allow_deprecation
95
+
94
96
  dbl = double
95
97
  dbl.stub(:foo).and_yield(5).and_return { :return }
96
98
 
@@ -2,7 +2,7 @@ require "spec_helper"
2
2
 
3
3
  describe "double" do
4
4
  it "is an alias for stub and mock" do
5
- expect(double()).to be_a(RSpec::Mocks::Mock)
5
+ expect(double()).to be_a(RSpec::Mocks::Double)
6
6
  end
7
7
 
8
8
  it "uses 'Double' in failure messages" do
@@ -28,4 +28,41 @@ describe "double" do
28
28
  expect(dbl.foo).to eq(2)
29
29
  expect { reset dbl }.not_to raise_error
30
30
  end
31
+
32
+ context "after it has been torn down" do
33
+ let(:dbl) { double }
34
+
35
+ before do
36
+ expect(dbl).to receive(:foo).at_least(:once)
37
+ allow(dbl).to receive(:bar)
38
+ dbl.foo
39
+
40
+ RSpec::Mocks.verify
41
+ RSpec::Mocks.teardown
42
+ RSpec::Mocks.setup
43
+ end
44
+
45
+ it 'warns when stubbing new methods (with receive)' do
46
+ expect_deprecation_with_call_site(__FILE__, __LINE__ + 1)
47
+ allow(dbl).to receive(:bazz).and_return(3)
48
+ expect(dbl.bazz).to eq(3)
49
+ end
50
+
51
+ it 'warns when mocking new methods' do
52
+ expect_deprecation_with_call_site(__FILE__, __LINE__ + 1)
53
+ expect(dbl).to receive(:bazz)
54
+ dbl.bazz
55
+ end
56
+
57
+ it 'warns when turned into a null object' do
58
+ expect_deprecation_with_call_site(__FILE__, __LINE__ + 1)
59
+ dbl.as_null_object
60
+ dbl.foo.bar.bazz.goo
61
+ end
62
+
63
+ it 'warns when checked for nullness' do
64
+ expect_deprecation_with_call_site(__FILE__, __LINE__ + 1)
65
+ dbl.null_object?
66
+ end
67
+ end
31
68
  end
@@ -178,6 +178,8 @@ module RSpec
178
178
  end
179
179
 
180
180
  describe "allow_any_instance_of(...).to receive" do
181
+ before { allow_unavoidable_1_8_deprecation }
182
+
181
183
  include_examples "an expect syntax allowance" do
182
184
  let(:klass) { Class.new }
183
185
  let(:wrapped) { allow_any_instance_of(klass) }
@@ -199,6 +201,8 @@ module RSpec
199
201
  end
200
202
 
201
203
  describe "expect_any_instance_of(...).to receive" do
204
+ before { allow_unavoidable_1_8_deprecation }
205
+
202
206
  include_examples "an expect syntax expectation", :does_not_report_line_num do
203
207
  let(:klass) { Class.new }
204
208
  let(:wrapped) { expect_any_instance_of(klass) }
@@ -9,6 +9,7 @@ module RSpec
9
9
  let(:dbl_2) { Object.new }
10
10
 
11
11
  before do
12
+ space.outside_example = false
12
13
  space.ensure_registered(dbl_1)
13
14
  space.ensure_registered(dbl_2)
14
15
  end
@@ -2,16 +2,35 @@ require 'spec_helper'
2
2
 
3
3
  module RSpec
4
4
  module Mocks
5
- describe Mock do
5
+ describe "::Mock" do
6
+ before { allow_deprecation }
7
+
8
+ it 'returns a reference to Double' do
9
+ expect(RSpec::Mocks::Mock).to be(RSpec::Mocks::Double)
10
+ end
11
+
12
+ it 'prints a deprecation warning' do
13
+ expect_deprecation_with_call_site(__FILE__, __LINE__ + 1)
14
+ RSpec::Mocks::Mock
15
+ end
16
+
17
+ it 'does not clobber the normal const missing behavior' do
18
+ expect {
19
+ RSpec::Mocks::AZBYCX
20
+ }.to raise_error(NameError, /RSpec::Mocks::AZBYCX/)
21
+ end
22
+ end
23
+
24
+ describe Double do
6
25
  before(:each) { @double = double("test double") }
7
26
  after(:each) { reset @double }
8
27
 
9
28
  it "has method_missing as private" do
10
- expect(RSpec::Mocks::Mock.private_instance_methods).to include_method(:method_missing)
29
+ expect(RSpec::Mocks::Double.private_instance_methods).to include_method(:method_missing)
11
30
  end
12
31
 
13
32
  it "does not respond_to? method_missing (because it's private)" do
14
- expect(RSpec::Mocks::Mock.new).not_to respond_to(:method_missing)
33
+ expect(RSpec::Mocks::Double.new).not_to respond_to(:method_missing)
15
34
  end
16
35
 
17
36
  it "reports line number of expectation of unreceived message" do
@@ -142,6 +161,7 @@ module RSpec
142
161
  end
143
162
 
144
163
  it "allows block to calculate return values" do
164
+ allow_deprecation
145
165
  @double.should_receive(:something).with("a","b","c").and_return { |a,b,c| c+b+a }
146
166
  expect(@double.something("a","b","c")).to eq "cba"
147
167
  verify @double
@@ -631,7 +651,7 @@ module RSpec
631
651
  end
632
652
 
633
653
  it "assigns stub return values" do
634
- double = RSpec::Mocks::Mock.new('name', :message => :response)
654
+ double = RSpec::Mocks::Double.new('name', :message => :response)
635
655
  expect(double.message).to eq :response
636
656
  end
637
657
 
@@ -104,7 +104,7 @@ module RSpec
104
104
 
105
105
  describe "a message expectation with multiple return values with a specified count larger than the number of values" do
106
106
  before(:each) do
107
- @double = RSpec::Mocks::Mock.new("double")
107
+ @double = RSpec::Mocks::Double.new("double")
108
108
  @double.should_receive(:do_something).exactly(3).times.and_return(11, 22)
109
109
  end
110
110
 
@@ -92,16 +92,11 @@ module RSpec
92
92
  it "preserves its nullness to subsequent examples to " +
93
93
  "maintain compatibility with <= 2.13" do
94
94
  RSpec::Mocks.teardown
95
+ RSpec::Mocks.setup
95
96
  allow(RSpec).to receive(:deprecate)
96
97
  expect(@double).to be_null_object
97
98
  expect { @double.some.long.message.chain }.not_to raise_error
98
99
  end
99
-
100
- it 'prints a deprecation warning when a double is re-used between examples' do
101
- RSpec::Mocks.teardown
102
- expect(RSpec).to receive(:deprecate).with(/null-ness/)
103
- expect { @double.some.long.message.chain }.not_to raise_error
104
- end
105
100
  end
106
101
 
107
102
  describe "#as_null_object" do
@@ -5,7 +5,7 @@ module RSpec
5
5
  describe "calling :should_receive with an options hash" do
6
6
  it "reports the file and line submitted with :expected_from" do
7
7
  begin
8
- mock = RSpec::Mocks::Mock.new("a mock")
8
+ mock = RSpec::Mocks::Double.new("a mock")
9
9
  mock.should_receive(:message, :expected_from => "/path/to/blah.ext:37")
10
10
  verify mock
11
11
  rescue Exception => e
@@ -16,7 +16,7 @@ module RSpec
16
16
 
17
17
  it "uses the message supplied with :message" do
18
18
  expect {
19
- m = RSpec::Mocks::Mock.new("a mock")
19
+ m = RSpec::Mocks::Double.new("a mock")
20
20
  m.should_receive(:message, :message => "recebi nada")
21
21
  verify m
22
22
  }.to raise_error("recebi nada")
@@ -24,7 +24,7 @@ module RSpec
24
24
 
25
25
  it "uses the message supplied with :message after a similar stub" do
26
26
  expect {
27
- m = RSpec::Mocks::Mock.new("a mock")
27
+ m = RSpec::Mocks::Double.new("a mock")
28
28
  m.stub(:message)
29
29
  m.should_receive(:message, :message => "from mock")
30
30
  verify m
@@ -5,6 +5,7 @@ module RSpec::Mocks
5
5
 
6
6
  describe "#proxies_of(klass)" do
7
7
  let(:space) { Space.new }
8
+ before { space.outside_example = false }
8
9
 
9
10
  it 'returns proxies' do
10
11
  space.proxy_for("")
@@ -37,6 +37,18 @@ module RSpec
37
37
  end
38
38
 
39
39
  context "with two methods in chain" do
40
+ it "accepts any number of arguments to the stubbed messages" do
41
+ object.stub_chain(:msg1, :msg2).and_return(:return_value)
42
+
43
+ expect(object.msg1("nonsense", :value).msg2("another", :nonsense, 3.0, "value")).to eq(:return_value)
44
+ end
45
+
46
+ it "accepts any number of arguments to the stubbed messages with a return value from a hash" do
47
+ object.stub_chain(:msg1, :msg2 => :return_value)
48
+
49
+ expect(object.msg1("nonsense", :value).msg2("another", :nonsense, 3.0, "value")).to eq(:return_value)
50
+ end
51
+
40
52
  context "using and_return" do
41
53
  it "returns expected value from chaining two method calls" do
42
54
  object.stub_chain(:msg1, :msg2).and_return(:return_value)
@@ -285,6 +285,7 @@ module RSpec
285
285
  end
286
286
 
287
287
  it "calculates return value by executing block passed to #and_return" do
288
+ allow_deprecation
288
289
  @stub.stub(:something).with("a","b","c").and_return { |a,b,c| c+b+a }
289
290
  expect(@stub.something("a","b","c")).to eq "cba"
290
291
  verify @stub
@@ -2,6 +2,25 @@ require "spec_helper"
2
2
 
3
3
  describe RSpec::Mocks do
4
4
  describe "::setup" do
5
+ it "prints a deprecation warning when given a non-rspec host" do
6
+ o = Object.new
7
+ expect(RSpec).to receive(:deprecate).with(
8
+ "The host argument to `RSpec::Mocks.setup`",
9
+ :replacement=>"`include RSpec::Mocks::ExampleMethods` in #{o}"
10
+ )
11
+ RSpec::Mocks::setup(o)
12
+ end
13
+
14
+ it "prints the deprecation warning with the correct line" do
15
+ expect_deprecation_with_call_site(__FILE__, __LINE__ + 1)
16
+ RSpec::Mocks::setup(Object.new)
17
+ end
18
+
19
+ it "does not print a deprecation warning when self (the example group) is passed." do
20
+ expect(RSpec).not_to receive(:deprecate)
21
+ RSpec::Mocks::setup(self)
22
+ end
23
+
5
24
  context "with an existing Mock::Space" do
6
25
  before do
7
26
  @orig_space = RSpec::Mocks::space
@@ -12,20 +31,12 @@ describe RSpec::Mocks do
12
31
  end
13
32
 
14
33
  it "memoizes the space" do
15
- RSpec::Mocks::setup(Object.new)
34
+ RSpec::Mocks::setup
16
35
  space = RSpec::Mocks::space
17
- RSpec::Mocks::setup(Object.new)
36
+ RSpec::Mocks::setup
18
37
  expect(RSpec::Mocks::space).to equal(space)
19
38
  end
20
39
  end
21
-
22
- context "with no pre-existing Mock::Space" do
23
- it "initializes a Mock::Space" do
24
- RSpec::Mocks::space = nil
25
- RSpec::Mocks::setup(Object.new)
26
- expect(RSpec::Mocks::space).not_to be_nil
27
- end
28
- end
29
40
  end
30
41
 
31
42
  describe "::verify" do
@@ -40,12 +51,11 @@ describe RSpec::Mocks do
40
51
 
41
52
  describe "::teardown" do
42
53
  it "delegates to the space" do
43
- foo = double
44
- foo.should_receive(:bar)
45
- RSpec::Mocks::teardown
46
- expect do
47
- foo.bar
48
- end.to raise_error(/received unexpected message/)
54
+ foo = "foo"
55
+ foo.stub(:reverse) { "reversed" }
56
+ RSpec::Mocks.teardown
57
+ RSpec::Mocks.setup
58
+ expect(foo.reverse).to eq("oof")
49
59
  end
50
60
  end
51
61
 
@@ -20,18 +20,29 @@ module VerifyAndResetHelpers
20
20
  end
21
21
  end
22
22
 
23
- # TODO: This is duplicated in rspec-core, should be extracted into
24
- # rspec-support when that project gets started.
25
23
  module HelperMethods
26
- def expect_deprecation_with_call_site(file, line)
24
+ def expect_deprecation_with_call_site(file, line, snippet=//)
27
25
  expect(RSpec.configuration.reporter).to receive(:deprecation) do |options|
28
26
  expect(options[:call_site]).to include([file, line].join(':'))
27
+ expect(options[:deprecated]).to match(snippet)
28
+ end
29
+ end
30
+
31
+ def expect_warn_deprecation_with_call_site(file, line, snippet=//)
32
+ expect(RSpec.configuration.reporter).to receive(:deprecation) do |options|
33
+ message = options[:message]
34
+ expect(message).to match(snippet)
35
+ expect(message).to include([file, line].join(':'))
29
36
  end
30
37
  end
31
38
 
32
39
  def allow_deprecation
33
40
  allow(RSpec.configuration.reporter).to receive(:deprecation)
34
41
  end
42
+
43
+ def allow_unavoidable_1_8_deprecation
44
+ allow_deprecation if RUBY_VERSION.to_f < 1.9
45
+ end
35
46
  end
36
47
 
37
48
  RSpec.configure do |config|
metadata CHANGED
@@ -1,7 +1,8 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rspec-mocks
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.99.0.beta1
4
+ version: 2.99.0.beta2
5
+ prerelease: 7
5
6
  platform: ruby
6
7
  authors:
7
8
  - Steven Baker
@@ -9,11 +10,12 @@ authors:
9
10
  autorequire:
10
11
  bindir: bin
11
12
  cert_chain: []
12
- date: 2013-11-07 00:00:00.000000000 Z
13
+ date: 2014-02-18 00:00:00.000000000 Z
13
14
  dependencies:
14
15
  - !ruby/object:Gem::Dependency
15
16
  name: rake
16
17
  requirement: !ruby/object:Gem::Requirement
18
+ none: false
17
19
  requirements:
18
20
  - - ~>
19
21
  - !ruby/object:Gem::Version
@@ -21,6 +23,7 @@ dependencies:
21
23
  type: :development
22
24
  prerelease: false
23
25
  version_requirements: !ruby/object:Gem::Requirement
26
+ none: false
24
27
  requirements:
25
28
  - - ~>
26
29
  - !ruby/object:Gem::Version
@@ -28,6 +31,7 @@ dependencies:
28
31
  - !ruby/object:Gem::Dependency
29
32
  name: cucumber
30
33
  requirement: !ruby/object:Gem::Requirement
34
+ none: false
31
35
  requirements:
32
36
  - - ~>
33
37
  - !ruby/object:Gem::Version
@@ -35,6 +39,7 @@ dependencies:
35
39
  type: :development
36
40
  prerelease: false
37
41
  version_requirements: !ruby/object:Gem::Requirement
42
+ none: false
38
43
  requirements:
39
44
  - - ~>
40
45
  - !ruby/object:Gem::Version
@@ -42,6 +47,7 @@ dependencies:
42
47
  - !ruby/object:Gem::Dependency
43
48
  name: aruba
44
49
  requirement: !ruby/object:Gem::Requirement
50
+ none: false
45
51
  requirements:
46
52
  - - ~>
47
53
  - !ruby/object:Gem::Version
@@ -49,6 +55,7 @@ dependencies:
49
55
  type: :development
50
56
  prerelease: false
51
57
  version_requirements: !ruby/object:Gem::Requirement
58
+ none: false
52
59
  requirements:
53
60
  - - ~>
54
61
  - !ruby/object:Gem::Version
@@ -140,6 +147,7 @@ files:
140
147
  - features/support/rubinius.rb
141
148
  - features/test_frameworks/test_unit.feature
142
149
  - spec/rspec/mocks/and_call_original_spec.rb
150
+ - spec/rspec/mocks/and_return_spec.rb
143
151
  - spec/rspec/mocks/and_yield_spec.rb
144
152
  - spec/rspec/mocks/any_instance/message_chains_spec.rb
145
153
  - spec/rspec/mocks/any_instance_spec.rb
@@ -147,6 +155,7 @@ files:
147
155
  - spec/rspec/mocks/argument_expectation_spec.rb
148
156
  - spec/rspec/mocks/at_least_spec.rb
149
157
  - spec/rspec/mocks/at_most_spec.rb
158
+ - spec/rspec/mocks/before_all_spec.rb
150
159
  - spec/rspec/mocks/block_return_value_spec.rb
151
160
  - spec/rspec/mocks/bug_report_10260_spec.rb
152
161
  - spec/rspec/mocks/bug_report_10263_spec.rb
@@ -198,28 +207,32 @@ files:
198
207
  homepage: http://github.com/rspec/rspec-mocks
199
208
  licenses:
200
209
  - MIT
201
- metadata: {}
202
210
  post_install_message:
203
211
  rdoc_options:
204
212
  - --charset=UTF-8
205
213
  require_paths:
206
214
  - lib
207
215
  required_ruby_version: !ruby/object:Gem::Requirement
216
+ none: false
208
217
  requirements:
209
218
  - - ! '>='
210
219
  - !ruby/object:Gem::Version
211
220
  version: '0'
221
+ segments:
222
+ - 0
223
+ hash: 1858263502933685358
212
224
  required_rubygems_version: !ruby/object:Gem::Requirement
225
+ none: false
213
226
  requirements:
214
227
  - - ! '>'
215
228
  - !ruby/object:Gem::Version
216
229
  version: 1.3.1
217
230
  requirements: []
218
231
  rubyforge_project: rspec
219
- rubygems_version: 2.0.7
232
+ rubygems_version: 1.8.23
220
233
  signing_key:
221
- specification_version: 4
222
- summary: rspec-mocks-2.99.0.beta1
234
+ specification_version: 3
235
+ summary: rspec-mocks-2.99.0.beta2
223
236
  test_files:
224
237
  - features/README.md
225
238
  - features/Scope.md
@@ -260,6 +273,7 @@ test_files:
260
273
  - features/support/rubinius.rb
261
274
  - features/test_frameworks/test_unit.feature
262
275
  - spec/rspec/mocks/and_call_original_spec.rb
276
+ - spec/rspec/mocks/and_return_spec.rb
263
277
  - spec/rspec/mocks/and_yield_spec.rb
264
278
  - spec/rspec/mocks/any_instance/message_chains_spec.rb
265
279
  - spec/rspec/mocks/any_instance_spec.rb
@@ -267,6 +281,7 @@ test_files:
267
281
  - spec/rspec/mocks/argument_expectation_spec.rb
268
282
  - spec/rspec/mocks/at_least_spec.rb
269
283
  - spec/rspec/mocks/at_most_spec.rb
284
+ - spec/rspec/mocks/before_all_spec.rb
270
285
  - spec/rspec/mocks/block_return_value_spec.rb
271
286
  - spec/rspec/mocks/bug_report_10260_spec.rb
272
287
  - spec/rspec/mocks/bug_report_10263_spec.rb
checksums.yaml DELETED
@@ -1,15 +0,0 @@
1
- ---
2
- !binary "U0hBMQ==":
3
- metadata.gz: !binary |-
4
- OThjNzA2ZTdkZmU2MWE5OWVhMzIzMjI4NjZkNGNlY2QwZTY1ZDMyYQ==
5
- data.tar.gz: !binary |-
6
- OGY4OTQwMGY4NTZhMGEzMmVhY2NlODAzZTYxMWMyNWFmZjVjMWIwYg==
7
- !binary "U0hBNTEy":
8
- metadata.gz: !binary |-
9
- Njc3ODhhZTYxMzMyNWU3MzIxM2MzMTdjNWQ0N2Q4MWNiNTIyZDYwNGIzZjI4
10
- NzRmZjk1YjYzNDExMmZkYWNiM2E4NjQ0ZWVkOWM4MGU2NzNiMjNlYjY4ZWEw
11
- Zjg5ZDNkOTY0NGNkOTUxZjc1NWM3MDcyM2Y1NThjNDgwNDI1YjQ=
12
- data.tar.gz: !binary |-
13
- MGIzMGMxYzg2OTE4NzY1NzA5ZTM4MDIxZmRhZDQ1NjM0OWE0YjIwOWQ3MTFj
14
- YWFiYzQwNGRhMDEzNTc2YWVlNzYyMDcwNTNiZGU5MWE4NmZiMzc4MGYzNzQ5
15
- NWM1YjA3OTBmMzg5Njk1MWZkZDFjNmUxNDc4ODA5Y2NiMTAyNGQ=