adequack 0.0.3 → 0.0.4
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.travis.yml +4 -0
- data/CHANGELOG.md +10 -0
- data/README.md +10 -10
- data/adequack.gemspec +4 -2
- data/lib/adequack.rb +5 -2
- data/lib/adequack/integration/expect_syntax_support.rb +38 -0
- data/lib/adequack/integration/rspec_proxy.rb +37 -0
- data/lib/adequack/integration/rspec_setup.rb +3 -1
- data/lib/adequack/proxy.rb +7 -34
- data/lib/adequack/version.rb +1 -1
- data/spec/adequack_spec.rb +4 -4
- data/spec/integration/fixtures/animal.rb +24 -0
- data/spec/integration/fixtures/interfaces/animal.rb +7 -0
- data/spec/integration/fixtures/interfaces/identificationable.rb +5 -0
- data/spec/integration/fixtures/owner.rb +15 -0
- data/spec/integration/rspec/integration_spec.rb +57 -0
- data/spec/spec_helper.rb +1 -1
- metadata +46 -7
- data/spec/integration_spec.rb +0 -64
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: cb0c0c9b3407f1c1dae6c369e477b99d01dca4d2
|
4
|
+
data.tar.gz: 2ff4f234e3298d02d5315aa2127ace31024bf60d
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 4fbada0961dff547e86707db6be7de200fb23aa69f48ee0e75cc782b25e51605e4e4a7910673fa5a462778537a32c3538b040413d4f8fa3954f657210f3d05e3
|
7
|
+
data.tar.gz: e9a43c8b583c386929e6c64221ad2f5ad33343f12d82a63182b6bf8806e3ca8b40c2d0a7a97811783a3766fc7905619ffa973a5f534881287ff546921ac9b869
|
data/.travis.yml
ADDED
data/CHANGELOG.md
CHANGED
@@ -1,3 +1,13 @@
|
|
1
|
+
# Version 0.0.4 (unreleased)
|
2
|
+
|
3
|
+
* `behavioral_double` now supports multiple interfaces
|
4
|
+
|
5
|
+
# Version 0.0.3
|
6
|
+
|
7
|
+
* Ruby 2.0 key arguments support
|
8
|
+
|
9
|
+
* New descriptive helper names: `behave_like` and `behavioral_double`
|
10
|
+
|
1
11
|
# Version 0.0.2
|
2
12
|
|
3
13
|
* Class methods now counted too when trying to stub them
|
data/README.md
CHANGED
@@ -1,12 +1,12 @@
|
|
1
1
|
# Adequack
|
2
2
|
|
3
3
|
[![Gem Version](https://badge.fury.io/rb/adequack.png)](http://badge.fury.io/rb/adequack)
|
4
|
-
[![Build Status](https://travis-ci.org/
|
4
|
+
[![Build Status](https://travis-ci.org/somebody32/adequack.png?branch=master)](https://travis-ci.org/Somebody32/adequack)
|
5
5
|
[![Dependency Status](https://gemnasium.com/Somebody32/adequack.png)](https://gemnasium.com/Somebody32/adequack)
|
6
6
|
|
7
|
-
Everyone likes isolation testing. And when you do it
|
8
|
-
But the main concern when you use this approach is that
|
9
|
-
real objects.
|
7
|
+
Everyone likes isolation testing. And when you do it, you are stubbing and mocking a lot.
|
8
|
+
But the main concern when you use this approach is that your stubs will be out of sync with the
|
9
|
+
real objects.
|
10
10
|
Adequack addresses this issue.
|
11
11
|
|
12
12
|
## Problem 1. Missing methods
|
@@ -85,11 +85,11 @@ end
|
|
85
85
|
|
86
86
|
describe Dog do
|
87
87
|
subject { described_class }
|
88
|
-
it { should
|
88
|
+
it { should behave_like DogInterface }
|
89
89
|
end
|
90
90
|
|
91
91
|
describe Owner do
|
92
|
-
let(:dog) {
|
92
|
+
let(:dog) { behavioral_double double, DogInterface }
|
93
93
|
subject { described_class.new dog }
|
94
94
|
|
95
95
|
it "feeds animal" do
|
@@ -109,9 +109,9 @@ Finished in 0.00128 seconds
|
|
109
109
|
```
|
110
110
|
|
111
111
|
We should validate not only our mocks, but also that our core object really responds to the interface.
|
112
|
-
Use `
|
112
|
+
Use `behave_like` matcher with a core class as an argument.
|
113
113
|
|
114
|
-
And to create doubles and stubs use `
|
114
|
+
And to create doubles and stubs use `behavioral_double` helper. This will return a proxy object that
|
115
115
|
will translate all calls to the object that you'll pass first (plain `double` at the example).
|
116
116
|
|
117
117
|
Let's replay our changes again:
|
@@ -130,7 +130,7 @@ F.
|
|
130
130
|
Failures:
|
131
131
|
|
132
132
|
1) Dog
|
133
|
-
Failure/Error: it { should
|
133
|
+
Failure/Error: it { should behave_like DogInterface }
|
134
134
|
Adequack::InterfaceImplementationError:
|
135
135
|
object does not respond to 'eat_food' method
|
136
136
|
|
@@ -203,7 +203,7 @@ gem install adequack
|
|
203
203
|
|
204
204
|
and require it when you need it: `require 'adequack'`
|
205
205
|
|
206
|
-
After that your rspec tests will have `
|
206
|
+
After that your rspec tests will have `behave_like` matcher and `behavioral_double` helper.
|
207
207
|
|
208
208
|
## Usage
|
209
209
|
|
data/adequack.gemspec
CHANGED
@@ -10,7 +10,7 @@ Gem::Specification.new do |spec|
|
|
10
10
|
spec.email = ["somebody32@gmail.com"]
|
11
11
|
spec.description = %q{Be sure that your mocks are adequate}
|
12
12
|
spec.summary = %q{Be sure that your mocks are adequate}
|
13
|
-
spec.homepage = "https://github.com/
|
13
|
+
spec.homepage = "https://github.com/somebody32/adequack"
|
14
14
|
spec.license = "MIT"
|
15
15
|
|
16
16
|
spec.files = `git ls-files`.split($/)
|
@@ -18,8 +18,10 @@ Gem::Specification.new do |spec|
|
|
18
18
|
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
19
19
|
spec.require_paths = ["lib"]
|
20
20
|
|
21
|
-
spec.add_dependency "rspec", "~> 2.
|
21
|
+
spec.add_dependency "rspec", "~> 2.11"
|
22
22
|
|
23
23
|
spec.add_development_dependency "bundler", "~> 1.3"
|
24
24
|
spec.add_development_dependency "rake"
|
25
|
+
spec.add_development_dependency "rspec", "~> 2.14"
|
26
|
+
spec.add_development_dependency "pry"
|
25
27
|
end
|
data/lib/adequack.rb
CHANGED
@@ -1,7 +1,10 @@
|
|
1
1
|
require "adequack/version"
|
2
2
|
require "adequack/core"
|
3
3
|
require "adequack/proxy"
|
4
|
+
|
5
|
+
require "adequack/integration/rspec_proxy"
|
4
6
|
require "adequack/integration/rspec_setup"
|
7
|
+
require "adequack/integration/expect_syntax_support"
|
5
8
|
|
6
9
|
module Adequack
|
7
10
|
InterfaceImplementationError = Class.new(::StandardError)
|
@@ -10,7 +13,7 @@ module Adequack
|
|
10
13
|
Core.implements duck, interface
|
11
14
|
end
|
12
15
|
|
13
|
-
def self.double(core,
|
14
|
-
|
16
|
+
def self.double(core, interfaces)
|
17
|
+
RspecProxy.new core, interfaces
|
15
18
|
end
|
16
19
|
end
|
@@ -0,0 +1,38 @@
|
|
1
|
+
module RSpec
|
2
|
+
module Expectations
|
3
|
+
class ExpectationTarget
|
4
|
+
|
5
|
+
def to(matcher = nil, message = nil, &block)
|
6
|
+
matcher_message = get_affected_message(matcher)
|
7
|
+
|
8
|
+
if matcher.kind_of?(RSpec::Mocks::Matchers::HaveReceived) && @target.kind_of?(Adequack::RspecProxy)
|
9
|
+
@target = @target.instance_variable_get(:"@target")
|
10
|
+
end
|
11
|
+
|
12
|
+
if @target.kind_of?(Adequack::RspecProxy) && matcher_message
|
13
|
+
@target.send(
|
14
|
+
:check_method_existence,
|
15
|
+
matcher.instance_variable_get(:"@#{matcher_message}"))
|
16
|
+
|
17
|
+
end
|
18
|
+
|
19
|
+
prevent_operator_matchers(:to, matcher)
|
20
|
+
RSpec::Expectations::PositiveExpectationHandler
|
21
|
+
.handle_matcher(
|
22
|
+
@target,
|
23
|
+
matcher,
|
24
|
+
message,
|
25
|
+
&block
|
26
|
+
)
|
27
|
+
end
|
28
|
+
|
29
|
+
private
|
30
|
+
|
31
|
+
def get_affected_message(matcher)
|
32
|
+
if matcher.kind_of? RSpec::Mocks::Matchers::Receive
|
33
|
+
"message"
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
@@ -0,0 +1,37 @@
|
|
1
|
+
module Adequack
|
2
|
+
class RspecProxy < Proxy
|
3
|
+
|
4
|
+
def stub(message_or_hash, opts = {}, &block)
|
5
|
+
methods =
|
6
|
+
Hash === message_or_hash ? message_or_hash.keys : [message_or_hash]
|
7
|
+
|
8
|
+
methods.each { |m| check_method_existence m }
|
9
|
+
|
10
|
+
target.stub(message_or_hash, opts, &block)
|
11
|
+
end
|
12
|
+
|
13
|
+
alias_method :stub!, :stub
|
14
|
+
|
15
|
+
def stub_chain(*chain, &blk)
|
16
|
+
method =
|
17
|
+
String === chain.first ? chain.first.split(".").first : chain.first
|
18
|
+
|
19
|
+
check_method_existence method
|
20
|
+
|
21
|
+
target.stub_chain(*chain, &blk)
|
22
|
+
end
|
23
|
+
|
24
|
+
def should_receive(message, opts = {}, &block)
|
25
|
+
check_method_existence message
|
26
|
+
|
27
|
+
target.should_receive(message, opts, &block)
|
28
|
+
end
|
29
|
+
|
30
|
+
def receive(method_name, &block)
|
31
|
+
binding.pry
|
32
|
+
check_method_existence method_name
|
33
|
+
|
34
|
+
target.receive method_name, &block
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
data/lib/adequack/proxy.rb
CHANGED
@@ -1,40 +1,14 @@
|
|
1
1
|
module Adequack
|
2
2
|
class Proxy
|
3
3
|
|
4
|
-
def initialize(target,
|
4
|
+
def initialize(target, interfaces)
|
5
5
|
self.target = target
|
6
|
-
self.
|
7
|
-
end
|
8
|
-
|
9
|
-
def stub(message_or_hash, opts = {}, &block)
|
10
|
-
methods =
|
11
|
-
Hash === message_or_hash ? message_or_hash.keys : [message_or_hash]
|
12
|
-
|
13
|
-
methods.each { |m| check_method_existence m }
|
14
|
-
|
15
|
-
target.stub(message_or_hash, opts, &block)
|
16
|
-
end
|
17
|
-
|
18
|
-
alias_method :stub!, :stub
|
19
|
-
|
20
|
-
def stub_chain(*chain, &blk)
|
21
|
-
method =
|
22
|
-
String === chain.first ? chain.first.split(".").first : chain.first
|
23
|
-
|
24
|
-
check_method_existence method
|
25
|
-
|
26
|
-
target.stub_chain(*chain, &blk)
|
27
|
-
end
|
28
|
-
|
29
|
-
def should_receive(message, opts = {}, &block)
|
30
|
-
check_method_existence message
|
31
|
-
|
32
|
-
target.should_receive(message, opts, &block)
|
6
|
+
self.interfaces = interfaces
|
33
7
|
end
|
34
8
|
|
35
9
|
private
|
36
10
|
|
37
|
-
attr_accessor :target, :
|
11
|
+
attr_accessor :target, :interfaces
|
38
12
|
|
39
13
|
def method_missing(name, *args, &block)
|
40
14
|
check_interface_implementation name, args
|
@@ -81,12 +55,11 @@ module Adequack
|
|
81
55
|
end
|
82
56
|
|
83
57
|
def get_methods
|
84
|
-
cm =
|
85
|
-
interface.public_method(m)
|
86
|
-
end
|
58
|
+
cm, im = [], []
|
87
59
|
|
88
|
-
|
89
|
-
interface.
|
60
|
+
interfaces.each do |interface|
|
61
|
+
cm += interface.methods.map { |m| interface.public_method(m) }
|
62
|
+
im += interface.instance_methods.map { |m| interface.public_instance_method(m) }
|
90
63
|
end
|
91
64
|
|
92
65
|
cm + im
|
data/lib/adequack/version.rb
CHANGED
data/spec/adequack_spec.rb
CHANGED
@@ -28,7 +28,7 @@ describe Adequack do
|
|
28
28
|
end
|
29
29
|
|
30
30
|
expect { described_class.check_implementation(Animal, interface) }.
|
31
|
-
not_to raise_error
|
31
|
+
not_to raise_error
|
32
32
|
end
|
33
33
|
|
34
34
|
it "fails when no class method" do
|
@@ -68,7 +68,7 @@ describe Adequack do
|
|
68
68
|
end
|
69
69
|
|
70
70
|
expect { described_class.check_implementation(Animal, bad_interface) }.
|
71
|
-
not_to raise_error
|
71
|
+
not_to raise_error
|
72
72
|
end
|
73
73
|
|
74
74
|
end
|
@@ -76,7 +76,7 @@ describe Adequack do
|
|
76
76
|
context "when stubbing and mocking" do
|
77
77
|
|
78
78
|
let(:core) { double }
|
79
|
-
let(:subject) { Adequack.double core, interface }
|
79
|
+
let(:subject) { Adequack.double core, [interface] }
|
80
80
|
|
81
81
|
it "let you stub methods that exists and return actual object" do
|
82
82
|
core.should_receive(:stub).with({ bark: "woof" }, {})
|
@@ -127,7 +127,7 @@ describe Adequack do
|
|
127
127
|
end
|
128
128
|
|
129
129
|
it "works with class method defs too" do
|
130
|
-
d = Adequack.double Class.new, interface
|
130
|
+
d = Adequack.double Class.new, [interface]
|
131
131
|
d.should_receive(:evolutionize)
|
132
132
|
d.evolutionize
|
133
133
|
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
class Animal
|
2
|
+
def initialize(name)
|
3
|
+
@name = name
|
4
|
+
end
|
5
|
+
|
6
|
+
def identify
|
7
|
+
self.class.name
|
8
|
+
end
|
9
|
+
|
10
|
+
def self.evolutionize(from_what)
|
11
|
+
new("next step from #{from_what}")
|
12
|
+
end
|
13
|
+
|
14
|
+
def bark(what)
|
15
|
+
puts what
|
16
|
+
end
|
17
|
+
|
18
|
+
def feed(what, many = false)
|
19
|
+
emotion = "So yammy #{what}"
|
20
|
+
emotion = [emotion, "I'm full up"].join(", ") if many
|
21
|
+
|
22
|
+
bark emotion
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,57 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
require_relative "../fixtures/interfaces/animal"
|
3
|
+
require_relative "../fixtures/interfaces/identificationable"
|
4
|
+
require_relative "../fixtures/animal"
|
5
|
+
require_relative "../fixtures/owner"
|
6
|
+
|
7
|
+
describe Animal do
|
8
|
+
it do
|
9
|
+
described_class.should behave_like Interface::AnimalInterface,
|
10
|
+
Interface::Identificationable
|
11
|
+
expect(described_class).to behave_like Interface::AnimalInterface,
|
12
|
+
Interface::Identificationable
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
describe Owner do
|
17
|
+
let(:animal) do
|
18
|
+
behavioral_double double,
|
19
|
+
Interface::AnimalInterface, Interface::Identificationable
|
20
|
+
end
|
21
|
+
|
22
|
+
subject { described_class.new animal }
|
23
|
+
|
24
|
+
context "when using should syntax" do
|
25
|
+
it "tricks animal" do
|
26
|
+
animal.should_receive(:bark).and_return("barked")
|
27
|
+
subject.trick_animal.should eql "barked"
|
28
|
+
end
|
29
|
+
|
30
|
+
it "feeds animal the right way" do
|
31
|
+
-> {
|
32
|
+
animal.should_receive(:not_right_feed).and_return("barked")
|
33
|
+
}.should raise_error Adequack::InterfaceImplementationError
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
context "when using expect syntax" do
|
38
|
+
it "tricks animal" do
|
39
|
+
expect(animal).to receive(:bark).and_return("barked")
|
40
|
+
expect(subject.trick_animal).to eql "barked"
|
41
|
+
end
|
42
|
+
|
43
|
+
context "works with spies" do
|
44
|
+
it "works when all is ok" do
|
45
|
+
animal.stub(:bark)
|
46
|
+
subject.trick_animal
|
47
|
+
expect(animal).to have_received(:bark)
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
it "feeds animal" do
|
52
|
+
expect {
|
53
|
+
expect(animal).to receive(:not_right_feed).and_return("barked")
|
54
|
+
}.to raise_error Adequack::InterfaceImplementationError
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
data/spec/spec_helper.rb
CHANGED
@@ -1 +1 @@
|
|
1
|
-
require "adequack"
|
1
|
+
require "adequack"
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: adequack
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.4
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Ilya Zayats
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2013-
|
11
|
+
date: 2013-08-09 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rspec
|
@@ -16,14 +16,14 @@ dependencies:
|
|
16
16
|
requirements:
|
17
17
|
- - ~>
|
18
18
|
- !ruby/object:Gem::Version
|
19
|
-
version: '2.
|
19
|
+
version: '2.11'
|
20
20
|
type: :runtime
|
21
21
|
prerelease: false
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
23
23
|
requirements:
|
24
24
|
- - ~>
|
25
25
|
- !ruby/object:Gem::Version
|
26
|
-
version: '2.
|
26
|
+
version: '2.11'
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
28
|
name: bundler
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
@@ -52,6 +52,34 @@ dependencies:
|
|
52
52
|
- - '>='
|
53
53
|
- !ruby/object:Gem::Version
|
54
54
|
version: '0'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: rspec
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - ~>
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '2.14'
|
62
|
+
type: :development
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - ~>
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '2.14'
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: pry
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - '>='
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: '0'
|
76
|
+
type: :development
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - '>='
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: '0'
|
55
83
|
description: Be sure that your mocks are adequate
|
56
84
|
email:
|
57
85
|
- somebody32@gmail.com
|
@@ -61,6 +89,7 @@ extra_rdoc_files: []
|
|
61
89
|
files:
|
62
90
|
- .gitignore
|
63
91
|
- .rspec
|
92
|
+
- .travis.yml
|
64
93
|
- CHANGELOG.md
|
65
94
|
- Gemfile
|
66
95
|
- LICENSE.txt
|
@@ -69,13 +98,19 @@ files:
|
|
69
98
|
- adequack.gemspec
|
70
99
|
- lib/adequack.rb
|
71
100
|
- lib/adequack/core.rb
|
101
|
+
- lib/adequack/integration/expect_syntax_support.rb
|
102
|
+
- lib/adequack/integration/rspec_proxy.rb
|
72
103
|
- lib/adequack/integration/rspec_setup.rb
|
73
104
|
- lib/adequack/proxy.rb
|
74
105
|
- lib/adequack/version.rb
|
75
106
|
- spec/adequack_spec.rb
|
76
|
-
- spec/
|
107
|
+
- spec/integration/fixtures/animal.rb
|
108
|
+
- spec/integration/fixtures/interfaces/animal.rb
|
109
|
+
- spec/integration/fixtures/interfaces/identificationable.rb
|
110
|
+
- spec/integration/fixtures/owner.rb
|
111
|
+
- spec/integration/rspec/integration_spec.rb
|
77
112
|
- spec/spec_helper.rb
|
78
|
-
homepage: https://github.com/
|
113
|
+
homepage: https://github.com/somebody32/adequack
|
79
114
|
licenses:
|
80
115
|
- MIT
|
81
116
|
metadata: {}
|
@@ -101,5 +136,9 @@ specification_version: 4
|
|
101
136
|
summary: Be sure that your mocks are adequate
|
102
137
|
test_files:
|
103
138
|
- spec/adequack_spec.rb
|
104
|
-
- spec/
|
139
|
+
- spec/integration/fixtures/animal.rb
|
140
|
+
- spec/integration/fixtures/interfaces/animal.rb
|
141
|
+
- spec/integration/fixtures/interfaces/identificationable.rb
|
142
|
+
- spec/integration/fixtures/owner.rb
|
143
|
+
- spec/integration/rspec/integration_spec.rb
|
105
144
|
- spec/spec_helper.rb
|
data/spec/integration_spec.rb
DELETED
@@ -1,64 +0,0 @@
|
|
1
|
-
require "spec_helper"
|
2
|
-
|
3
|
-
module AnimalInterface
|
4
|
-
def self.evolutionize(from_what); end
|
5
|
-
def bark(what); end
|
6
|
-
def feed(what, many = false); end
|
7
|
-
end
|
8
|
-
|
9
|
-
class Animal
|
10
|
-
def initialize(name)
|
11
|
-
@name = name
|
12
|
-
end
|
13
|
-
|
14
|
-
def self.evolutionize(from_what)
|
15
|
-
new("next step from #{from_what}")
|
16
|
-
end
|
17
|
-
|
18
|
-
def bark(what)
|
19
|
-
puts what
|
20
|
-
end
|
21
|
-
|
22
|
-
def feed(what, many = false)
|
23
|
-
emotion = "So yammy #{what}"
|
24
|
-
emotion = [emotion, "I'm full up"].join(", ") if many
|
25
|
-
|
26
|
-
bark emotion
|
27
|
-
end
|
28
|
-
end
|
29
|
-
|
30
|
-
describe Animal do
|
31
|
-
subject { described_class }
|
32
|
-
it { should behave_like AnimalInterface }
|
33
|
-
end
|
34
|
-
|
35
|
-
class Owner
|
36
|
-
|
37
|
-
def initialize(animal)
|
38
|
-
@animal = animal
|
39
|
-
end
|
40
|
-
|
41
|
-
def trick_animal
|
42
|
-
@animal.bark("woof")
|
43
|
-
end
|
44
|
-
|
45
|
-
def enormously_feed_animal
|
46
|
-
@animal.feed("chappy", true)
|
47
|
-
end
|
48
|
-
|
49
|
-
end
|
50
|
-
|
51
|
-
describe Owner do
|
52
|
-
let(:animal) { behavioral_double double, AnimalInterface }
|
53
|
-
subject { described_class.new animal }
|
54
|
-
|
55
|
-
it "tricks animal" do
|
56
|
-
animal.should_receive(:bark).and_return("barked")
|
57
|
-
expect(subject.trick_animal).to eql "barked"
|
58
|
-
end
|
59
|
-
|
60
|
-
it "feeds animal" do
|
61
|
-
animal.should_receive(:feed).and_return("barked")
|
62
|
-
expect(subject.enormously_feed_animal).to eql "barked"
|
63
|
-
end
|
64
|
-
end
|