octiron 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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 336926004fffc1105bb354c76c1e5435d95b27fc
4
- data.tar.gz: 9d6efe5638f209dfabf38062969b72dc0ce71ec6
3
+ metadata.gz: 5f6820493b0a41711b72e1cfa9b460a668c1c51a
4
+ data.tar.gz: 927c382237fb5ac19863356b451a5cef89610248
5
5
  SHA512:
6
- metadata.gz: 05c58fdb427c609711728fb4f965a7e5a86cebe5ccac9d8f87043e1921c690562f775c0a14fb3204b7dc9b4a6d33fc6c2ddbad2999352aa2b5966d353193089a
7
- data.tar.gz: fbec63c5c3956741db10a49445503aa8892d77956e3139e9539749b06e6b524998dc91e30992ec26f9b272b35d923537753b34ebdfcd4bbaed8a7708e57b5ac7
6
+ metadata.gz: 4a2ed141ecc3d958d49e9e9e3e79ee6e2d6187b4c470934119f8cfb71c7a756d7b8caf89a2b26552d69cc7545d61d72c342ed076c0a7a97b152e875c0afed399
7
+ data.tar.gz: d6843fe8e9550957fb1eee0a2cfdbee28d01ee65eab309c69842f1056709c26ad9a0bc4707c515e8c2213ca74fcdc6ba8665fdea2d996cb12e4e9189b7f53953
@@ -6,7 +6,6 @@ engines:
6
6
  enabled: true
7
7
  exclude_fingerprints:
8
8
  - 8d15a3402e79d161b5ae30535883e4e4
9
- engines:
10
9
  config:
11
10
  languages:
12
11
  - ruby
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- octiron (0.1.1)
4
+ octiron (0.2.0)
5
5
  collapsium (~> 0.8)
6
6
  rgl (~> 0.5)
7
7
 
data/README.md CHANGED
@@ -52,7 +52,7 @@ end
52
52
  ```
53
53
 
54
54
  As long as the transmogrifier returns an object of the `AnotherEvent` type,
55
- all is well.
55
+ all is well. Otherwise, an exception is raised.
56
56
 
57
57
  Putting this together with the hitherto unmentioned `#publish` method, you can
58
58
  easily build processing pipelines.
@@ -78,6 +78,50 @@ publish MyEvent.new
78
78
 
79
79
  There are some more advanced topics that might be useful to understand.
80
80
 
81
+ ### Automatic Transmogrification
82
+
83
+ When you write a lot of transmogrifiers, chances are your event handlers all
84
+ look roughly the same:
85
+
86
+ ```ruby
87
+ on_event(SourceEvent) do |event|
88
+ begin
89
+ new_event = transmogrify(event).to AnotherEvent
90
+ publish(new_event)
91
+ rescue RuntimeError
92
+ end
93
+ end
94
+ ```
95
+
96
+ This event handler pattern *tries* to transmogrify the source event to another
97
+ type, and on success will publish the result. On failure, it just wants to
98
+ swallow the event.
99
+
100
+ This pattern is supported with the `#autotransmogrify` function:
101
+
102
+ ```ruby
103
+ autotransmogrify(SourceEvent) do |event|
104
+ if not some_condition
105
+ next
106
+ end
107
+ AnotherEvent.new
108
+ end
109
+ ```
110
+
111
+ Your transmogrifier is installed as previously, and additionally an event handler
112
+ is registered that follows the pattern above. If the transmogrifier returns
113
+ no new event, that is silently accepted.
114
+
115
+ You can use `#autotransmogrify` and still raise errors, of course:
116
+
117
+ ```ruby
118
+ autotransmogrify(SourceEvent, raise_on_nil: true) do |_|
119
+ # do nothing
120
+ end
121
+
122
+ publish(SourceEvent.new) # will raise RuntimeError
123
+ ```
124
+
81
125
  ### Singletons vs. API
82
126
 
83
127
  The octiron gem exposes a number of simple wrapper functions we've used so far
@@ -26,6 +26,12 @@ module Octiron::Events
26
26
  # Event classes.
27
27
  def initialize(default_namespace = ::Octiron::Events)
28
28
  @default_namespace = default_namespace.to_s
29
+ clear
30
+ end
31
+
32
+ ##
33
+ # Clears all event handlers
34
+ def clear
29
35
  @handlers = {}
30
36
  end
31
37
 
@@ -42,6 +42,12 @@ module Octiron::Transmogrifiers
42
42
  # Transmogrifier classes.
43
43
  def initialize(default_namespace = ::Octiron::Transmogrifiers)
44
44
  @default_namespace = default_namespace.to_s
45
+ clear
46
+ end
47
+
48
+ ##
49
+ # Clears the registry of all transmogrifiers
50
+ def clear
45
51
  @graph = RGL::DirectedAdjacencyGraph.new
46
52
  @visitor = RGL::DijkstraVisitor.new(@graph)
47
53
  @map_data = {}
@@ -8,5 +8,5 @@
8
8
  #
9
9
  module Octiron
10
10
  # The current release version
11
- VERSION = "0.1.1".freeze
11
+ VERSION = "0.2.0".freeze
12
12
  end
@@ -67,12 +67,51 @@ module Octiron::World
67
67
  end
68
68
  end
69
69
 
70
+ ##
71
+ # Delegator for the autotransmogiry(FROM).to TO syntax
72
+ # @api private
73
+ class AutoTransmogrifyDelegator < TransmogrifierRegistrator
74
+ def initialize(from, raise_on_nil)
75
+ @from = from
76
+ @raise_on_nil = raise_on_nil
77
+ end
78
+
79
+ def to(to, transmogrifier_object = nil, &transmogrifier_proc)
80
+ # First register the transmogrifier
81
+ super
82
+
83
+ # Then create an event handler that chains the transmogrify step with a
84
+ # publish step.
85
+ ::Octiron::World.event_bus.subscribe(@from) do |event|
86
+ # By default, we don't want to raise errors if the transmogrifier
87
+ # returns nil. Still, raising should be activated optionally.
88
+ begin
89
+ new_ev = ::Octiron::World.transmogrifier_registry.transmogrify(event, to)
90
+ ::Octiron::World.event_bus.publish(new_ev)
91
+ rescue RuntimeError
92
+ if @raise_on_nil
93
+ raise
94
+ end
95
+ end
96
+ end
97
+ end
98
+ end
99
+
70
100
  ##
71
101
  # Register a transmogrifier with the singleton transmogrifier registry
72
102
  def on_transmogrify(from)
73
103
  return TransmogrifierRegistrator.new(from)
74
104
  end
75
105
 
106
+ ##
107
+ # Automatically transmogrify one event type to another, and publish the result.
108
+ # By default, a transmogrifier that returns a nil object simply does not
109
+ # publish a result.
110
+ def autotransmogrify(from, options = {})
111
+ raise_on_nil = options[:raise_on_nil] || false
112
+ return AutoTransmogrifyDelegator.new(from, raise_on_nil)
113
+ end
114
+
76
115
  ##
77
116
  # Transmogrify using the singleton transmogrifier registry
78
117
  def transmogrify(from)
@@ -11,6 +11,9 @@ describe Octiron::World do
11
11
  before :each do
12
12
  @tester = Class.new
13
13
  @tester.extend(Octiron::World)
14
+
15
+ Octiron::World.transmogrifier_registry.clear
16
+ Octiron::World.event_bus.clear
14
17
  end
15
18
 
16
19
  describe "singletons" do
@@ -55,4 +58,41 @@ describe Octiron::World do
55
58
  expect(result.class).to eql Test2
56
59
  end
57
60
  end
61
+
62
+ describe "autotransmogrification" do
63
+ it "autotransmogrifies events" do
64
+ @tester.autotransmogrify(Test1).to Test2 do |_|
65
+ next Test2.new
66
+ end
67
+
68
+ invoked = 0
69
+ @tester.on_event(Test2) do |_|
70
+ invoked += 1
71
+ end
72
+
73
+ @tester.publish(Test1.new)
74
+ expect(invoked).to eql 1
75
+ end
76
+
77
+ it "ignores nil transmogrification results by default" do
78
+ @tester.autotransmogrify(Test1).to Test2 do |_|
79
+ # Nothing happening here
80
+ end
81
+
82
+ invoked = 0
83
+ @tester.on_event(Test2) do |_|
84
+ invoked += 1
85
+ end
86
+
87
+ @tester.publish(Test1.new)
88
+ expect(invoked).to eql 0
89
+ end
90
+
91
+ it "can raise on nil transmogrification results" do
92
+ @tester.autotransmogrify(Test1, raise_on_nil: true).to Test2 do |_|
93
+ # Nothing happening here
94
+ end
95
+ expect { @tester.publish(Test1.new) }.to raise_error(RuntimeError)
96
+ end
97
+ end
58
98
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: octiron
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.1
4
+ version: 0.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jens Finkhaeuser
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2016-12-12 00:00:00.000000000 Z
11
+ date: 2016-12-14 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler