rspec-mocks 3.0.0.beta1 → 3.0.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 (114) hide show
  1. data.tar.gz.sig +1 -1
  2. data/Changelog.md +95 -3
  3. data/README.md +27 -13
  4. data/features/README.md +15 -7
  5. data/features/argument_matchers/README.md +5 -5
  6. data/features/argument_matchers/explicit.feature +6 -6
  7. data/features/argument_matchers/general_matchers.feature +4 -4
  8. data/features/argument_matchers/type_matchers.feature +2 -2
  9. data/features/message_expectations/README.md +29 -27
  10. data/features/message_expectations/call_original.feature +0 -1
  11. data/features/message_expectations/message_chains_using_expect.feature +49 -0
  12. data/features/method_stubs/README.md +2 -1
  13. data/features/method_stubs/{any_instance.feature → allow_any_instance_of.feature} +12 -12
  14. data/features/method_stubs/{stub_chain.feature → receive_message_chain.feature} +3 -3
  15. data/features/method_stubs/to_ary.feature +1 -1
  16. data/features/mutating_constants/stub_defined_constant.feature +0 -1
  17. data/features/outside_rspec/standalone.feature +1 -1
  18. data/features/spies/spy_pure_mock_method.feature +1 -1
  19. data/features/test_frameworks/test_unit.feature +21 -10
  20. data/features/verifying_doubles/README.md +17 -0
  21. data/features/verifying_doubles/class_doubles.feature +1 -16
  22. data/features/verifying_doubles/dynamic_classes.feature +0 -1
  23. data/features/verifying_doubles/{introduction.feature → instance_doubles.feature} +41 -23
  24. data/features/verifying_doubles/partial_doubles.feature +2 -2
  25. data/lib/rspec/mocks.rb +69 -82
  26. data/lib/rspec/mocks/any_instance/expect_chain_chain.rb +35 -0
  27. data/lib/rspec/mocks/any_instance/expectation_chain.rb +1 -2
  28. data/lib/rspec/mocks/any_instance/recorder.rb +52 -18
  29. data/lib/rspec/mocks/any_instance/stub_chain.rb +1 -1
  30. data/lib/rspec/mocks/any_instance/stub_chain_chain.rb +4 -0
  31. data/lib/rspec/mocks/argument_list_matcher.rb +10 -44
  32. data/lib/rspec/mocks/argument_matchers.rb +132 -163
  33. data/lib/rspec/mocks/configuration.rb +28 -4
  34. data/lib/rspec/mocks/error_generator.rb +46 -13
  35. data/lib/rspec/mocks/example_methods.rb +13 -12
  36. data/lib/rspec/mocks/extensions/marshal.rb +1 -1
  37. data/lib/rspec/mocks/framework.rb +3 -4
  38. data/lib/rspec/mocks/instance_method_stasher.rb +2 -3
  39. data/lib/rspec/mocks/matchers/have_received.rb +8 -6
  40. data/lib/rspec/mocks/matchers/receive.rb +28 -20
  41. data/lib/rspec/mocks/matchers/receive_message_chain.rb +65 -0
  42. data/lib/rspec/mocks/matchers/receive_messages.rb +3 -2
  43. data/lib/rspec/mocks/message_chain.rb +91 -0
  44. data/lib/rspec/mocks/message_expectation.rb +86 -80
  45. data/lib/rspec/mocks/method_double.rb +2 -11
  46. data/lib/rspec/mocks/method_reference.rb +82 -23
  47. data/lib/rspec/mocks/method_signature_verifier.rb +207 -0
  48. data/lib/rspec/mocks/mutate_const.rb +34 -50
  49. data/lib/rspec/mocks/object_reference.rb +0 -1
  50. data/lib/rspec/mocks/proxy.rb +70 -13
  51. data/lib/rspec/mocks/ruby_features.rb +24 -0
  52. data/lib/rspec/mocks/space.rb +105 -31
  53. data/lib/rspec/mocks/standalone.rb +2 -2
  54. data/lib/rspec/mocks/syntax.rb +43 -8
  55. data/lib/rspec/mocks/targets.rb +16 -7
  56. data/lib/rspec/mocks/test_double.rb +41 -15
  57. data/lib/rspec/mocks/verifying_double.rb +51 -4
  58. data/lib/rspec/mocks/verifying_message_expecation.rb +12 -12
  59. data/lib/rspec/mocks/verifying_proxy.rb +32 -19
  60. data/lib/rspec/mocks/version.rb +1 -1
  61. data/spec/rspec/mocks/and_call_original_spec.rb +28 -7
  62. data/spec/rspec/mocks/and_return_spec.rb +23 -0
  63. data/spec/rspec/mocks/and_yield_spec.rb +1 -2
  64. data/spec/rspec/mocks/any_instance_spec.rb +33 -17
  65. data/spec/rspec/mocks/array_including_matcher_spec.rb +6 -6
  66. data/spec/rspec/mocks/before_all_spec.rb +132 -0
  67. data/spec/rspec/mocks/block_return_value_spec.rb +12 -1
  68. data/spec/rspec/mocks/combining_implementation_instructions_spec.rb +9 -11
  69. data/spec/rspec/mocks/configuration_spec.rb +14 -1
  70. data/spec/rspec/mocks/double_spec.rb +867 -24
  71. data/spec/rspec/mocks/example_methods_spec.rb +13 -0
  72. data/spec/rspec/mocks/extensions/marshal_spec.rb +17 -17
  73. data/spec/rspec/mocks/failing_argument_matchers_spec.rb +29 -1
  74. data/spec/rspec/mocks/hash_excluding_matcher_spec.rb +12 -12
  75. data/spec/rspec/mocks/hash_including_matcher_spec.rb +21 -17
  76. data/spec/rspec/mocks/instance_method_stasher_spec.rb +2 -3
  77. data/spec/rspec/mocks/matchers/have_received_spec.rb +7 -0
  78. data/spec/rspec/mocks/matchers/receive_message_chain_spec.rb +198 -0
  79. data/spec/rspec/mocks/matchers/receive_messages_spec.rb +2 -2
  80. data/spec/rspec/mocks/matchers/receive_spec.rb +19 -6
  81. data/spec/rspec/mocks/method_signature_verifier_spec.rb +272 -0
  82. data/spec/rspec/mocks/methods_spec.rb +0 -1
  83. data/spec/rspec/mocks/multiple_return_value_spec.rb +2 -2
  84. data/spec/rspec/mocks/mutate_const_spec.rb +24 -1
  85. data/spec/rspec/mocks/nil_expectation_warning_spec.rb +6 -22
  86. data/spec/rspec/mocks/null_object_mock_spec.rb +13 -7
  87. data/spec/rspec/mocks/options_hash_spec.rb +3 -3
  88. data/spec/rspec/mocks/{partial_mock_spec.rb → partial_double_spec.rb} +5 -2
  89. data/spec/rspec/mocks/{partial_mock_using_mocks_directly_spec.rb → partial_double_using_mocks_directly_spec.rb} +1 -1
  90. data/spec/rspec/mocks/passing_argument_matchers_spec.rb +18 -0
  91. data/spec/rspec/mocks/serialization_spec.rb +1 -0
  92. data/spec/rspec/mocks/space_spec.rb +218 -7
  93. data/spec/rspec/mocks/stub_chain_spec.rb +6 -0
  94. data/spec/rspec/mocks/stub_spec.rb +0 -6
  95. data/spec/rspec/mocks/syntax_spec.rb +19 -0
  96. data/spec/rspec/mocks/test_double_spec.rb +0 -1
  97. data/spec/rspec/mocks/verifying_double_spec.rb +281 -18
  98. data/spec/rspec/mocks/verifying_message_expecation_spec.rb +7 -6
  99. data/spec/rspec/mocks_spec.rb +168 -42
  100. data/spec/spec_helper.rb +34 -22
  101. metadata +94 -63
  102. metadata.gz.sig +0 -0
  103. checksums.yaml +0 -15
  104. checksums.yaml.gz.sig +0 -2
  105. data/features/outside_rspec/configuration.feature +0 -60
  106. data/lib/rspec/mocks/arity_calculator.rb +0 -66
  107. data/lib/rspec/mocks/errors.rb +0 -12
  108. data/lib/rspec/mocks/mock.rb +0 -7
  109. data/lib/rspec/mocks/proxy_for_nil.rb +0 -37
  110. data/lib/rspec/mocks/stub_chain.rb +0 -51
  111. data/spec/rspec/mocks/argument_expectation_spec.rb +0 -32
  112. data/spec/rspec/mocks/arity_calculator_spec.rb +0 -95
  113. data/spec/rspec/mocks/mock_space_spec.rb +0 -113
  114. data/spec/rspec/mocks/mock_spec.rb +0 -788
@@ -21,4 +21,3 @@ Feature: Calling the original method
21
21
  """
22
22
  When I run `rspec call_original_spec.rb`
23
23
  Then the examples should all pass
24
-
@@ -0,0 +1,49 @@
1
+ Feature: Message chains in the expect syntax
2
+
3
+ You can use `receive_message_chain` to stub nested calls
4
+ on both partial and pure mock objects.
5
+
6
+ Scenario: allow a chained message
7
+ Given a file named "spec/chained_messages.rb" with:
8
+ """ruby
9
+ describe "a chained message expectation" do
10
+ it "passes if the expected number of calls happen" do
11
+ d = double
12
+ allow(d).to receive_message_chain(:to_a, :length)
13
+
14
+ d.to_a.length
15
+ end
16
+ end
17
+ """
18
+ When I run `rspec spec/chained_messages.rb`
19
+ Then the output should contain "1 example, 0 failures"
20
+
21
+ Scenario: allow a chained message with a return value
22
+ Given a file named "spec/chained_messages.rb" with:
23
+ """ruby
24
+ describe "a chained message expectation" do
25
+ it "passes if the expected number of calls happen" do
26
+ d = double
27
+ allow(d).to receive_message_chain(:to_a, :length).and_return(3)
28
+
29
+ expect(d.to_a.length).to eq(3)
30
+ end
31
+ end
32
+ """
33
+ When I run `rspec spec/chained_messages.rb`
34
+ Then the output should contain "1 example, 0 failures"
35
+
36
+ Scenario: expect a chained message with a return value
37
+ Given a file named "spec/chained_messages.rb" with:
38
+ """ruby
39
+ describe "a chained message expectation" do
40
+ it "passes if the expected number of calls happen" do
41
+ d = double
42
+ expect(d).to receive_message_chain(:to_a, :length).and_return(3)
43
+
44
+ expect(d.to_a.length).to eq(3)
45
+ end
46
+ end
47
+ """
48
+ When I run `rspec spec/chained_messages.rb`
49
+ Then the output should contain "1 example, 0 failures"
@@ -20,7 +20,7 @@ block contents are evaluated lazily when the `obj` receives the
20
20
 
21
21
  allow(obj).to receive(:message) do |arg1, arg2|
22
22
  # set expectations about the args in this block
23
- # and/or return value
23
+ # and/or return value
24
24
  end
25
25
 
26
26
  obj.stub(:message) do |arg1, arg2|
@@ -49,6 +49,7 @@ You can also use the block format:
49
49
  #### Explicit arguments
50
50
 
51
51
  allow(obj).to receive(:message).with('an argument') { ... }
52
+ allow(obj).to receive(:message).with('more than', 'an argument') { ... }
52
53
 
53
54
  obj.stub(:message).with('an argument') { ... }
54
55
  obj.stub(:message).with('more_than', 'one_argument') { ... }
@@ -1,6 +1,6 @@
1
1
  Feature: stub on any instance of a class
2
2
 
3
- Use `any_instance.stub` on a class to tell any instance of that class to
3
+ Use `allow_any_instance_of` on a class to tell any instance of that class to
4
4
  return a value (or values) in response to a given message. If no instance
5
5
  receives the message, nothing happens.
6
6
 
@@ -10,12 +10,12 @@ Feature: stub on any instance of a class
10
10
  to the object that receives a message in your test. For more information,
11
11
  see the message_expectations/allow_any_instance_of feature.
12
12
 
13
- Scenario: any_instance stub with a single return value
13
+ Scenario: Stubbing any instance of an object with a single return value
14
14
  Given a file named "example_spec.rb" with:
15
15
  """ruby
16
- describe "any_instance.stub" do
16
+ describe "stubbing any instance" do
17
17
  it "returns the specified value on any instance of the class" do
18
- Object.any_instance.stub(:foo).and_return(:return_value)
18
+ allow_any_instance_of(Object).to receive(:foo).and_return(:return_value)
19
19
 
20
20
  o = Object.new
21
21
  expect(o.foo).to eq(:return_value)
@@ -31,7 +31,7 @@ Feature: stub on any instance of a class
31
31
  describe "any_instance.stub" do
32
32
  context "with a hash" do
33
33
  it "returns the hash values on any instance of the class" do
34
- Object.any_instance.stub(:foo => 'foo', :bar => 'bar')
34
+ allow_any_instance_of(Object).to receive_messages(:foo => 'foo', :bar => 'bar')
35
35
 
36
36
  o = Object.new
37
37
  expect(o.foo).to eq('foo')
@@ -43,14 +43,14 @@ Feature: stub on any instance of a class
43
43
  When I run `rspec example_spec.rb`
44
44
  Then the examples should all pass
45
45
 
46
- Scenario: any_instance stub with specific arguments matchers
46
+ Scenario: Stubbing any instance of an object with specific arguments matchers
47
47
  Given a file named "example_spec.rb" with:
48
48
  """ruby
49
- describe "any_instance.stub" do
49
+ describe "stubbing any instance" do
50
50
  context "with arguments" do
51
51
  it "returns the stubbed value when arguments match" do
52
- Object.any_instance.stub(:foo).with(:param_one, :param_two).and_return(:result_one)
53
- Object.any_instance.stub(:foo).with(:param_three, :param_four).and_return(:result_two)
52
+ allow_any_instance_of(Object).to receive(:foo).with(:param_one, :param_two).and_return(:result_one)
53
+ allow_any_instance_of(Object).to receive(:foo).with(:param_three, :param_four).and_return(:result_two)
54
54
 
55
55
  o = Object.new
56
56
  expect(o.foo(:param_one, :param_two)).to eq(:result_one)
@@ -112,21 +112,21 @@ Feature: stub on any instance of a class
112
112
  describe "stubbing a chain of methods" do
113
113
  context "given symbols representing methods" do
114
114
  it "returns the correct value" do
115
- Object.any_instance.stub_chain(:one, :two, :three).and_return(:four)
115
+ allow_any_instance_of(Object).to receive_message_chain(:one, :two, :three).and_return(:four)
116
116
  expect(Object.new.one.two.three).to eq(:four)
117
117
  end
118
118
  end
119
119
 
120
120
  context "given a hash at the end" do
121
121
  it "returns the correct value" do
122
- Object.any_instance.stub_chain(:one, :two, :three => :four)
122
+ allow_any_instance_of(Object).to receive_message_chain(:one, :two, :three=> :four)
123
123
  expect(Object.new.one.two.three).to eq(:four)
124
124
  end
125
125
  end
126
126
 
127
127
  context "given a string of methods separated by dots" do
128
128
  it "returns the correct value" do
129
- Object.any_instance.stub_chain("one.two.three").and_return(:four)
129
+ allow_any_instance_of(Object).to receive_message_chain("one.two.three").and_return(:four)
130
130
  expect(Object.new.one.two.three).to eq(:four)
131
131
  end
132
132
  end
@@ -27,21 +27,21 @@ Feature: stub a chain of methods
27
27
 
28
28
  context "given symbols representing methods" do
29
29
  it "returns the correct value" do
30
- subject.stub_chain(:one, :two, :three).and_return(:four)
30
+ allow(subject).to receive_message_chain(:one, :two, :three).and_return(:four)
31
31
  expect(subject.one.two.three).to eq(:four)
32
32
  end
33
33
  end
34
34
 
35
35
  context "given a hash at the end" do
36
36
  it "returns the correct value" do
37
- subject.stub_chain(:one, :two, :three => :four)
37
+ allow(subject).to receive_message_chain(:one, :two, :three => :four)
38
38
  expect(subject.one.two.three).to eq(:four)
39
39
  end
40
40
  end
41
41
 
42
42
  context "given a string of methods separated by dots" do
43
43
  it "returns the correct value" do
44
- subject.stub_chain("one.two.three").and_return(:four)
44
+ allow(subject).to receive_message_chain("one.two.three").and_return(:four)
45
45
  expect(subject.one.two.three).to eq(:four)
46
46
  end
47
47
  end
@@ -18,7 +18,7 @@ Feature: double handling to_ary
18
18
  describe "#to_ary" do
19
19
  shared_examples "to_ary" do
20
20
  it "can be overridden with a stub" do
21
- obj.stub(:to_ary) { :non_nil_value }
21
+ allow(obj).to receive(:to_ary) { :non_nil_value }
22
22
  expect(obj.to_ary).to be(:non_nil_value)
23
23
  end
24
24
 
@@ -76,4 +76,3 @@ Feature: Stub Defined Constant
76
76
  """
77
77
  When I run `rspec stub_const_spec.rb`
78
78
  Then the examples should all pass
79
-
@@ -10,7 +10,7 @@ Feature: standalone
10
10
  require "rspec/mocks/standalone"
11
11
 
12
12
  greeter = double("greeter")
13
- greeter.stub(:say_hi) { "Hello!" }
13
+ allow(greeter).to receive(:say_hi) { "Hello!" }
14
14
  puts greeter.say_hi
15
15
  """
16
16
  When I run `ruby example.rb`
@@ -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) }
@@ -13,31 +13,42 @@ Feature: Test::Unit integration
13
13
  require 'rspec/mocks'
14
14
 
15
15
  class RSpecMocksTest < Test::Unit::TestCase
16
+ include RSpec::Mocks::ExampleMethods
17
+
16
18
  def setup
17
- RSpec::Mocks.setup(Object)
18
- RSpec::Mocks.setup(self)
19
+ RSpec::Mocks.setup
20
+ end
21
+
22
+ def teardown
23
+ RSpec::Mocks.verify
24
+ ensure
25
+ RSpec::Mocks.teardown
19
26
  end
20
27
 
21
- def test_passing_expectation
28
+ def test_passing_positive_expectation
22
29
  obj = Object.new
23
30
  expect(obj).to receive(:message)
24
31
  obj.message
25
32
  end
26
33
 
27
- def test_failing_expectation
34
+ def test_failing_positive_expectation
28
35
  obj = Object.new
29
- expect(obj).to_not receive(:message)
36
+ expect(obj).to receive(:message)
30
37
  obj.message
31
38
  end
32
39
 
33
- def test_with_deprecation_warning
40
+ def test_passing_negative_expectation
34
41
  obj = Object.new
35
- obj.stub(:old_message) { RSpec.deprecate(:old_message, :replacement => :message) }
36
- obj.old_message
42
+ expect(obj).to_not receive(:message)
43
+ end
44
+
45
+ def test_failing_negative_expectation
46
+ obj = Object.new
47
+ expect(obj).to_not receive(:message)
48
+ obj.message
37
49
  end
38
50
  end
39
51
  """
40
52
  When I run `ruby rspec_mocks_test.rb`
41
- Then the output should contain "3 tests, 0 assertions, 0 failures, 1 errors" or "3 tests, 0 assertions, 1 failures, 0 errors"
53
+ Then the output should contain "4 tests, 0 assertions, 0 failures, 1 errors" or "4 tests, 0 assertions, 1 failures, 0 errors"
42
54
  And the output should contain "expected: 0 times with any arguments"
43
- And the output should contain "old_message is deprecated"
@@ -0,0 +1,17 @@
1
+ ## Verifying Doubles
2
+
3
+ Verifying doubles are a stricter alternative to normal doubles that provide
4
+ guarantees about what is being verified. When using verifying doubles, RSpec
5
+ will check that the methods being stubbed are actually present on the
6
+ underlying object if it is available. Prefer using veryifing doubles over
7
+ normal doubles.
8
+
9
+ No checking will happen if the underlying object or class is not defined, but
10
+ when run with it present (either as a full spec run or by explicitly preloading
11
+ collaborators) a failure will be triggered if an invalid method is being
12
+ stubbed or a method is called with an invalid number of arguments.
13
+
14
+ This dual approach allows you to move very quickly and test components in
15
+ isolation, while giving you confidence that your doubles are not a complete
16
+ fiction. Testing in isolation is optional but recommend for classes that do not
17
+ depend on third-party components.
@@ -1,7 +1,7 @@
1
1
  Feature: Using a class double
2
2
 
3
3
  `class_double` is provided as a complement to `instance_double`, with the
4
- difference that it verifies class methods on the given class rather than
4
+ difference that it verifies _class_ methods on the given class rather than
5
5
  instance methods.
6
6
 
7
7
  In addition, it also provides a convenience method `as_stubbed_const` to
@@ -71,18 +71,3 @@ Feature: Using a class double
71
71
  When I run `rspec spec/user_spec.rb`
72
72
  Then the output should contain "1 example, 1 failure"
73
73
  And the output should contain "ConsoleNotifier does not implement:"
74
-
75
- Scenario: adding `color` as a second argument to `ConsoleNotifier.notify`
76
- Given a file named "lib/console_notifier.rb" with:
77
- """ruby
78
- class ConsoleNotifier
79
- MAX_WIDTH = 80
80
-
81
- def self.notify(message, color)
82
- puts color + message
83
- end
84
- end
85
- """
86
- When I run `rspec spec/user_spec.rb`
87
- Then the output should contain "1 example, 1 failure"
88
- And the output should contain "Wrong number of arguments."
@@ -69,4 +69,3 @@ Feature: Dynamic classes
69
69
 
70
70
  When I run `rspec spec/user_spec.rb`
71
71
  Then the examples should all pass
72
-
@@ -1,20 +1,13 @@
1
- Feature: Verifying doubles
1
+ Feature: Using an instance double
2
2
 
3
- Verifying doubles are a stricter alternative to normal doubles that provide
4
- guarantees about what is being verified. When using verifying doubles, RSpec
5
- will check that the methods being stubbed are actually present on the
6
- underlying object if it is available. Prefer using veryifing doubles over
7
- normal doubles.
3
+ An `instance_double` is the most common type of verifying double. It takes a
4
+ class name or object as its first argument, then verifies that any methods
5
+ being stubbed would be present on an _instance_ of that class. If any
6
+ argument matchers are specified, it also verifies that the number of
7
+ arguments is correct.
8
8
 
9
- No checking will happen if the constant name is not defined, but when run
10
- with the constant present (either as a full spec run or by explicitly
11
- preloading collaborators) a failure will be triggered if an invalid method is
12
- being stubbed.
13
-
14
- This dual approach allows you to move very quickly and test components in
15
- isolation, while giving you confidence that your doubles are not a complete
16
- fiction. Testing in isolation is optional but recommend for classes that do
17
- not depend on third-party components.
9
+ For methods handled by `method_missing`, see [dynamic
10
+ objects](./dynamic-objects).
18
11
 
19
12
  Background:
20
13
  Given a file named "app/models/user.rb" with:
@@ -26,13 +19,6 @@ Feature: Verifying doubles
26
19
  end
27
20
  """
28
21
 
29
- Given a file named "app/models/console_notifier.rb" with:
30
- """ruby
31
- class ConsoleNotifier
32
- # notify is not defined yet.
33
- end
34
- """
35
-
36
22
  Given a file named "spec/unit_helper.rb" with:
37
23
  """ruby
38
24
  $LOAD_PATH.unshift("app/models")
@@ -80,6 +66,38 @@ Feature: Verifying doubles
80
66
  When I run `rspec spec/unit/user_spec.rb`
81
67
  Then the examples should all pass
82
68
 
83
- Scenario: spec fails with dependencies loaded
69
+ Scenario: spec passes with dependencies loaded and method implemented
70
+ Given a file named "app/models/console_notifier.rb" with:
71
+ """ruby
72
+ class ConsoleNotifier
73
+ def notify(msg)
74
+ puts message
75
+ end
76
+ end
77
+ """
78
+
79
+ When I run `rspec -r./spec/spec_helper spec/unit/user_spec.rb`
80
+ Then the examples should all pass
81
+
82
+ Scenario: spec fails with dependencies loaded and method unimplemented
83
+ Given a file named "app/models/console_notifier.rb" with:
84
+ """ruby
85
+ class ConsoleNotifier
86
+ end
87
+ """
88
+ When I run `rspec -r./spec/spec_helper spec/unit/user_spec.rb`
89
+ Then the output should contain "1 example, 1 failure"
90
+ And the output should contain "ConsoleNotifier does not implement:"
91
+
92
+ Scenario: spec fails with dependencies loaded and incorrect arity
93
+ Given a file named "app/models/console_notifier.rb" with:
94
+ """ruby
95
+ class ConsoleNotifier
96
+ def notify(msg, color)
97
+ puts color + message
98
+ end
99
+ end
100
+ """
84
101
  When I run `rspec -r./spec/spec_helper spec/unit/user_spec.rb`
85
102
  Then the output should contain "1 example, 1 failure"
103
+ And the output should contain "Wrong number of arguments."
@@ -1,7 +1,7 @@
1
1
  Feature: Partial doubles
2
2
 
3
- When the `verify_partial_doubles` configuration option is set, the same arity
4
- and method existince checks that are performed for `object_double` are also
3
+ When the `verify_partial_doubles` configuration option is set, the same argument
4
+ and method existence checks that are performed for `object_double` are also
5
5
  performed on partial doubles. You should set this unless you have a good
6
6
  reason not to. It defaults to off only for backwards compatibility.
7
7
 
@@ -1,100 +1,87 @@
1
1
  require 'rspec/mocks/framework'
2
2
  require 'rspec/mocks/version'
3
+ require 'rspec/support'
3
4
 
4
5
  module RSpec
5
-
6
+ # Contains top-level utility methods. While this contains a few
7
+ # public methods, these are not generally meant to be called from
8
+ # a test or example. They exist primarily for integration with
9
+ # test frameworks (such as rspec-core).
6
10
  module Mocks
7
- class << self
8
- attr_accessor :space
9
-
10
- def setup(host)
11
- (class << host; self; end).class_exec do
12
- include RSpec::Mocks::ExampleMethods
13
- end
14
- self.space ||= RSpec::Mocks::Space.new
15
- end
16
-
17
- def verify
18
- space.verify_all
19
- end
20
-
21
- def teardown
22
- space.reset_all
23
- end
24
-
25
- def proxy_for(object)
26
- space.proxy_for(object)
27
- end
11
+ # Performs per-test/example setup. This should be called before
12
+ # an test or example begins.
13
+ def self.setup
14
+ @space_stack << (@space = space.new_scope)
15
+ end
28
16
 
29
- def proxies_of(klass)
30
- space.proxies_of(klass)
31
- end
17
+ # Verifies any message expectations that were set during the
18
+ # test or example. This should be called at the end of an example.
19
+ def self.verify
20
+ space.verify_all
21
+ end
32
22
 
33
- def any_instance_recorder_for(klass)
34
- space.any_instance_recorder_for(klass)
35
- end
23
+ # Cleans up all test double state (including any methods that were
24
+ # redefined on partial doubles). This _must_ be called after
25
+ # each example, even if an error was raised during the example.
26
+ def self.teardown
27
+ space.reset_all
28
+ @space_stack.pop
29
+ @space = @space_stack.last || @root_space
30
+ end
36
31
 
37
- # Adds an allowance (stub) on `subject`
38
- #
39
- # @param subject the subject to which the message will be added
40
- # @param message a symbol, representing the message that will be
41
- # added.
42
- # @param opts a hash of options, :expected_from is used to set the
43
- # original call site
44
- # @param block an optional implementation for the allowance
45
- #
46
- # @example Defines the implementation of `foo` on `bar`, using the passed block
47
- # x = 0
48
- # RSpec::Mocks.allow_message(bar, :foo) { x += 1 }
49
- def allow_message(subject, message, opts={}, &block)
50
- orig_caller = opts.fetch(:expected_from) {
51
- CallerFilter.first_non_rspec_line
52
- }
53
- ::RSpec::Mocks.proxy_for(subject).
54
- add_stub(orig_caller, message, opts, &block)
55
- end
32
+ # Adds an allowance (stub) on `subject`
33
+ #
34
+ # @param subject the subject to which the message will be added
35
+ # @param message a symbol, representing the message that will be
36
+ # added.
37
+ # @param opts a hash of options, :expected_from is used to set the
38
+ # original call site
39
+ # @param block an optional implementation for the allowance
40
+ #
41
+ # @example Defines the implementation of `foo` on `bar`, using the passed block
42
+ # x = 0
43
+ # RSpec::Mocks.allow_message(bar, :foo) { x += 1 }
44
+ def self.allow_message(subject, message, opts={}, &block)
45
+ orig_caller = opts.fetch(:expected_from) {
46
+ CallerFilter.first_non_rspec_line
47
+ }
48
+ space.proxy_for(subject).add_stub(orig_caller, message, opts, &block)
49
+ end
56
50
 
57
- # Sets a message expectation on `subject`.
58
- # @param subject the subject on which the message will be expected
59
- # @param message a symbol, representing the message that will be
60
- # expected.
61
- # @param opts a hash of options, :expected_from is used to set the
62
- # original call site
63
- # @param block an optional implementation for the expectation
64
- #
65
- # @example Expect the message `foo` to receive `bar`, then call it
66
- # RSpec::Mocks.expect_message(bar, :foo)
67
- # bar.foo
68
- def expect_message(subject, message, opts={}, &block)
69
- orig_caller = opts.fetch(:expected_from) {
70
- CallerFilter.first_non_rspec_line
71
- }
72
- ::RSpec::Mocks.proxy_for(subject).
73
- add_message_expectation(orig_caller, message, opts, &block)
74
- end
51
+ # Sets a message expectation on `subject`.
52
+ # @param subject the subject on which the message will be expected
53
+ # @param message a symbol, representing the message that will be
54
+ # expected.
55
+ # @param opts a hash of options, :expected_from is used to set the
56
+ # original call site
57
+ # @param block an optional implementation for the expectation
58
+ #
59
+ # @example Expect the message `foo` to receive `bar`, then call it
60
+ # RSpec::Mocks.expect_message(bar, :foo)
61
+ # bar.foo
62
+ def self.expect_message(subject, message, opts={}, &block)
63
+ orig_caller = opts.fetch(:expected_from) {
64
+ CallerFilter.first_non_rspec_line
65
+ }
66
+ space.proxy_for(subject).add_message_expectation(orig_caller, message, opts, &block)
67
+ end
75
68
 
76
- # @api private
77
- KERNEL_METHOD_METHOD = ::Kernel.instance_method(:method)
69
+ def self.with_temporary_scope
70
+ setup
78
71
 
79
- # @api private
80
- # Used internally to get a method handle for a particular object
81
- # and method name.
82
- #
83
- # Includes handling for a few special cases:
84
- #
85
- # - Objects that redefine #method (e.g. an HTTPRequest struct)
86
- # - BasicObject subclasses that mixin a Kernel dup (e.g. SimpleDelegator)
87
- def method_handle_for(object, method_name)
88
- if ::Kernel === object
89
- KERNEL_METHOD_METHOD.bind(object).call(method_name)
90
- else
91
- object.method(method_name)
92
- end
72
+ begin
73
+ yield
74
+ verify
75
+ ensure
76
+ teardown
93
77
  end
94
78
  end
95
79
 
80
+ class << self; attr_reader :space; end
81
+ @space_stack = []
82
+ @root_space = @space = RSpec::Mocks::RootSpace.new
83
+
96
84
  # @private
97
85
  IGNORED_BACKTRACE_LINE = 'this backtrace line is ignored'
98
86
  end
99
87
  end
100
-