evil_events 0.1.1 → 0.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.
Files changed (44) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop.yml +17 -1
  3. data/.travis.yml +1 -1
  4. data/CHANGELOG.md +29 -1
  5. data/evil_events.gemspec +17 -16
  6. data/lib/evil_events.rb +3 -1
  7. data/lib/evil_events/application.rb +16 -0
  8. data/lib/evil_events/config.rb +23 -6
  9. data/lib/evil_events/{adapters.rb → config/adapters.rb} +4 -4
  10. data/lib/evil_events/config/types.rb +24 -0
  11. data/lib/evil_events/core.rb +1 -0
  12. data/lib/evil_events/core/bootstrap.rb +1 -1
  13. data/lib/evil_events/core/broadcasting/emitter.rb +1 -1
  14. data/lib/evil_events/core/error.rb +8 -0
  15. data/lib/evil_events/core/events.rb +3 -0
  16. data/lib/evil_events/core/events/abstract_event.rb +2 -0
  17. data/lib/evil_events/core/events/event_extensions/class_signature.rb +30 -0
  18. data/lib/evil_events/core/events/event_extensions/class_signature/equalizer.rb +82 -0
  19. data/lib/evil_events/core/events/event_extensions/class_signature/signature.rb +70 -0
  20. data/lib/evil_events/core/events/event_extensions/metadata_extendable.rb +16 -4
  21. data/lib/evil_events/core/events/event_extensions/payloadable.rb +16 -4
  22. data/lib/evil_events/core/events/event_extensions/type_aliasing.rb +1 -1
  23. data/lib/evil_events/core/events/event_factory.rb +7 -2
  24. data/lib/evil_events/core/events/manager.rb +1 -1
  25. data/lib/evil_events/core/events/manager/notifier.rb +2 -1
  26. data/lib/evil_events/core/events/manager_factory.rb +1 -1
  27. data/lib/evil_events/core/events/manager_registry.rb +39 -2
  28. data/lib/evil_events/core/events/serializers.rb +2 -1
  29. data/lib/evil_events/core/events/subscriber/mixin.rb +20 -11
  30. data/lib/evil_events/core/system.rb +16 -0
  31. data/lib/evil_events/core/system/event_manager.rb +33 -3
  32. data/lib/evil_events/core/system/mock.rb +20 -0
  33. data/lib/evil_events/core/system/type_manager.rb +35 -0
  34. data/lib/evil_events/plugins.rb +33 -0
  35. data/lib/evil_events/plugins/elastic_search.rb +6 -0
  36. data/lib/evil_events/plugins/rails.rb +6 -0
  37. data/lib/evil_events/shared.rb +4 -0
  38. data/lib/evil_events/shared/crypto.rb +1 -1
  39. data/lib/evil_events/shared/type_converter.rb +43 -0
  40. data/lib/evil_events/shared/type_converter/converter.rb +45 -0
  41. data/lib/evil_events/shared/type_converter/converter_registry.rb +51 -0
  42. data/lib/evil_events/shared/type_converter/type_builder.rb +51 -0
  43. data/lib/evil_events/version.rb +2 -2
  44. metadata +73 -59
@@ -0,0 +1,70 @@
1
+ # frozen_string_literal: true
2
+
3
+ module EvilEvents::Core::Events::EventExtensions::ClassSignature
4
+ # @api private
5
+ # @since 0.2.0
6
+ class Signature
7
+ # @return [Class{EvilEvents::Core::Events::AbstractEvent}]
8
+ #
9
+ # @since 0.2.0
10
+ attr_reader :event_class
11
+
12
+ # @param event_calass [Class{EvilEvents::Core::Events::AbstractEvent}]
13
+ #
14
+ # @since 0.2.0
15
+ def initialize(event_class)
16
+ @event_class = event_class
17
+ end
18
+
19
+ # @return [Hash]
20
+ #
21
+ # @since 0.2.0
22
+ def payload_stamp
23
+ event_class::Payload.schema
24
+ end
25
+
26
+ # @return [Hash]
27
+ #
28
+ # @since 0.2.0
29
+ def metadata_stamp
30
+ event_class::Metadata.schema
31
+ end
32
+
33
+ # @return [Hash]
34
+ #
35
+ # @since 0.2.0
36
+ def class_stamp
37
+ { name: event_class.name, creation_strategy: event_class.__creation_strategy }
38
+ end
39
+
40
+ # @return [String]
41
+ #
42
+ # @since 0.2.0
43
+ def type_alias_stamp
44
+ event_class.type
45
+ end
46
+
47
+ # @return [Symbol,String]
48
+ #
49
+ # @since 0.2.0
50
+ def delegator_stamp
51
+ event_class.default_delegator
52
+ end
53
+
54
+ # @return [Hash]
55
+ #
56
+ # @since 0.2.0
57
+ def adapter_stamp
58
+ { event_class.adapter_name => event_class.adapter }
59
+ end
60
+
61
+ # @param other [Signature]
62
+ # @return [Boolean]
63
+ #
64
+ # @since 0.2.0
65
+ def ==(other)
66
+ Equalizer.new(self, other).similar_signatures?
67
+ end
68
+ alias_method :eql?, :==
69
+ end
70
+ end
@@ -19,7 +19,7 @@ module EvilEvents::Core::Events::EventExtensions
19
19
  #
20
20
  # @since 0.1.0
21
21
  def build_metadata(**metadata_attributes)
22
- self.class.const_get(:Metadata).new(**metadata_attributes)
22
+ self.class.metadata_class.new(**metadata_attributes)
23
23
  end
24
24
 
25
25
  # @since 0.1.0
@@ -32,20 +32,32 @@ module EvilEvents::Core::Events::EventExtensions
32
32
  super
33
33
  end
34
34
 
35
+ # @return [Class{AbstractMetadata}]
36
+ #
37
+ # @since 0.2.0
38
+ def metadata_class
39
+ const_get(:Metadata)
40
+ end
41
+
35
42
  # @param key [Symbol]
36
43
  # @param type [EvilEvents::Shared::Types::Any]
44
+ # @param options [Hash]
37
45
  # @return void
38
46
  #
39
47
  # @since 0.1.0
40
- def metadata(key, type = EvilEvents::Types::Any)
41
- const_get(:Metadata).attribute(key, type)
48
+ def metadata(key, type = EvilEvents::Types::Any, **options)
49
+ if type.is_a?(Symbol)
50
+ type = EvilEvents::Core::Bootstrap[:event_system].resolve_type(type, **options)
51
+ end
52
+
53
+ metadata_class.attribute(key, type)
42
54
  end
43
55
 
44
56
  # @return [Array<Symbol>]
45
57
  #
46
58
  # @since 0.1.0
47
59
  def metadata_fields
48
- const_get(:Metadata).attribute_names
60
+ metadata_class.attribute_names
49
61
  end
50
62
  end
51
63
  end
@@ -19,7 +19,7 @@ module EvilEvents::Core::Events::EventExtensions
19
19
  #
20
20
  # @since 0.1.0
21
21
  def build_payload(**payload_attributes)
22
- self.class.const_get(:Payload).new(**payload_attributes)
22
+ self.class.payload_class.new(**payload_attributes)
23
23
  end
24
24
 
25
25
  # @since 0.1.0
@@ -32,20 +32,32 @@ module EvilEvents::Core::Events::EventExtensions
32
32
  super
33
33
  end
34
34
 
35
+ # @return [Class{AbstractPayload}]
36
+ #
37
+ # @since 0.2.0
38
+ def payload_class
39
+ const_get(:Payload)
40
+ end
41
+
35
42
  # @param key [Symbol]
36
43
  # @param type [EvilEvents::Shared::Types::Any]
44
+ # @param options [Hash]
37
45
  # @return void
38
46
  #
39
47
  # @since 0.1.0
40
- def payload(key, type = EvilEvents::Types::Any)
41
- const_get(:Payload).attribute(key, type)
48
+ def payload(key, type = EvilEvents::Types::Any, **options)
49
+ if type.is_a?(Symbol)
50
+ type = EvilEvents::Core::Bootstrap[:event_system].resolve_type(type, **options)
51
+ end
52
+
53
+ payload_class.attribute(key, type)
42
54
  end
43
55
 
44
56
  # @return [Array<Symbol>]
45
57
  #
46
58
  # @since 0.1.0
47
59
  def payload_fields
48
- const_get(:Payload).attribute_names
60
+ payload_class.attribute_names
49
61
  end
50
62
  end
51
63
  end
@@ -5,7 +5,7 @@ module EvilEvents::Core::Events::EventExtensions
5
5
  # @since 0.1.0
6
6
  module TypeAliasing
7
7
  # @since 0.1.0
8
- TypeAliasingError = Class.new(StandardError)
8
+ TypeAliasingError = Class.new(EvilEvents::Core::Error)
9
9
  # @since 0.1.0
10
10
  IncopatibleEventTypeError = Class.new(TypeAliasingError)
11
11
  # @since 0.1.0
@@ -5,7 +5,9 @@ module EvilEvents::Core::Events
5
5
  # @since 0.1.1
6
6
  module EventFactory
7
7
  # @since 0.1.1
8
- UNDEFINED_EVENT_ID = 'unknown'
8
+ UNDEFINED_EVENT_ID = 'unknown'
9
+ CLASS_INHERITANCE_STRATEGY = :class_inheritance
10
+ PROC_EVAL_STRATEGY = :proc_eval
9
11
 
10
12
  module_function
11
13
 
@@ -17,10 +19,12 @@ module EvilEvents::Core::Events
17
19
  def create_abstract_class(event_type)
18
20
  Class.new(AbstractEvent).tap do |klass|
19
21
  klass.type(event_type)
22
+ klass.__creation_strategy = CLASS_INHERITANCE_STRATEGY
20
23
 
21
24
  class << klass
22
25
  def inherited(child_class)
23
26
  child_class.type(type)
27
+ child_class.__creation_strategy = CLASS_INHERITANCE_STRATEGY
24
28
  child_class.manage!
25
29
  rescue EvilEvents::Core::Events::ManagerRegistry::AlreadyManagedEventClassError
26
30
  EvilEvents::Core::Bootstrap[:event_system].unregister_event_class(child_class)
@@ -40,10 +44,11 @@ module EvilEvents::Core::Events
40
44
  def create_class(event_type, &event_class_definitions)
41
45
  Class.new(AbstractEvent).tap do |klass|
42
46
  begin
47
+ klass.__creation_strategy = PROC_EVAL_STRATEGY
43
48
  klass.type(event_type)
44
49
  klass.manage!
45
50
  klass.evaluate(&event_class_definitions) if block_given?
46
- rescue EvilEvents::Core::Events::ManagerRegistry::AlreadyManagedEventClassError
51
+ rescue StandardError
47
52
  EvilEvents::Core::Bootstrap[:event_system].unregister_event_class(klass)
48
53
  raise
49
54
  end
@@ -5,7 +5,7 @@ module EvilEvents::Core::Events
5
5
  # @since 0.1.0
6
6
  class Manager
7
7
  # @since 0.1.0
8
- ManagerError = Class.new(StandardError)
8
+ ManagerError = Class.new(EvilEvents::Core::Error)
9
9
  # @since 0.1.0
10
10
  InconsistentEventClassError = Class.new(ManagerError)
11
11
  # @since 0.1.0
@@ -5,7 +5,7 @@ class EvilEvents::Core::Events::Manager
5
5
  # @since 0.1.0
6
6
  module Notifier
7
7
  # @since 0.1.0
8
- NotifierError = Class.new(StandardError)
8
+ NotifierError = Class.new(EvilEvents::Core::Error)
9
9
  # @since 0.1.0
10
10
  InconsistentEventClassError = Class.new(NotifierError)
11
11
 
@@ -14,6 +14,7 @@ class EvilEvents::Core::Events::Manager
14
14
  # @since 0.1.0
15
15
  extend Forwardable
16
16
 
17
+ # @since 0.1.0
17
18
  def_delegators :errors_stack, :<<, :empty?
18
19
 
19
20
  # @return [Concurrent::Array]
@@ -5,7 +5,7 @@ module EvilEvents::Core::Events
5
5
  # @since 0.1.0
6
6
  module ManagerFactory
7
7
  # @since 0.1.0
8
- ManagerFactoryError = Class.new(StandardError)
8
+ ManagerFactoryError = Class.new(EvilEvents::Core::Error)
9
9
  # @since 0.1.0
10
10
  IncorrectEventClassError = Class.new(ManagerFactoryError)
11
11
 
@@ -8,7 +8,7 @@ module EvilEvents::Core::Events
8
8
  extend Forwardable
9
9
 
10
10
  # @since 0.1.0
11
- ManagerRegistryError = Class.new(StandardError)
11
+ ManagerRegistryError = Class.new(EvilEvents::Core::Error)
12
12
  # @since 0.1.0
13
13
  IncorrectManagerObjectError = Class.new(ManagerRegistryError)
14
14
  # @since 0.1.0
@@ -16,6 +16,7 @@ module EvilEvents::Core::Events
16
16
  # @since 0.1.0
17
17
  AlreadyManagedEventClassError = Class.new(ManagerRegistryError)
18
18
 
19
+ # @since 0.1.0
19
20
  def_delegators :managers, :empty?, :size
20
21
 
21
22
  # @return [Concurrent::Map]
@@ -44,10 +45,37 @@ module EvilEvents::Core::Events
44
45
  #
45
46
  # @since 0.1.0
46
47
  def manager_of_event_type(event_type)
47
- event_class = managed_events.find { |managed_event| managed_event.type == event_type }
48
+ event_class = managed_events.find do |managed_event|
49
+ managed_event.type == event_type
50
+ end
51
+
48
52
  manager_of_event(event_class)
49
53
  end
50
54
 
55
+ # @param event_pattern [Regexp]
56
+ # @return [Array<EvilEvents::Core::Events::Manager>]
57
+ #
58
+ # @since 0.2.0
59
+ def managers_of_event_pattern(event_pattern)
60
+ event_classes = managed_events.select do |managed_event|
61
+ managed_event.type.match(event_pattern)
62
+ end
63
+
64
+ event_classes.map { |event_class| manager_of_event(event_class) }
65
+ end
66
+
67
+ # @param event_condition [Proc]
68
+ # @return [Array<EvilEvents::Core::Event::Manager>]
69
+ #
70
+ # @since 0.2.0
71
+ def managers_of_event_condition(event_condition)
72
+ event_classes = managed_events.select do |managed_event|
73
+ !!event_condition.call(managed_event.type)
74
+ end
75
+
76
+ event_classes.map { |event_class| manager_of_event(event_class) }
77
+ end
78
+
51
79
  # @param manager [EvilEvents::Core::Events::Manager]
52
80
  # @raise [IncorrectManagerObjectError]
53
81
  # @raise [AlreadyManagedEventClassError]
@@ -105,6 +133,15 @@ module EvilEvents::Core::Events
105
133
  managers.key?(event_class)
106
134
  end
107
135
 
136
+ # @return [Hash]
137
+ #
138
+ # @since 0.2.0
139
+ def managed_events_map
140
+ managed_events.each_with_object({}) do |event, accumulator|
141
+ accumulator[event.type] = event
142
+ end
143
+ end
144
+
108
145
  private
109
146
 
110
147
  # @return [Array<EvilEvents::Core::Events::AbstractEvent>]
@@ -4,10 +4,11 @@ module EvilEvents::Core::Events
4
4
  # @api private
5
5
  # @since 0.1.0
6
6
  class Serializers
7
+ # @since 0.1.0
7
8
  extend EvilEvents::Shared::DependencyContainer::Mixin
8
9
 
9
10
  # @since 0.1.0
10
- SerializersError = Class.new(StandardError)
11
+ SerializersError = Class.new(EvilEvents::Core::Error)
11
12
  # @since 0.1.0
12
13
  SerializationError = Class.new(SerializersError)
13
14
  # @since 0.1.0
@@ -4,19 +4,28 @@ class EvilEvents::Core::Events::Subscriber
4
4
  # @api public
5
5
  # @since 0.1.0
6
6
  Mixin = EvilEvents::Shared::ClonableModuleBuilder.build do
7
- # @param event_type [String, Class{EvilEvents::Core::Events::AbstractEvent}]
7
+ # @param event_type [Array<String, Class{EvilEvents::Core::Events::AbstractEvent}, Regexp>]
8
8
  # @param delegator [String, Symbol, NilClass]
9
- # @raise [IncompatibleEventAttrTypeError]
9
+ # @raise [EvilEvents::Core::ArgumentError]
10
10
  #
11
- # @since 0.1.0
12
- def subscribe_to(event_type, delegator: nil)
13
- case event_type
14
- when Class
15
- EvilEvents::Core::Bootstrap[:event_system].observe(event_type, self, delegator)
16
- when String
17
- EvilEvents::Core::Bootstrap[:event_system].raw_observe(event_type, self, delegator)
18
- else
19
- raise ArgumentError
11
+ # @since 0.2.0
12
+ def subscribe_to(*event_types, delegator: nil)
13
+ raise EvilEvents::Core::ArgumentError unless event_types.all? do |event_type|
14
+ event_type.is_a?(Class) ||
15
+ event_type.is_a?(String) ||
16
+ event_type.is_a?(Regexp) ||
17
+ event_type.is_a?(Proc)
18
+ end
19
+
20
+ event_system = EvilEvents::Core::Bootstrap[:event_system]
21
+
22
+ event_types.each do |event_type|
23
+ case event_type
24
+ when Class then event_system.observe(event_type, self, delegator)
25
+ when String then event_system.raw_observe(event_type, self, delegator)
26
+ when Regexp then event_system.observe_list(event_type, self, delegator)
27
+ when Proc then event_system.conditional_observe(event_type, self, delegator)
28
+ end
20
29
  end
21
30
  end
22
31
  end
@@ -9,6 +9,7 @@ module EvilEvents::Core
9
9
  require_relative 'system/broadcaster'
10
10
  require_relative 'system/event_builder'
11
11
  require_relative 'system/event_manager'
12
+ require_relative 'system/type_manager'
12
13
 
13
14
  # @since 0.1.0
14
15
  extend Forwardable
@@ -28,11 +29,14 @@ module EvilEvents::Core
28
29
  def_delegators :event_manager,
29
30
  :observe,
30
31
  :raw_observe,
32
+ :observe_list,
33
+ :conditional_observe,
31
34
  :observers,
32
35
  :register_event_class,
33
36
  :unregister_event_class,
34
37
  :manager_of_event,
35
38
  :manager_of_event_type,
39
+ :registered_events,
36
40
  :resolve_event_class,
37
41
  :resolve_event_object,
38
42
  :managed_event?
@@ -45,6 +49,12 @@ module EvilEvents::Core
45
49
  :deserialize_from_json,
46
50
  :deserialize_from_hash
47
51
 
52
+ # @see EvilEvents::Core::System::TypeManager
53
+ # @since 0.2.0
54
+ def_delegators :type_manager,
55
+ :register_converter,
56
+ :resolve_type
57
+
48
58
  # @return [EvilEvents::Core::System::Broadcaster]
49
59
  #
50
60
  # @since 0.1.0
@@ -55,10 +65,16 @@ module EvilEvents::Core
55
65
  # @since 0.1.0
56
66
  attr_reader :event_manager
57
67
 
68
+ # @return [EvilEvents::Core::System::TypeManager]
69
+ #
70
+ # @since 0.2.0
71
+ attr_reader :type_manager
72
+
58
73
  # @since 0.1.0
59
74
  def initialize
60
75
  @broadcaster = Broadcaster.new
61
76
  @event_manager = EventManager.new
77
+ @type_manager = TypeManager.new
62
78
  end
63
79
  end
64
80
  end
@@ -14,7 +14,7 @@ class EvilEvents::Core::System
14
14
  end
15
15
 
16
16
  # @param event_class [Class{Evilevents::Core::Events::AbstractEvent}]
17
- # @param raw_subscriber [Object]
17
+ # @param raw_subscriber [Mixed]
18
18
  # @param delegator [String, Symbol, NilClass]
19
19
  # @return void
20
20
  #
@@ -25,7 +25,7 @@ class EvilEvents::Core::System
25
25
  end
26
26
 
27
27
  # @param event_type [String, Symbol]
28
- # @param raw_subscriber [Object]
28
+ # @param raw_subscriber [Mixed]
29
29
  # @param delegator [String, Symbol, NilClass]
30
30
  # @return void
31
31
  #
@@ -35,6 +35,28 @@ class EvilEvents::Core::System
35
35
  .observe(raw_subscriber, delegator)
36
36
  end
37
37
 
38
+ # @param event_pattern [Regexp]
39
+ # @param raw_subscriber [Mixed]
40
+ # @param delegator [String, Symbol, NilClass]
41
+ # @return void
42
+ #
43
+ # @since 0.2.0
44
+ def observe_list(event_pattern, raw_subscriber, delegator)
45
+ manager_registry.managers_of_event_pattern(event_pattern)
46
+ .each { |manager| manager.observe(raw_subscriber, delegator) }
47
+ end
48
+
49
+ # @param event_condition [Proc]
50
+ # @param raw_subscriber [Mixed]
51
+ # @param delegator [String, Symbol, NilClass]
52
+ # @return void
53
+ #
54
+ # @since 0.2.0
55
+ def conditional_observe(event_condition, raw_subscriber, delegator)
56
+ manager_registry.managers_of_event_condition(event_condition)
57
+ .each { |manager| manager.observe(raw_subscriber, delegator) }
58
+ end
59
+
38
60
  # @param event_class [Class{EvilEvents::Core::Events::AbstractEvent}]
39
61
  # @return [Array<EvilEvents::Core::Events::Subscriber>]
40
62
  #
@@ -76,11 +98,12 @@ class EvilEvents::Core::System
76
98
  end
77
99
 
78
100
  # @param event_type [String]
101
+ # @option id [String,NilClass]
79
102
  # @option payload [Hash]
80
103
  # @option metadata [Hash]
81
104
  # @return [EvilEvents::Core::Events::AbstractEvent]
82
105
  #
83
- # @since 0.1.0
106
+ # @since 0.1.1
84
107
  def resolve_event_object(event_type, id: nil, payload: {}, metadata: {})
85
108
  manager_of_event_type(event_type).event_class.new(
86
109
  id: id, payload: payload, metadata: metadata
@@ -95,6 +118,13 @@ class EvilEvents::Core::System
95
118
  manager_of_event_type(event_type).event_class
96
119
  end
97
120
 
121
+ # @return [Hash]
122
+ #
123
+ # @since 0.2.0
124
+ def registered_events
125
+ manager_registry.managed_events_map
126
+ end
127
+
98
128
  # @param event_class [EvilEvents::Core::Events::AbstractEvent]
99
129
  # @return [Boolean]
100
130
  #