hooks 0.3.1 → 0.3.2

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.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 17924e6e39cc1e9257eb89343e4b714bc617c1e3
4
+ data.tar.gz: c5f79d3aec15fc0ae9a6e36f11b7db3c1c35455c
5
+ SHA512:
6
+ metadata.gz: 55f49769f6dd5bb4cce4dfcea66546d6681580479be431409eff36d884417898bfcf5d903d0ebed765d20fa32ca772880bc7463805ed8c55428b60b28ef97501
7
+ data.tar.gz: c216a9b2d5f1b841b91c83a8cee5a20cc0425789dd95d147ef9474af389234e990d13f46e1694966a39c1eaaa9441d86aa46f1f3f1a6cce908e05f3abe3fda30
data/CHANGES.md CHANGED
@@ -1,3 +1,7 @@
1
+ ## 0.3.2
2
+
3
+ * Added `Hooks::InstanceHooks` to add hooks and/or callbacks on instance level. Thanks to @mpapis for that suggestion.
4
+
1
5
  ## 0.3.1
2
6
 
3
7
  * Fix a bug, string hook names are now treated as symbols.
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2011-2013 Nick Sutterer
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md CHANGED
@@ -138,12 +138,49 @@ This will only run the first two callbacks. Note that the result doesn't contain
138
138
  result.halted? #=> true
139
139
  ```
140
140
 
141
+ ## Instance Hooks
142
+
143
+ You can also define hooks and/or add callbacks per instance. This is helpful if your class should define a basic set of hooks and callbacks that are then extended by instances.
144
+
145
+ ```ruby
146
+ class Cat
147
+ include Hooks
148
+ include Hooks::InstanceHooks
149
+
150
+ define_hook :after_dark
151
+
152
+ after_dark { "Chase mice" }
153
+ end
154
+ ```
155
+
156
+ Note that you have to include `Hooks::InstanceHooks` to get this additional functionality.
157
+
158
+ See how callbacks can be added to a separate object, now.
159
+
160
+ ```ruby
161
+ garfield = Cat.new
162
+
163
+ garfield.after_dark :sleep
164
+ garfield.run_hook(:after_dark) # => invoke "Chase mice" hook and #sleep
165
+ ```
166
+
167
+ This will copy all callbacks from the `after_dark` hook to the instance and add a second hook. This all happens on the `garfield` instance, only, and leaves the class untouched.
168
+
169
+ Naturally, adding new hooks works like-wise.
170
+
171
+ ```ruby
172
+ garfield.define_hook :before_six
173
+ garfield.before_six { .. }
174
+ ```
175
+ This feature was added in 0.3.2.
176
+
177
+
141
178
  ## Installation
142
179
 
143
180
  In your Gemfile, do
144
181
 
145
182
  ```ruby
146
- gem hooks
183
+ gem "hooks"
147
184
  ```
148
185
 
149
186
  ## Anybody using it?
@@ -1,7 +1,7 @@
1
1
  lib = File.expand_path('../lib/', __FILE__)
2
2
  $:.unshift lib unless $:.include?(lib)
3
3
 
4
- require 'hooks'
4
+ require 'hooks/version'
5
5
 
6
6
  Gem::Specification.new do |s|
7
7
  s.name = "hooks"
@@ -12,10 +12,12 @@ Gem::Specification.new do |s|
12
12
  s.homepage = "http://nicksda.apotomo.de/2010/09/hooks-and-callbacks-for-ruby-but-simple/"
13
13
  s.summary = %q{Generic hooks with callbacks for Ruby.}
14
14
  s.description = %q{Declaratively define hooks, add callbacks and run them with the options you like.}
15
+ s.license = "MIT"
15
16
 
16
17
  s.files = `git ls-files`.split("\n")
17
18
  s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
18
19
  s.require_paths = ["lib"]
20
+ s.license = 'MIT'
19
21
 
20
22
  s.add_development_dependency "minitest", ">= 5.0.0"
21
23
  s.add_development_dependency "rake"
@@ -18,8 +18,6 @@ require "hooks/hook"
18
18
  #
19
19
  # cat.run_hook :after_dinner
20
20
  module Hooks
21
- VERSION = "0.3.1"
22
-
23
21
  def self.included(base)
24
22
  base.class_eval do
25
23
  extend InheritableAttribute
@@ -122,3 +120,5 @@ module Hooks
122
120
  end
123
121
  end
124
122
  end
123
+
124
+ require "hooks/instance_hooks"
@@ -0,0 +1,13 @@
1
+ module Hooks
2
+ module InstanceHooks
3
+ include ClassMethods
4
+
5
+ def _hooks
6
+ @_hooks ||= self.class._hooks.clone # TODO: generify that with representable_attrs.
7
+ end
8
+
9
+ def run_hook(name, *args)
10
+ run_hook_for(name, self, *args)
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,3 @@
1
+ module Hooks
2
+ VERSION = "0.3.2"
3
+ end
@@ -10,7 +10,7 @@ class HooksTest < MiniTest::Spec
10
10
  end
11
11
 
12
12
 
13
- describe "Hooks.define_hook" do
13
+ describe "::define_hook" do
14
14
  let(:klass) do
15
15
  Class.new(TestClass) do
16
16
  define_hook :after_eight
@@ -73,6 +73,10 @@ class HooksTest < MiniTest::Spec
73
73
  assert_equal [:b, :a], subject.executed
74
74
  end
75
75
 
76
+ it "returns empty Results when no callbacks defined" do
77
+ subject.run_hook(:after_eight).must_equal Hooks::Hook::Results.new
78
+ end
79
+
76
80
  it "accept arbitrary parameters" do
77
81
  subject.instance_eval do
78
82
  def a(me, arg); executed << arg+1; end
@@ -145,17 +149,17 @@ class HooksTest < MiniTest::Spec
145
149
  end
146
150
 
147
151
  describe "in class context" do
148
- it "run a callback block" do
152
+ it "runs callback block" do
149
153
  executed = []
150
154
  klass.after_eight do
151
155
  executed << :klass
152
156
  end
153
157
  klass.run_hook(:after_eight)
154
158
 
155
- assert_equal [:klass], executed
159
+ executed.must_equal([:klass])
156
160
  end
157
161
 
158
- it "run a class methods" do
162
+ it "runs instance methods" do
159
163
  executed = []
160
164
  klass.instance_eval do
161
165
  after_eight :have_dinner
@@ -166,7 +170,7 @@ class HooksTest < MiniTest::Spec
166
170
  end
167
171
  klass.run_hook(:after_eight, executed)
168
172
 
169
- assert_equal [:have_dinner], executed
173
+ executed.must_equal([:have_dinner])
170
174
  end
171
175
  end
172
176
  end
@@ -195,11 +199,18 @@ end
195
199
  class HookSetTest < MiniTest::Spec
196
200
  subject { Hooks::HookSet.new }
197
201
 
202
+ let (:first_hook) { Hooks::Hook.new(:halts_on_falsey => true) }
203
+ let (:second_hook) { Hooks::Hook.new(:halts_on_falsey => false) }
204
+
198
205
  it "responds to #clone" do
199
- subject[:after_eight] = [:drink_beer]
206
+ subject[:after_eight] = [first_hook]
207
+
200
208
  clone = subject.clone
201
- clone[:after_eight] << :open_fridge
202
209
 
203
- subject.must_equal(:after_eight => [:drink_beer])
210
+ clone[:after_eight] << second_hook
211
+
212
+ subject.must_equal(:after_eight => [first_hook])
213
+ clone.must_equal(:after_eight => [first_hook, second_hook])
204
214
  end
215
+ # TODO: test if options get cloned.
205
216
  end
@@ -0,0 +1,44 @@
1
+ require "test_helper"
2
+
3
+ class InstanceHooksTest < HooksTest
4
+ describe "#define_hook" do
5
+ let(:klass) { Class.new(TestClass) do
6
+ include Hooks::InstanceHooks
7
+ end }
8
+
9
+ subject { klass.new }
10
+
11
+ it "adds hook to instance" do
12
+ subject.define_hook :after_eight
13
+
14
+ assert_equal [], subject.callbacks_for_hook(:after_eight)
15
+ end
16
+
17
+ it "copies existing class hook" do
18
+ klass.define_hook :after_eight
19
+ klass.after_eight :dine
20
+
21
+ assert_equal [:dine], subject.callbacks_for_hook(:after_eight)
22
+ end
23
+
24
+ describe "#after_eight (adding callbacks)" do
25
+ before do
26
+ subject.define_hook :after_eight
27
+ subject.after_eight :dine
28
+ end
29
+
30
+ it "adds #after_eight hook" do
31
+ assert_equal [:dine], subject.callbacks_for_hook(:after_eight)
32
+ end
33
+
34
+ it "responds to #run_hook" do
35
+ subject.instance_eval do
36
+ def dine; executed << :dine; end
37
+ end
38
+
39
+ subject.run_hook :after_eight
40
+ subject.executed.must_equal [:dine]
41
+ end
42
+ end
43
+ end
44
+ end
metadata CHANGED
@@ -1,62 +1,55 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: hooks
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.1
5
- prerelease:
4
+ version: 0.3.2
6
5
  platform: ruby
7
6
  authors:
8
7
  - Nick Sutterer
9
8
  autorequire:
10
9
  bindir: bin
11
10
  cert_chain: []
12
- date: 2013-05-29 00:00:00.000000000 Z
11
+ date: 2013-11-06 00:00:00.000000000 Z
13
12
  dependencies:
14
13
  - !ruby/object:Gem::Dependency
15
14
  name: minitest
16
15
  requirement: !ruby/object:Gem::Requirement
17
- none: false
18
16
  requirements:
19
- - - ! '>='
17
+ - - '>='
20
18
  - !ruby/object:Gem::Version
21
19
  version: 5.0.0
22
20
  type: :development
23
21
  prerelease: false
24
22
  version_requirements: !ruby/object:Gem::Requirement
25
- none: false
26
23
  requirements:
27
- - - ! '>='
24
+ - - '>='
28
25
  - !ruby/object:Gem::Version
29
26
  version: 5.0.0
30
27
  - !ruby/object:Gem::Dependency
31
28
  name: rake
32
29
  requirement: !ruby/object:Gem::Requirement
33
- none: false
34
30
  requirements:
35
- - - ! '>='
31
+ - - '>='
36
32
  - !ruby/object:Gem::Version
37
33
  version: '0'
38
34
  type: :development
39
35
  prerelease: false
40
36
  version_requirements: !ruby/object:Gem::Requirement
41
- none: false
42
37
  requirements:
43
- - - ! '>='
38
+ - - '>='
44
39
  - !ruby/object:Gem::Version
45
40
  version: '0'
46
41
  - !ruby/object:Gem::Dependency
47
42
  name: pry
48
43
  requirement: !ruby/object:Gem::Requirement
49
- none: false
50
44
  requirements:
51
- - - ! '>='
45
+ - - '>='
52
46
  - !ruby/object:Gem::Version
53
47
  version: '0'
54
48
  type: :development
55
49
  prerelease: false
56
50
  version_requirements: !ruby/object:Gem::Requirement
57
- none: false
58
51
  requirements:
59
- - - ! '>='
52
+ - - '>='
60
53
  - !ruby/object:Gem::Version
61
54
  version: '0'
62
55
  description: Declaratively define hooks, add callbacks and run them with the options
@@ -71,38 +64,42 @@ files:
71
64
  - .travis.yml
72
65
  - CHANGES.md
73
66
  - Gemfile
67
+ - LICENSE.txt
74
68
  - README.md
75
69
  - Rakefile
76
70
  - hooks.gemspec
77
71
  - lib/hooks.rb
78
72
  - lib/hooks/hook.rb
79
73
  - lib/hooks/inheritable_attribute.rb
74
+ - lib/hooks/instance_hooks.rb
75
+ - lib/hooks/version.rb
80
76
  - test/hook_test.rb
81
77
  - test/hooks_test.rb
82
78
  - test/inheritable_attribute_test.rb
79
+ - test/instance_hooks_test.rb
83
80
  - test/test_helper.rb
84
81
  homepage: http://nicksda.apotomo.de/2010/09/hooks-and-callbacks-for-ruby-but-simple/
85
- licenses: []
82
+ licenses:
83
+ - MIT
84
+ metadata: {}
86
85
  post_install_message:
87
86
  rdoc_options: []
88
87
  require_paths:
89
88
  - lib
90
89
  required_ruby_version: !ruby/object:Gem::Requirement
91
- none: false
92
90
  requirements:
93
- - - ! '>='
91
+ - - '>='
94
92
  - !ruby/object:Gem::Version
95
93
  version: '0'
96
94
  required_rubygems_version: !ruby/object:Gem::Requirement
97
- none: false
98
95
  requirements:
99
- - - ! '>='
96
+ - - '>='
100
97
  - !ruby/object:Gem::Version
101
98
  version: '0'
102
99
  requirements: []
103
100
  rubyforge_project:
104
- rubygems_version: 1.8.25
101
+ rubygems_version: 2.0.3
105
102
  signing_key:
106
- specification_version: 3
103
+ specification_version: 4
107
104
  summary: Generic hooks with callbacks for Ruby.
108
105
  test_files: []