better_receive 0.2.0 → 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
data/README.md CHANGED
@@ -1,24 +1,26 @@
1
1
  # BetterReceive
2
2
 
3
- TODO: Write a gem description
3
+ BetterReceive helps test drive new functionality and prevent bugs by asserting that an object responds to a method before mocking it.
4
4
 
5
5
  ## Installation
6
6
 
7
- Add this line to your application's Gemfile:
7
+ $ gem install better_receive
8
8
 
9
- gem 'better_receive'
9
+ ## Usage
10
10
 
11
- And then execute:
12
11
 
13
- $ bundle
12
+ ```ruby
13
+ class Foo; end
14
+ foo = Foo.new
14
15
 
15
- Or install it yourself as:
16
+ foo.better_receive(:bar)
17
+ ```
18
+ or
19
+ ```ruby
20
+ Foo.any_instance.better_receive(:bar)
21
+ ```
16
22
 
17
- $ gem install better_receive
18
-
19
- ## Usage
20
-
21
- TODO: Write usage instructions here
23
+ Either situation will raise an error because instances of Foo do not respond to :bar.
22
24
 
23
25
  ## Contributing
24
26
 
@@ -27,3 +29,10 @@ TODO: Write usage instructions here
27
29
  3. Commit your changes (`git commit -am 'Added some feature'`)
28
30
  4. Push to the branch (`git push origin my-new-feature`)
29
31
  5. Create new Pull Request
32
+
33
+ ## To Do
34
+
35
+ * #better_stub
36
+ * support arrity checks with #responds_to
37
+ * support options other than Ruby 1.9.2+ and RSpec
38
+
@@ -5,7 +5,7 @@ Gem::Specification.new do |gem|
5
5
  gem.authors = ["Steve Ellis", "Matthew Horan"]
6
6
  gem.email = ["email@steveell.is", "matt@matthoran.com"]
7
7
  gem.description = %q{Assert that an object responds to a method before asserting that the method is received.}
8
- gem.summary = %q{A better should_receive}
8
+ gem.summary = %q{A more assertive mock.}
9
9
  gem.homepage = "http://github.com/se3000/better_receive"
10
10
 
11
11
  gem.files = `git ls-files`.split($\)
@@ -13,7 +13,7 @@ Gem::Specification.new do |gem|
13
13
  gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
14
14
  gem.name = "better_receive"
15
15
  gem.require_paths = ["lib"]
16
- gem.version = BetterReceive::VERSION
16
+ gem.version = BetterReceive::BETTER_VERSION
17
17
 
18
18
  gem.add_dependency("rspec", "~> 2.0")
19
19
  gem.add_development_dependency("rake", ">= 0")
@@ -1,65 +1,64 @@
1
1
  module BetterReceive
2
2
  class Mock
3
3
 
4
- def initialize(object)
5
- @object = object
4
+ def initialize(subject)
5
+ @subject = subject
6
6
  end
7
7
 
8
- def responds_to_and_receives(selector, options, &block)
9
- better_respond_to(selector)
10
-
11
- mock_method(selector, options, &block)
8
+ def responds_to_and_receives(selector, options={}, &block)
9
+ if subject.is_a?(RSpec::Mocks::AnyInstance::Recorder)
10
+ any_instance_better_receive(selector, options, &block)
11
+ else
12
+ subject.should respond_to selector
13
+ mock_subject_method(selector, options, &block)
14
+ end
12
15
  end
13
16
 
14
- def rspec_verify
15
- end
16
17
 
17
18
  private
18
19
 
19
- attr_reader :object
20
+ attr_reader :subject
20
21
 
21
- def better_respond_to(selector)
22
- case object
23
- when RSpec::Mocks::AnyInstance::Recorder
24
- any_instance_should_respond_to selector
25
- else
26
- object.should respond_to(selector)
27
- end
22
+ def respond_to(selector)
23
+ RSpec::Matchers::BuiltIn::RespondTo.new(selector)
28
24
  end
29
25
 
30
- def any_instance_should_respond_to(selector)
31
- klass = object.instance_variable_get(:@klass)
32
- unless klass.method_defined?(selector)
33
- raise "Expected instances of #{klass.name} to respond to :#{selector}"
34
- end
26
+ def mock_subject_method(selector, options, &block)
27
+ location = options[:expected_from] || caller(1)[2]
28
+ subject_mock_proxy.add_message_expectation(location, selector, options, &block)
35
29
  end
36
30
 
37
- def respond_to(selector)
38
- RSpec::Matchers::BuiltIn::RespondTo.new(selector)
31
+ def subject_mock_proxy
32
+ @mock_proxy ||= subject.send(:__mock_proxy)
39
33
  end
40
34
 
41
- def mock_method(selector, options, &block)
42
- case object
43
- when RSpec::Mocks::AnyInstance::Recorder
44
- any_instance_should_receive selector, &block
45
- else
46
- location = options[:expected_from] || caller(1)[2]
47
- mock_proxy.add_message_expectation(location, selector, options, &block)
35
+ def any_instance_better_receive(selector, options, &block)
36
+ any_instance_should_respond_to selector
37
+ any_instance_should_receive selector, &block
38
+ end
39
+
40
+ def any_instance_should_respond_to(selector)
41
+ klass = subject.instance_variable_get(:@klass)
42
+ unless klass.method_defined?(selector)
43
+ raise "Expected instances of #{klass.name} to respond to :#{selector}"
48
44
  end
49
45
  end
50
46
 
51
47
  def any_instance_should_receive(selector, &block)
52
- RSpec::Mocks::space.add(object)
48
+ RSpec::Mocks::space.add(subject)
53
49
 
54
- object.instance_variable_set(:@expectation_set, true)
55
- object.send(:observe!, selector)
50
+ subject.instance_variable_set(:@expectation_set, true)
51
+ subject.send(:observe!, selector)
56
52
 
57
- expectation_chain = RSpec::Mocks::AnyInstance::PositiveExpectationChain.new(selector, &block)
58
- object.message_chains.add(selector, expectation_chain)
53
+ subject.message_chains.add(selector, expectation_chain(selector, &block))
59
54
  end
60
55
 
61
- def mock_proxy
62
- @mock_proxy ||= object.send(:__mock_proxy)
56
+ def expectation_chain(*args)
57
+ if defined?(RSpec::Mocks::AnyInstance::PositiveExpectationChain)
58
+ RSpec::Mocks::AnyInstance::PositiveExpectationChain.new(*args)
59
+ else
60
+ RSpec::Mocks::AnyInstance::ExpectationChain.new(*args)
61
+ end
63
62
  end
64
63
 
65
64
  end
@@ -1,3 +1,3 @@
1
1
  module BetterReceive
2
- VERSION = "0.2.0"
2
+ BETTER_VERSION = "0.3.0"
3
3
  end
@@ -2,8 +2,8 @@ require "better_receive/version"
2
2
  require "better_receive/mock"
3
3
 
4
4
  module BetterReceive
5
- def better_receive(method_name, options={}, &block)
6
- Mock.new(self).responds_to_and_receives(method_name, options, &block)
5
+ def better_receive(*args)
6
+ Mock.new(self).responds_to_and_receives(*args)
7
7
  end
8
8
  end
9
9
 
@@ -0,0 +1,102 @@
1
+ require 'spec_helper'
2
+
3
+ describe BetterReceive do
4
+ class Foo
5
+ def bar(baz = nil)
6
+ end
7
+ end
8
+
9
+ describe "#responds_to_and_receives" do
10
+ let(:foo) { Foo.new }
11
+ let(:br_mock) { BetterReceive::Mock.new(foo) }
12
+
13
+ it "determines whether an object responds to a method" do
14
+ foo.should_receive(:respond_to?).with(:bar).and_return(true)
15
+
16
+ br_mock.responds_to_and_receives :bar
17
+
18
+ foo.bar
19
+ end
20
+
21
+ it "raises an error if it the method is not defined" do
22
+ expect {
23
+ br_mock.responds_to_and_receives :bar_baz
24
+ }.to raise_error(RSpec::Expectations::ExpectationNotMetError) { |error|
25
+ error.message.should =~ /to respond to :bar_baz/
26
+ }
27
+ end
28
+
29
+ context "when mocking" do
30
+ let(:mock_proxy) { double(RSpec::Mocks::Proxy) }
31
+
32
+ it "creates a mock proxy and adds an expectation to it" do
33
+ foo.should_receive(:send).with(:__mock_proxy).and_return(mock_proxy)
34
+ mock_proxy.should_receive(:add_message_expectation)
35
+
36
+ br_mock.responds_to_and_receives :bar
37
+ end
38
+
39
+ it "returns an rspec message expectation(responds to additional matchers ('with', 'once'...))" do
40
+ foo.better_receive(:bar).should be_a RSpec::Mocks::MessageExpectation
41
+
42
+ foo.bar
43
+
44
+ br_mock.responds_to_and_receives(:bar).with('wibble')
45
+
46
+ foo.bar('wibble')
47
+ end
48
+
49
+ context "and passing arguments" do
50
+ let(:block_param) { Proc.new {} }
51
+ let(:options) { {passed: true} }
52
+
53
+ it "passes all arguments through to the mock_proxy" do
54
+ foo.should_receive(:send).with(:__mock_proxy).and_return(mock_proxy)
55
+ mock_proxy.should_receive(:add_message_expectation) do |*args, &block|
56
+ args[1].should == :bar
57
+ args[2].should == options
58
+ block.should == block_param
59
+ end
60
+
61
+ br_mock.responds_to_and_receives(:bar, passed: true, &block_param)
62
+ end
63
+ end
64
+
65
+ context "on .any_instance" do
66
+ let(:br_mock) { BetterReceive::Mock.new(Foo.any_instance) }
67
+
68
+ context "when the method is defined" do
69
+ context "and the method is called" do
70
+ it 'does not raise an error' do
71
+ expect {
72
+ br_mock.responds_to_and_receives(:bar)
73
+ foo.bar
74
+ }.to_not raise_error
75
+ end
76
+ end
77
+
78
+ context 'and the method is not called' do
79
+ it 'does raise an error' do
80
+ expect {
81
+ br_mock.responds_to_and_receives(:bar)
82
+ RSpec::Mocks::space.verify_all
83
+ }.to raise_error(RSpec::Mocks::MockExpectationError) { |error|
84
+ error.message.should == "Exactly one instance should have received the following message(s) but didn't: bar"
85
+ }
86
+ end
87
+ end
88
+ end
89
+
90
+ context 'when the method is not defined' do
91
+ it 'raises an error' do
92
+ expect {
93
+ br_mock.responds_to_and_receives(:baz)
94
+ }.to raise_error { |error|
95
+ error.message.should == "Expected instances of Foo to respond to :baz"
96
+ }
97
+ end
98
+ end
99
+ end
100
+ end
101
+ end
102
+ end
@@ -2,98 +2,25 @@ require 'spec_helper'
2
2
 
3
3
  describe BetterReceive do
4
4
  class Foo
5
- def bar(baz = nil)
6
- end
5
+ def bar; end
7
6
  end
8
7
 
9
8
  describe "#better_receive" do
10
9
  let(:foo) { Foo.new }
10
+ let(:br_instance) { double(BetterReceive::Mock).as_null_object }
11
11
 
12
- it "determines whether an object responds to a method" do
13
- foo.should_receive(:respond_to?).with(:bar).and_call_original
12
+ it "passes the object being mocked into a new BetterReceive::Mock instance" do
13
+ BetterReceive::Mock.should_receive(:new).with(foo).and_return(br_instance)
14
14
 
15
15
  foo.better_receive(:bar)
16
-
17
- foo.bar
18
- end
19
-
20
- it "raises an error if it the method is not defined" do
21
- expect {
22
- foo.better_receive(:bar_baz)
23
- }.to raise_error(RSpec::Expectations::ExpectationNotMetError) { |error|
24
- error.message.should =~ /to respond to :bar_baz/
25
- }
26
16
  end
27
17
 
28
- context "when mocking" do
29
- let(:mock_proxy) { double(RSpec::Mocks::Proxy) }
30
-
31
- it "creates a mock proxy and adds an expectation to it" do
32
- foo.should_receive(:send).with(:__mock_proxy).and_return(mock_proxy)
33
- mock_proxy.should_receive(:add_message_expectation)
34
-
35
- foo.better_receive(:bar)
36
- end
37
-
38
- it "returns an rspec message expectation(responds to additional matchers ('with', 'once'...))" do
39
- foo.better_receive(:bar).should be_a RSpec::Mocks::MessageExpectation
40
-
41
- foo.bar
18
+ it "checks that the object responds to the method and that the method is called" do
19
+ BetterReceive::Mock.stub(:new).with(foo).and_return(br_instance)
42
20
 
43
- foo.better_receive(:bar).with('wibble')
21
+ br_instance.should_receive(:responds_to_and_receives).with(:bar)
44
22
 
45
- foo.bar('wibble')
46
- end
47
-
48
- context "and passing arguments" do
49
- let(:block_param) { Proc.new {} }
50
- let(:options) { {passed: true} }
51
-
52
- it "passes all arguments through to the mock_proxy" do
53
- foo.should_receive(:send).with(:__mock_proxy).and_return(mock_proxy)
54
- mock_proxy.should_receive(:add_message_expectation) do |*args, &block|
55
- args[1].should == :bar
56
- args[2].should == options
57
- block.should == block_param
58
- end
59
-
60
- foo.better_receive(:bar, passed: true, &block_param)
61
- end
62
- end
63
-
64
- context "on .any_instance" do
65
- context "when the method is defined" do
66
- context "and the method is called" do
67
- it 'does not raise an error' do
68
- expect {
69
- Foo.any_instance.better_receive(:bar)
70
- foo.bar
71
- }.to_not raise_error
72
- end
73
- end
74
-
75
- context 'and the method is not called' do
76
- it 'does raise an error' do
77
- expect {
78
- Foo.any_instance.better_receive(:bar)
79
- RSpec::Mocks::space.verify_all
80
- }.to raise_error(RSpec::Mocks::MockExpectationError) { |error|
81
- error.message.should == "Exactly one instance should have received the following message(s) but didn't: bar"
82
- }
83
- end
84
- end
85
- end
86
-
87
- context 'when the method is not defined' do
88
- it 'raises an error' do
89
- expect {
90
- Foo.any_instance.better_receive(:baz)
91
- }.to raise_error { |error|
92
- error.message.should == "Expected instances of Foo to respond to :baz"
93
- }
94
- end
95
- end
96
- end
23
+ foo.better_receive(:bar)
97
24
  end
98
25
  end
99
26
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: better_receive
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.0
4
+ version: 0.3.0
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -10,7 +10,7 @@ authors:
10
10
  autorequire:
11
11
  bindir: bin
12
12
  cert_chain: []
13
- date: 2013-01-15 00:00:00.000000000 Z
13
+ date: 2013-01-27 00:00:00.000000000 Z
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: rspec
@@ -79,6 +79,7 @@ files:
79
79
  - lib/better_receive.rb
80
80
  - lib/better_receive/mock.rb
81
81
  - lib/better_receive/version.rb
82
+ - spec/lib/better_receive/mock_spec.rb
82
83
  - spec/lib/better_receive_spec.rb
83
84
  - spec/spec_helper.rb
84
85
  homepage: http://github.com/se3000/better_receive
@@ -104,7 +105,8 @@ rubyforge_project:
104
105
  rubygems_version: 1.8.23
105
106
  signing_key:
106
107
  specification_version: 3
107
- summary: A better should_receive
108
+ summary: A more assertive mock.
108
109
  test_files:
110
+ - spec/lib/better_receive/mock_spec.rb
109
111
  - spec/lib/better_receive_spec.rb
110
112
  - spec/spec_helper.rb