synapse-core 0.1.2
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/lib/synapse.rb +351 -0
- data/lib/synapse/command/command_bus.rb +45 -0
- data/lib/synapse/command/command_callback.rb +18 -0
- data/lib/synapse/command/command_filter.rb +17 -0
- data/lib/synapse/command/command_handler.rb +13 -0
- data/lib/synapse/command/dispatch_interceptor.rb +16 -0
- data/lib/synapse/command/duplication.rb +43 -0
- data/lib/synapse/command/errors.rb +27 -0
- data/lib/synapse/command/filters/validation.rb +32 -0
- data/lib/synapse/command/gateway.rb +34 -0
- data/lib/synapse/command/interceptor_chain.rb +31 -0
- data/lib/synapse/command/interceptors/serialization.rb +35 -0
- data/lib/synapse/command/message.rb +19 -0
- data/lib/synapse/command/rollback_policy.rb +22 -0
- data/lib/synapse/command/simple_command_bus.rb +138 -0
- data/lib/synapse/command/wiring.rb +47 -0
- data/lib/synapse/domain/aggregate_root.rb +121 -0
- data/lib/synapse/domain/event_container.rb +127 -0
- data/lib/synapse/domain/message.rb +82 -0
- data/lib/synapse/domain/message_builder.rb +34 -0
- data/lib/synapse/domain/stream.rb +108 -0
- data/lib/synapse/duplication.rb +60 -0
- data/lib/synapse/errors.rb +13 -0
- data/lib/synapse/event_bus/event_bus.rb +40 -0
- data/lib/synapse/event_bus/event_listener.rb +16 -0
- data/lib/synapse/event_bus/event_listener_proxy.rb +12 -0
- data/lib/synapse/event_bus/simple_event_bus.rb +69 -0
- data/lib/synapse/event_bus/wiring.rb +23 -0
- data/lib/synapse/event_sourcing/aggregate_factory.rb +69 -0
- data/lib/synapse/event_sourcing/aggregate_root.rb +104 -0
- data/lib/synapse/event_sourcing/conflict_resolver.rb +80 -0
- data/lib/synapse/event_sourcing/entity.rb +64 -0
- data/lib/synapse/event_sourcing/member.rb +72 -0
- data/lib/synapse/event_sourcing/repository.rb +119 -0
- data/lib/synapse/event_sourcing/snapshot/count_stream.rb +86 -0
- data/lib/synapse/event_sourcing/snapshot/count_trigger.rb +91 -0
- data/lib/synapse/event_sourcing/snapshot/taker.rb +73 -0
- data/lib/synapse/event_sourcing/storage_listener.rb +34 -0
- data/lib/synapse/event_sourcing/stream_decorator.rb +25 -0
- data/lib/synapse/event_store/errors.rb +16 -0
- data/lib/synapse/event_store/event_store.rb +43 -0
- data/lib/synapse/event_store/in_memory.rb +59 -0
- data/lib/synapse/event_store/mongo/cursor_event_stream.rb +63 -0
- data/lib/synapse/event_store/mongo/event_store.rb +86 -0
- data/lib/synapse/event_store/mongo/per_commit_strategy.rb +253 -0
- data/lib/synapse/event_store/mongo/per_event_strategy.rb +143 -0
- data/lib/synapse/event_store/mongo/storage_strategy.rb +113 -0
- data/lib/synapse/event_store/mongo/template.rb +73 -0
- data/lib/synapse/identifier.rb +23 -0
- data/lib/synapse/message.rb +101 -0
- data/lib/synapse/message_builder.rb +38 -0
- data/lib/synapse/process_manager/correlation.rb +32 -0
- data/lib/synapse/process_manager/correlation_resolver.rb +14 -0
- data/lib/synapse/process_manager/correlation_set.rb +58 -0
- data/lib/synapse/process_manager/process.rb +71 -0
- data/lib/synapse/repository/errors.rb +26 -0
- data/lib/synapse/repository/lock_manager.rb +40 -0
- data/lib/synapse/repository/locking.rb +97 -0
- data/lib/synapse/repository/pessimistic_lock_manager.rb +61 -0
- data/lib/synapse/repository/repository.rb +109 -0
- data/lib/synapse/serialization/converter.rb +39 -0
- data/lib/synapse/serialization/converter/chain.rb +45 -0
- data/lib/synapse/serialization/converter/factory.rb +68 -0
- data/lib/synapse/serialization/converter/identity.rb +29 -0
- data/lib/synapse/serialization/converter/json.rb +31 -0
- data/lib/synapse/serialization/converter/ox.rb +31 -0
- data/lib/synapse/serialization/errors.rb +12 -0
- data/lib/synapse/serialization/lazy_object.rb +61 -0
- data/lib/synapse/serialization/message/data.rb +25 -0
- data/lib/synapse/serialization/message/metadata.rb +13 -0
- data/lib/synapse/serialization/message/serialization_aware.rb +17 -0
- data/lib/synapse/serialization/message/serialization_aware_message.rb +66 -0
- data/lib/synapse/serialization/message/serialized_message.rb +201 -0
- data/lib/synapse/serialization/message/serialized_message_builder.rb +64 -0
- data/lib/synapse/serialization/message/serialized_object_cache.rb +50 -0
- data/lib/synapse/serialization/message/serializer.rb +47 -0
- data/lib/synapse/serialization/revision_resolver.rb +30 -0
- data/lib/synapse/serialization/serialized_object.rb +37 -0
- data/lib/synapse/serialization/serialized_type.rb +31 -0
- data/lib/synapse/serialization/serializer.rb +98 -0
- data/lib/synapse/serialization/serializer/marshal.rb +32 -0
- data/lib/synapse/serialization/serializer/oj.rb +34 -0
- data/lib/synapse/serialization/serializer/ox.rb +31 -0
- data/lib/synapse/uow/factory.rb +28 -0
- data/lib/synapse/uow/listener.rb +79 -0
- data/lib/synapse/uow/listener_collection.rb +93 -0
- data/lib/synapse/uow/nesting.rb +262 -0
- data/lib/synapse/uow/provider.rb +71 -0
- data/lib/synapse/uow/storage_listener.rb +14 -0
- data/lib/synapse/uow/transaction_manager.rb +27 -0
- data/lib/synapse/uow/uow.rb +178 -0
- data/lib/synapse/upcasting/chain.rb +78 -0
- data/lib/synapse/upcasting/context.rb +58 -0
- data/lib/synapse/upcasting/data.rb +30 -0
- data/lib/synapse/upcasting/single_upcaster.rb +57 -0
- data/lib/synapse/upcasting/upcaster.rb +55 -0
- data/lib/synapse/version.rb +3 -0
- data/lib/synapse/wiring/message_wiring.rb +41 -0
- data/lib/synapse/wiring/wire.rb +55 -0
- data/lib/synapse/wiring/wire_registry.rb +61 -0
- data/test/command/duplication_test.rb +54 -0
- data/test/command/gateway_test.rb +25 -0
- data/test/command/interceptor_chain_test.rb +26 -0
- data/test/command/serialization_test.rb +37 -0
- data/test/command/simple_command_bus_test.rb +141 -0
- data/test/command/validation_test.rb +42 -0
- data/test/command/wiring_test.rb +73 -0
- data/test/domain/aggregate_root_test.rb +57 -0
- data/test/domain/fixtures.rb +31 -0
- data/test/domain/message_test.rb +61 -0
- data/test/domain/stream_test.rb +35 -0
- data/test/duplication_test.rb +40 -0
- data/test/event_bus/wiring_test.rb +46 -0
- data/test/event_sourcing/aggregate_factory_test.rb +28 -0
- data/test/event_sourcing/aggregate_root_test.rb +76 -0
- data/test/event_sourcing/entity_test.rb +34 -0
- data/test/event_sourcing/fixtures.rb +85 -0
- data/test/event_sourcing/repository_test.rb +102 -0
- data/test/event_sourcing/snapshot/aggregate_taker_test.rb +39 -0
- data/test/event_sourcing/snapshot/deferred_taker_test.rb +19 -0
- data/test/event_sourcing/snapshot/integration_test.rb +65 -0
- data/test/event_sourcing/storage_listener_test.rb +77 -0
- data/test/event_store/in_memory_test.rb +47 -0
- data/test/process_manager/correlation_set_test.rb +49 -0
- data/test/process_manager/correlation_test.rb +24 -0
- data/test/process_manager/process_test.rb +52 -0
- data/test/repository/locking_test.rb +101 -0
- data/test/serialization/converter/factory_test.rb +33 -0
- data/test/serialization/converter/identity_test.rb +17 -0
- data/test/serialization/converter/json_test.rb +31 -0
- data/test/serialization/converter/ox_test.rb +40 -0
- data/test/serialization/fixtures.rb +17 -0
- data/test/serialization/lazy_object_test.rb +32 -0
- data/test/serialization/message/metadata_test.rb +19 -0
- data/test/serialization/message/serialization_aware_message_test.rb +88 -0
- data/test/serialization/message/serialized_message_builder_test.rb +41 -0
- data/test/serialization/message/serialized_message_test.rb +140 -0
- data/test/serialization/message/serializer_test.rb +50 -0
- data/test/serialization/revision_resolver_test.rb +12 -0
- data/test/serialization/serialized_object_test.rb +36 -0
- data/test/serialization/serialized_type_test.rb +27 -0
- data/test/serialization/serializer/marshal_test.rb +22 -0
- data/test/serialization/serializer/oj_test.rb +24 -0
- data/test/serialization/serializer/ox_test.rb +36 -0
- data/test/serialization/serializer_test.rb +20 -0
- data/test/test_helper.rb +19 -0
- data/test/uow/factory_test.rb +23 -0
- data/test/uow/outer_commit_listener_test.rb +50 -0
- data/test/uow/provider_test.rb +70 -0
- data/test/uow/uow_test.rb +337 -0
- data/test/upcasting/chain_test.rb +29 -0
- data/test/upcasting/fixtures.rb +66 -0
- data/test/wiring/wire_registry_test.rb +60 -0
- data/test/wiring/wire_test.rb +51 -0
- metadata +263 -0
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
module Synapse
|
|
2
|
+
module Domain
|
|
3
|
+
|
|
4
|
+
class Person
|
|
5
|
+
include AggregateRoot
|
|
6
|
+
|
|
7
|
+
attr_reader :id, :name
|
|
8
|
+
|
|
9
|
+
def initialize(id, name)
|
|
10
|
+
@id, @name = id, name
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
def change_name(name)
|
|
14
|
+
@name = name
|
|
15
|
+
publish_event NameChangedEvent.new(id, name)
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
def delete
|
|
19
|
+
mark_deleted
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
class NameChangedEvent
|
|
24
|
+
attr_reader :id, :name
|
|
25
|
+
def initialize(id, name)
|
|
26
|
+
@id, @name = id, name
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
end
|
|
31
|
+
end
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
require 'test_helper'
|
|
2
|
+
|
|
3
|
+
module Synapse
|
|
4
|
+
module Domain
|
|
5
|
+
class DomainEventMessageTest < Test::Unit::TestCase
|
|
6
|
+
def setup
|
|
7
|
+
@payload = OpenStruct.new
|
|
8
|
+
@aggregate_id = 123
|
|
9
|
+
@sequence_number = 1
|
|
10
|
+
|
|
11
|
+
@message = DomainEventMessage.build do |b|
|
|
12
|
+
b.payload = @payload
|
|
13
|
+
b.aggregate_id = @aggregate_id
|
|
14
|
+
b.sequence_number = @sequence_number
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
def test_initialize
|
|
19
|
+
# ensure empty fields were populated with default values
|
|
20
|
+
assert @message.id
|
|
21
|
+
assert @message.metadata
|
|
22
|
+
assert @message.timestamp
|
|
23
|
+
|
|
24
|
+
# ensure other fields were populated
|
|
25
|
+
assert_equal @payload, @message.payload
|
|
26
|
+
assert_equal @payload.class, @message.payload_type
|
|
27
|
+
assert_equal @aggregate_id, @message.aggregate_id
|
|
28
|
+
assert_equal @sequence_number, @message.sequence_number
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
def test_and_metadata
|
|
32
|
+
additional_metadata_a = { foo: 'bar' }
|
|
33
|
+
additional_metadata_b = { baz: 'qux' }
|
|
34
|
+
|
|
35
|
+
merged = @message.and_metadata additional_metadata_a
|
|
36
|
+
merged = merged.and_metadata additional_metadata_b
|
|
37
|
+
|
|
38
|
+
# Ensure everything was populated in the duplicate message
|
|
39
|
+
assert_equal @message.id, merged.id
|
|
40
|
+
assert_equal @message.payload, merged.payload
|
|
41
|
+
assert_equal @message.timestamp, merged.timestamp
|
|
42
|
+
assert_equal @message.aggregate_id, merged.aggregate_id
|
|
43
|
+
assert_equal @message.sequence_number, merged.sequence_number
|
|
44
|
+
|
|
45
|
+
# Now ensure that metadata was merged, not replaced
|
|
46
|
+
assert_equal additional_metadata_a.merge(additional_metadata_b), merged.metadata
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
def test_with_metadata
|
|
50
|
+
additional_metadata_a = { foo: 'bar' }
|
|
51
|
+
additional_metadata_b = { baz: 'qux' }
|
|
52
|
+
|
|
53
|
+
merged = @message.with_metadata additional_metadata_a
|
|
54
|
+
merged = merged.with_metadata additional_metadata_b
|
|
55
|
+
|
|
56
|
+
# Ensure that the metadata was replaced
|
|
57
|
+
assert_equal additional_metadata_b, merged.metadata
|
|
58
|
+
end
|
|
59
|
+
end
|
|
60
|
+
end
|
|
61
|
+
end
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
require 'test_helper'
|
|
2
|
+
|
|
3
|
+
module Synapse
|
|
4
|
+
module Domain
|
|
5
|
+
class SimpleDomainEventStreamTest < Test::Unit::TestCase
|
|
6
|
+
|
|
7
|
+
def setup
|
|
8
|
+
@events = Array.new
|
|
9
|
+
@events.push DomainEventMessage.build
|
|
10
|
+
@events.push DomainEventMessage.build
|
|
11
|
+
|
|
12
|
+
@stream = SimpleDomainEventStream.new @events
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
def test_peek
|
|
16
|
+
assert_same @events.at(0), @stream.peek
|
|
17
|
+
assert_same @events.at(0), @stream.peek
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
def test_end_of_stream
|
|
21
|
+
@stream.next_event
|
|
22
|
+
@stream.next_event
|
|
23
|
+
|
|
24
|
+
assert_raise EndOfStreamError do
|
|
25
|
+
@stream.next_event
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
assert_raise EndOfStreamError do
|
|
29
|
+
@stream.peek
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
end
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
require 'test_helper'
|
|
2
|
+
|
|
3
|
+
module Synapse
|
|
4
|
+
class DuplicationRecorderTest < Test::Unit::TestCase
|
|
5
|
+
def setup
|
|
6
|
+
@recorder = DuplicationRecorder.new
|
|
7
|
+
@message = Message.build
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
def test_record
|
|
11
|
+
refute @recorder.recorded? @message
|
|
12
|
+
|
|
13
|
+
@recorder.record @message
|
|
14
|
+
assert @recorder.recorded? @message
|
|
15
|
+
|
|
16
|
+
assert_raise DuplicationError do
|
|
17
|
+
@recorder.record @message
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
def test_forget
|
|
22
|
+
@recorder.record @message
|
|
23
|
+
@recorder.forget @message
|
|
24
|
+
|
|
25
|
+
refute @recorder.recorded? @message
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
def test_forget_older_than
|
|
29
|
+
@recorder.record @message
|
|
30
|
+
|
|
31
|
+
threshold = 60 * 20 # 20 minutes
|
|
32
|
+
|
|
33
|
+
Timecop.freeze(Time.now + 3600) do
|
|
34
|
+
@recorder.forget_older_than Time.now - threshold
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
refute @recorder.recorded? @message
|
|
38
|
+
end
|
|
39
|
+
end
|
|
40
|
+
end
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
require 'test_helper'
|
|
2
|
+
|
|
3
|
+
module Synapse
|
|
4
|
+
module EventBus
|
|
5
|
+
|
|
6
|
+
class WiringEventListenerTest < Test::Unit::TestCase
|
|
7
|
+
def test_notify
|
|
8
|
+
listener = ExampleWiringEventListener.new
|
|
9
|
+
|
|
10
|
+
event = Domain::EventMessage.build do |builder|
|
|
11
|
+
builder.payload = TestEvent.new
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
listener.notify event
|
|
15
|
+
|
|
16
|
+
assert listener.handled
|
|
17
|
+
|
|
18
|
+
event = Domain::EventMessage.build do |builder|
|
|
19
|
+
builder.payload = TestSubEvent.new
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
listener.notify event
|
|
23
|
+
|
|
24
|
+
assert listener.sub_handled
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
class TestEvent; end
|
|
29
|
+
class TestSubEvent < TestEvent; end
|
|
30
|
+
|
|
31
|
+
class ExampleWiringEventListener
|
|
32
|
+
include WiringEventListener
|
|
33
|
+
|
|
34
|
+
attr_accessor :handled, :sub_handled
|
|
35
|
+
|
|
36
|
+
wire TestEvent do |event|
|
|
37
|
+
@handled = true
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
wire TestSubEvent do |event|
|
|
41
|
+
@sub_handled = true
|
|
42
|
+
end
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
end
|
|
46
|
+
end
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
require 'test_helper'
|
|
2
|
+
|
|
3
|
+
module Synapse
|
|
4
|
+
module EventSourcing
|
|
5
|
+
|
|
6
|
+
class GenericAggregateFactoryTest < Test::Unit::TestCase
|
|
7
|
+
def test_create_aggregate
|
|
8
|
+
factory = GenericAggregateFactory.new StubAggregate
|
|
9
|
+
|
|
10
|
+
event = Domain::DomainEventMessage.build do |m|
|
|
11
|
+
m.payload = StubCreatedEvent.new 123
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
snapshot = StubAggregate.new 123
|
|
15
|
+
snapshot_event = Domain::DomainEventMessage.build do |m|
|
|
16
|
+
m.payload = snapshot
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
aggregate_a = factory.create_aggregate(123, snapshot_event)
|
|
20
|
+
aggregate_b = factory.create_aggregate(123, event)
|
|
21
|
+
|
|
22
|
+
assert aggregate_a.equal? snapshot
|
|
23
|
+
assert aggregate_b.is_a? StubAggregate
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
end
|
|
28
|
+
end
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
require 'test_helper'
|
|
2
|
+
require 'event_sourcing/fixtures'
|
|
3
|
+
|
|
4
|
+
module Synapse
|
|
5
|
+
module EventSourcing
|
|
6
|
+
|
|
7
|
+
class AggregateRootTest < Test::Unit::TestCase
|
|
8
|
+
def test_apply
|
|
9
|
+
stub = StubAggregate.new 123
|
|
10
|
+
stub.change_something
|
|
11
|
+
stub.change_something
|
|
12
|
+
|
|
13
|
+
assert_equal 123, stub.id
|
|
14
|
+
assert_equal 3, stub.uncommitted_event_count
|
|
15
|
+
|
|
16
|
+
assert_nil stub.version
|
|
17
|
+
|
|
18
|
+
stub.mark_committed
|
|
19
|
+
|
|
20
|
+
assert_equal 2, stub.version
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
def test_new_from_stream
|
|
24
|
+
events = Array.new
|
|
25
|
+
events.push create_event(123, 0, StubCreatedEvent.new(123))
|
|
26
|
+
events.push create_event(123, 1, StubChangedEvent.new)
|
|
27
|
+
events.push create_event(123, 2, StubChangedEvent.new)
|
|
28
|
+
|
|
29
|
+
stream = Domain::SimpleDomainEventStream.new events
|
|
30
|
+
|
|
31
|
+
aggregate = StubAggregate.new_from_stream stream
|
|
32
|
+
|
|
33
|
+
assert_equal 123, aggregate.id
|
|
34
|
+
assert_equal 2, aggregate.version
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
def test_initialize_fails_after_initialization
|
|
38
|
+
aggregate = StubAggregate.new 123
|
|
39
|
+
|
|
40
|
+
assert_raise RuntimeError do
|
|
41
|
+
aggregate.initialize_from_stream Domain::SimpleDomainEventStream.new
|
|
42
|
+
end
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
def test_child_entities
|
|
46
|
+
stub_entity_a = StubEntity.new
|
|
47
|
+
stub_entity_b = StubEntity.new
|
|
48
|
+
|
|
49
|
+
aggregate = StubAggregate.new 123
|
|
50
|
+
aggregate.stub_entity = stub_entity_a
|
|
51
|
+
aggregate.change_something
|
|
52
|
+
|
|
53
|
+
stub_entity_a.change_something
|
|
54
|
+
|
|
55
|
+
aggregate.stub_entities << stub_entity_b
|
|
56
|
+
|
|
57
|
+
aggregate.change_something
|
|
58
|
+
|
|
59
|
+
assert_equal 4, aggregate.event_count
|
|
60
|
+
assert_equal 3, stub_entity_a.event_count
|
|
61
|
+
assert_equal 1, stub_entity_b.event_count
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
private
|
|
65
|
+
|
|
66
|
+
def create_event(aggregate_id, seq, payload)
|
|
67
|
+
Domain::DomainEventMessage.build do |m|
|
|
68
|
+
m.aggregate_id = aggregate_id
|
|
69
|
+
m.sequence_number = seq
|
|
70
|
+
m.payload = payload
|
|
71
|
+
end
|
|
72
|
+
end
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
end
|
|
76
|
+
end
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
require 'test_helper'
|
|
2
|
+
require 'event_sourcing/fixtures'
|
|
3
|
+
|
|
4
|
+
module Synapse
|
|
5
|
+
module EventSourcing
|
|
6
|
+
|
|
7
|
+
class EntityTest < Test::Unit::TestCase
|
|
8
|
+
def test_aggregate_root
|
|
9
|
+
entity = StubEntity.new
|
|
10
|
+
aggregate_a = StubAggregate.new 123
|
|
11
|
+
aggregate_b = StubAggregate.new 123
|
|
12
|
+
|
|
13
|
+
assert_raise RuntimeError do
|
|
14
|
+
entity.change_something
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
entity.aggregate_root = aggregate_a
|
|
18
|
+
|
|
19
|
+
assert_raise RuntimeError do
|
|
20
|
+
entity.aggregate_root = aggregate_b
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
def test_apply
|
|
25
|
+
entity = StubEntity.new
|
|
26
|
+
|
|
27
|
+
assert_raise RuntimeError do
|
|
28
|
+
entity.change_something
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
end
|
|
34
|
+
end
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
module Synapse
|
|
2
|
+
module EventSourcing
|
|
3
|
+
|
|
4
|
+
class IncompatibleStubAggregate
|
|
5
|
+
include AggregateRoot
|
|
6
|
+
|
|
7
|
+
def change_something
|
|
8
|
+
apply StubChangedEvent.new
|
|
9
|
+
end
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
class StubAggregate
|
|
13
|
+
include AggregateRoot
|
|
14
|
+
|
|
15
|
+
attr_accessor :stub_entity, :stub_entities, :event_count
|
|
16
|
+
child_entity :stub_entity, :stub_entities
|
|
17
|
+
|
|
18
|
+
def initialize(id)
|
|
19
|
+
pre_initialize
|
|
20
|
+
apply StubCreatedEvent.new id
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
def change_something
|
|
24
|
+
apply StubChangedEvent.new
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
def delete_me
|
|
28
|
+
apply StubDeletedEvent.new
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
protected
|
|
32
|
+
|
|
33
|
+
def pre_initialize
|
|
34
|
+
@event_count = 0
|
|
35
|
+
@stub_entities = Array.new
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
def handle_event(event)
|
|
39
|
+
payload = event.payload
|
|
40
|
+
type = event.payload_type
|
|
41
|
+
|
|
42
|
+
if type.eql? StubCreatedEvent
|
|
43
|
+
@id = payload.id
|
|
44
|
+
elsif type.eql? StubDeletedEvent
|
|
45
|
+
mark_deleted
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
@event_count = @event_count.next
|
|
49
|
+
end
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
class StubEntity
|
|
53
|
+
include Entity
|
|
54
|
+
|
|
55
|
+
attr_reader :event_count
|
|
56
|
+
|
|
57
|
+
def initialize
|
|
58
|
+
@event_count = 0
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
def change_something
|
|
62
|
+
apply StubChangedEvent.new
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
protected
|
|
66
|
+
|
|
67
|
+
def handle_event(event)
|
|
68
|
+
@event_count = @event_count.next
|
|
69
|
+
end
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
class StubCreatedEvent
|
|
73
|
+
attr_reader :id
|
|
74
|
+
|
|
75
|
+
def initialize(id)
|
|
76
|
+
@id = id
|
|
77
|
+
end
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
class StubDeletedEvent; end
|
|
81
|
+
|
|
82
|
+
class StubChangedEvent; end
|
|
83
|
+
|
|
84
|
+
end
|
|
85
|
+
end
|