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.
- data/CHANGELOG.markdown +8 -0
- data/README.md +21 -49
- data/features/CHANGELOG.markdown +8 -0
- data/features/accessor_method_contracts.feature +107 -0
- data/features/customizing_arguments_and_return_values.feature +2 -2
- data/features/readme.md +21 -49
- data/features/rspec_mock_compatibility.feature +230 -0
- data/features/step_definitions/verified_double_steps.rb +17 -0
- data/features/{verified_double.feature → verified_mocks.feature} +5 -6
- data/features/verified_stubs.feature +94 -0
- data/lib/verified_double.rb +25 -10
- data/lib/verified_double/matchers.rb +35 -0
- data/lib/verified_double/method_signature_value.rb +15 -1
- data/lib/verified_double/method_signatures_report.rb +55 -0
- data/lib/verified_double/recording_double.rb +33 -12
- data/lib/verified_double/relays_to_internal_double_returning_self.rb +12 -0
- data/lib/verified_double/version.rb +1 -1
- data/spec/spec_helper.rb +3 -4
- data/spec/unit_helper.rb +3 -2
- data/spec/verified_double/matchers_spec.rb +96 -0
- data/spec/verified_double/method_signature_value_spec.rb +35 -0
- data/spec/verified_double/method_signatures_report_spec.rb +214 -0
- data/spec/verified_double/parse_method_signature_spec.rb +5 -1
- data/spec/verified_double/recording_double_spec.rb +103 -30
- data/spec/verified_double_spec.rb +70 -7
- data/verified_double.gemspec +0 -2
- metadata +17 -38
- data/lib/verified_double/get_registered_signatures.rb +0 -11
- data/lib/verified_double/get_unverified_signatures.rb +0 -13
- data/lib/verified_double/get_verified_signatures.rb +0 -17
- data/lib/verified_double/output_unverified_signatures.rb +0 -18
- data/lib/verified_double/report_unverified_signatures.rb +0 -16
- data/lib/verified_double/verify_doubles_service.rb +0 -15
- data/spec/verified_double/get_registered_signatures_spec.rb +0 -42
- data/spec/verified_double/get_unverified_signatures_spec.rb +0 -52
- data/spec/verified_double/get_verified_signatures_spec.rb +0 -63
- data/spec/verified_double/output_unverified_signatures_spec.rb +0 -58
- data/spec/verified_double/report_unverified_signatures_spec.rb +0 -57
- data/spec/verified_double/verify_doubles_service_spec.rb +0 -24
data/spec/unit_helper.rb
CHANGED
@@ -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 "#
|
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) {
|
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) {
|
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
|
48
|
-
it "is the name of the class represented by the
|
49
|
-
internal_double =
|
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
|
56
|
-
it "is the name of the class represented by the
|
57
|
-
internal_double =
|
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
|
66
|
-
internal_double =
|
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
|
72
|
-
internal_double =
|
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) {
|
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) {
|
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(:
|
105
|
-
subject.should_receive(:
|
115
|
+
subject.should_receive(:fake_to_s)
|
116
|
+
subject.should_receive(:fake_inspect)
|
106
117
|
|
107
|
-
expect(subject.method_signatures.map(&:method)).to eq(['
|
118
|
+
expect(subject.method_signatures.map(&:method)).to eq(['fake_to_s', 'fake_inspect'])
|
108
119
|
|
109
|
-
subject.
|
110
|
-
subject.
|
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(:
|
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.
|
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(:
|
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.
|
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
|