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