rspec-hollerback-mocks 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: eed0783475a82c560add2cc33847fba5a78a5cdd
4
+ data.tar.gz: 1983d97e4e2baa2bf3403280cf39bc0634ec9ebb
5
+ SHA512:
6
+ metadata.gz: 2357ae5a903126d420f5022cf64484ccaac29fa4777e1531f4a27cc045f08288140a6842c97f12ebf9e4253ebd320ad100d68af90d5ecf4e03fa31cb3d3ae9b9
7
+ data.tar.gz: 8e00351747a32d5630697ce5cc4039b9fd546f26fd7eb87e21a03e6ada2a3dd9953ac15d8eeb5c67ef07c5952caaa70663140d1788bee92765cf5252d3b5d27a
data/.gitignore ADDED
@@ -0,0 +1,10 @@
1
+ *.gem
2
+ /.bundle/
3
+ /.yardoc
4
+ /Gemfile.lock
5
+ /_yardoc/
6
+ /coverage/
7
+ /doc/
8
+ /pkg/
9
+ /spec/reports/
10
+ /tmp/
data/.rspec ADDED
@@ -0,0 +1,2 @@
1
+ --format documentation
2
+ --color
data/.ruby-version ADDED
@@ -0,0 +1 @@
1
+ 2.3.0
data/.travis.yml ADDED
@@ -0,0 +1,11 @@
1
+ language: ruby
2
+ matrix:
3
+ allow_failures:
4
+ - rvm: ruby-head
5
+ rvm:
6
+ - ruby-head
7
+ - 2.3.0
8
+ - 2.2.4
9
+ - 2.1.8
10
+ - 2.0.0
11
+ before_install: gem install bundler -v 1.11.2
data/Gemfile ADDED
@@ -0,0 +1,20 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Get local or master 'hollerback' gem
4
+ library_path = File.expand_path("../../hollerback", __FILE__)
5
+ if File.exist?(library_path)
6
+ gem 'hollerback', path: library_path
7
+ else
8
+ gem 'hollerback', git: "git://github.com/delner/hollerback.git",
9
+ branch: ENV.fetch('BRANCH',"master")
10
+ end
11
+
12
+ gem "rspec", :git => "git://github.com/rspec/rspec.git"
13
+ gem "rspec-core", :git => "git://github.com/rspec/rspec-core.git"
14
+ gem "rspec-expectations", :git => "git://github.com/rspec/rspec-expectations.git"
15
+ gem "rspec-mocks", :git => "git://github.com/rspec/rspec-mocks.git"
16
+ gem "rspec-support", :git => "git://github.com/rspec/rspec-support.git"
17
+
18
+ gem "pry-stack_explorer"
19
+
20
+ gemspec
data/LICENSE.txt ADDED
@@ -0,0 +1,21 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2016 David Elner
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in
13
+ all copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
+ THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,189 @@
1
+ RSpec Hollerback Mocks
2
+ ==========
3
+
4
+ [![Build Status](https://travis-ci.org/delner/rspec-hollerback-mocks.svg?branch=master)](https://travis-ci.org/delner/rspec-hollerback-mocks) ![Gem Version](https://badge.fury.io/rb/rspec-hollerback-mocks.svg)
5
+ ###### *For Ruby 2+, RSpec 3+*
6
+
7
+ ### Introduction
8
+
9
+ Adds mocking extensions to RSpec for testing code that implements Hollerback.
10
+
11
+ ### Installation
12
+
13
+ ##### If you're not using Bundler...
14
+
15
+ Install the gem via:
16
+
17
+ ```
18
+ gem install rspec-hollerback-mocks
19
+ ```
20
+
21
+ Then require it in your `spec_helper.rb` with:
22
+
23
+ ```
24
+ require 'rspec/hollerback/mocks'
25
+ ```
26
+
27
+ ##### If you're using Bundler...
28
+
29
+ Add the gem to your Gemfile:
30
+
31
+ ```
32
+ gem 'rspec-hollerback-mocks'
33
+ ```
34
+
35
+ Then `bundle install` to install the gem and its dependencies.
36
+
37
+ Finally require it in your `spec_helper.rb` with:
38
+
39
+ ```
40
+ require 'rspec/hollerback/mocks'
41
+ ```
42
+
43
+ ### Usage
44
+
45
+ ##### Triggering a callback using and_callback
46
+
47
+ Given a class that implements Hollerback, e.g:
48
+
49
+ ```ruby
50
+ class NoteApi
51
+ include Hollerback
52
+
53
+ # Callback-enabled function
54
+ def get_note(&block)
55
+ # ...
56
+ end
57
+ end
58
+ ```
59
+
60
+ You can mock callbacks on the class, or objects of the class using the `and_callback` condition.
61
+
62
+ ```ruby
63
+ context "for a class" do
64
+ subject do
65
+ NoteApi.get_note do |on|
66
+ on.success { "Success!" }
67
+ end
68
+ end
69
+ it do
70
+ expect(NoteApi).to receive(:get_note).and_callback(:success)
71
+ expect(subject).to eq("Success!")
72
+ end
73
+ end
74
+
75
+ context "for an object" do
76
+ let(:client) { NoteApi.new }
77
+ subject do
78
+ client.get_note do |on|
79
+ on.success { "Success!" }
80
+ end
81
+ end
82
+ it do
83
+ expect(client).to receive(:get_note).and_callback(:success)
84
+ expect(subject).to eq("Success!")
85
+ end
86
+ end
87
+ ```
88
+
89
+ The mocked function will return the output of the callback block you invoke.
90
+
91
+ ##### Chaining callbacks
92
+
93
+ You can also chain multiple callbacks, in which case the last callback will be the return value.
94
+
95
+ ```ruby
96
+ context "for an object that invokes multiple callbacks" do
97
+ let(:client) { NoteApi.new }
98
+ subject do
99
+ client.get_note do |on|
100
+ on.created { "Created new note!" }
101
+ on.success { "Success!" }
102
+ end
103
+ end
104
+ it do
105
+ expect(client).to receive(:get_note).and_callback(:created).and_callback(:success)
106
+ expect(subject).to eq("Success!")
107
+ end
108
+ end
109
+ ```
110
+
111
+ ##### Returning a value after callbacks
112
+
113
+ If you want the mocked function to return a different value, then you can add RSpec's `and_return` to the end of the call.
114
+
115
+ ```ruby
116
+ context "for an object that invokes a callback and returns a value" do
117
+ let(:note) { Note.new }
118
+ let(:client) { NoteApi.new }
119
+ subject do
120
+ client.get_note do |on|
121
+ on.success { "Success!" }
122
+ end
123
+ end
124
+ it do
125
+ expect(client).to receive(:get_note).and_callback(:success).and_return(note)
126
+ expect(subject).to eq(note)
127
+ end
128
+ end
129
+ ```
130
+
131
+ ##### Mocking a class that uses a callback
132
+
133
+ This feature is most useful when you want to mock behavior on a class that consumes the callback-enabled class.
134
+
135
+ For example, let's say there is a `NoteApi#get_note` function that makes HTTP requests and triggers callbacks. Let's also say we wanted to use this `NoteApi` to power a feature that adds signatures to our notes.
136
+
137
+ ```ruby
138
+ class Autopen
139
+ def self.get_signed_note(note_id, signature)
140
+ note = NoteApi.get_note note_id do |on|
141
+ # If the note exists, add a signature to it and return it
142
+ on.found { |note| note.tap { |n| n.append(signature) } }
143
+
144
+ # Otherwise just return a new note without a signature
145
+ on.not_found { |note_id| Note.new(note_id) }
146
+ end
147
+ end
148
+ end
149
+ ```
150
+
151
+ If we are writing specs for `Autopen` to test the `get_signed_note` method, we aren't interested in testing `NoteApi`. More importantly, we might not want that `NoteApi` class making actual HTTP calls that might make our test suite brittle, or otherwise slow it down.
152
+
153
+ This is where a mock is appropriate and the `and_callback` condition is most useful. Using it, we can implement a test that allows us to make the `NoteApi` trigger any callbacks we need to test the code we care about inside `get_signed_note`.
154
+
155
+ ```ruby
156
+ describe Autopen do
157
+ describe "#get_signed_note" do
158
+ subject { Autopen.get_signed_note(note_id, signature) }
159
+ let(:note_id) { "TPS Report" }
160
+ let(:signature) { "Peter Gibbons\nSoftware Engineer\nInitech" }
161
+
162
+ context "for a note that exists" do
163
+ let(:note) { Note.new("Yes, I already got the memo.") }
164
+ before(:each) { expect_any_instance_of(NoteApi).to receive(:get_signed_note).with(note_id).and_callback(:found, note) }
165
+ it { is_expected.to eq(note) }
166
+ it { expect(subject.body).to end_with(signature) }
167
+ end
168
+ context "when given a note that does not exist" do
169
+ before(:each) { expect_any_instance_of(NoteApi).to receive(:get_signed_note).with(note_id).and_callback(:not_found, note_id) }
170
+ it { expect(subject.body).to_not end_with(signature) }
171
+ end
172
+ end
173
+ end
174
+ ```
175
+
176
+ ## Development
177
+
178
+ Install dependencies using `bundle install`. Run tests using `bundle exec rspec`
179
+
180
+ To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
181
+
182
+ ## Contributing
183
+
184
+ Bug reports and pull requests are welcome on GitHub at https://github.com/delner/rspec-hollerback-mocks.
185
+
186
+ ## License
187
+
188
+ The gem is available as open source under the terms of the [MIT License](http://opensource.org/licenses/MIT).
189
+
data/Rakefile ADDED
@@ -0,0 +1,6 @@
1
+ require "bundler/gem_tasks"
2
+ require "rspec/core/rake_task"
3
+
4
+ RSpec::Core::RakeTask.new(:spec)
5
+
6
+ task :default => :spec
data/bin/console ADDED
@@ -0,0 +1,14 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require "bundler/setup"
4
+ require "rspec/hollerback/mocks"
5
+
6
+ # You can add fixtures and/or initialization code here to make experimenting
7
+ # with your gem easier. You can also use a different console, if you like.
8
+
9
+ # (If you use this, don't forget to add pry to your Gemfile!)
10
+ # require "pry"
11
+ # Pry.start
12
+
13
+ require "irb"
14
+ IRB.start
data/bin/setup ADDED
@@ -0,0 +1,8 @@
1
+ #!/usr/bin/env bash
2
+ set -euo pipefail
3
+ IFS=$'\n\t'
4
+ set -vx
5
+
6
+ bundle install
7
+
8
+ # Do any other automated setup that you need to do here
@@ -0,0 +1,8 @@
1
+ require 'rspec/mocks'
2
+ require 'hollerback'
3
+ require "rspec/hollerback/mocks/version"
4
+
5
+ require "rspec/hollerback/mocks/and_callback_implementation"
6
+ require "rspec/hollerback/mocks/callback_message_expectation"
7
+ require "rspec/hollerback/mocks/receive_callback_message_expectation"
8
+ require "rspec/hollerback/mocks/callback_actions"
@@ -0,0 +1,23 @@
1
+ module RSpec
2
+ module Hollerback
3
+ module Mocks
4
+ class AndCallbackImplementation
5
+ def initialize(callback_class, callback_name, *callback_args, &callback_block)
6
+ @callback_class = callback_class
7
+ @callback_name = callback_name
8
+ @callback_args = callback_args
9
+ @callback_block = callback_block if callback_block
10
+ end
11
+
12
+ def call(*args, &block)
13
+ callback_instance = @callback_class.new(block)
14
+ if @callback_block
15
+ callback_instance.respond_with(@callback_name, *@callback_args, &@callback_block)
16
+ else
17
+ callback_instance.respond_with(@callback_name, *@callback_args)
18
+ end
19
+ end
20
+ end
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,16 @@
1
+ module RSpec
2
+ module Hollerback
3
+ module Mocks
4
+ module CallbackActions
5
+ attr_accessor :callback_actions
6
+ def actions
7
+ actions_array = super
8
+ actions_array.insert(actions_array.size - 1, callback_actions).flatten.compact
9
+ end
10
+ end
11
+ end
12
+ end
13
+ end
14
+
15
+ # Inject into RSpec
16
+ RSpec::Mocks::Implementation.send(:prepend, RSpec::Hollerback::Mocks::CallbackActions)
@@ -0,0 +1,27 @@
1
+ module RSpec
2
+ module Hollerback
3
+ module Mocks
4
+ module CallbackMessageExpectation
5
+ def and_callback(callback_name, *callback_args, &callback_block)
6
+ # Lookup callback class
7
+ target_class = @method_double.object.is_a?(Module) ? @method_double.object : @method_double.object.class
8
+ raise ArgumentError.new("Target class #{target_class.name.to_s} does not implement Hollerback!") if !(target_class < ::Hollerback)
9
+ callback_class = target_class.const_get("Callbacks")
10
+
11
+ # Add callback action
12
+ self.callback_implementation_action(RSpec::Hollerback::Mocks::AndCallbackImplementation.new(callback_class, callback_name, *callback_args, &callback_block))
13
+
14
+ self
15
+ end
16
+
17
+ def callback_implementation_action(action)
18
+ return unless action
19
+ (implementation.callback_actions ||= []).push(action)
20
+ end
21
+ end
22
+ end
23
+ end
24
+ end
25
+
26
+ # Inject into RSpec
27
+ RSpec::Mocks::MessageExpectation.send(:include, RSpec::Hollerback::Mocks::CallbackMessageExpectation)
@@ -0,0 +1,21 @@
1
+ module RSpec
2
+ module Hollerback
3
+ module Mocks
4
+ module ReceiveCallbackMessageExpectation
5
+ def self.included(mod)
6
+ RSpec::Hollerback::Mocks::CallbackMessageExpectation.public_instance_methods(false).each do |method|
7
+ next if method_defined?(method)
8
+
9
+ define_method(method) do |*args, &block|
10
+ @recorded_customizations << RSpec::Mocks::Matchers::ExpectationCustomization.new(method, args, block)
11
+ self
12
+ end
13
+ end
14
+ end
15
+ end
16
+ end
17
+ end
18
+ end
19
+
20
+ # Inject into RSpec
21
+ RSpec::Mocks::Matchers::Receive.send(:include, RSpec::Hollerback::Mocks::ReceiveCallbackMessageExpectation)
@@ -0,0 +1,7 @@
1
+ module RSpec
2
+ module Hollerback
3
+ module Mocks
4
+ VERSION = "0.1.0"
5
+ end
6
+ end
7
+ end
@@ -0,0 +1,28 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'rspec/hollerback/mocks/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "rspec-hollerback-mocks"
8
+ spec.version = RSpec::Hollerback::Mocks::VERSION
9
+ spec.authors = ["David Elner"]
10
+ spec.email = ["david@davidelner.com"]
11
+
12
+ spec.summary = %q{RSpec mocks for the Hollerback gem.}
13
+ spec.homepage = "https://github.com/delner/rspec-hollerback-mocks"
14
+ spec.license = "MIT"
15
+
16
+ spec.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
17
+ spec.bindir = "exe"
18
+ spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
19
+ spec.require_paths = ["lib"]
20
+
21
+ spec.add_runtime_dependency "rspec-mocks", "~> 3.0"
22
+ spec.add_runtime_dependency "hollerback", "~> 0.1"
23
+
24
+ spec.add_development_dependency "bundler", "~> 1.11"
25
+ spec.add_development_dependency "rake", "~> 10.0"
26
+ spec.add_development_dependency "pry"
27
+ spec.add_development_dependency "rspec", "~> 3.0"
28
+ end
metadata ADDED
@@ -0,0 +1,145 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: rspec-hollerback-mocks
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - David Elner
8
+ autorequire:
9
+ bindir: exe
10
+ cert_chain: []
11
+ date: 2016-04-21 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: rspec-mocks
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '3.0'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '3.0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: hollerback
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '0.1'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '0.1'
41
+ - !ruby/object:Gem::Dependency
42
+ name: bundler
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: '1.11'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '1.11'
55
+ - !ruby/object:Gem::Dependency
56
+ name: rake
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - "~>"
60
+ - !ruby/object:Gem::Version
61
+ version: '10.0'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - "~>"
67
+ - !ruby/object:Gem::Version
68
+ version: '10.0'
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'
83
+ - !ruby/object:Gem::Dependency
84
+ name: rspec
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - "~>"
88
+ - !ruby/object:Gem::Version
89
+ version: '3.0'
90
+ type: :development
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - "~>"
95
+ - !ruby/object:Gem::Version
96
+ version: '3.0'
97
+ description:
98
+ email:
99
+ - david@davidelner.com
100
+ executables: []
101
+ extensions: []
102
+ extra_rdoc_files: []
103
+ files:
104
+ - ".gitignore"
105
+ - ".rspec"
106
+ - ".ruby-version"
107
+ - ".travis.yml"
108
+ - Gemfile
109
+ - LICENSE.txt
110
+ - README.md
111
+ - Rakefile
112
+ - bin/console
113
+ - bin/setup
114
+ - lib/rspec/hollerback/mocks.rb
115
+ - lib/rspec/hollerback/mocks/and_callback_implementation.rb
116
+ - lib/rspec/hollerback/mocks/callback_actions.rb
117
+ - lib/rspec/hollerback/mocks/callback_message_expectation.rb
118
+ - lib/rspec/hollerback/mocks/receive_callback_message_expectation.rb
119
+ - lib/rspec/hollerback/mocks/version.rb
120
+ - rspec-hollerback-mocks.gemspec
121
+ homepage: https://github.com/delner/rspec-hollerback-mocks
122
+ licenses:
123
+ - MIT
124
+ metadata: {}
125
+ post_install_message:
126
+ rdoc_options: []
127
+ require_paths:
128
+ - lib
129
+ required_ruby_version: !ruby/object:Gem::Requirement
130
+ requirements:
131
+ - - ">="
132
+ - !ruby/object:Gem::Version
133
+ version: '0'
134
+ required_rubygems_version: !ruby/object:Gem::Requirement
135
+ requirements:
136
+ - - ">="
137
+ - !ruby/object:Gem::Version
138
+ version: '0'
139
+ requirements: []
140
+ rubyforge_project:
141
+ rubygems_version: 2.5.1
142
+ signing_key:
143
+ specification_version: 4
144
+ summary: RSpec mocks for the Hollerback gem.
145
+ test_files: []