verified_double 0.2.0 → 0.3.0
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGELOG.markdown +5 -0
- data/features/CHANGELOG.markdown +5 -0
- data/lib/verified_double/can_record_interactions.rb +24 -0
- data/lib/verified_double/method_signature/rspec_double_value.rb +5 -1
- data/lib/verified_double/method_signature/value.rb +0 -6
- data/lib/verified_double/method_signatures_report.rb +1 -1
- data/lib/verified_double/recorded_method_signature_registry.rb +13 -0
- data/lib/verified_double/simple_double.rb +21 -0
- data/lib/verified_double/version.rb +1 -1
- data/lib/verified_double.rb +14 -14
- data/spec/verified_double/can_record_interactions_spec.rb +47 -0
- data/spec/verified_double/method_signature/rspec_double_spec.rb +13 -2
- data/spec/verified_double/method_signature/value_spec.rb +3 -20
- data/spec/verified_double/method_signatures_report_spec.rb +9 -20
- data/spec/verified_double/recorded_method_signature_registry_spec.rb +27 -0
- data/spec/verified_double/simple_double_spec.rb +57 -0
- data/spec/verified_double_spec.rb +27 -28
- metadata +11 -12
- data/lib/verified_double/method_signature/instance_double_value.rb +0 -9
- data/lib/verified_double/method_signature/recording_double_class_value.rb +0 -9
- data/lib/verified_double/recording_double.rb +0 -92
- data/lib/verified_double/relays_to_internal_double_returning_self.rb +0 -12
- data/spec/verified_double/method_signature/instance_double_value_spec.rb +0 -17
- data/spec/verified_double/method_signature/recording_double_class_value_spec.rb +0 -23
- data/spec/verified_double/recording_double_spec.rb +0 -236
data/CHANGELOG.markdown
CHANGED
data/features/CHANGELOG.markdown
CHANGED
@@ -0,0 +1,24 @@
|
|
1
|
+
module VerifiedDouble
|
2
|
+
module CanRecordInteractions
|
3
|
+
def and_return(*return_values)
|
4
|
+
VerifiedDouble.registry.last.return_values = [MethodSignature::Value.from(return_values[0])]
|
5
|
+
super(*return_values)
|
6
|
+
end
|
7
|
+
|
8
|
+
def should_receive(*args)
|
9
|
+
VerifiedDouble.registry.add_method_signature(self, args[0])
|
10
|
+
super(*args).tap {|result| result.extend(VerifiedDouble::CanRecordInteractions) }
|
11
|
+
end
|
12
|
+
|
13
|
+
def stub(*args)
|
14
|
+
VerifiedDouble.registry.add_method_signature(self, args[0])
|
15
|
+
super(*args).tap {|result| result.extend(VerifiedDouble::CanRecordInteractions) }
|
16
|
+
end
|
17
|
+
|
18
|
+
def with(*args)
|
19
|
+
VerifiedDouble.registry.last.args =
|
20
|
+
args.map{|arg| MethodSignature::Value.from(arg) }
|
21
|
+
super(*args)
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
@@ -1,6 +1,10 @@
|
|
1
1
|
module VerifiedDouble
|
2
2
|
class MethodSignature
|
3
|
-
class RspecDoubleValue <
|
3
|
+
class RspecDoubleValue < InstanceValue
|
4
|
+
def content_as_instance
|
5
|
+
Value.from(content_class).content_as_instance
|
6
|
+
end
|
7
|
+
|
4
8
|
def content_class
|
5
9
|
content.instance_variable_get('@name').constantize
|
6
10
|
end
|
@@ -8,12 +8,6 @@ module VerifiedDouble
|
|
8
8
|
BooleanValue.new(content)
|
9
9
|
elsif content.is_a?(RSpec::Mocks::Mock)
|
10
10
|
RspecDoubleValue.new(content)
|
11
|
-
elsif content.respond_to?(:doubled_class)
|
12
|
-
if content.class_double?
|
13
|
-
RecordingDoubleClassValue.new(content)
|
14
|
-
else
|
15
|
-
InstanceDoubleValue.new(content)
|
16
|
-
end
|
17
11
|
elsif content.is_a?(Module)
|
18
12
|
ClassValue.new(content)
|
19
13
|
else
|
@@ -0,0 +1,13 @@
|
|
1
|
+
module VerifiedDouble
|
2
|
+
class RecordedMethodSignatureRegistry < Array
|
3
|
+
def add_method_signature(a_double, method)
|
4
|
+
simple_double = SimpleDouble.new(a_double)
|
5
|
+
|
6
|
+
self << RecordedMethodSignature.new(
|
7
|
+
class_name: simple_double.class_name,
|
8
|
+
method_operator: simple_double.method_operator,
|
9
|
+
method: method.to_s,
|
10
|
+
stack_frame: StackFrame.new(caller(0).detect{|line| line =~ /_spec\.rb/ }))
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
module VerifiedDouble
|
2
|
+
class SimpleDouble
|
3
|
+
attr_reader :internal
|
4
|
+
|
5
|
+
def initialize(internal)
|
6
|
+
@internal = internal
|
7
|
+
end
|
8
|
+
|
9
|
+
def class_name
|
10
|
+
class_double? ? internal.name : internal.instance_variable_get('@name')
|
11
|
+
end
|
12
|
+
|
13
|
+
def class_double?
|
14
|
+
internal.is_a?(Class)
|
15
|
+
end
|
16
|
+
|
17
|
+
def method_operator
|
18
|
+
class_double? ? '.' : '#'
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
data/lib/verified_double.rb
CHANGED
@@ -2,40 +2,40 @@ require 'active_support/core_ext/string'
|
|
2
2
|
require 'rspec/mocks'
|
3
3
|
|
4
4
|
require 'verified_double/boolean'
|
5
|
+
require 'verified_double/can_record_interactions'
|
5
6
|
require 'verified_double/matchers'
|
6
7
|
require 'verified_double/method_signature'
|
7
8
|
require 'verified_double/method_signature/value'
|
8
9
|
require 'verified_double/method_signature/instance_value'
|
9
10
|
require 'verified_double/method_signature/boolean_value'
|
10
11
|
require 'verified_double/method_signature/class_value'
|
11
|
-
require 'verified_double/method_signature/instance_double_value'
|
12
|
-
require 'verified_double/method_signature/recording_double_class_value'
|
13
12
|
require 'verified_double/method_signature/rspec_double_value'
|
14
13
|
require 'verified_double/method_signatures_report'
|
15
14
|
require 'verified_double/parse_method_signature'
|
16
15
|
require 'verified_double/recorded_method_signature'
|
17
|
-
require 'verified_double/
|
18
|
-
require 'verified_double/
|
16
|
+
require 'verified_double/recorded_method_signature_registry'
|
17
|
+
require 'verified_double/simple_double'
|
19
18
|
require 'verified_double/stack_frame'
|
20
19
|
|
21
20
|
module VerifiedDouble
|
22
21
|
extend RSpec::Mocks::ExampleMethods
|
23
22
|
|
24
|
-
def self.of_class(class_name,
|
25
|
-
|
26
|
-
|
27
|
-
registry << double
|
28
|
-
end
|
23
|
+
def self.of_class(class_name, options = {})
|
24
|
+
options[:transfer_nested_constants] = true if options[:transfer_nested_constants].nil?
|
25
|
+
VerifiedDouble.record(stub_const(class_name, Class.new, options))
|
29
26
|
end
|
30
27
|
|
31
|
-
def self.of_instance(
|
32
|
-
|
33
|
-
|
34
|
-
|
28
|
+
def self.of_instance(*args)
|
29
|
+
VerifiedDouble.record(double(*args))
|
30
|
+
end
|
31
|
+
|
32
|
+
def self.record(a_double)
|
33
|
+
a_double.extend(VerifiedDouble::CanRecordInteractions)
|
34
|
+
a_double
|
35
35
|
end
|
36
36
|
|
37
37
|
def self.registry
|
38
|
-
@registry ||=
|
38
|
+
@registry ||= RecordedMethodSignatureRegistry.new
|
39
39
|
end
|
40
40
|
|
41
41
|
def self.report_unverified_signatures(nested_example_group)
|
@@ -0,0 +1,47 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe VerifiedDouble::CanRecordInteractions do
|
4
|
+
let(:a_double){ double('Object') }
|
5
|
+
|
6
|
+
before do
|
7
|
+
a_double.extend(VerifiedDouble::CanRecordInteractions)
|
8
|
+
end
|
9
|
+
|
10
|
+
describe "#should_receive(method)" do
|
11
|
+
it "appends a new method signature with the method to the registry", verifies_contract: 'Object#mocked_fake_to_s()' do
|
12
|
+
a_double.should_receive(:mocked_fake_to_s)
|
13
|
+
expect(VerifiedDouble.registry.last.method).to eq('mocked_fake_to_s')
|
14
|
+
a_double.mocked_fake_to_s
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
describe "#stub(method)" do
|
19
|
+
it "appends a new method signature with the method to the registry", verifies_contract: 'Object#stubbed_fake_to_s()' do
|
20
|
+
a_double.stub(:stubbed_fake_to_s)
|
21
|
+
expect(VerifiedDouble.registry.last.method).to eq('stubbed_fake_to_s')
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
describe "#with(*args)" do
|
26
|
+
it "sets the args of the last method signature", verifies_contract: 'Object#fake_to_s(Symbol, Symbol)' do
|
27
|
+
a_double.should_receive(:fake_to_s).with(:arg_1, :arg_2)
|
28
|
+
|
29
|
+
expect(VerifiedDouble.registry.last.args).to be_all{|arg| arg.is_a?(VerifiedDouble::MethodSignature::Value) }
|
30
|
+
expect(VerifiedDouble.registry.last.args.map(&:content)).to eq([:arg_1, :arg_2])
|
31
|
+
|
32
|
+
a_double.fake_to_s(:arg_1, :arg_2)
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
describe "#and_return(return_value)" do
|
37
|
+
it "sets the return value of the last method signature", verifies_contract: 'Object#fake_to_s(Symbol, Symbol)=>Symbol' do
|
38
|
+
a_double.should_receive(:fake_to_s).with(:arg_1, :arg_2).and_return(:return_value)
|
39
|
+
|
40
|
+
expect(VerifiedDouble.registry.last.return_values).to have(1).return_value
|
41
|
+
expect(VerifiedDouble.registry.last.return_values.first).to be_a(VerifiedDouble::MethodSignature::Value)
|
42
|
+
expect(VerifiedDouble.registry.last.return_values.first.content).to eq(:return_value)
|
43
|
+
|
44
|
+
a_double.fake_to_s(:arg_1, :arg_2)
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
@@ -1,14 +1,25 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
3
|
describe VerifiedDouble::MethodSignature::RspecDoubleValue do
|
4
|
-
|
4
|
+
class Item
|
5
|
+
end
|
6
|
+
|
7
|
+
let(:class_name){ 'Item' }
|
8
|
+
|
9
|
+
let(:rspec_double) { double(class_name) }
|
5
10
|
subject { described_class.new(rspec_double) }
|
6
11
|
|
7
12
|
describe "#content_class" do
|
8
13
|
context "where the value is a double" do
|
9
14
|
it "is the class represented by the class_name of the recording double" do
|
10
|
-
expect(subject.content_class).to eq(
|
15
|
+
expect(subject.content_class).to eq(Item)
|
11
16
|
end
|
12
17
|
end
|
13
18
|
end
|
19
|
+
|
20
|
+
describe "#content_as_instance" do
|
21
|
+
it "is the equivalent content_as_instance of the content's class" do
|
22
|
+
expect(subject.content_as_instance).to be_a(Item)
|
23
|
+
end
|
24
|
+
end
|
14
25
|
end
|
@@ -37,18 +37,10 @@ describe VerifiedDouble::MethodSignature::Value do
|
|
37
37
|
it { expect(subject).to be_a(VerifiedDouble::MethodSignature::RspecDoubleValue) }
|
38
38
|
end
|
39
39
|
|
40
|
-
context "where content is
|
41
|
-
let(:
|
42
|
-
let(:content) { VerifiedDouble::RecordingDouble.new(class_double, class_name) }
|
40
|
+
context "where content is a class double" do
|
41
|
+
let(:content){ stub_const(class_name, Class.new, transfer_nested_constants: true) }
|
43
42
|
|
44
|
-
it { expect(subject).to be_a(VerifiedDouble::MethodSignature::
|
45
|
-
end
|
46
|
-
|
47
|
-
context "where content is an instance recording double" do
|
48
|
-
let(:some_instance_double){ double('Dummy') }
|
49
|
-
let(:content) { VerifiedDouble::RecordingDouble.new(some_instance_double, class_name) }
|
50
|
-
|
51
|
-
it { expect(subject).to be_a(VerifiedDouble::MethodSignature::InstanceDoubleValue) }
|
43
|
+
it { expect(subject).to be_a(VerifiedDouble::MethodSignature::ClassValue) }
|
52
44
|
end
|
53
45
|
|
54
46
|
context "where content is an instance" do
|
@@ -61,15 +53,6 @@ describe VerifiedDouble::MethodSignature::Value do
|
|
61
53
|
describe "#content_class" do
|
62
54
|
subject { method_signature_value.content_class }
|
63
55
|
|
64
|
-
context "where the value is recording double" do
|
65
|
-
let(:recording_double){ VerifiedDouble.of_instance('Object') }
|
66
|
-
let(:method_signature_value) { described_class.new(recording_double) }
|
67
|
-
|
68
|
-
it "is the class represented by the class_name of the recording double" do
|
69
|
-
expect(subject).to eq(Object)
|
70
|
-
end
|
71
|
-
end
|
72
|
-
|
73
56
|
context "where the value is not true or false" do
|
74
57
|
let(:method_signature_value) { described_class.new(1) }
|
75
58
|
it "is the class of the value" do
|
@@ -9,42 +9,31 @@ describe VerifiedDouble::MethodSignaturesReport do
|
|
9
9
|
|
10
10
|
describe "#set_registered_signatures", verifies_contract: 'VerifiedDouble::MethodSignaturesReport#set_registered_signatures()=>VerifiedDouble::MethodSignaturesReport' do
|
11
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
12
|
let(:method_signature_1) {
|
21
13
|
VerifiedDouble::MethodSignature.new(class_name: 'Object', method_operator: '#', method: 'to_s') }
|
22
14
|
|
23
15
|
let(:method_signature_2) {
|
24
16
|
VerifiedDouble::MethodSignature.new(class_name: 'Object', method_operator: '#', method: 'inspect') }
|
25
17
|
|
26
|
-
let(:verified_double_module){
|
18
|
+
let(:verified_double_module){
|
19
|
+
stub_const('VerifiedDouble', Class.new, transfer_nested_constants: true) }
|
27
20
|
|
28
|
-
context "with multiple
|
29
|
-
it "
|
21
|
+
context "with multiple signatures in the registry" do
|
22
|
+
it "sets the signatures from the registry" do
|
30
23
|
verified_double_module
|
31
24
|
.should_receive(:registry)
|
32
|
-
.and_return([
|
25
|
+
.and_return([method_signature_1, method_signature_2])
|
33
26
|
|
34
|
-
expect(subject.set_registered_signatures.registered_signatures).to eq(
|
27
|
+
expect(subject.set_registered_signatures.registered_signatures.to_a).to eq(
|
35
28
|
[method_signature_1, method_signature_2])
|
36
29
|
end
|
37
30
|
end
|
38
31
|
|
39
|
-
context "with
|
40
|
-
let(:recording_double_2) {
|
41
|
-
double('VerifiedDouble::RecordingDouble',
|
42
|
-
method_signatures: [method_signature_1]) }
|
43
|
-
|
32
|
+
context "with duplicate signatures" do
|
44
33
|
it "returns distinct method signatures" do
|
45
34
|
verified_double_module
|
46
35
|
.should_receive(:registry)
|
47
|
-
.and_return([
|
36
|
+
.and_return([method_signature_1, method_signature_1])
|
48
37
|
|
49
38
|
expect(subject.set_registered_signatures.registered_signatures).to eq([method_signature_1])
|
50
39
|
end
|
@@ -187,7 +176,7 @@ describe VerifiedDouble::MethodSignaturesReport do
|
|
187
176
|
|
188
177
|
describe "#set_verified_signatures_from_matchers", verifies_contract: 'VerifiedDouble::MethodSignaturesReport#set_verified_signatures_from_matchers()=>VerifiedDouble::MethodSignaturesReport' do
|
189
178
|
let(:verified_double_module){
|
190
|
-
|
179
|
+
stub_const('VerifiedDouble', Class.new, transfer_nested_constants: true) }
|
191
180
|
|
192
181
|
let(:method_signature) { VerifiedDouble::MethodSignature.new }
|
193
182
|
|
@@ -0,0 +1,27 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe VerifiedDouble::RecordedMethodSignatureRegistry do
|
4
|
+
describe "#add_method_signature(a_double, method)" do
|
5
|
+
let(:class_name){ 'Object' }
|
6
|
+
let(:a_double){ double(class_name) }
|
7
|
+
let(:method){ :fake_to_s }
|
8
|
+
|
9
|
+
it "adds a method signture matching the method to itself" do
|
10
|
+
expect(subject).to be_empty
|
11
|
+
|
12
|
+
subject.add_method_signature(a_double, method)
|
13
|
+
|
14
|
+
expect(subject).to have(1).method_signature
|
15
|
+
method_signature = subject[0]
|
16
|
+
expect(method_signature.class_name).to eq(class_name)
|
17
|
+
expect(method_signature.method_operator).to eq('#')
|
18
|
+
expect(method_signature.method).to eq(method.to_s)
|
19
|
+
end
|
20
|
+
|
21
|
+
it "records the stack frames of the double's caller" do
|
22
|
+
subject.add_method_signature(a_double, method)
|
23
|
+
expect(subject.first.stack_frame.to_s)
|
24
|
+
.to include("./spec/verified_double/recorded_method_signature_registry_spec.rb")
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
@@ -0,0 +1,57 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe VerifiedDouble::SimpleDouble do
|
4
|
+
class Dummy
|
5
|
+
end
|
6
|
+
|
7
|
+
let(:class_name) { 'Dummy' }
|
8
|
+
let(:some_instance_double) { double(class_name) }
|
9
|
+
let(:some_class_double) { stub_const(class_name, Class.new) }
|
10
|
+
|
11
|
+
let(:simple_instance_double) { described_class.new(some_instance_double) }
|
12
|
+
let(:simple_class_double) { described_class.new(some_class_double) }
|
13
|
+
|
14
|
+
describe "#initialize" do
|
15
|
+
it "requires a double" do
|
16
|
+
expect(simple_instance_double.internal).to eq(some_instance_double)
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
describe "#class_name" do
|
21
|
+
context "where the internal double is a double" do
|
22
|
+
it "is the name of the class represented by the double" do
|
23
|
+
expect(simple_instance_double.class_name).to eq(class_name)
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
context "where the internal double is a stub const" do
|
28
|
+
it "is the name of the class represented by the class double" do
|
29
|
+
expect(simple_class_double.class_name).to eq(class_name)
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
describe "#class_double?" do
|
35
|
+
it "should be true if the internal double is a class double" do
|
36
|
+
expect(simple_instance_double).to_not be_class_double
|
37
|
+
end
|
38
|
+
|
39
|
+
it "should be false if the internal double is not an class double" do
|
40
|
+
expect(simple_class_double).to be_class_double
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
describe "#method_operator" do
|
45
|
+
context "when the simple_instance_double wraps an instance double" do
|
46
|
+
it "is #" do
|
47
|
+
expect(simple_instance_double.method_operator).to eq("#")
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
context "when the simple_instance_double wraps a class double" do
|
52
|
+
it "is '.'" do
|
53
|
+
expect(simple_class_double.method_operator).to eq(".")
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
@@ -3,9 +3,9 @@ require 'verified_double'
|
|
3
3
|
|
4
4
|
describe VerifiedDouble do
|
5
5
|
describe ".registry" do
|
6
|
-
it "is
|
6
|
+
it "is an RecordedMethodSignatureRegistry", verifies_contract: 'VerifiedDouble.registry()=>RecordedMethodSignatureRegistry' do
|
7
7
|
registry = VerifiedDouble.registry
|
8
|
-
expect(registry).to be_an(
|
8
|
+
expect(registry).to be_an(described_class::RecordedMethodSignatureRegistry)
|
9
9
|
end
|
10
10
|
|
11
11
|
it "is memoized" do
|
@@ -29,15 +29,14 @@ describe VerifiedDouble do
|
|
29
29
|
|
30
30
|
let(:subject) { described_class.of_instance(class_name) }
|
31
31
|
|
32
|
-
it "
|
33
|
-
|
34
|
-
expect(subject).
|
35
|
-
expect(subject.class_name).to eq(class_name)
|
32
|
+
it "extends the double with VerifiedDouble::CanRecordInteractions" do
|
33
|
+
subject = described_class.of_instance(class_name)
|
34
|
+
expect(subject).to be_a(VerifiedDouble::CanRecordInteractions)
|
36
35
|
end
|
37
36
|
|
38
|
-
it "
|
39
|
-
|
40
|
-
expect(
|
37
|
+
it "returns the double" do
|
38
|
+
subject = described_class.of_instance(class_name)
|
39
|
+
expect(subject).to be_a(RSpec::Mocks::Mock)
|
41
40
|
end
|
42
41
|
|
43
42
|
context "with method_stubs hash", verifies_contract: 'Object#some_method()=>Symbol' do
|
@@ -57,27 +56,14 @@ describe VerifiedDouble do
|
|
57
56
|
|
58
57
|
let(:subject) { described_class.of_class(class_name) }
|
59
58
|
|
60
|
-
it "
|
61
|
-
|
62
|
-
expect(
|
63
|
-
expect(subject.double).to be_a(Module)
|
64
|
-
expect(subject.class_name).to eq(class_name)
|
59
|
+
it "extends the double with VerifiedDouble::CanRecordInteractions" do
|
60
|
+
the_double = subject
|
61
|
+
expect(the_double).to be_a(VerifiedDouble::CanRecordInteractions)
|
65
62
|
end
|
66
63
|
|
67
|
-
it "
|
68
|
-
|
69
|
-
expect(
|
70
|
-
end
|
71
|
-
|
72
|
-
context "with methods hash", verifies_contract: 'Object.some_method()=>Symbol' do
|
73
|
-
let(:stubbed_method){ :some_method }
|
74
|
-
let(:assumed_output){ :some_output }
|
75
|
-
|
76
|
-
subject { described_class.of_class(class_name, some_method: assumed_output) }
|
77
|
-
|
78
|
-
it "stubs the methods of the class" do
|
79
|
-
expect(subject.send(stubbed_method)).to eq(assumed_output)
|
80
|
-
end
|
64
|
+
it "returns the double" do
|
65
|
+
subject = described_class.of_class(class_name)
|
66
|
+
expect(subject).to eq(class_name.constantize)
|
81
67
|
end
|
82
68
|
end
|
83
69
|
|
@@ -112,4 +98,17 @@ describe VerifiedDouble do
|
|
112
98
|
described_class.report_unverified_signatures(nested_example_group)
|
113
99
|
end
|
114
100
|
end
|
101
|
+
|
102
|
+
describe ".record(double)" do
|
103
|
+
let(:the_double){ double }
|
104
|
+
|
105
|
+
it "extends the double with VerifiedDouble::CanRecordInteractions" do
|
106
|
+
described_class.record(the_double)
|
107
|
+
expect(the_double).to be_a(VerifiedDouble::CanRecordInteractions)
|
108
|
+
end
|
109
|
+
|
110
|
+
it "returns the double" do
|
111
|
+
expect(described_class.record(the_double)).to eq(the_double)
|
112
|
+
end
|
113
|
+
end
|
115
114
|
end
|
metadata
CHANGED
@@ -2,14 +2,14 @@
|
|
2
2
|
name: verified_double
|
3
3
|
version: !ruby/object:Gem::Version
|
4
4
|
prerelease:
|
5
|
-
version: 0.
|
5
|
+
version: 0.3.0
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
8
8
|
- George Mendoza
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2013-
|
12
|
+
date: 2013-07-19 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
type: :runtime
|
@@ -116,36 +116,35 @@ files:
|
|
116
116
|
- features/verified_stubs.feature
|
117
117
|
- lib/verified_double.rb
|
118
118
|
- lib/verified_double/boolean.rb
|
119
|
+
- lib/verified_double/can_record_interactions.rb
|
119
120
|
- lib/verified_double/matchers.rb
|
120
121
|
- lib/verified_double/method_signature.rb
|
121
122
|
- lib/verified_double/method_signature/boolean_value.rb
|
122
123
|
- lib/verified_double/method_signature/class_value.rb
|
123
|
-
- lib/verified_double/method_signature/instance_double_value.rb
|
124
124
|
- lib/verified_double/method_signature/instance_value.rb
|
125
|
-
- lib/verified_double/method_signature/recording_double_class_value.rb
|
126
125
|
- lib/verified_double/method_signature/rspec_double_value.rb
|
127
126
|
- lib/verified_double/method_signature/value.rb
|
128
127
|
- lib/verified_double/method_signatures_report.rb
|
129
128
|
- lib/verified_double/parse_method_signature.rb
|
130
129
|
- lib/verified_double/recorded_method_signature.rb
|
131
|
-
- lib/verified_double/
|
132
|
-
- lib/verified_double/
|
130
|
+
- lib/verified_double/recorded_method_signature_registry.rb
|
131
|
+
- lib/verified_double/simple_double.rb
|
133
132
|
- lib/verified_double/stack_frame.rb
|
134
133
|
- lib/verified_double/version.rb
|
135
134
|
- spec/spec_helper.rb
|
135
|
+
- spec/verified_double/can_record_interactions_spec.rb
|
136
136
|
- spec/verified_double/matchers_spec.rb
|
137
137
|
- spec/verified_double/method_signature/boolean_value_spec.rb
|
138
138
|
- spec/verified_double/method_signature/class_value_spec.rb
|
139
|
-
- spec/verified_double/method_signature/instance_double_value_spec.rb
|
140
139
|
- spec/verified_double/method_signature/instance_value_spec.rb
|
141
|
-
- spec/verified_double/method_signature/recording_double_class_value_spec.rb
|
142
140
|
- spec/verified_double/method_signature/rspec_double_spec.rb
|
143
141
|
- spec/verified_double/method_signature/value_spec.rb
|
144
142
|
- spec/verified_double/method_signature_spec.rb
|
145
143
|
- spec/verified_double/method_signatures_report_spec.rb
|
146
144
|
- spec/verified_double/parse_method_signature_spec.rb
|
145
|
+
- spec/verified_double/recorded_method_signature_registry_spec.rb
|
147
146
|
- spec/verified_double/recorded_method_signature_spec.rb
|
148
|
-
- spec/verified_double/
|
147
|
+
- spec/verified_double/simple_double_spec.rb
|
149
148
|
- spec/verified_double/stack_frame_spec.rb
|
150
149
|
- spec/verified_double_spec.rb
|
151
150
|
- verified_double.gemspec
|
@@ -185,19 +184,19 @@ test_files:
|
|
185
184
|
- features/verified_mocks.feature
|
186
185
|
- features/verified_stubs.feature
|
187
186
|
- spec/spec_helper.rb
|
187
|
+
- spec/verified_double/can_record_interactions_spec.rb
|
188
188
|
- spec/verified_double/matchers_spec.rb
|
189
189
|
- spec/verified_double/method_signature/boolean_value_spec.rb
|
190
190
|
- spec/verified_double/method_signature/class_value_spec.rb
|
191
|
-
- spec/verified_double/method_signature/instance_double_value_spec.rb
|
192
191
|
- spec/verified_double/method_signature/instance_value_spec.rb
|
193
|
-
- spec/verified_double/method_signature/recording_double_class_value_spec.rb
|
194
192
|
- spec/verified_double/method_signature/rspec_double_spec.rb
|
195
193
|
- spec/verified_double/method_signature/value_spec.rb
|
196
194
|
- spec/verified_double/method_signature_spec.rb
|
197
195
|
- spec/verified_double/method_signatures_report_spec.rb
|
198
196
|
- spec/verified_double/parse_method_signature_spec.rb
|
197
|
+
- spec/verified_double/recorded_method_signature_registry_spec.rb
|
199
198
|
- spec/verified_double/recorded_method_signature_spec.rb
|
200
|
-
- spec/verified_double/
|
199
|
+
- spec/verified_double/simple_double_spec.rb
|
201
200
|
- spec/verified_double/stack_frame_spec.rb
|
202
201
|
- spec/verified_double_spec.rb
|
203
202
|
has_rdoc:
|
@@ -1,92 +0,0 @@
|
|
1
|
-
require 'delegate'
|
2
|
-
require 'verified_double/relays_to_internal_double_returning_self'
|
3
|
-
|
4
|
-
module VerifiedDouble
|
5
|
-
class RecordingDouble < ::SimpleDelegator
|
6
|
-
extend VerifiedDouble::RelaysToInternalDoubleReturningSelf
|
7
|
-
|
8
|
-
relays_to_internal_double_returning_self :any_number_of_times, :and_raise,
|
9
|
-
:and_throw, :at_least, :at_most, :exactly, :once, :twice
|
10
|
-
|
11
|
-
attr_reader :class_name
|
12
|
-
|
13
|
-
def initialize(double, class_name, method_stubs={})
|
14
|
-
@double = double
|
15
|
-
@class_name = class_name
|
16
|
-
|
17
|
-
super(@double)
|
18
|
-
method_stubs.each do |method, output|
|
19
|
-
self.stub(method).and_return(output)
|
20
|
-
end
|
21
|
-
end
|
22
|
-
|
23
|
-
def and_return(return_value)
|
24
|
-
self.method_signatures.last.return_values = [MethodSignature::Value.from(return_value)]
|
25
|
-
@double_call.and_return(return_value)
|
26
|
-
self
|
27
|
-
end
|
28
|
-
|
29
|
-
def class
|
30
|
-
class_double? ? Class : doubled_class
|
31
|
-
end
|
32
|
-
|
33
|
-
def class_double?
|
34
|
-
! double.is_a?(RSpec::Mocks::Mock)
|
35
|
-
end
|
36
|
-
|
37
|
-
def double
|
38
|
-
__getobj__
|
39
|
-
end
|
40
|
-
|
41
|
-
def doubled_class
|
42
|
-
class_name.constantize
|
43
|
-
end
|
44
|
-
|
45
|
-
def inspect
|
46
|
-
to_s
|
47
|
-
end
|
48
|
-
|
49
|
-
def method_operator
|
50
|
-
class_double? ? '.' : '#'
|
51
|
-
end
|
52
|
-
|
53
|
-
def method_signatures
|
54
|
-
@method_signatures ||= []
|
55
|
-
end
|
56
|
-
|
57
|
-
def should_receive(method)
|
58
|
-
add_method_signature method
|
59
|
-
@double_call = double.should_receive(method)
|
60
|
-
self
|
61
|
-
end
|
62
|
-
|
63
|
-
def stub(method)
|
64
|
-
add_method_signature method
|
65
|
-
@double_call = double.stub(method)
|
66
|
-
self
|
67
|
-
end
|
68
|
-
|
69
|
-
def to_s
|
70
|
-
"#{VerifiedDouble}.of_#{class_double? ? 'class' : 'instance' }('#{class_name}')"
|
71
|
-
end
|
72
|
-
|
73
|
-
def with(*args)
|
74
|
-
self.method_signatures.last.args =
|
75
|
-
args.map{|arg| MethodSignature::Value.from(arg) }
|
76
|
-
@double_call.with(*args)
|
77
|
-
self
|
78
|
-
end
|
79
|
-
|
80
|
-
private
|
81
|
-
|
82
|
-
def add_method_signature(method)
|
83
|
-
method_signature = RecordedMethodSignature.new(
|
84
|
-
class_name: class_name,
|
85
|
-
method_operator: method_operator,
|
86
|
-
method: method.to_s,
|
87
|
-
stack_frame: StackFrame.new(caller(2)[0]))
|
88
|
-
|
89
|
-
self.method_signatures << method_signature
|
90
|
-
end
|
91
|
-
end
|
92
|
-
end
|
@@ -1,12 +0,0 @@
|
|
1
|
-
module VerifiedDouble
|
2
|
-
module RelaysToInternalDoubleReturningSelf
|
3
|
-
def relays_to_internal_double_returning_self(*methods)
|
4
|
-
methods.each do |method|
|
5
|
-
define_method method do |*args|
|
6
|
-
@double_call.send(method, *args)
|
7
|
-
self
|
8
|
-
end
|
9
|
-
end
|
10
|
-
end
|
11
|
-
end
|
12
|
-
end
|
@@ -1,17 +0,0 @@
|
|
1
|
-
require 'spec_helper'
|
2
|
-
|
3
|
-
describe VerifiedDouble::MethodSignature::InstanceDoubleValue do
|
4
|
-
class Item
|
5
|
-
end
|
6
|
-
|
7
|
-
let(:class_name){ 'Item' }
|
8
|
-
let(:some_instance_double){ double(class_name) }
|
9
|
-
let(:recording_instance_double) { VerifiedDouble::RecordingDouble.new(some_instance_double, class_name) }
|
10
|
-
subject { described_class.new(recording_instance_double) }
|
11
|
-
|
12
|
-
describe "#content_as_instance" do
|
13
|
-
it "is the equivalent content_as_instance of the content's class" do
|
14
|
-
expect(subject.content_as_instance).to be_a(Item)
|
15
|
-
end
|
16
|
-
end
|
17
|
-
end
|
@@ -1,23 +0,0 @@
|
|
1
|
-
require 'spec_helper'
|
2
|
-
|
3
|
-
describe VerifiedDouble::MethodSignature::RecordingDoubleClassValue do
|
4
|
-
class Dummy
|
5
|
-
end
|
6
|
-
|
7
|
-
let(:class_name) { 'Dummy' }
|
8
|
-
let(:some_class_double) { stub_const(class_name, Class.new) }
|
9
|
-
let(:recording_class_double) { VerifiedDouble::RecordingDouble.new(some_class_double, class_name) }
|
10
|
-
|
11
|
-
subject { described_class.new(recording_class_double) }
|
12
|
-
|
13
|
-
describe "#belongs_to(other)" do
|
14
|
-
context "where the doubled class of the recording double belongs to the other value" do
|
15
|
-
it { expect(subject.belongs_to?(VerifiedDouble::MethodSignature::ClassValue.new(Dummy))).to be_true }
|
16
|
-
end
|
17
|
-
|
18
|
-
context "where the doubled class of the recording double does not belong to the other value" do
|
19
|
-
it { expect(subject.belongs_to?(VerifiedDouble::MethodSignature::ClassValue.new(Object))).to be_false }
|
20
|
-
end
|
21
|
-
end
|
22
|
-
|
23
|
-
end
|
@@ -1,236 +0,0 @@
|
|
1
|
-
require 'spec_helper'
|
2
|
-
require "verified_double/recording_double"
|
3
|
-
|
4
|
-
describe VerifiedDouble::RecordingDouble do
|
5
|
-
class Dummy
|
6
|
-
end
|
7
|
-
|
8
|
-
let(:class_name) { 'Dummy' }
|
9
|
-
let(:some_instance_double) { double(class_name) }
|
10
|
-
let(:some_class_double) { stub_const(class_name, Class.new) }
|
11
|
-
|
12
|
-
let(:recording_instance_double) { VerifiedDouble::RecordingDouble.new(some_instance_double, class_name) }
|
13
|
-
let(:recording_class_double) { VerifiedDouble::RecordingDouble.new(some_class_double, class_name) }
|
14
|
-
|
15
|
-
describe "#initialize" do
|
16
|
-
it "requires a double" do
|
17
|
-
expect(recording_instance_double.double).to eq(some_instance_double)
|
18
|
-
end
|
19
|
-
|
20
|
-
context "with method_stubs hash" do
|
21
|
-
let(:stubbed_method){ :some_method }
|
22
|
-
let(:assumed_output){ :some_output }
|
23
|
-
|
24
|
-
let(:recording_instance_double) {
|
25
|
-
VerifiedDouble::RecordingDouble.new(
|
26
|
-
some_instance_double,
|
27
|
-
class_name,
|
28
|
-
some_method: assumed_output) }
|
29
|
-
|
30
|
-
it "stubs the methods of the instance" do
|
31
|
-
expect(recording_instance_double.send(stubbed_method)).to eq(assumed_output)
|
32
|
-
end
|
33
|
-
end
|
34
|
-
end
|
35
|
-
|
36
|
-
it "delegates all unknown calls to its internal double" do
|
37
|
-
some_instance_double.should_receive(:do_something)
|
38
|
-
recording_instance_double.do_something
|
39
|
-
end
|
40
|
-
|
41
|
-
describe "#to_s" do
|
42
|
-
context "where the internal double is a class" do
|
43
|
-
it { expect(recording_class_double.to_s).to eq("VerifiedDouble.of_class('#{class_name}')") }
|
44
|
-
end
|
45
|
-
|
46
|
-
context "where the internal double is an instance" do
|
47
|
-
let(:some_instance_double) { double(class_name) }
|
48
|
-
|
49
|
-
it { expect(recording_instance_double.to_s).to eq("VerifiedDouble.of_instance('#{class_name}')") }
|
50
|
-
end
|
51
|
-
end
|
52
|
-
|
53
|
-
describe "#inspect" do
|
54
|
-
it "is human-readable representation of the recording double, NOT the internal double" do
|
55
|
-
expect(recording_instance_double.inspect).to match("VerifiedDouble")
|
56
|
-
end
|
57
|
-
end
|
58
|
-
|
59
|
-
describe "#class_name" do
|
60
|
-
context "where the internal double is a double" do
|
61
|
-
it "is the name of the class represented by the double" do
|
62
|
-
expect(recording_instance_double.class_name).to eq(class_name)
|
63
|
-
end
|
64
|
-
end
|
65
|
-
|
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
|
-
expect(recording_class_double.class_name).to eq(class_name)
|
69
|
-
end
|
70
|
-
end
|
71
|
-
end
|
72
|
-
|
73
|
-
describe "#class_double?" do
|
74
|
-
it "should be true if the internal double is a class double" do
|
75
|
-
expect(recording_instance_double).to_not be_class_double
|
76
|
-
end
|
77
|
-
|
78
|
-
it "should be false if the internal double is not an class double" do
|
79
|
-
expect(recording_class_double).to be_class_double
|
80
|
-
end
|
81
|
-
end
|
82
|
-
|
83
|
-
describe "#method_operator" do
|
84
|
-
context "when the recording_instance_double wraps an instance double" do
|
85
|
-
it "is #" do
|
86
|
-
expect(recording_instance_double.method_operator).to eq("#")
|
87
|
-
end
|
88
|
-
end
|
89
|
-
|
90
|
-
context "when the recording_instance_double wraps a class double" do
|
91
|
-
it "is '.'" do
|
92
|
-
expect(recording_class_double.method_operator).to eq(".")
|
93
|
-
end
|
94
|
-
end
|
95
|
-
end
|
96
|
-
|
97
|
-
describe "#should_receive(method)" do
|
98
|
-
it "appends a new method signature with the method to the recording double's method signatures" do
|
99
|
-
expect(recording_instance_double.method_signatures).to be_empty
|
100
|
-
|
101
|
-
recording_instance_double.should_receive(:fake_to_s)
|
102
|
-
recording_instance_double.should_receive(:fake_inspect)
|
103
|
-
|
104
|
-
expect(recording_instance_double.method_signatures.map(&:method)).to eq(['fake_to_s', 'fake_inspect'])
|
105
|
-
|
106
|
-
recording_instance_double.fake_to_s
|
107
|
-
recording_instance_double.fake_inspect
|
108
|
-
end
|
109
|
-
|
110
|
-
it "records the stack frames of the recording double's caller" do
|
111
|
-
recording_instance_double.should_receive(:fake_to_s)
|
112
|
-
recording_instance_double.fake_to_s
|
113
|
-
expect(recording_instance_double.method_signatures.first.stack_frame.to_s)
|
114
|
-
.to include("spec/verified_double/recording_double_spec.rb")
|
115
|
-
end
|
116
|
-
end
|
117
|
-
|
118
|
-
describe "#stub(method)" do
|
119
|
-
it "appends a new method signature with the method to the recording double's method signatures" do
|
120
|
-
expect(recording_instance_double.method_signatures).to be_empty
|
121
|
-
|
122
|
-
recording_instance_double.stub(:fake_to_s)
|
123
|
-
recording_instance_double.stub(:fake_inspect)
|
124
|
-
|
125
|
-
expect(recording_instance_double.method_signatures.map(&:method)).to eq(['fake_to_s', 'fake_inspect'])
|
126
|
-
end
|
127
|
-
|
128
|
-
it "records the stack frames of the recording double's caller" do
|
129
|
-
recording_instance_double.stub(:fake_to_s)
|
130
|
-
|
131
|
-
expect(recording_instance_double.method_signatures.first.stack_frame.to_s)
|
132
|
-
.to include("spec/verified_double/recording_double_spec.rb")
|
133
|
-
end
|
134
|
-
end
|
135
|
-
|
136
|
-
describe "#with(*args)" do
|
137
|
-
it "sets the args of the last method signature" do
|
138
|
-
recording_instance_double.should_receive(:fake_to_s).with(:arg_1, :arg_2)
|
139
|
-
|
140
|
-
expect(recording_instance_double.method_signatures[0].args).to be_all{|arg| arg.is_a?(VerifiedDouble::MethodSignature::Value) }
|
141
|
-
expect(recording_instance_double.method_signatures[0].args.map(&:content)).to eq([:arg_1, :arg_2])
|
142
|
-
|
143
|
-
recording_instance_double.fake_to_s(:arg_1, :arg_2)
|
144
|
-
end
|
145
|
-
end
|
146
|
-
|
147
|
-
describe "#and_return(return_value)" do
|
148
|
-
it "sets the return value of the last method signature" do
|
149
|
-
recording_instance_double.should_receive(:fake_to_s).with(:arg_1, :arg_2).and_return(:return_value)
|
150
|
-
|
151
|
-
return_values = recording_instance_double.method_signatures[0].return_values
|
152
|
-
expect(return_values).to have(1).return_value
|
153
|
-
expect(return_values.first).to be_a(VerifiedDouble::MethodSignature::Value)
|
154
|
-
expect(return_values.first.content).to eq(:return_value)
|
155
|
-
|
156
|
-
recording_instance_double.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(recording_instance_double.should_receive(:fake_to_s).once).to be_a(described_class)
|
163
|
-
recording_instance_double.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(recording_instance_double.should_receive(:fake_to_s).twice).to be_a(described_class)
|
170
|
-
recording_instance_double.fake_to_s
|
171
|
-
recording_instance_double.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(recording_instance_double.should_receive(:fake_to_s).at_least(:once)).to be_a(described_class)
|
178
|
-
recording_instance_double.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(recording_instance_double.should_receive(:fake_to_s).at_most(:once)).to be_a(described_class)
|
185
|
-
recording_instance_double.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(recording_instance_double.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(recording_instance_double.should_receive(:fake_to_s).and_raise(some_error)).to be_a(described_class)
|
200
|
-
expect { recording_instance_double.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(recording_instance_double.should_receive(:fake_to_s).and_throw(:some_error)).to be_a(described_class)
|
207
|
-
expect { recording_instance_double.fake_to_s }.to throw_symbol(:some_error)
|
208
|
-
end
|
209
|
-
end
|
210
|
-
|
211
|
-
describe "#class" do
|
212
|
-
context "where the internal double is an instance" do
|
213
|
-
it "is the constant matching the class name" do
|
214
|
-
expect(recording_instance_double.class).to eq(Dummy)
|
215
|
-
end
|
216
|
-
end
|
217
|
-
|
218
|
-
context "where the internal double is a class" do
|
219
|
-
it { expect(recording_class_double.class).to eq(Class) }
|
220
|
-
end
|
221
|
-
end
|
222
|
-
|
223
|
-
describe "#doubled_class" do
|
224
|
-
context "where the internal double is an instance" do
|
225
|
-
it "is the constant matching the class name" do
|
226
|
-
expect(recording_instance_double.doubled_class).to eq(Dummy)
|
227
|
-
end
|
228
|
-
end
|
229
|
-
|
230
|
-
context "where the internal double is a class" do
|
231
|
-
it "is the constant matching the class name" do
|
232
|
-
expect(recording_class_double.doubled_class).to eq(Dummy)
|
233
|
-
end
|
234
|
-
end
|
235
|
-
end
|
236
|
-
end
|