sandthorn_driver_sequel_2 0.0.1

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 (47) hide show
  1. checksums.yaml +7 -0
  2. data/.autotest +3 -0
  3. data/.gitignore +20 -0
  4. data/.rspec +2 -0
  5. data/.ruby-gemset +1 -0
  6. data/.ruby-version +1 -0
  7. data/.travis.yml +4 -0
  8. data/Gemfile +4 -0
  9. data/Guardfile +7 -0
  10. data/LICENSE.txt +22 -0
  11. data/README.md +37 -0
  12. data/Rakefile +10 -0
  13. data/lib/sandthorn_driver_sequel_2/access/event_access.rb +94 -0
  14. data/lib/sandthorn_driver_sequel_2/access/snapshot_access.rb +88 -0
  15. data/lib/sandthorn_driver_sequel_2/access.rb +19 -0
  16. data/lib/sandthorn_driver_sequel_2/errors.rb +49 -0
  17. data/lib/sandthorn_driver_sequel_2/event_query.rb +68 -0
  18. data/lib/sandthorn_driver_sequel_2/event_store.rb +138 -0
  19. data/lib/sandthorn_driver_sequel_2/event_store_context.rb +15 -0
  20. data/lib/sandthorn_driver_sequel_2/file_output_wrappers/events.rb +37 -0
  21. data/lib/sandthorn_driver_sequel_2/migration.rb +81 -0
  22. data/lib/sandthorn_driver_sequel_2/sequel_driver.rb +23 -0
  23. data/lib/sandthorn_driver_sequel_2/storage.rb +43 -0
  24. data/lib/sandthorn_driver_sequel_2/utilities/array.rb +13 -0
  25. data/lib/sandthorn_driver_sequel_2/utilities.rb +1 -0
  26. data/lib/sandthorn_driver_sequel_2/version.rb +3 -0
  27. data/lib/sandthorn_driver_sequel_2/wrappers/event_wrapper.rb +12 -0
  28. data/lib/sandthorn_driver_sequel_2/wrappers/snapshot_wrapper.rb +11 -0
  29. data/lib/sandthorn_driver_sequel_2/wrappers.rb +2 -0
  30. data/lib/sandthorn_driver_sequel_2.rb +24 -0
  31. data/sandthorn_driver_sequel_2.gemspec +41 -0
  32. data/spec/asking_for_aggregates_to_snapshot_spec.rb +64 -0
  33. data/spec/benchmark_spec.rb +125 -0
  34. data/spec/db/.keep +0 -0
  35. data/spec/driver_interface_spec.rb +31 -0
  36. data/spec/event_access_spec.rb +100 -0
  37. data/spec/event_store_file_output_spec.rb +44 -0
  38. data/spec/event_store_with_context_spec.rb +25 -0
  39. data/spec/get_events_spec.rb +128 -0
  40. data/spec/migration_specifying_domain_spec.rb +32 -0
  41. data/spec/saving_events_spec.rb +90 -0
  42. data/spec/saving_snapshot_spec.rb +77 -0
  43. data/spec/snapshot_access_spec.rb +125 -0
  44. data/spec/spec_helper.rb +31 -0
  45. data/spec/storage_spec.rb +66 -0
  46. data/spec/storage_to_file_spec.rb +53 -0
  47. metadata +334 -0
@@ -0,0 +1,128 @@
1
+ require 'spec_helper'
2
+
3
+ module SandthornDriverSequel2
4
+ describe EventStore do
5
+ before(:each) { prepare_for_test }
6
+ let(:test_events_a) do
7
+ e = []
8
+ e << {aggregate_version: 1, event_name: "new", event_data: "---\n:method_name: new\n:method_args: []\n:attribute_deltas:\n- :attribute_name: :@aggregate_id\n :old_value: \n :new_value: 0a74e545-be84-4506-8b0a-73e947856327\n"}
9
+ e << {aggregate_version: 2, event_name: "foo", event_data: "A2"}
10
+ e << {aggregate_version: 3, event_name: "bard", event_data: "A3"}
11
+ end
12
+ let(:aggregate_id_a) {"c0456e26-e29a-4f67-92fa-130b3a31a39a"}
13
+ let(:test_events_b) do
14
+ e = []
15
+ e << {aggregate_version: 1, event_name: "new", event_data: "B1" }
16
+ e << {aggregate_version: 2, event_name: "foo", event_data: "B2"}
17
+ e << {aggregate_version: 3, event_name: "bar", event_data: "B3"}
18
+ end
19
+ let(:aggregate_id_b) {"c0456e26-1234-4f67-92fa-130b3a31a39a"}
20
+ let(:test_events_c) do
21
+ e = []
22
+ e << {aggregate_version: 1, event_name: "new", event_data: "C1" }
23
+ end
24
+ let(:test_events_c_2) do
25
+ e = []
26
+ e << {aggregate_version: 2, event_name: "flubber", event_data: "C2" }
27
+ end
28
+ let(:aggregate_id_c) {"c0456e26-2345-4f67-92fa-130b3a31a39a"}
29
+ before(:each) do
30
+ event_store.save_events test_events_a, aggregate_id_a, SandthornDriverSequel2::EventStore
31
+ event_store.save_events test_events_c, aggregate_id_c, String
32
+ event_store.save_events test_events_b, aggregate_id_b, SandthornDriverSequel2::SequelDriver
33
+ event_store.save_events test_events_c_2, aggregate_id_c, String
34
+ end
35
+
36
+ let(:event) { event_store.get_events(take: 1).first }
37
+
38
+ it "returns events that can be merged" do
39
+ expect(event).to respond_to(:merge)
40
+ end
41
+
42
+ context "when using get_events" do
43
+ context "and using take" do
44
+ let(:events) {event_store.get_events after_sequence_number: 0, take: 2}
45
+ it "should find 2 events" do
46
+ expect(events.length).to eql 2
47
+ end
48
+ end
49
+ context "and combining args" do
50
+ let(:events) do
51
+ all = event_store.get_events after_sequence_number: 0
52
+ first_seq_number = all[0][:sequence_number]
53
+ event_store.get_events after_sequence_number: first_seq_number, take: 100
54
+ end
55
+ it "should find 7 events" do
56
+ expect(events.length).to eql 7
57
+ end
58
+
59
+ end
60
+ context "and getting events for SandthornDriverSequel2::EventStore, and String after 0" do
61
+ let(:events) {event_store.get_events after_sequence_number: 0, aggregate_types: [SandthornDriverSequel2::EventStore, String]}
62
+ it "should find 5 events" do
63
+ expect(events.length).to eql 5
64
+ end
65
+ it "should be in sequence_number order" do
66
+ check = 0
67
+ events.each { |e| expect(e[:sequence_number]).to be > check; check = e[:sequence_number] }
68
+ end
69
+ it "should contain only events for aggregate_id_a and aggregate_id_c" do
70
+ events.each { |e| expect([aggregate_id_a, aggregate_id_c].include?(e[:aggregate_id])).to be_truthy }
71
+ end
72
+ end
73
+ context "and getting events for SandthornDriverSequel2::EventStore after 0" do
74
+ let(:events) {event_store.get_events after_sequence_number: 0, aggregate_types: [SandthornDriverSequel2::EventStore]}
75
+ it "should find 3 events" do
76
+ expect(events.length).to eql 3
77
+ end
78
+ it "should be in sequence_number order" do
79
+ check = 0
80
+ events.each { |e| expect(e[:sequence_number]).to be > check; check = e[:sequence_number] }
81
+ end
82
+ it "should contain only events for aggregate_id_a" do
83
+ events.each { |e| expect(e[:aggregate_id]).to eql aggregate_id_a }
84
+ end
85
+ end
86
+ end
87
+ context "when using :get_new_events_after_event_id_matching_classname to get events" do
88
+ context "and getting events for SandthornDriverSequel2::EventStore after 0" do
89
+ let(:events) {event_store.get_new_events_after_event_id_matching_classname 0, SandthornDriverSequel2::EventStore}
90
+ it "should find 3 events" do
91
+ expect(events.length).to eql 3
92
+ end
93
+ it "should be in sequence_number order" do
94
+ check = 0
95
+ events.each { |e| expect(e[:sequence_number]).to be > check; check = e[:sequence_number] }
96
+ end
97
+ it "should contain only events for aggregate_id_a" do
98
+ events.each { |e| expect(e[:aggregate_id]).to eql aggregate_id_a }
99
+ end
100
+ it "should be able to get events after a sequence number" do
101
+ new_from = events[1][:sequence_number]
102
+ ev = event_store.get_new_events_after_event_id_matching_classname new_from, SandthornDriverSequel2::EventStore
103
+ expect(ev.last[:aggregate_version]).to eql 3
104
+ expect(ev.length).to eql 1
105
+ end
106
+ it "should be able to limit the number of results" do
107
+ ev = event_store.get_new_events_after_event_id_matching_classname 0, SandthornDriverSequel2::EventStore, take: 2
108
+ expect(ev.length).to eql 2
109
+ expect(ev.last[:aggregate_version]).to eql 2
110
+ end
111
+ end
112
+ context "and getting events for String after 0" do
113
+ let(:events) {event_store.get_new_events_after_event_id_matching_classname 0, "String"}
114
+ it "should find 3 events" do
115
+ expect(events.length).to eql 2
116
+ end
117
+ it "should be in sequence_number order" do
118
+ check = 0
119
+ events.each { |e| expect(e[:sequence_number]).to be > check; check = e[:sequence_number] }
120
+ end
121
+ it "should contain only events for aggregate_id_c" do
122
+ events.each { |e| expect(e[:aggregate_id]).to eql aggregate_id_c }
123
+ end
124
+ end
125
+ end
126
+
127
+ end
128
+ end
@@ -0,0 +1,32 @@
1
+ require 'spec_helper'
2
+
3
+ module SandthornDriverSequel2
4
+ describe Migration do
5
+ def check_tables context = nil
6
+ events = :events
7
+ snapshots = :snapshots
8
+ if context
9
+ events = "#{context}_#{events}".to_sym
10
+ snapshots = "#{context}_#{snapshots}".to_sym
11
+ end
12
+ migration.driver.execute do |db|
13
+ expect(db.table_exists? events).to be_truthy, "expected table :#{events} to exist, but it didn't"
14
+ expect(db.table_exists? snapshots).to be_truthy, "expected table :#{snapshots} to exist, but it didn't"
15
+ end
16
+ end
17
+ let(:migration) { Migration.new url: event_store_url, context: context }
18
+ before(:each) { migration.migrate! }
19
+ context "when default (nil) eventstore contex" do
20
+ let(:context) { nil }
21
+ it "should create the tables events, aggregates and snapshots" do
22
+ check_tables
23
+ end
24
+ end
25
+ context "when specifying context" do
26
+ let(:context) { :another_domain }
27
+ it "should create the tables events, aggregates and snapshots" do
28
+ check_tables context
29
+ end
30
+ end
31
+ end
32
+ end
@@ -0,0 +1,90 @@
1
+ require 'spec_helper'
2
+ require 'msgpack'
3
+
4
+ module SandthornDriverSequel2
5
+ describe EventStore do
6
+ before(:each) { prepare_for_test }
7
+ context "when saving a prefectly sane event stream" do
8
+ let(:test_events) do
9
+ e = []
10
+ e << {aggregate_version: 1, event_name: "new", event_args: nil, event_data: "---\n:method_name: new\n:method_args: []\n:attribute_deltas:\n- :attribute_name: :@aggregate_id\n :old_value: \n :new_value: 0a74e545-be84-4506-8b0a-73e947856327\n"}
11
+ e << {aggregate_version: 2, event_name: "foo", event_args: ["bar"], event_data: "noop"}
12
+ e << {aggregate_version: 3, event_name: "flubber", event_args: ["bar"] , event_data: "noop"}
13
+ end
14
+
15
+ let(:aggregate_id) { "c0456e26-e29a-4f67-92fa-130b3a31a39a" }
16
+
17
+ it "should be able to save and retrieve events on the aggregate" do
18
+ event_store.save_events test_events, aggregate_id, String
19
+ events = event_store.get_aggregate_events aggregate_id
20
+ expect(events.length).to eql test_events.length
21
+ end
22
+
23
+ it "should have correct keys when asking for events" do
24
+ event_store.save_events test_events, aggregate_id, String
25
+ events = event_store.get_aggregate aggregate_id, String
26
+ event = events.first
27
+ expect(event[:event_data]).to eql(test_events.first[:event_data])
28
+ expect(event[:event_name]).to eql("new")
29
+ expect(event[:aggregate_id]).to eql aggregate_id
30
+ expect(event[:aggregate_version]).to eql 1
31
+ expect(event[:sequence_number]).to be_a(Fixnum)
32
+ expect(event[:timestamp]).to be_a(Time)
33
+ end
34
+ end
35
+
36
+ context "when saving two aggregate types" do
37
+ let(:test_events_1) do
38
+ e = []
39
+ e << {aggregate_version: 1, event_name: "new", event_args: nil, event_data: "---\n:method_name: new\n:method_args: []\n:attribute_deltas:\n- :attribute_name: :@aggregate_id\n :old_value: \n :new_value: 0a74e545-be84-4506-8b0a-73e947856327\n"}
40
+ e << {aggregate_version: 2, event_name: "foo", event_args: "bar", event_data: "noop"}
41
+ e << {aggregate_version: 3, event_name: "flubber", event_args: "bar", event_data: "noop"}
42
+ end
43
+ let(:test_events_2) do
44
+ e = []
45
+ e << {aggregate_version: 1, event_name: "new", event_args: nil, event_data: "---\n:method_name: new\n:method_args: []\n:attribute_deltas:\n- :attribute_name: :@aggregate_id\n :old_value: \n :new_value: 0a74e545-be84-4506-8b0a-73e947856327\n"}
46
+ end
47
+ let(:aggregate_id_1) {"c0456e26-e29a-4f67-92fa-130b3a31a39a"}
48
+ let(:aggregate_id_2) {"c0456e26-e92b-4f67-92fa-130b3a31b93b"}
49
+ let(:aggregate_id_3) {"c0456e26-e92b-1234-92fa-130b3a31b93b"}
50
+
51
+ before(:each) do
52
+ event_store.save_events test_events_1, aggregate_id_1, String
53
+ event_store.save_events test_events_2, aggregate_id_2, Hash
54
+ event_store.save_events test_events_2, aggregate_id_3, String
55
+ end
56
+
57
+ # it "both types should exist in get_all_typenames in alphabetical order" do
58
+ # names = event_store.get_all_types
59
+ # expect(names.length).to eql 2
60
+ # expect(names.first).to eql "Hash"
61
+ # expect(names.last).to eql "String"
62
+ # end
63
+
64
+ # it "should list the aggregate ids when asking for get_aggregate_list_by_typename" do
65
+ # ids = event_store.get_aggregate_ids(aggregate_type: String)
66
+ # expect(ids.length).to eql 2
67
+ # expect(ids.any? { |e| e == aggregate_id_1 }).to be_truthy
68
+ # expect(ids.any? { |e| e == aggregate_id_3 }).to be_truthy
69
+ # end
70
+ end
71
+
72
+ context "when saving events that are serilized with msgpack" do
73
+ let(:test_data) { {name: "test", hash: {t: 123}} }
74
+ let(:test_events) do
75
+ e = []
76
+ data = MessagePack.pack(test_data, symbolize_keys: true)
77
+ e << {aggregate_version: 1, event_name: "new", event_args: nil, event_data: data}
78
+ end
79
+ let(:aggregate_id_1) {"c0456e26-e29a-4f67-92fa-130b3a31a39a"}
80
+
81
+ it "should save and get events that are serialized with msgpack" do
82
+ event_store.save_events test_events, aggregate_id_1, String
83
+ events = event_store.get_aggregate aggregate_id_1, String
84
+ expect(MessagePack.unpack(events.first[:event_data], symbolize_keys: true)).to eql test_data
85
+ end
86
+
87
+ end
88
+
89
+ end
90
+ end
@@ -0,0 +1,77 @@
1
+ # require 'spec_helper'
2
+ # require 'yaml'
3
+
4
+ # module SandthornDriverSequel2
5
+ # describe EventStore do
6
+ # before(:each) { prepare_for_test }
7
+ # let(:aggregate_id) { @id ||= UUIDTools::UUID.random_create.to_s }
8
+ # let(:test_events) { [{aggregate_version: 1, event_data: nil, event_name: "new"},{aggregate_version: 2, event_data: nil, event_name: "foo"}] }
9
+ # let(:additional_events) { [{aggregate_version: 3, event_data: nil, event_name: "klopp"},{aggregate_version: 4, event_data: nil, event_name: "flipp"}] }
10
+ # let(:snapshot_data) { { event_data: YAML.dump(Object.new), aggregate_version: 2 } }
11
+ # let(:save_snapshot) { event_store.save_snapshot snapshot_data, aggregate_id }
12
+ # let(:save_events) { event_store.save_events test_events, aggregate_id, SandthornDriverSequel2::EventStore }
13
+ # let(:save_additional_events) { event_store.save_events additional_events, aggregate_id, SandthornDriverSequel2::EventStore }
14
+ # context "when loading an aggregate using get_aggregate" do
15
+ # context "and it has a snapshot" do
16
+ # before(:each) do
17
+ # save_events
18
+ # save_snapshot
19
+ # save_additional_events
20
+ # end
21
+ # let(:events) { event_store.get_aggregate aggregate_id, SandthornDriverSequel2::EventStore }
22
+ # it "should have the first event as :aggregate_set_from_snapshot" do
23
+ # expect(events.first[:event_name]).to eql "aggregate_set_from_snapshot"
24
+ # end
25
+ # it "should have additional events after first snapshot-event" do
26
+ # expect(events.length).to eql 1+additional_events.length
27
+ # expect(events[1][:aggregate_version]).to eql additional_events[0][:aggregate_version]
28
+ # expect(events.last[:aggregate_version]).to eql additional_events.last[:aggregate_version]
29
+ # end
30
+ # end
31
+
32
+ # end
33
+ # context "when saving a snapshot" do
34
+
35
+ # context "and events are saved beforehand" do
36
+ # before(:each) { save_events }
37
+ # it "should be able to save snapshot" do
38
+ # expect { save_snapshot }.to_not raise_error
39
+ # end
40
+ # it "should be able to save and get snapshot" do
41
+ # save_snapshot
42
+ # snap = event_store.get_snapshot(aggregate_id)
43
+ # expect(snap).to eql snapshot_data
44
+ # end
45
+ # end
46
+ # context "when trying to save a snapshot on a non-existing aggregate" do
47
+ # it "should raise a NonAggregateError" do
48
+ # expect { save_snapshot }.to raise_error SandthornDriverSequel2::Errors::NoAggregateError
49
+ # end
50
+ # end
51
+ # context "when trying to save a snapshot with a non-existing aggregate_version" do
52
+ # before(:each) { save_events }
53
+ # it "should raise a WrongAggregateVersion error" do
54
+ # data = snapshot_data
55
+ # data[:aggregate_version] = 100
56
+ # expect { event_store.save_snapshot data, aggregate_id }.to raise_error SandthornDriverSequel2::Errors::WrongSnapshotVersionError
57
+ # end
58
+ # end
59
+ # context "when saving a snapshot twice" do
60
+ # before(:each) { save_events; save_snapshot }
61
+ # it "should not raise error" do
62
+ # expect { save_snapshot }.to_not raise_error
63
+ # end
64
+ # end
65
+ # context "when saving a snapshot on a version less than current version" do
66
+ # before(:each) { save_events; }
67
+ # it "should save without protesting" do
68
+ # data = snapshot_data
69
+ # data[:aggregate_version] = 1
70
+ # event_store.save_snapshot(data, aggregate_id)
71
+ # snap = event_store.get_snapshot(aggregate_id)
72
+ # expect(snap).to eql data
73
+ # end
74
+ # end
75
+ # end
76
+ # end
77
+ # end
@@ -0,0 +1,125 @@
1
+ # require 'spec_helper'
2
+
3
+ # module SandthornDriverSequel2
4
+ # describe SnapshotAccess do
5
+ # include EventStoreContext
6
+
7
+ # before do
8
+ # prepare_for_test
9
+ # end
10
+
11
+ # let(:context) { :test }
12
+ # let(:db) { Sequel.connect(event_store_url)}
13
+ # let(:aggregate_id) { generate_uuid }
14
+ # let(:storage) { Storage.new(db, :test) }
15
+ # let(:aggregate_access) { AggregateAccess.new(storage) }
16
+ # let(:event_access) { EventAccess.new(storage) }
17
+ # let(:aggregate) { aggregate_access.register_aggregate(aggregate_id, "foo") }
18
+ # let(:access) { SnapshotAccess.new(storage) }
19
+ # let(:events) do
20
+ # [
21
+ # {
22
+ # aggregate_id: aggregate_id,
23
+ # aggregate_type: "Foo",
24
+ # aggregate_version: 1,
25
+ # event_name: "new",
26
+ # event_data: "new_data"
27
+ # },{
28
+ # aggregate_id: aggregate_id,
29
+ # aggregate_type: "Foo",
30
+ # aggregate_version: 2,
31
+ # event_name: "foo",
32
+ # event_data: "foo_data"
33
+ # }
34
+ # ]
35
+ # end
36
+
37
+ # describe "#find_by_aggregate_id" do
38
+ # it "returns the correct data" do
39
+ # aggregate = aggregate_access.register_aggregate(aggregate_id, "foo")
40
+ # access.record_snapshot(aggregate.aggregate_id, { aggregate_version: 0, event_data: "data" })
41
+ # aggregate.update(aggregate_version: 1)
42
+ # snapshot = access.find_by_aggregate_id(aggregate.aggregate_id)
43
+ # expected = {
44
+ # # aggregate_table_id: aggregate.id,
45
+ # aggregate_id: aggregate.aggregate_id,
46
+ # aggregate_type: "Foo",
47
+ # aggregate_version: 0,
48
+ # snapshot_data: "data",
49
+ # id: snapshot.id
50
+ # }
51
+ # expect(snapshot.values).to eq(expected)
52
+ # end
53
+ # end
54
+
55
+ # describe "#record" do
56
+ # context "when the aggregate doesn't exist" do
57
+ # it "raises an error" do
58
+ # expect { access.record_snapshot("qux", "data") }.to raise_error(Errors::NoAggregateError)
59
+ # end
60
+ # end
61
+ # context "when the aggregate exists" do
62
+ # context "when no previous snapshot exists" do
63
+ # it "records the snapshot" do
64
+ # #aggregate_table_id = aggregate_access.register_aggregate(aggregate_id, "foo").id
65
+ # expect(access.find_by_aggregate_id(aggregate_id)).to be_nil
66
+ # access.record_snapshot(aggregate_id, { aggregate_version: 0, event_data: "data"})
67
+
68
+ # snapshot = access.find_by_aggregate_id(aggregate_id)
69
+ # expect(snapshot).to_not be_nil
70
+ # expect(snapshot.aggregate_id).to eq(aggregate_id)
71
+ # expect(snapshot.snapshot_data).to eq("data")
72
+ # expect(snapshot.aggregate_version).to eq(0)
73
+ # end
74
+ # end
75
+ # context "when the snapshot isn't fresh" do
76
+ # context "when the versions match" do
77
+ # it "records a new snapshot" do
78
+ # #aggregate = aggregate_access.register_aggregate(aggregate_id, "foo")
79
+ # expect(access.find_by_aggregate_id(aggregate_id)).to be_nil
80
+ # access.record_snapshot(aggregate_id, { aggregate_version: 0, aggregate_type: "Foo", event_data: "data"})
81
+ # event_access.store_events(events)
82
+ # access.record_snapshot(aggregate_id, { aggregate_version: 2, aggregate_type: "Foo", event_data: "other_data"})
83
+
84
+ # snapshot = access.find_by_aggregate_id(aggregate_id)
85
+ # expect(snapshot).to_not be_nil
86
+ # expect(snapshot.aggregate_id).to eq(aggregate_id)
87
+ # expect(snapshot.snapshot_data).to eq("other_data")
88
+ # expect(snapshot.aggregate_version).to eq(2)
89
+ # end
90
+ # end
91
+
92
+ # # context "when the versions don't match" do
93
+ # # it "raises an error" do
94
+ # # aggregate = aggregate_access.register_aggregate(aggregate_id, "foo")
95
+ # # aggregate.update(aggregate_version: 10)
96
+ # # expect { access.record_snapshot(aggregate_id, snapshot_data) }.to raise_error
97
+ # # end
98
+ # # end
99
+ # end
100
+ # context "when the snapshot is fresh" do
101
+ # it "doesn't record a snapshot" do
102
+ # aggregate = aggregate_access.register_aggregate(aggregate_id, "foo")
103
+ # expect(access.find_by_aggregate_id(aggregate_id)).to be_nil
104
+ # access.record_snapshot(aggregate_id, { aggregate_version: 0, event_data: "data"})
105
+ # access.record_snapshot(aggregate_id, { aggregate_version: 0, event_data: "new_data"})
106
+ # snapshot = access.find_by_aggregate_id(aggregate_id)
107
+ # expect(snapshot.snapshot_data).to eq("data")
108
+ # end
109
+ # end
110
+ # end
111
+ # end
112
+
113
+ # it "can write and read snapshots" do
114
+ # snapshot_id = access.record_snapshot(aggregate.aggregate_id, { aggregate_version: 0, event_data: "data" })
115
+ # snapshot = access.find(snapshot_id)
116
+ # expect(snapshot).to_not be_nil
117
+ # expect(snapshot.snapshot_data).to eq("data")
118
+ # expect(snapshot)
119
+ # end
120
+
121
+ # def generate_uuid
122
+ # SecureRandom.uuid
123
+ # end
124
+ # end
125
+ # end
@@ -0,0 +1,31 @@
1
+ require 'sandthorn_driver_sequel_2'
2
+ require 'sandthorn_driver_sequel_2/migration'
3
+ require 'ap'
4
+ require 'uuidtools'
5
+
6
+ # This file was generated by the `rspec --init` command. Conventionally, all
7
+ # specs live under a `spec` directory, which RSpec adds to the `$LOAD_PATH`.
8
+ # Require this file using `require "spec_helper"` to ensure that it is only
9
+ # loaded once.
10
+ #
11
+ # See http://rubydoc.info/gems/rspec-core/RSpec/Core/Configuration
12
+ RSpec.configure do |config|
13
+ config.run_all_when_everything_filtered = true
14
+ config.filter_run :focus
15
+ config.filter_run_excluding benchmark: true
16
+ config.order = 'random'
17
+ end
18
+ def prepare_for_test context: :test
19
+ migrator = SandthornDriverSequel2::Migration.new url: event_store_url, context: context
20
+ migrator.migrate!
21
+ migrator.send(:clear_for_test)
22
+ end
23
+
24
+ def event_store_url
25
+ "sqlite://spec/db/event_store.sqlite3"
26
+ #"postgres://morganhallgren@localhost:5432/test_1"
27
+ end
28
+
29
+ def event_store context: :test
30
+ SandthornDriverSequel2::EventStore.new url: event_store_url, context: context
31
+ end
@@ -0,0 +1,66 @@
1
+ require 'spec_helper'
2
+
3
+ module SandthornDriverSequel2
4
+
5
+ describe Storage do
6
+ let(:context) { :test }
7
+ before do
8
+ prepare_for_test(context: context)
9
+ end
10
+ let(:db) { Sequel.connect(event_store_url) }
11
+ let(:driver) { SequelDriver.new(event_store_url)}
12
+ let(:storage) { Storage.new(db, context, nil) }
13
+
14
+ # describe "anonymous aggegrate class" do
15
+ # it "can insert and read data" do
16
+ # create_aggregate
17
+ # aggregate = storage.aggregates.first(aggregate_id: "foo", aggregate_type: "Foo")
18
+ # expect(aggregate).to_not be_nil
19
+ # end
20
+
21
+ # it "can update data" do
22
+ # create_aggregate
23
+ # storage.aggregates.where(aggregate_id: "foo").update(aggregate_version: 2)
24
+ # aggregate = storage.aggregates.first(aggregate_id: "foo")
25
+ # expect(aggregate.aggregate_version).to eq(2)
26
+ # end
27
+ # end
28
+
29
+ describe "anonymous event class" do
30
+ it "can insert and read data" do
31
+ data, event_id = create_event
32
+ event = storage.events.first(sequence_number: event_id).values
33
+ expected = data.merge(sequence_number: event_id)
34
+ expected_time = expected.delete(:timestamp)
35
+ actual_time = event.delete(:timestamp)
36
+ expect(event).to eq(expected)
37
+ expect(actual_time.to_i).to eq(actual_time.to_i)
38
+ end
39
+
40
+ it "can update data" do
41
+ data, event_id = create_event
42
+ storage.events.where(sequence_number: event_id).update(event_name: "qux")
43
+ event = storage.events.first(sequence_number: event_id)
44
+ expect(event.event_name).to eq("qux")
45
+ end
46
+ end
47
+
48
+ # def create_aggregate
49
+ # storage.aggregates.insert(aggregate_id: "foo", aggregate_type: "Foo")
50
+ # end
51
+
52
+ def create_event
53
+ data = {
54
+ aggregate_id: "foo",
55
+ aggregate_version: 1,
56
+ aggregate_type: "Foo",
57
+ event_name: "foo",
58
+ event_data: "bar",
59
+ timestamp: Time.now.utc
60
+ }
61
+ event_id = storage.events.insert(data)
62
+ return data, event_id
63
+ end
64
+
65
+ end
66
+ end
@@ -0,0 +1,53 @@
1
+ require 'spec_helper'
2
+
3
+ module SandthornDriverSequel2
4
+
5
+ describe Storage do
6
+
7
+ context "ToFile" do
8
+
9
+ let(:context) { :test }
10
+ let(:event_file) { "spec/db_file/events.csv" }
11
+
12
+ before do
13
+ prepare_for_test(context: context)
14
+ end
15
+ after(:each) do
16
+ File.delete(event_file)
17
+ end
18
+ let(:db) { Sequel.connect(event_store_url) }
19
+ let(:driver) { SequelDriver.new(event_store_url)}
20
+ let(:storage) { Storage.new(db, context, event_file) }
21
+
22
+ describe "anonymous event class" do
23
+ it "insert no data to the db" do
24
+ data, event_id = create_event
25
+ event = storage.events.first
26
+
27
+ expect(event).to be_nil
28
+ end
29
+
30
+ it "can read data from file" do
31
+ data, event_id = create_event
32
+ file = File.open event_file
33
+ expect(file.first).to eq("1;foo;1;Foo;foo;bar;#{data[:timestamp]}\n")
34
+ end
35
+ end
36
+
37
+ def create_event
38
+ data = {
39
+ aggregate_id: "foo",
40
+ aggregate_version: 1,
41
+ aggregate_type: "Foo",
42
+ event_name: "foo",
43
+ event_data: "bar",
44
+ timestamp: Time.now.utc
45
+ }
46
+ event_id = storage.events.insert(data)
47
+ storage.events.flush
48
+ return data, event_id
49
+ end
50
+
51
+ end
52
+ end
53
+ end