better_receive 0.2.0 → 0.3.0

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