has-guarded-handlers 1.1.0 → 1.2.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/.travis.yml +9 -0
- data/CHANGELOG.md +7 -3
- data/has-guarded-handlers.gemspec +4 -2
- data/lib/has_guarded_handlers.rb +75 -22
- data/lib/has_guarded_handlers/version.rb +1 -1
- data/spec/has_guarded_handlers_spec.rb +21 -2
- data/spec/spec_helper.rb +0 -4
- metadata +31 -24
data/.travis.yml
ADDED
data/CHANGELOG.md
CHANGED
@@ -1,9 +1,13 @@
|
|
1
|
-
# develop
|
1
|
+
# [develop](https://github.com/adhearsion/has-guarded-handlers)
|
2
2
|
|
3
|
-
# 1.1.0 - 2012-
|
3
|
+
# [1.2.0](https://github.com/adhearsion/has-guarded-handlers/compare/v1.1.0...v1.2.0) - [2012-03-28](https://rubygems.org/gems/has-guarded-handlers/versions/1.2.0)
|
4
|
+
* Feature: Allow registering temporary (single execution) handlers which are removed after they are triggered
|
5
|
+
* Feature: Registering a handler returns an ID by which it may be unregistered
|
6
|
+
|
7
|
+
# [1.1.0](https://github.com/adhearsion/has-guarded-handlers/compare/v1.0.0...v1.1.0) - [2012-01-21](https://rubygems.org/gems/has-guarded-handlers/versions/1.1.0)
|
4
8
|
* Feature: Allow guarding on the value of method calls with arguments, by using an array as a hash key
|
5
9
|
|
6
|
-
# 1.0.0 - 2012-01-19
|
10
|
+
# [1.0.0](https://github.com/adhearsion/has-guarded-handlers/compare/v0.0.1...v1.0.0) - [2012-01-19](https://rubygems.org/gems/has-guarded-handlers/versions/1.0.0)
|
7
11
|
* Bump to 1.0.0 because the API is stable
|
8
12
|
* Feature: Allow guarding with a module to test if an object has a mixin
|
9
13
|
|
@@ -18,11 +18,13 @@ Gem::Specification.new do |s|
|
|
18
18
|
s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
|
19
19
|
s.require_paths = ["lib"]
|
20
20
|
|
21
|
-
s.
|
21
|
+
s.add_dependency 'uuid'
|
22
|
+
|
23
|
+
s.add_development_dependency 'bundler', ["~> 1.0"]
|
22
24
|
s.add_development_dependency 'rspec', [">= 2.5.0"]
|
23
25
|
s.add_development_dependency 'mocha', [">= 0"]
|
24
26
|
s.add_development_dependency 'ci_reporter', [">= 1.6.3"]
|
25
|
-
s.add_development_dependency 'yard', ["
|
27
|
+
s.add_development_dependency 'yard', [">= 0.7.0"]
|
26
28
|
s.add_development_dependency 'rake', [">= 0"]
|
27
29
|
s.add_development_dependency 'guard-rspec'
|
28
30
|
end
|
data/lib/has_guarded_handlers.rb
CHANGED
@@ -1,27 +1,69 @@
|
|
1
1
|
require "has_guarded_handlers/version"
|
2
|
+
require 'uuid'
|
2
3
|
|
3
4
|
module HasGuardedHandlers
|
4
5
|
# Register a handler
|
5
6
|
#
|
6
|
-
# @param [Symbol, nil] type
|
7
|
+
# @param [Symbol, nil] type a classification to separate handlers/events into channels
|
7
8
|
# @param [guards] guards take a look at the guards documentation
|
8
|
-
#
|
9
|
+
#
|
10
|
+
# @yield [Object] trigger_object the incoming event
|
11
|
+
#
|
12
|
+
# @return [String] handler ID for later manipulation
|
9
13
|
def register_handler(type, *guards, &handler)
|
10
|
-
|
14
|
+
register_handler_with_options type, {}, *guards, &handler
|
15
|
+
end
|
16
|
+
|
17
|
+
# Register a temporary handler. Once triggered, the handler will be de-registered
|
18
|
+
#
|
19
|
+
# @param [Symbol, nil] type a classification to separate handlers/events into channels
|
20
|
+
# @param [guards] guards take a look at the guards documentation
|
21
|
+
#
|
22
|
+
# @yield [Object] trigger_object the incoming event
|
23
|
+
#
|
24
|
+
# @return [String] handler ID for later manipulation
|
25
|
+
def register_tmp_handler(type, *guards, &handler)
|
26
|
+
register_handler_with_options type, {:tmp => true}, *guards, &handler
|
11
27
|
end
|
12
28
|
|
13
29
|
# Register a handler with a specified priority
|
14
30
|
#
|
15
|
-
# @param [Symbol, nil] type
|
31
|
+
# @param [Symbol, nil] type a classification to separate handlers/events into channels
|
16
32
|
# @param [Integer] priority the priority of the handler. Higher priority executes first
|
17
33
|
# @param [guards] guards take a look at the guards documentation
|
18
|
-
#
|
34
|
+
#
|
35
|
+
# @yield [Object] trigger_object the incoming event
|
36
|
+
#
|
37
|
+
# @return [String] handler ID for later manipulation
|
19
38
|
def register_handler_with_priority(type, priority, *guards, &handler)
|
20
|
-
|
39
|
+
register_handler_with_options type, {:priority => priority}, *guards, &handler
|
40
|
+
end
|
41
|
+
|
42
|
+
# Register a handler with a specified set of options
|
43
|
+
#
|
44
|
+
# @param [Symbol, nil] type a classification to separate handlers/events into channels
|
45
|
+
# @param [Hash] options the options for the handler
|
46
|
+
# @option options [Integer] :priority (0) the priority of the handler. Higher priority executes first
|
47
|
+
# @option options [true, false] :tmp (false) Wether or not the handler should be considered temporary (single execution)
|
48
|
+
# @param [guards] guards take a look at the guards documentation
|
49
|
+
#
|
50
|
+
# @yield [Object] trigger_object the incoming event
|
51
|
+
#
|
52
|
+
# @return [String] handler ID for later manipulation
|
53
|
+
def register_handler_with_options(type, options, *guards, &handler)
|
21
54
|
check_guards guards
|
22
|
-
|
23
|
-
|
24
|
-
|
55
|
+
options[:priority] ||= 0
|
56
|
+
new_handler_id.tap do |handler_id|
|
57
|
+
guarded_handlers[type][options[:priority]] << [guards, handler, options[:tmp], handler_id]
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
# Unregister a handler by ID
|
62
|
+
#
|
63
|
+
# @param [Symbol] type the handler classification used at registration
|
64
|
+
# @param [String] handler_id the handler ID returned by registration
|
65
|
+
def unregister_handler(type, handler_id)
|
66
|
+
delete_handler_if(type) { |_, _, _, id| id == handler_id }
|
25
67
|
end
|
26
68
|
|
27
69
|
# Clear handlers with given guards
|
@@ -29,26 +71,33 @@ module HasGuardedHandlers
|
|
29
71
|
# @param [Symbol, nil] type remove filters for a specific handler
|
30
72
|
# @param [guards] guards take a look at the guards documentation
|
31
73
|
def clear_handlers(type, *guards)
|
32
|
-
|
33
|
-
@handlers[type].each_pair do |priority, handlers|
|
34
|
-
handlers.delete_if { |g, _| g == guards }
|
35
|
-
end
|
74
|
+
delete_handler_if(type) { |g, _| g == guards }
|
36
75
|
end
|
37
76
|
|
77
|
+
# Trigger a handler classification with an event object
|
78
|
+
#
|
79
|
+
# @param [Symbol, nil] type a classification to separate handlers/events into channels
|
80
|
+
# @param [Object] the event object to yield to the handler block
|
38
81
|
def trigger_handler(type, event)
|
39
|
-
initialize_guarded_handlers
|
40
82
|
return unless handler = handlers_of_type(type)
|
41
83
|
catch :halt do
|
42
|
-
handler.find do |guards, handler|
|
84
|
+
handler.find do |guards, handler, tmp|
|
43
85
|
catch(:pass) { call_handler handler, guards, event }
|
86
|
+
delete_handler_if(type) { |_, h, _| h.equal? handler } if tmp
|
44
87
|
end
|
45
88
|
end
|
46
89
|
end
|
47
90
|
|
48
91
|
private
|
49
92
|
|
50
|
-
def
|
51
|
-
|
93
|
+
def delete_handler_if(type, &block) # :nodoc:
|
94
|
+
guarded_handlers[type].each_pair do |priority, handlers|
|
95
|
+
handlers.delete_if(&block)
|
96
|
+
end
|
97
|
+
end
|
98
|
+
|
99
|
+
def handlers_of_type(type) # :nodoc:
|
100
|
+
return unless hash = guarded_handlers[type]
|
52
101
|
values = []
|
53
102
|
hash.keys.sort.reverse.each do |key|
|
54
103
|
values += hash[key]
|
@@ -56,16 +105,20 @@ module HasGuardedHandlers
|
|
56
105
|
values
|
57
106
|
end
|
58
107
|
|
59
|
-
def call_handler(handler, guards, event)
|
108
|
+
def call_handler(handler, guards, event) # :nodoc:
|
60
109
|
handler.call event unless guarded?(guards, event)
|
61
110
|
end
|
62
111
|
|
112
|
+
def new_handler_id # :nodoc:
|
113
|
+
UUID.new.generate.to_s
|
114
|
+
end
|
115
|
+
|
63
116
|
# If any of the guards returns FALSE this returns true
|
64
117
|
# the logic is reversed to allow short circuiting
|
65
118
|
# (why would anyone want to loop over more values than necessary?)
|
66
119
|
#
|
67
120
|
# @private
|
68
|
-
def guarded?(guards, event)
|
121
|
+
def guarded?(guards, event) # :nodoc:
|
69
122
|
guards.find do |guard|
|
70
123
|
case guard
|
71
124
|
when Class, Module
|
@@ -94,7 +147,7 @@ module HasGuardedHandlers
|
|
94
147
|
end
|
95
148
|
end
|
96
149
|
|
97
|
-
def check_guards(guards)
|
150
|
+
def check_guards(guards) # :nodoc:
|
98
151
|
guards.each do |guard|
|
99
152
|
case guard
|
100
153
|
when Array
|
@@ -107,7 +160,7 @@ module HasGuardedHandlers
|
|
107
160
|
end
|
108
161
|
end
|
109
162
|
|
110
|
-
def
|
111
|
-
@handlers ||= {}
|
163
|
+
def guarded_handlers # :nodoc:
|
164
|
+
@handlers ||= Hash.new { |h, k| h[k] = Hash.new { |h, k| h[k] = [] } }
|
112
165
|
end
|
113
166
|
end
|
@@ -1,7 +1,11 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
|
-
describe
|
4
|
-
|
3
|
+
describe HasGuardedHandlers do
|
4
|
+
subject do
|
5
|
+
Object.new.tap do |o|
|
6
|
+
o.extend HasGuardedHandlers
|
7
|
+
end
|
8
|
+
end
|
5
9
|
|
6
10
|
let(:event) { mock 'Event' }
|
7
11
|
let(:response) { mock 'Response' }
|
@@ -13,6 +17,21 @@ describe TestObject do
|
|
13
17
|
subject.trigger_handler :event, event
|
14
18
|
end
|
15
19
|
|
20
|
+
it 'can register a one-shot (tmp) handler' do
|
21
|
+
response.expects(:call).once.with(event)
|
22
|
+
subject.register_tmp_handler(:event) { |e| response.call e }
|
23
|
+
subject.trigger_handler :event, event
|
24
|
+
subject.trigger_handler :event, event
|
25
|
+
end
|
26
|
+
|
27
|
+
it 'can unregister a handler after registration' do
|
28
|
+
response.expects(:call).once.with(event)
|
29
|
+
subject.register_handler(:event) { |e| response.call e }
|
30
|
+
id = subject.register_handler(:event) { |e| response.call :foo }
|
31
|
+
subject.unregister_handler :event, id
|
32
|
+
subject.trigger_handler :event, event
|
33
|
+
end
|
34
|
+
|
16
35
|
it 'does not fail when no handlers are set' do
|
17
36
|
lambda do
|
18
37
|
subject.trigger_handler :event, event
|
data/spec/spec_helper.rb
CHANGED
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: has-guarded-handlers
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.2.0
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -10,22 +10,33 @@ authors:
|
|
10
10
|
autorequire:
|
11
11
|
bindir: bin
|
12
12
|
cert_chain: []
|
13
|
-
date: 2012-
|
13
|
+
date: 2012-03-28 00:00:00.000000000 Z
|
14
14
|
dependencies:
|
15
|
+
- !ruby/object:Gem::Dependency
|
16
|
+
name: uuid
|
17
|
+
requirement: &2152452540 !ruby/object:Gem::Requirement
|
18
|
+
none: false
|
19
|
+
requirements:
|
20
|
+
- - ! '>='
|
21
|
+
- !ruby/object:Gem::Version
|
22
|
+
version: '0'
|
23
|
+
type: :runtime
|
24
|
+
prerelease: false
|
25
|
+
version_requirements: *2152452540
|
15
26
|
- !ruby/object:Gem::Dependency
|
16
27
|
name: bundler
|
17
|
-
requirement: &
|
28
|
+
requirement: &2152452020 !ruby/object:Gem::Requirement
|
18
29
|
none: false
|
19
30
|
requirements:
|
20
31
|
- - ~>
|
21
32
|
- !ruby/object:Gem::Version
|
22
|
-
version: 1.0
|
33
|
+
version: '1.0'
|
23
34
|
type: :development
|
24
35
|
prerelease: false
|
25
|
-
version_requirements: *
|
36
|
+
version_requirements: *2152452020
|
26
37
|
- !ruby/object:Gem::Dependency
|
27
38
|
name: rspec
|
28
|
-
requirement: &
|
39
|
+
requirement: &2152451500 !ruby/object:Gem::Requirement
|
29
40
|
none: false
|
30
41
|
requirements:
|
31
42
|
- - ! '>='
|
@@ -33,10 +44,10 @@ dependencies:
|
|
33
44
|
version: 2.5.0
|
34
45
|
type: :development
|
35
46
|
prerelease: false
|
36
|
-
version_requirements: *
|
47
|
+
version_requirements: *2152451500
|
37
48
|
- !ruby/object:Gem::Dependency
|
38
49
|
name: mocha
|
39
|
-
requirement: &
|
50
|
+
requirement: &2152451020 !ruby/object:Gem::Requirement
|
40
51
|
none: false
|
41
52
|
requirements:
|
42
53
|
- - ! '>='
|
@@ -44,10 +55,10 @@ dependencies:
|
|
44
55
|
version: '0'
|
45
56
|
type: :development
|
46
57
|
prerelease: false
|
47
|
-
version_requirements: *
|
58
|
+
version_requirements: *2152451020
|
48
59
|
- !ruby/object:Gem::Dependency
|
49
60
|
name: ci_reporter
|
50
|
-
requirement: &
|
61
|
+
requirement: &2164285360 !ruby/object:Gem::Requirement
|
51
62
|
none: false
|
52
63
|
requirements:
|
53
64
|
- - ! '>='
|
@@ -55,21 +66,21 @@ dependencies:
|
|
55
66
|
version: 1.6.3
|
56
67
|
type: :development
|
57
68
|
prerelease: false
|
58
|
-
version_requirements: *
|
69
|
+
version_requirements: *2164285360
|
59
70
|
- !ruby/object:Gem::Dependency
|
60
71
|
name: yard
|
61
|
-
requirement: &
|
72
|
+
requirement: &2164284000 !ruby/object:Gem::Requirement
|
62
73
|
none: false
|
63
74
|
requirements:
|
64
|
-
- -
|
75
|
+
- - ! '>='
|
65
76
|
- !ruby/object:Gem::Version
|
66
77
|
version: 0.7.0
|
67
78
|
type: :development
|
68
79
|
prerelease: false
|
69
|
-
version_requirements: *
|
80
|
+
version_requirements: *2164284000
|
70
81
|
- !ruby/object:Gem::Dependency
|
71
82
|
name: rake
|
72
|
-
requirement: &
|
83
|
+
requirement: &2164282100 !ruby/object:Gem::Requirement
|
73
84
|
none: false
|
74
85
|
requirements:
|
75
86
|
- - ! '>='
|
@@ -77,10 +88,10 @@ dependencies:
|
|
77
88
|
version: '0'
|
78
89
|
type: :development
|
79
90
|
prerelease: false
|
80
|
-
version_requirements: *
|
91
|
+
version_requirements: *2164282100
|
81
92
|
- !ruby/object:Gem::Dependency
|
82
93
|
name: guard-rspec
|
83
|
-
requirement: &
|
94
|
+
requirement: &2164281140 !ruby/object:Gem::Requirement
|
84
95
|
none: false
|
85
96
|
requirements:
|
86
97
|
- - ! '>='
|
@@ -88,7 +99,7 @@ dependencies:
|
|
88
99
|
version: '0'
|
89
100
|
type: :development
|
90
101
|
prerelease: false
|
91
|
-
version_requirements: *
|
102
|
+
version_requirements: *2164281140
|
92
103
|
description: Allow an object's API to provide flexible handler registration, storage
|
93
104
|
and matching to arbitrary events.
|
94
105
|
email:
|
@@ -99,6 +110,7 @@ extra_rdoc_files: []
|
|
99
110
|
files:
|
100
111
|
- .gitignore
|
101
112
|
- .rspec
|
113
|
+
- .travis.yml
|
102
114
|
- CHANGELOG.md
|
103
115
|
- Gemfile
|
104
116
|
- Guardfile
|
@@ -122,18 +134,12 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
122
134
|
- - ! '>='
|
123
135
|
- !ruby/object:Gem::Version
|
124
136
|
version: '0'
|
125
|
-
segments:
|
126
|
-
- 0
|
127
|
-
hash: 2115013965424304008
|
128
137
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
129
138
|
none: false
|
130
139
|
requirements:
|
131
140
|
- - ! '>='
|
132
141
|
- !ruby/object:Gem::Version
|
133
142
|
version: '0'
|
134
|
-
segments:
|
135
|
-
- 0
|
136
|
-
hash: 2115013965424304008
|
137
143
|
requirements: []
|
138
144
|
rubyforge_project: has-guarded-handlers
|
139
145
|
rubygems_version: 1.8.10
|
@@ -144,3 +150,4 @@ summary: A library for associating a set of event handlers, complete with guards
|
|
144
150
|
test_files:
|
145
151
|
- spec/has_guarded_handlers_spec.rb
|
146
152
|
- spec/spec_helper.rb
|
153
|
+
has_rdoc:
|