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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 19d707b457e7ae1fd0ad7067027fa90a39697869
4
- data.tar.gz: 90d10cb4dd9d948e98c4c688ea75e9521c0888ac
3
+ metadata.gz: cb0c0c9b3407f1c1dae6c369e477b99d01dca4d2
4
+ data.tar.gz: 2ff4f234e3298d02d5315aa2127ace31024bf60d
5
5
  SHA512:
6
- metadata.gz: f3e5594e0a8d0b60a1a0dbb4b630bd498f6666d7903c3dd8a8d3a3512696da715858487594a12dbfef3c39fa9ea39c1ce294da7cf2b1554f6de8f997629df66f
7
- data.tar.gz: 7476ef90343baf2a48f5ffed1989644cd4ccc472b9197d89bd5d7d6758db1729c34fe5681c9b666382c9cabba2132e9877be00712e20c5554d2b8569d0251077
6
+ metadata.gz: 4fbada0961dff547e86707db6be7de200fb23aa69f48ee0e75cc782b25e51605e4e4a7910673fa5a462778537a32c3538b040413d4f8fa3954f657210f3d05e3
7
+ data.tar.gz: e9a43c8b583c386929e6c64221ad2f5ad33343f12d82a63182b6bf8806e3ca8b40c2d0a7a97811783a3766fc7905619ffa973a5f534881287ff546921ac9b869
@@ -0,0 +1,4 @@
1
+ rvm:
2
+ - "2.0.0"
3
+ - "1.9.3"
4
+ - "1.9.2"
@@ -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/Somebody32/adequack.png?branch=master)](https://travis-ci.org/Somebody32/adequack)
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 then you stubbing and mocking a lot.
8
- But the main concern when you use this approach is that you stubs will be out of sync with the
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 be_adequack_to DogInterface }
88
+ it { should behave_like DogInterface }
89
89
  end
90
90
 
91
91
  describe Owner do
92
- let(:dog) { adequack_double double, DogInterface }
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 `be_adequack_to` matcher with a core class as an argument.
112
+ Use `behave_like` matcher with a core class as an argument.
113
113
 
114
- And to create doubles and stubs use `adequack_double` helper. This will return a proxy object that
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 be_adequack_to DogInterface }
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 `be_adequack_to` matcher and `adequack_double` helper.
206
+ After that your rspec tests will have `behave_like` matcher and `behavioral_double` helper.
207
207
 
208
208
  ## Usage
209
209
 
@@ -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/Somebody32/adequack"
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.13"
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
@@ -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, interface)
14
- Proxy.new core, interface
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
@@ -1,7 +1,9 @@
1
+ require "rspec/matchers" unless RSpec::Matchers.respond_to? :define
2
+
1
3
  module Adequack
2
4
  module Integration
3
5
  module RSpecHelpers
4
- def behavioral_double(object, interface)
6
+ def behavioral_double(object, *interface)
5
7
  Adequack.double object, interface
6
8
  end
7
9
 
@@ -1,40 +1,14 @@
1
1
  module Adequack
2
2
  class Proxy
3
3
 
4
- def initialize(target, interface)
4
+ def initialize(target, interfaces)
5
5
  self.target = target
6
- self.interface = interface
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, :interface
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 = interface.methods.map do |m|
85
- interface.public_method(m)
86
- end
58
+ cm, im = [], []
87
59
 
88
- im = interface.instance_methods.map do |m|
89
- interface.public_instance_method(m)
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
@@ -1,3 +1,3 @@
1
1
  module Adequack
2
- VERSION = "0.0.3"
2
+ VERSION = "0.0.4"
3
3
  end
@@ -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 Adequack::InterfaceImplementationError
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 Adequack::InterfaceImplementationError
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,7 @@
1
+ module Interface
2
+ module AnimalInterface
3
+ def self.evolutionize(from_what); end
4
+ def bark(what); end
5
+ def feed(what, many = false); end
6
+ end
7
+ end
@@ -0,0 +1,5 @@
1
+ module Interface
2
+ module Identificationable
3
+ def identify; end
4
+ end
5
+ end
@@ -0,0 +1,15 @@
1
+ class Owner
2
+
3
+ def initialize(animal)
4
+ @animal = animal
5
+ end
6
+
7
+ def trick_animal
8
+ @animal.bark("woof")
9
+ end
10
+
11
+ def enormously_feed_animal
12
+ @animal.feed("chappy", true)
13
+ end
14
+
15
+ 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
@@ -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.3
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-05-19 00:00:00.000000000 Z
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.13'
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.13'
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/integration_spec.rb
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/Somebody32/adequack
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/integration_spec.rb
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
@@ -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