verified_double 0.0.2 → 0.1.0

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 (39) hide show
  1. data/CHANGELOG.markdown +8 -0
  2. data/README.md +21 -49
  3. data/features/CHANGELOG.markdown +8 -0
  4. data/features/accessor_method_contracts.feature +107 -0
  5. data/features/customizing_arguments_and_return_values.feature +2 -2
  6. data/features/readme.md +21 -49
  7. data/features/rspec_mock_compatibility.feature +230 -0
  8. data/features/step_definitions/verified_double_steps.rb +17 -0
  9. data/features/{verified_double.feature → verified_mocks.feature} +5 -6
  10. data/features/verified_stubs.feature +94 -0
  11. data/lib/verified_double.rb +25 -10
  12. data/lib/verified_double/matchers.rb +35 -0
  13. data/lib/verified_double/method_signature_value.rb +15 -1
  14. data/lib/verified_double/method_signatures_report.rb +55 -0
  15. data/lib/verified_double/recording_double.rb +33 -12
  16. data/lib/verified_double/relays_to_internal_double_returning_self.rb +12 -0
  17. data/lib/verified_double/version.rb +1 -1
  18. data/spec/spec_helper.rb +3 -4
  19. data/spec/unit_helper.rb +3 -2
  20. data/spec/verified_double/matchers_spec.rb +96 -0
  21. data/spec/verified_double/method_signature_value_spec.rb +35 -0
  22. data/spec/verified_double/method_signatures_report_spec.rb +214 -0
  23. data/spec/verified_double/parse_method_signature_spec.rb +5 -1
  24. data/spec/verified_double/recording_double_spec.rb +103 -30
  25. data/spec/verified_double_spec.rb +70 -7
  26. data/verified_double.gemspec +0 -2
  27. metadata +17 -38
  28. data/lib/verified_double/get_registered_signatures.rb +0 -11
  29. data/lib/verified_double/get_unverified_signatures.rb +0 -13
  30. data/lib/verified_double/get_verified_signatures.rb +0 -17
  31. data/lib/verified_double/output_unverified_signatures.rb +0 -18
  32. data/lib/verified_double/report_unverified_signatures.rb +0 -16
  33. data/lib/verified_double/verify_doubles_service.rb +0 -15
  34. data/spec/verified_double/get_registered_signatures_spec.rb +0 -42
  35. data/spec/verified_double/get_unverified_signatures_spec.rb +0 -52
  36. data/spec/verified_double/get_verified_signatures_spec.rb +0 -63
  37. data/spec/verified_double/output_unverified_signatures_spec.rb +0 -58
  38. data/spec/verified_double/report_unverified_signatures_spec.rb +0 -57
  39. data/spec/verified_double/verify_doubles_service_spec.rb +0 -24
@@ -1,6 +1,5 @@
1
1
  require 'active_support/core_ext/string'
2
2
  require 'pry'
3
- require 'rspec/fire'
4
3
 
5
4
  require 'verified_double/boolean'
6
5
 
@@ -10,6 +9,8 @@ require 'verified_double/boolean'
10
9
  require "verified_double/method_signature"
11
10
  require "verified_double/method_signature_value"
12
11
 
12
+ # Requiring because these are macros.
13
+ require 'verified_double/relays_to_internal_double_returning_self'
14
+
13
15
  RSpec.configure do |config|
14
- config.include(RSpec::Fire)
15
16
  end
@@ -0,0 +1,96 @@
1
+ require 'unit_helper'
2
+ require 'verified_double/matchers'
3
+
4
+ describe VerifiedDouble::Matchers do
5
+ include VerifiedDouble::Matchers
6
+
7
+ describe "#verify_accessor_contract(contract)" do
8
+ class Collaborator
9
+ attr_accessor :value
10
+ end
11
+
12
+ let(:contract) { 'Collaborator#value()=>String' }
13
+
14
+ subject { Collaborator.new }
15
+
16
+ it "adds the method signature to the verified signatures from matchers" do
17
+ expect(subject).to verify_accessor_contract(contract)
18
+ expect(VerifiedDouble.verified_signatures_from_matchers.last.to_s).to eq(contract)
19
+ end
20
+
21
+ context "where the contract has multiple return values" do
22
+ let(:contract) { 'Collaborator#value=>String,Integer' }
23
+
24
+ it "complains that the matcher expects only one return value" do
25
+ expect { expect(subject).to verify_accessor_contract(contract) }
26
+ .to raise_error(described_class::CannotHandleMultipleReturnValues)
27
+ end
28
+ end
29
+
30
+ context "where the contract return value can be initialized" do
31
+ let(:contract) { 'Collaborator#value=>String' }
32
+
33
+ it "assigns the initialized value to the subject's writer and compares it to the subject's reader" do
34
+ expect(subject.value).to be_nil
35
+
36
+ expect(subject).to verify_accessor_contract(contract)
37
+ expect(subject.value).to eq(String.new)
38
+ end
39
+ end
40
+
41
+ context "where the contract return value is a class which cannot be initialized" do
42
+ let(:contract) { 'Collaborator#value=>Integer' }
43
+
44
+ it "assigns the a new object to the subject's writer and compares it to the subject's reader" do
45
+ expect(subject.value).to be_nil
46
+
47
+ expect(subject).to verify_accessor_contract(contract)
48
+ expect(subject.value.class).to eq(Object)
49
+ end
50
+ end
51
+
52
+ context "where the contract return value is an instance" do
53
+ let(:contract) { 'Collaborator#value=>1' }
54
+
55
+ it "assigns the instance to the subject's writer and compares it to the subject's reader" do
56
+ expect(subject.value).to be_nil
57
+
58
+ expect(subject).to verify_accessor_contract(contract)
59
+ expect(subject.value).to eq(1)
60
+ end
61
+ end
62
+ end
63
+
64
+ describe "#verify_reader_contract" do
65
+ class AnotherCollaborator
66
+ attr_reader :value
67
+
68
+ def initialize(value)
69
+ @value = value
70
+ end
71
+ end
72
+
73
+ let(:contract) { 'AnotherCollaborator#value()=>String' }
74
+ let(:value) { 'a string' }
75
+
76
+ subject { AnotherCollaborator.new(value) }
77
+
78
+ it "checks if the method being verified has the same class as the return value" do
79
+ expect(subject).to verify_reader_contract(contract)
80
+ end
81
+
82
+ it "adds the method signature to the verified signatures from matchers" do
83
+ expect(subject).to verify_reader_contract(contract)
84
+ expect(VerifiedDouble.verified_signatures_from_matchers.last.to_s).to eq(contract)
85
+ end
86
+
87
+ context "where the contract has multiple return values" do
88
+ let(:contract) { 'Collaborator#value=>String,Integer' }
89
+
90
+ it "complains that the matcher expects only one return value" do
91
+ expect { expect(subject).to verify_reader_contract(contract) }
92
+ .to raise_error(described_class::CannotHandleMultipleReturnValues)
93
+ end
94
+ end
95
+ end
96
+ end
@@ -53,6 +53,15 @@ describe VerifiedDouble::MethodSignatureValue do
53
53
  describe "#modified_class" do
54
54
  subject { method_signature_value.modified_class }
55
55
 
56
+ context "where the value is recording double" do
57
+ let(:recording_double){ VerifiedDouble.of_instance('Object') }
58
+ let(:method_signature_value) { described_class.new(recording_double) }
59
+
60
+ it "is the class represented by the class_name of the recording double" do
61
+ expect(subject).to eq(Object)
62
+ end
63
+ end
64
+
56
65
  context "where the value is true" do
57
66
  let(:method_signature_value) { described_class.new(true) }
58
67
  it { expect(subject).to eq(VerifiedDouble::Boolean) }
@@ -79,4 +88,30 @@ describe VerifiedDouble::MethodSignatureValue do
79
88
  expect(subject.recommended_value.value).to_not eq(subject)
80
89
  end
81
90
  end
91
+
92
+ describe "#as_instance" do
93
+ context "where the value is an instance" do
94
+ subject { described_class.new(:some_value) }
95
+
96
+ it "returns the value" do
97
+ expect(subject.as_instance).to eq(:some_value)
98
+ end
99
+ end
100
+
101
+ context "where the value is a class which can be initialized" do
102
+ subject { described_class.new(String) }
103
+
104
+ it "returns the initialized instance of the value " do
105
+ expect(subject.as_instance).to eq(String.new)
106
+ end
107
+ end
108
+
109
+ context "where the value is a class which cannot be initialized" do
110
+ subject { described_class.new(Integer) }
111
+
112
+ it "returns an object" do
113
+ expect(subject.as_instance).to be_an(Object)
114
+ end
115
+ end
116
+ end
82
117
  end
@@ -0,0 +1,214 @@
1
+ require 'unit_helper'
2
+ require 'verified_double'
3
+ require 'verified_double/method_signatures_report'
4
+
5
+ describe VerifiedDouble::MethodSignaturesReport do
6
+ describe "initialize", verifies_contract: 'VerifiedDouble::MethodSignaturesReport.new()=>VerifiedDouble::MethodSignaturesReport' do
7
+ it { expect(described_class.new).to be_a(VerifiedDouble::MethodSignaturesReport) }
8
+ end
9
+
10
+ describe "#set_registered_signatures", verifies_contract: 'VerifiedDouble::MethodSignaturesReport#set_registered_signatures()=>VerifiedDouble::MethodSignaturesReport' do
11
+
12
+ let(:recording_double_1) {
13
+ double('VerifiedDouble::RecordingDouble',
14
+ method_signatures: [method_signature_1]) }
15
+
16
+ let(:recording_double_2) {
17
+ double('VerifiedDouble::RecordingDouble',
18
+ method_signatures: [method_signature_2]) }
19
+
20
+ let(:method_signature_1) {
21
+ VerifiedDouble::MethodSignature.new(class_name: 'Object', method_operator: '#', method: 'to_s') }
22
+
23
+ let(:method_signature_2) {
24
+ VerifiedDouble::MethodSignature.new(class_name: 'Object', method_operator: '#', method: 'inspect') }
25
+
26
+ let(:verified_double_module){ VerifiedDouble.of_class('VerifiedDouble') }
27
+
28
+ context "with multiple recording doubles in the registry" do
29
+ it "maps and flattens the method signatures of the recording doubles" do
30
+ verified_double_module
31
+ .should_receive(:registry)
32
+ .and_return([recording_double_1, recording_double_2])
33
+
34
+ expect(subject.set_registered_signatures.registered_signatures).to eq(
35
+ [method_signature_1, method_signature_2])
36
+ end
37
+ end
38
+
39
+ context "with recording doubles with duplicate signatures" do
40
+ let(:recording_double_2) {
41
+ double('VerifiedDouble::RecordingDouble',
42
+ method_signatures: [method_signature_1]) }
43
+
44
+ it "returns distinct method signatures" do
45
+ verified_double_module
46
+ .should_receive(:registry)
47
+ .and_return([recording_double_1, recording_double_2])
48
+
49
+ expect(subject.set_registered_signatures.registered_signatures).to eq([method_signature_1])
50
+ end
51
+ end
52
+ end
53
+
54
+ describe "#set_verified_signatures_from_tags", verifies_contract: 'VerifiedDouble::MethodSignaturesReport#set_verified_signatures_from_tags()=>VerifiedDouble::MethodSignaturesReport' do
55
+ let(:method_signature) { VerifiedDouble::MethodSignature.new }
56
+
57
+ let(:nested_example_group){ double(:nested_example_group) }
58
+
59
+ let(:parse_method_signature_service) {
60
+ VerifiedDouble.of_instance('VerifiedDouble::ParseMethodSignature') }
61
+
62
+ let(:parse_method_signature_service_class) {
63
+ VerifiedDouble.of_class('VerifiedDouble::ParseMethodSignature') }
64
+
65
+ let(:example_with_verified_contract_tag){
66
+ double(:example_with_verified_contract_tag,
67
+ metadata: { verifies_contract: 'signature' }) }
68
+
69
+ let(:example_without_verified_contract_tag){
70
+ double(:example_without_verified_contract_tag,
71
+ metadata: { focus: true }) }
72
+
73
+ subject { described_class.new.set_verified_signatures_from_tags(nested_example_group) }
74
+
75
+ it "filters rspec examples with the tag 'verifies_contract'" do
76
+ nested_example_group
77
+ .stub_chain(:class, :descendant_filtered_examples)
78
+ .and_return([example_with_verified_contract_tag, example_without_verified_contract_tag])
79
+
80
+ parse_method_signature_service_class
81
+ .should_receive(:new)
82
+ .with(example_with_verified_contract_tag.metadata[:verifies_contract])
83
+ .and_return(parse_method_signature_service)
84
+
85
+ parse_method_signature_service
86
+ .should_receive(:execute)
87
+ .and_return(method_signature)
88
+
89
+ expect(subject.verified_signatures_from_tags).to eq([method_signature])
90
+ end
91
+
92
+ it "returns unique signatures" do
93
+ nested_example_group
94
+ .stub_chain(:class, :descendant_filtered_examples)
95
+ .and_return([example_with_verified_contract_tag, example_with_verified_contract_tag])
96
+
97
+ parse_method_signature_service_class
98
+ .should_receive(:new)
99
+ .with(example_with_verified_contract_tag.metadata[:verifies_contract])
100
+ .at_least(:once)
101
+ .and_return(parse_method_signature_service)
102
+
103
+ parse_method_signature_service
104
+ .should_receive(:execute)
105
+ .and_return(method_signature)
106
+
107
+ expect(subject.verified_signatures_from_tags).to eq([method_signature])
108
+ end
109
+ end
110
+
111
+ describe "#identify_unverified_signatures", verifies_contract: 'VerifiedDouble::MethodSignaturesReport#identify_unverified_signatures()=>VerifiedDouble::MethodSignaturesReport' do
112
+ let(:registered_signature) {
113
+ VerifiedDouble::MethodSignature.new(
114
+ class_name: 'Person',
115
+ method: 'find',
116
+ method_operator: '.',
117
+ args: [VerifiedDouble::MethodSignatureValue.new(1)]) }
118
+
119
+ let(:registered_signature_without_match) {
120
+ VerifiedDouble::MethodSignature.new(
121
+ class_name: 'Person',
122
+ method: 'save!',
123
+ method_operator: '#') }
124
+
125
+ let(:verified_signature) {
126
+ VerifiedDouble::MethodSignature.new(
127
+ class_name: 'Person',
128
+ method: 'find',
129
+ method_operator: '.',
130
+ args: [VerifiedDouble::MethodSignatureValue.new(Object)]) }
131
+
132
+ it "retains registered signatures that cannot accept any of the verified_signatures" do
133
+ expect(registered_signature.accepts?(verified_signature)).to be_true
134
+ expect(registered_signature_without_match.accepts?(verified_signature)).to be_false
135
+
136
+ subject.registered_signatures = [registered_signature, registered_signature_without_match]
137
+ subject.verified_signatures = [verified_signature]
138
+
139
+ expect(subject.unverified_signatures).to be_empty
140
+ expect(subject.identify_unverified_signatures).to eq(subject)
141
+ expect(subject.unverified_signatures).to eq([registered_signature_without_match])
142
+ end
143
+ end
144
+
145
+ describe "#output_unverified_signatures", verifies_contract: 'VerifiedDouble::MethodSignaturesReport#output_unverified_signatures()=>VerifiedDouble::MethodSignaturesReport' do
146
+ class Dummy
147
+ end
148
+
149
+ let(:unverified_signatures){ [
150
+ VerifiedDouble::MethodSignature.new(
151
+ class_name: 'Dummy',
152
+ method_operator: '.',
153
+ method: 'find',
154
+ args: [VerifiedDouble::MethodSignatureValue.new(1)],
155
+ return_values: [VerifiedDouble::MethodSignatureValue.new(Dummy.new)]),
156
+ VerifiedDouble::MethodSignature.new(
157
+ class_name: 'Dummy',
158
+ method_operator: '.',
159
+ method: 'where',
160
+ args: [VerifiedDouble::MethodSignatureValue.new(id: 1)],
161
+ return_values: [VerifiedDouble::MethodSignatureValue.new(Dummy.new)]) ] }
162
+
163
+ context "where there are no unverified_signatures" do
164
+ it "should not output anything" do
165
+ subject.unverified_signatures = []
166
+ subject.should_not_receive(:puts)
167
+ expect(subject.output_unverified_signatures).to eq(subject)
168
+ end
169
+ end
170
+
171
+ context "where there are unverified_signatures" do
172
+ it "should output the recommended versions of the unverified_signatures" do
173
+ subject.unverified_signatures = unverified_signatures
174
+
175
+ lines = [
176
+ "The following mocks are not verified:",
177
+ unverified_signatures[0].recommended_verified_signature,
178
+ unverified_signatures[1].recommended_verified_signature ]
179
+
180
+ subject.should_receive(:puts).with(lines.join("\n"))
181
+ subject.output_unverified_signatures
182
+ end
183
+ end
184
+ end
185
+
186
+ describe "#set_verified_signatures_from_matchers", verifies_contract: 'VerifiedDouble::MethodSignaturesReport#set_verified_signatures_from_matchers()=>VerifiedDouble::MethodSignaturesReport' do
187
+ let(:verified_double_module){
188
+ VerifiedDouble.of_class('VerifiedDouble') }
189
+
190
+ let(:method_signature) { VerifiedDouble::MethodSignature.new }
191
+
192
+ it "works" do
193
+ verified_double_module
194
+ .should_receive(:verified_signatures_from_matchers)
195
+ .and_return([method_signature])
196
+
197
+ expect(subject.set_verified_signatures_from_matchers.verified_signatures_from_matchers)
198
+ .to eq([method_signature])
199
+ end
200
+ end
201
+
202
+ describe "#merge_verified_signatures", verifies_contract: 'VerifiedDouble::MethodSignaturesReport#merge_verified_signatures()=>VerifiedDouble::MethodSignaturesReport' do
203
+ let(:method_signature_from_tag) { VerifiedDouble::MethodSignature.new }
204
+ let(:method_signature_from_matcher) { VerifiedDouble::MethodSignature.new }
205
+
206
+ it "merges the verified signatures from the tags and the matchers" do
207
+ subject.verified_signatures_from_tags = [method_signature_from_tag]
208
+ subject.verified_signatures_from_matchers = [method_signature_from_matcher]
209
+
210
+ expect(subject.verified_signatures).to be_empty
211
+ expect(subject.merge_verified_signatures.verified_signatures).to eq([method_signature_from_tag, method_signature_from_matcher])
212
+ end
213
+ end
214
+ end
@@ -4,7 +4,11 @@ require 'verified_double/parse_method_signature'
4
4
  describe VerifiedDouble::ParseMethodSignature do
5
5
  subject { described_class.new(string) }
6
6
 
7
- describe "#execute" do
7
+ describe "#initialize", verifies_contract: 'VerifiedDouble::ParseMethodSignature.new(String)=>VerifiedDouble::ParseMethodSignature' do
8
+ it { expect(described_class.new("Class#method(:arg_1, :arg_2)=>:return_value")).to be_a(VerifiedDouble::ParseMethodSignature) }
9
+ end
10
+
11
+ describe "#execute", verifies_contract: 'VerifiedDouble::ParseMethodSignature#execute()=>VerifiedDouble::MethodSignature' do
8
12
  let(:string){ "Class#method(:arg_1, :arg_2)=>:return_value" }
9
13
 
10
14
  subject { described_class.new(string).execute }
@@ -5,12 +5,23 @@ describe VerifiedDouble::RecordingDouble do
5
5
  let(:class_name) { 'Object' }
6
6
  let(:internal_double) { double(class_name) }
7
7
 
8
- subject { VerifiedDouble::RecordingDouble.new(internal_double) }
8
+ subject { VerifiedDouble::RecordingDouble.new(internal_double, class_name) }
9
9
 
10
10
  describe "#initialize" do
11
11
  it "requires a double" do
12
12
  expect(subject.double).to eq(internal_double)
13
13
  end
14
+
15
+ context "with method_stubs hash" do
16
+ let(:stubbed_method){ :some_method }
17
+ let(:assumed_output){ :some_output }
18
+
19
+ subject { VerifiedDouble::RecordingDouble.new(internal_double, class_name, some_method: assumed_output) }
20
+
21
+ it "stubs the methods of the instance" do
22
+ expect(subject.send(stubbed_method)).to eq(assumed_output)
23
+ end
24
+ end
14
25
  end
15
26
 
16
27
  it "delegates all unknown calls to its internal double" do
@@ -24,14 +35,14 @@ describe VerifiedDouble::RecordingDouble do
24
35
 
25
36
  context "where the internal double is a class" do
26
37
  let(:class_name) { 'Dummy' }
27
- let(:internal_double) { fire_class_double(class_name).as_replaced_constant }
38
+ let(:internal_double) { stub_const(class_name, Class.new) }
28
39
 
29
40
  it { expect(subject.to_s).to eq("VerifiedDouble.of_class('#{class_name}')") }
30
41
  end
31
42
 
32
43
  context "where the internal double is an instance" do
33
44
  let(:class_name) { 'Dummy' }
34
- let(:internal_double) { fire_double(class_name) }
45
+ let(:internal_double) { double(class_name) }
35
46
 
36
47
  it { expect(subject.to_s).to eq("VerifiedDouble.of_instance('#{class_name}')") }
37
48
  end
@@ -44,42 +55,42 @@ describe VerifiedDouble::RecordingDouble do
44
55
  end
45
56
 
46
57
  describe "#class_name" do
47
- context "where the internal double is an RSpec::Fire::FireObjectDouble" do
48
- it "is the name of the class represented by the FireObjectDouble" do
49
- internal_double = fire_double('Object')
50
- subject = described_class.new(internal_double)
58
+ context "where the internal double is a double" do
59
+ it "is the name of the class represented by the double" do
60
+ internal_double = double('Object')
61
+ subject = described_class.new(internal_double, 'Object')
51
62
  expect(subject.class_name).to eq('Object')
52
63
  end
53
64
  end
54
65
 
55
- context "where the internal double is an rspec fire class double" do
56
- it "is the name of the class represented by the rspec fire class double" do
57
- internal_double = fire_class_double('Object').as_replaced_constant
58
- subject = described_class.new(internal_double)
66
+ context "where the internal double is a stub const" do
67
+ it "is the name of the class represented by the class double" do
68
+ internal_double = stub_const('Object', Class.new)
69
+ subject = described_class.new(internal_double, 'Object')
59
70
  expect(subject.class_name).to eq('Object')
60
71
  end
61
72
  end
62
73
  end
63
74
 
64
75
  describe "#class_double?" do
65
- it "should be true if the internal double is an rspec fire class double" do
66
- internal_double = fire_double('Object')
67
- subject = described_class.new(internal_double)
76
+ it "should be true if the internal double is a class double" do
77
+ internal_double = double('Object')
78
+ subject = described_class.new(internal_double, 'Object')
68
79
  expect(subject).to_not be_class_double
69
80
  end
70
81
 
71
- it "should be false if the internal double is not an rspec fire class double" do
72
- internal_double = fire_class_double('Object').as_replaced_constant
73
- subject = described_class.new(internal_double)
82
+ it "should be false if the internal double is not an class double" do
83
+ internal_double = stub_const('Object', Class.new)
84
+ subject = described_class.new(internal_double, 'Object')
74
85
  expect(subject).to be_class_double
75
86
  end
76
87
  end
77
88
 
78
89
  describe "#method_operator" do
79
90
  context "when the subject wraps an instance double" do
80
- let(:internal_double) { fire_double('Object') }
91
+ let(:internal_double) { double(class_name) }
81
92
 
82
- subject { VerifiedDouble::RecordingDouble.new(internal_double) }
93
+ subject { VerifiedDouble::RecordingDouble.new(internal_double, class_name) }
83
94
 
84
95
  it "is #" do
85
96
  expect(subject.method_operator).to eq("#")
@@ -87,9 +98,9 @@ describe VerifiedDouble::RecordingDouble do
87
98
  end
88
99
 
89
100
  context "when the subject wraps a class double" do
90
- let(:internal_double) { fire_class_double('Object') }
101
+ let(:internal_double) { stub_const(class_name, Class.new) }
91
102
 
92
- subject { VerifiedDouble::RecordingDouble.new(internal_double) }
103
+ subject { VerifiedDouble::RecordingDouble.new(internal_double, class_name) }
93
104
 
94
105
  it "is '.'" do
95
106
  expect(subject.method_operator).to eq(".")
@@ -101,37 +112,99 @@ describe VerifiedDouble::RecordingDouble do
101
112
  it "appends a new method signature with the method to the recording double's method signatures" do
102
113
  expect(subject.method_signatures).to be_empty
103
114
 
104
- subject.should_receive(:to_s)
105
- subject.should_receive(:inspect)
115
+ subject.should_receive(:fake_to_s)
116
+ subject.should_receive(:fake_inspect)
106
117
 
107
- expect(subject.method_signatures.map(&:method)).to eq(['to_s', 'inspect'])
118
+ expect(subject.method_signatures.map(&:method)).to eq(['fake_to_s', 'fake_inspect'])
108
119
 
109
- subject.to_s
110
- subject.inspect
120
+ subject.fake_to_s
121
+ subject.fake_inspect
122
+ end
123
+ end
124
+
125
+ describe "#stub(method)" do
126
+ it "appends a new method signature with the method to the recording double's method signatures" do
127
+ expect(subject.method_signatures).to be_empty
128
+
129
+ subject.stub(:fake_to_s)
130
+ subject.stub(:fake_inspect)
131
+
132
+ expect(subject.method_signatures.map(&:method)).to eq(['fake_to_s', 'fake_inspect'])
111
133
  end
112
134
  end
113
135
 
114
136
  describe "#with(*args)" do
115
137
  it "sets the args of the last method signature" do
116
- subject.should_receive(:to_s).with(:arg_1, :arg_2)
138
+ subject.should_receive(:fake_to_s).with(:arg_1, :arg_2)
117
139
 
118
140
  expect(subject.method_signatures[0].args).to be_all{|arg| arg.is_a?(VerifiedDouble::MethodSignatureValue) }
119
141
  expect(subject.method_signatures[0].args.map(&:value)).to eq([:arg_1, :arg_2])
120
142
 
121
- subject.to_s(:arg_1, :arg_2)
143
+ subject.fake_to_s(:arg_1, :arg_2)
122
144
  end
123
145
  end
124
146
 
125
147
  describe "#and_return(return_value)" do
126
148
  it "sets the return value of the last method signature" do
127
- subject.should_receive(:to_s).with(:arg_1, :arg_2).and_return(:return_value)
149
+ subject.should_receive(:fake_to_s).with(:arg_1, :arg_2).and_return(:return_value)
128
150
 
129
151
  return_values = subject.method_signatures[0].return_values
130
152
  expect(return_values).to have(1).return_value
131
153
  expect(return_values.first).to be_a(VerifiedDouble::MethodSignatureValue)
132
154
  expect(return_values.first.value).to eq(:return_value)
133
155
 
134
- subject.to_s(:arg_1, :arg_2)
156
+ subject.fake_to_s(:arg_1, :arg_2)
157
+ end
158
+ end
159
+
160
+ describe "#once" do
161
+ it "is relayed to the internal double and returns the recording double" do
162
+ expect(subject.should_receive(:fake_to_s).once).to be_a(described_class)
163
+ subject.fake_to_s
164
+ end
165
+ end
166
+
167
+ describe "#twice" do
168
+ it "is relayed to the internal double and returns the recording double" do
169
+ expect(subject.should_receive(:fake_to_s).twice).to be_a(described_class)
170
+ subject.fake_to_s
171
+ subject.fake_to_s
172
+ end
173
+ end
174
+
175
+ describe "#at_least" do
176
+ it "is relayed to the internal double and returns the recording double" do
177
+ expect(subject.should_receive(:fake_to_s).at_least(:once)).to be_a(described_class)
178
+ subject.fake_to_s
179
+ end
180
+ end
181
+
182
+ describe "#at_most" do
183
+ it "is relayed to the internal double and returns the recording double" do
184
+ expect(subject.should_receive(:fake_to_s).at_most(:once)).to be_a(described_class)
185
+ subject.fake_to_s
186
+ end
187
+ end
188
+
189
+ describe "#any_number_of_times" do
190
+ it "is relayed to the internal double and returns the recording double" do
191
+ expect(subject.should_receive(:fake_to_s).any_number_of_times).to be_a(described_class)
192
+ end
193
+ end
194
+
195
+ describe "#and_raise" do
196
+ let(:some_error){ Exception.new }
197
+
198
+ it "is relayed to the internal double and returns the recording double" do
199
+ expect(subject.should_receive(:fake_to_s).and_raise(some_error)).to be_a(described_class)
200
+ expect { subject.fake_to_s }.to raise_error(some_error)
201
+ end
202
+ end
203
+
204
+ describe "#and_raise" do
205
+ it "is relayed to the internal double and returns the recording double" do
206
+ expect(subject.should_receive(:fake_to_s).and_throw(:some_error)).to be_a(described_class)
207
+ expect { subject.fake_to_s }.to throw_symbol(:some_error)
135
208
  end
136
209
  end
137
210
  end