emittance 0.0.2 → 0.0.3
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.
- checksums.yaml +4 -4
- data/.gitignore +2 -0
- data/.rubocop.yml +10 -0
- data/.travis.yml +9 -0
- data/Gemfile +4 -2
- data/Gemfile.lock +1 -1
- data/README.md +3 -2
- data/Rakefile +5 -3
- data/bin/console +1 -0
- data/emittance.gemspec +15 -22
- data/lib/emittance.rb +12 -6
- data/lib/emittance/action.rb +51 -37
- data/lib/emittance/brokerage.rb +23 -7
- data/lib/emittance/dispatcher.rb +21 -72
- data/lib/emittance/emitter.rb +48 -40
- data/lib/emittance/errors.rb +5 -2
- data/lib/emittance/event.rb +82 -11
- data/lib/emittance/event_lookup.rb +315 -0
- data/lib/emittance/helpers/constant_helpers.rb +33 -0
- data/lib/emittance/helpers/string_helpers.rb +48 -0
- data/lib/emittance/registration.rb +3 -3
- data/lib/emittance/version.rb +2 -2
- data/lib/emittance/watcher.rb +12 -0
- metadata +20 -19
- data/lib/emittance/event/event_builder.rb +0 -154
- data/pkg/emittance-0.0.1.gem +0 -0
@@ -0,0 +1,33 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Emittance
|
4
|
+
module Helpers
|
5
|
+
##
|
6
|
+
# Some helpers for fetching, setting, and manipulating constants.
|
7
|
+
#
|
8
|
+
module ConstantHelpers
|
9
|
+
# Since +Object.const_set+ does not support namespaced constant names, use this to set the constant to the
|
10
|
+
# correct namespace.
|
11
|
+
#
|
12
|
+
# Example:
|
13
|
+
#
|
14
|
+
# my_const_name = 'String::Foo'
|
15
|
+
# Object.const_set my_const_name, 'bar'
|
16
|
+
# # => NameError: wrong constant name String::Foo
|
17
|
+
#
|
18
|
+
# set_namespaced_constant_by_name my_const_name, 'bar'
|
19
|
+
# String::Foo
|
20
|
+
# # => 'bar'
|
21
|
+
#
|
22
|
+
# @param const_name [String] a valid namespaced constant name
|
23
|
+
# @param obj the value you wish to set that constant to
|
24
|
+
def set_namespaced_constant_by_name(const_name, obj)
|
25
|
+
names = const_name.split('::')
|
26
|
+
names.shift if names.size > 1 && names.first.empty?
|
27
|
+
|
28
|
+
namespace = names.size == 1 ? Object : Object.const_get(names[0...-1].join('::'))
|
29
|
+
namespace.const_set names.last, obj
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
@@ -0,0 +1,48 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Emittance
|
4
|
+
module Helpers
|
5
|
+
##
|
6
|
+
# Some helper methods to mix in for the purposes of manipulating strings.
|
7
|
+
#
|
8
|
+
module StringHelpers
|
9
|
+
# Snake case the string, like Rails' +String#underscore+ method. As such, strings that look like namespaced
|
10
|
+
# constants will have the namespace resolver operators replaced with +/+ characters, rather than underscores.
|
11
|
+
# For example: +'Foo::BarBaz'+ becomes +'foo/bar_baz'+.
|
12
|
+
#
|
13
|
+
# @param str [String] the string you wish to convert
|
14
|
+
# @return [String] a new string that is the snake-cased version of the old string
|
15
|
+
def snake_case(str)
|
16
|
+
str.gsub(/::/, '/')
|
17
|
+
.gsub(/([A-Z]+)([A-Z][a-z])/, '\1_\2')
|
18
|
+
.gsub(/([a-z\d])([A-Z])/, '\1_\2')
|
19
|
+
.tr('-', '_')
|
20
|
+
.downcase
|
21
|
+
end
|
22
|
+
|
23
|
+
# Camel case the string, like Rails' +String#classify+ method. This essentially works like the inverse of
|
24
|
+
# +snake_case+, so +'foo/bar_baz'+ becomes +'Foo::BarBaz'+. There is one one notable exception:
|
25
|
+
#
|
26
|
+
# camel_case(snake_case('APIFoo'))
|
27
|
+
# # => 'ApiFoo'
|
28
|
+
#
|
29
|
+
# As such, be mindful when naming your classes.
|
30
|
+
#
|
31
|
+
# @param str [String] the string you wish to convert
|
32
|
+
# @return [String] a new string converted to camel case.
|
33
|
+
def camel_case(str)
|
34
|
+
str = str.sub(/^[a-z\d]*/) { $&.capitalize }
|
35
|
+
str = str.gsub(%r{(?:_|(\/))([a-z\d]*)}) { "#{Regexp.last_match(1)}#{Regexp.last_match(2).capitalize}" }
|
36
|
+
str.gsub(%r{\/}, '::')
|
37
|
+
end
|
38
|
+
|
39
|
+
# Strip all characters that can't go into a constant name.
|
40
|
+
#
|
41
|
+
# @param str [String] the string from which you want to remove punctuation
|
42
|
+
# @return [String] a new string with punctuation stripped
|
43
|
+
def clean_up_punctuation(str)
|
44
|
+
str.gsub(%r{[^A-Za-z\d\_\:\/]}, '')
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
@@ -3,10 +3,10 @@
|
|
3
3
|
module Emittance
|
4
4
|
# @private
|
5
5
|
class Registration
|
6
|
-
attr_reader :
|
6
|
+
attr_reader :event_klass
|
7
7
|
|
8
|
-
def initialize(
|
9
|
-
@
|
8
|
+
def initialize(event_klass, &callback)
|
9
|
+
@event_klass = event_klass
|
10
10
|
@callback = callback
|
11
11
|
end
|
12
12
|
|
data/lib/emittance/version.rb
CHANGED
data/lib/emittance/watcher.rb
CHANGED
@@ -1,7 +1,19 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
module Emittance
|
4
|
+
##
|
5
|
+
# Can watch for events that propagate through the system.
|
6
|
+
#
|
4
7
|
module Watcher
|
8
|
+
# Watch for an event, identified by its class' identifier. If a callback method is provided, then it will call that
|
9
|
+
# method on the caller of +watch+ when the event happens. Otherwise, it will run the callback block.
|
10
|
+
#
|
11
|
+
# @param identifier [Symbol] the event's identifier
|
12
|
+
# @param callback_method [Symbol] one option for adding a callback--the method on the object to call when the
|
13
|
+
# event fires
|
14
|
+
# @param callback [Block] the other option for adding a callback--the block you wish to be executed when the event
|
15
|
+
# fires
|
16
|
+
# @return [Proc] the block that will run when the event fires
|
5
17
|
def watch(identifier, callback_method = nil, &callback)
|
6
18
|
if callback_method
|
7
19
|
Emittance::Dispatcher.register_method_call identifier, self, callback_method
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: emittance
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.3
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Tyler Guillen
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2017-12-
|
11
|
+
date: 2017-12-13 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -25,49 +25,49 @@ dependencies:
|
|
25
25
|
- !ruby/object:Gem::Version
|
26
26
|
version: '1.15'
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
|
-
name:
|
28
|
+
name: pry
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
30
30
|
requirements:
|
31
|
-
- - "
|
31
|
+
- - ">="
|
32
32
|
- !ruby/object:Gem::Version
|
33
|
-
version: '
|
33
|
+
version: '0'
|
34
34
|
type: :development
|
35
35
|
prerelease: false
|
36
36
|
version_requirements: !ruby/object:Gem::Requirement
|
37
37
|
requirements:
|
38
|
-
- - "
|
38
|
+
- - ">="
|
39
39
|
- !ruby/object:Gem::Version
|
40
|
-
version: '
|
40
|
+
version: '0'
|
41
41
|
- !ruby/object:Gem::Dependency
|
42
|
-
name:
|
42
|
+
name: rake
|
43
43
|
requirement: !ruby/object:Gem::Requirement
|
44
44
|
requirements:
|
45
45
|
- - "~>"
|
46
46
|
- !ruby/object:Gem::Version
|
47
|
-
version: '
|
47
|
+
version: '10.0'
|
48
48
|
type: :development
|
49
49
|
prerelease: false
|
50
50
|
version_requirements: !ruby/object:Gem::Requirement
|
51
51
|
requirements:
|
52
52
|
- - "~>"
|
53
53
|
- !ruby/object:Gem::Version
|
54
|
-
version: '
|
54
|
+
version: '10.0'
|
55
55
|
- !ruby/object:Gem::Dependency
|
56
|
-
name:
|
56
|
+
name: rspec
|
57
57
|
requirement: !ruby/object:Gem::Requirement
|
58
58
|
requirements:
|
59
|
-
- - "
|
59
|
+
- - "~>"
|
60
60
|
- !ruby/object:Gem::Version
|
61
|
-
version: '0'
|
61
|
+
version: '3.0'
|
62
62
|
type: :development
|
63
63
|
prerelease: false
|
64
64
|
version_requirements: !ruby/object:Gem::Requirement
|
65
65
|
requirements:
|
66
|
-
- - "
|
66
|
+
- - "~>"
|
67
67
|
- !ruby/object:Gem::Version
|
68
|
-
version: '0'
|
68
|
+
version: '3.0'
|
69
69
|
- !ruby/object:Gem::Dependency
|
70
|
-
name:
|
70
|
+
name: simplecov
|
71
71
|
requirement: !ruby/object:Gem::Requirement
|
72
72
|
requirements:
|
73
73
|
- - ">="
|
@@ -81,7 +81,7 @@ dependencies:
|
|
81
81
|
- !ruby/object:Gem::Version
|
82
82
|
version: '0'
|
83
83
|
- !ruby/object:Gem::Dependency
|
84
|
-
name:
|
84
|
+
name: yard
|
85
85
|
requirement: !ruby/object:Gem::Requirement
|
86
86
|
requirements:
|
87
87
|
- - ">="
|
@@ -124,11 +124,12 @@ files:
|
|
124
124
|
- lib/emittance/emitter.rb
|
125
125
|
- lib/emittance/errors.rb
|
126
126
|
- lib/emittance/event.rb
|
127
|
-
- lib/emittance/
|
127
|
+
- lib/emittance/event_lookup.rb
|
128
|
+
- lib/emittance/helpers/constant_helpers.rb
|
129
|
+
- lib/emittance/helpers/string_helpers.rb
|
128
130
|
- lib/emittance/registration.rb
|
129
131
|
- lib/emittance/version.rb
|
130
132
|
- lib/emittance/watcher.rb
|
131
|
-
- pkg/emittance-0.0.1.gem
|
132
133
|
homepage: https://github.com/aastronautss/emittance
|
133
134
|
licenses:
|
134
135
|
- MIT
|
@@ -1,154 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module Emittance
|
4
|
-
# @private
|
5
|
-
class Event
|
6
|
-
class EventBuilder
|
7
|
-
KLASS_NAME_SUFFIX = 'Event'
|
8
|
-
|
9
|
-
class << self
|
10
|
-
def klass_exists_for_identifier?(identifier)
|
11
|
-
klass_name = generate_event_klass_name identifier
|
12
|
-
!!lookup_event_klass(klass_name)
|
13
|
-
end
|
14
|
-
|
15
|
-
def objects_to_klass(*objs)
|
16
|
-
klass = nil
|
17
|
-
|
18
|
-
klass ||= pass_klass_through(*objs)
|
19
|
-
klass ||= find_by_custom_identifier(*objs)
|
20
|
-
klass ||= generate_event_klass(*objs)
|
21
|
-
|
22
|
-
klass
|
23
|
-
end
|
24
|
-
|
25
|
-
def klass_to_identifier(klass)
|
26
|
-
identifier = nil
|
27
|
-
|
28
|
-
identifier ||= reverse_find_by_custom_identifier(klass)
|
29
|
-
identifier ||= convert_klass_to_identifier(klass)
|
30
|
-
|
31
|
-
identifier
|
32
|
-
end
|
33
|
-
|
34
|
-
def register_custom_identifier(klass, identifier)
|
35
|
-
CustomIdentifiers.set identifier, klass
|
36
|
-
end
|
37
|
-
|
38
|
-
private
|
39
|
-
|
40
|
-
def pass_klass_through(*objs)
|
41
|
-
objs.length == 1 && objs[0].is_a?(Class) && objs[0] < Emittance::Event ? objs[0] : nil
|
42
|
-
end
|
43
|
-
|
44
|
-
def find_by_custom_identifier(*objs)
|
45
|
-
if objs.length == 1
|
46
|
-
CustomIdentifiers.event_klass_for objs[0]
|
47
|
-
else
|
48
|
-
nil
|
49
|
-
end
|
50
|
-
end
|
51
|
-
|
52
|
-
def reverse_find_by_custom_identifier(klass)
|
53
|
-
CustomIdentifiers.identifier_for klass
|
54
|
-
end
|
55
|
-
|
56
|
-
def generate_event_klass_name(*objs)
|
57
|
-
klass_name_parts = objs.map { |obj| klassable_name_for obj }
|
58
|
-
dress_up_klass_name klass_name_parts
|
59
|
-
end
|
60
|
-
|
61
|
-
def generate_event_klass(*objs)
|
62
|
-
klass_name = generate_event_klass_name(*objs)
|
63
|
-
find_or_create_event_klass klass_name
|
64
|
-
end
|
65
|
-
|
66
|
-
def convert_klass_to_identifier(klass)
|
67
|
-
identifier_str = klass.name
|
68
|
-
identifier_str = undress_klass_name identifier_str
|
69
|
-
identifier_str = snake_case identifier_str
|
70
|
-
|
71
|
-
identifier_str.to_sym
|
72
|
-
end
|
73
|
-
|
74
|
-
def klassable_name_for(obj)
|
75
|
-
name_str = obj.to_s
|
76
|
-
name_str = camel_case name_str
|
77
|
-
name_str = clean_up_punctuation name_str
|
78
|
-
|
79
|
-
name_str
|
80
|
-
end
|
81
|
-
|
82
|
-
def camel_case(str)
|
83
|
-
str = str.sub(/^[a-z\d]*/) { $&.capitalize }
|
84
|
-
str.gsub(/(?:_|(\/))([a-z\d]*)/) { "#{$1}#{$2.capitalize}" }
|
85
|
-
end
|
86
|
-
|
87
|
-
def snake_case(str)
|
88
|
-
str.gsub(/::/, '_')
|
89
|
-
.gsub(/([A-Z]+)([A-Z][a-z])/,'\1_\2')
|
90
|
-
.gsub(/([a-z\d])([A-Z])/,'\1_\2')
|
91
|
-
.tr("-", "_")
|
92
|
-
.downcase
|
93
|
-
end
|
94
|
-
|
95
|
-
def clean_up_punctuation(str)
|
96
|
-
str.gsub /[^A-Za-z\d]/, ''
|
97
|
-
end
|
98
|
-
|
99
|
-
def dress_up_klass_name(klass_name_parts)
|
100
|
-
"#{Array(klass_name_parts).join}#{KLASS_NAME_SUFFIX}"
|
101
|
-
end
|
102
|
-
|
103
|
-
def undress_klass_name(klass_name_str)
|
104
|
-
klass_name_str.gsub /#{KLASS_NAME_SUFFIX}$/, ''
|
105
|
-
end
|
106
|
-
|
107
|
-
def lookup_event_klass(klass_name)
|
108
|
-
if Object.const_defined? klass_name
|
109
|
-
Object.const_get klass_name
|
110
|
-
else
|
111
|
-
nil
|
112
|
-
end
|
113
|
-
end
|
114
|
-
|
115
|
-
def find_or_create_event_klass(klass_name)
|
116
|
-
lookup_event_klass(klass_name) || create_event_klass(klass_name)
|
117
|
-
end
|
118
|
-
|
119
|
-
def create_event_klass(klass_name)
|
120
|
-
new_klass = Class.new(Emittance::Event)
|
121
|
-
Object.const_set klass_name, new_klass
|
122
|
-
end
|
123
|
-
end
|
124
|
-
|
125
|
-
class CustomIdentifiers
|
126
|
-
@mappings = {}
|
127
|
-
|
128
|
-
class << self
|
129
|
-
def mapping_exists?(identifier)
|
130
|
-
!!mappings[identifier] || Emittance::Event::EventBuilder.klass_exists_for_identifier?(identifier)
|
131
|
-
end
|
132
|
-
|
133
|
-
def event_klass_for(identifier)
|
134
|
-
mappings[identifier]
|
135
|
-
end
|
136
|
-
|
137
|
-
def identifier_for(event_klass)
|
138
|
-
mappings.key event_klass
|
139
|
-
end
|
140
|
-
|
141
|
-
def set(identifier, event_klass)
|
142
|
-
raise Emittance::InvalidIdentifierError, 'Event identifiers must be a Symbol.' unless identifier.is_a? Symbol
|
143
|
-
raise Emittance::IdentifierTakenError if mapping_exists? identifier
|
144
|
-
mappings[identifier] = event_klass
|
145
|
-
end
|
146
|
-
|
147
|
-
private
|
148
|
-
|
149
|
-
attr_reader :mappings
|
150
|
-
end
|
151
|
-
end
|
152
|
-
end
|
153
|
-
end
|
154
|
-
end
|
data/pkg/emittance-0.0.1.gem
DELETED
Binary file
|