verified_double 0.2.0 → 0.3.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 +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
|