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