rspec-mocks 2.99.0.beta1 → 2.99.0.beta2

Sign up to get free protection for your applications and to get access to all the features.
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=