has-guarded-handlers 1.1.0 → 1.2.0

Sign up to get free protection for your applications and to get access to all the features.
data/.travis.yml ADDED
@@ -0,0 +1,9 @@
1
+ language: ruby
2
+ rvm:
3
+ - 1.9.2
4
+ - 1.9.3
5
+ - jruby-19mode # JRuby in 1.9 mode
6
+ - rbx-19mode # currently in active development, may or may not work for your project
7
+ - ruby-head
8
+ notifications:
9
+ irc: "irc.freenode.org#adhearsion"
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-01-21
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.add_development_dependency 'bundler', ["~> 1.0.0"]
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', ["~> 0.7.0"]
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
@@ -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 set the filter on a specific handler
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
- # @yield [Object] stanza the incoming event
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
- register_handler_with_priority type, 0, *guards, &handler
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 set the filter on a specific handler
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
- # @yield [Object] stanza the incoming event
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
- initialize_guarded_handlers
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
- @handlers[type] ||= {}
23
- @handlers[type][priority] ||= []
24
- @handlers[type][priority] << [guards, handler]
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
- initialize_guarded_handlers
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 handlers_of_type(type)
51
- return unless hash = @handlers[type]
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 initialize_guarded_handlers
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,3 +1,3 @@
1
1
  module HasGuardedHandlers
2
- VERSION = "1.1.0"
2
+ VERSION = "1.2.0"
3
3
  end
@@ -1,7 +1,11 @@
1
1
  require 'spec_helper'
2
2
 
3
- describe TestObject do
4
- it { should be_a TestObject }
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
@@ -9,7 +9,3 @@ RSpec.configure do |config|
9
9
  config.filter_run :focus => true
10
10
  config.run_all_when_everything_filtered = true
11
11
  end
12
-
13
- class TestObject
14
- include HasGuardedHandlers
15
- end
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.1.0
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-01-21 00:00:00.000000000 Z
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: &2152688380 !ruby/object:Gem::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.0
33
+ version: '1.0'
23
34
  type: :development
24
35
  prerelease: false
25
- version_requirements: *2152688380
36
+ version_requirements: *2152452020
26
37
  - !ruby/object:Gem::Dependency
27
38
  name: rspec
28
- requirement: &2152687820 !ruby/object:Gem::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: *2152687820
47
+ version_requirements: *2152451500
37
48
  - !ruby/object:Gem::Dependency
38
49
  name: mocha
39
- requirement: &2152687260 !ruby/object:Gem::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: *2152687260
58
+ version_requirements: *2152451020
48
59
  - !ruby/object:Gem::Dependency
49
60
  name: ci_reporter
50
- requirement: &2152683040 !ruby/object:Gem::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: *2152683040
69
+ version_requirements: *2164285360
59
70
  - !ruby/object:Gem::Dependency
60
71
  name: yard
61
- requirement: &2152682360 !ruby/object:Gem::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: *2152682360
80
+ version_requirements: *2164284000
70
81
  - !ruby/object:Gem::Dependency
71
82
  name: rake
72
- requirement: &2152681860 !ruby/object:Gem::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: *2152681860
91
+ version_requirements: *2164282100
81
92
  - !ruby/object:Gem::Dependency
82
93
  name: guard-rspec
83
- requirement: &2152681480 !ruby/object:Gem::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: *2152681480
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: