adequack 0.0.3 → 0.0.4

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