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.
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