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.
Files changed (25) hide show
  1. data/CHANGELOG.markdown +5 -0
  2. data/features/CHANGELOG.markdown +5 -0
  3. data/lib/verified_double/can_record_interactions.rb +24 -0
  4. data/lib/verified_double/method_signature/rspec_double_value.rb +5 -1
  5. data/lib/verified_double/method_signature/value.rb +0 -6
  6. data/lib/verified_double/method_signatures_report.rb +1 -1
  7. data/lib/verified_double/recorded_method_signature_registry.rb +13 -0
  8. data/lib/verified_double/simple_double.rb +21 -0
  9. data/lib/verified_double/version.rb +1 -1
  10. data/lib/verified_double.rb +14 -14
  11. data/spec/verified_double/can_record_interactions_spec.rb +47 -0
  12. data/spec/verified_double/method_signature/rspec_double_spec.rb +13 -2
  13. data/spec/verified_double/method_signature/value_spec.rb +3 -20
  14. data/spec/verified_double/method_signatures_report_spec.rb +9 -20
  15. data/spec/verified_double/recorded_method_signature_registry_spec.rb +27 -0
  16. data/spec/verified_double/simple_double_spec.rb +57 -0
  17. data/spec/verified_double_spec.rb +27 -28
  18. metadata +11 -12
  19. data/lib/verified_double/method_signature/instance_double_value.rb +0 -9
  20. data/lib/verified_double/method_signature/recording_double_class_value.rb +0 -9
  21. data/lib/verified_double/recording_double.rb +0 -92
  22. data/lib/verified_double/relays_to_internal_double_returning_self.rb +0 -12
  23. data/spec/verified_double/method_signature/instance_double_value_spec.rb +0 -17
  24. data/spec/verified_double/method_signature/recording_double_class_value_spec.rb +0 -23
  25. data/spec/verified_double/recording_double_spec.rb +0 -236
data/CHANGELOG.markdown CHANGED
@@ -1,3 +1,8 @@
1
+ 0.3.0 - 2013-07-19
2
+
3
+ * [#17] Major refactor: extend RSpec doubles with VerifiedDouble recording
4
+ functionality. No more need for RecordingDouble.
5
+
1
6
  0.2.0 - 2013-06-30
2
7
  ------------------
3
8
 
@@ -1,3 +1,8 @@
1
+ 0.3.0 - 2013-07-19
2
+
3
+ * [#17] Major refactor: extend RSpec doubles with VerifiedDouble recording
4
+ functionality. No more need for RecordingDouble.
5
+
1
6
  0.2.0 - 2013-06-30
2
7
  ------------------
3
8
 
@@ -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 < InstanceDoubleValue
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
@@ -39,7 +39,7 @@ module VerifiedDouble
39
39
  end
40
40
 
41
41
  def set_registered_signatures
42
- @registered_signatures = VerifiedDouble.registry.map(&:method_signatures).flatten.uniq
42
+ @registered_signatures = VerifiedDouble.registry.uniq
43
43
  self
44
44
  end
45
45
 
@@ -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
@@ -1,3 +1,3 @@
1
1
  module VerifiedDouble
2
- VERSION = "0.2.0"
2
+ VERSION = "0.3.0"
3
3
  end
@@ -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/recording_double'
18
- require 'verified_double/relays_to_internal_double_returning_self'
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, method_stubs = {})
25
- class_double = stub_const(class_name, Class.new, transfer_nested_constants: true)
26
- RecordingDouble.new(class_double, class_name, method_stubs).tap do |double|
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(class_name, method_stubs = {})
32
- RecordingDouble.new(double(class_name), class_name, method_stubs).tap do |double|
33
- registry << double
34
- end
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
- let(:rspec_double) { double('Object') }
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(Object)
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 an class recording double" do
41
- let(:class_double){ stub_const(class_name, Class.new, transfer_nested_constants: true) }
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::RecordingDoubleClassValue) }
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){ VerifiedDouble.of_class('VerifiedDouble') }
18
+ let(:verified_double_module){
19
+ stub_const('VerifiedDouble', Class.new, transfer_nested_constants: true) }
27
20
 
28
- context "with multiple recording doubles in the registry" do
29
- it "maps and flattens the method signatures of the recording doubles" do
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([recording_double_1, recording_double_2])
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 recording doubles with duplicate signatures" do
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([recording_double_1, recording_double_2])
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
- VerifiedDouble.of_class('VerifiedDouble') }
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 a array", verifies_contract: 'VerifiedDouble.registry()=>Array' do
6
+ it "is an RecordedMethodSignatureRegistry", verifies_contract: 'VerifiedDouble.registry()=>RecordedMethodSignatureRegistry' do
7
7
  registry = VerifiedDouble.registry
8
- expect(registry).to be_an(Array)
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 "creates an instance recording double" do
33
- expect(subject).to be_a(VerifiedDouble::RecordingDouble)
34
- expect(subject).to_not be_class_double
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 "adds the double to the registry" do
39
- recording_double = subject
40
- expect(described_class.registry.last).to eq(recording_double)
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 "creates a class recording double" do
61
- expect(subject).to be_a(VerifiedDouble::RecordingDouble)
62
- expect(subject).to be_class_double
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 "adds the double to the registry" do
68
- recording_double = subject
69
- expect(described_class.registry.last).to eq(recording_double)
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.2.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-06-30 00:00:00.000000000 Z
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/recording_double.rb
132
- - lib/verified_double/relays_to_internal_double_returning_self.rb
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/recording_double_spec.rb
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/recording_double_spec.rb
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,9 +0,0 @@
1
- module VerifiedDouble
2
- class MethodSignature
3
- class InstanceDoubleValue < InstanceValue
4
- def content_as_instance
5
- Value.from(content_class).content_as_instance
6
- end
7
- end
8
- end
9
- end
@@ -1,9 +0,0 @@
1
- module VerifiedDouble
2
- class MethodSignature
3
- class RecordingDoubleClassValue < ClassValue
4
- def belongs_to?(other)
5
- Value.from(content.doubled_class).belongs_to?(other)
6
- end
7
- end
8
- end
9
- end
@@ -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