ruby_cqrs 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,404 @@
1
+ require_relative('../spec_helper')
2
+
3
+ describe RubyCqrs::Data::InMemoryEventStore do
4
+ let(:command_context) {}
5
+ let(:event_store) { RubyCqrs::Data::InMemoryEventStore.new }
6
+ let(:repository) { RubyCqrs::Domain::AggregateRepository.new\
7
+ event_store, command_context }
8
+ let(:aggregate_type) { SomeDomain::AggregateRoot }
9
+ let(:aggregate_type_str) { SomeDomain::AggregateRoot.to_s }
10
+ # an aggregate has a SNAPSHOT_THRESHOLD of 45
11
+ let(:aggregate_s_45_type) { SomeDomain::AggregateRoot45Snapshot }
12
+ let(:aggregate_s_45_type_str) { SomeDomain::AggregateRoot45Snapshot.to_s }
13
+
14
+ describe '#load & #save' do
15
+ it 'saves a new aggregate then is able to load the correct data back' do
16
+ new_aggregate = aggregate_type.new
17
+ new_aggregate.test_fire
18
+ new_aggregate.test_fire_ag
19
+ repository.save new_aggregate
20
+
21
+ state = event_store.load_by new_aggregate.aggregate_id, command_context
22
+ expect(state[:aggregate_type]).to eq(aggregate_type_str)
23
+ expect(state[:events].size).to eq(2)
24
+ expect(state[:events][0][:version]).to eq(1)
25
+ expect(state[:events][0][:aggregate_id]).to eq(new_aggregate.aggregate_id)
26
+ expect(state[:events][1][:version]).to eq(2)
27
+ expect(state[:events][1][:aggregate_id]).to eq(new_aggregate.aggregate_id)
28
+ end
29
+
30
+ it 'saves an existing aggregate then is able to load the correct data back' do
31
+ new_aggregate = aggregate_type.new
32
+ new_aggregate.test_fire
33
+ new_aggregate.test_fire_ag
34
+ repository.save new_aggregate
35
+ old_aggregate = repository.find_by new_aggregate.aggregate_id
36
+ old_aggregate.test_fire
37
+ old_aggregate.test_fire_ag
38
+ repository.save old_aggregate
39
+ state = event_store.load_by old_aggregate.aggregate_id, command_context
40
+
41
+ expect(state[:aggregate_type]).to eq(aggregate_type_str)
42
+ expect(state[:events].size).to eq(4)
43
+ expect(state[:events][0][:version]).to eq(1)
44
+ expect(state[:events][0][:aggregate_id]).to eq(old_aggregate.aggregate_id)
45
+ expect(state[:events][1][:version]).to eq(2)
46
+ expect(state[:events][1][:aggregate_id]).to eq(old_aggregate.aggregate_id)
47
+ expect(state[:events][2][:version]).to eq(3)
48
+ expect(state[:events][2][:aggregate_id]).to eq(old_aggregate.aggregate_id)
49
+ expect(state[:events][3][:version]).to eq(4)
50
+ expect(state[:events][3][:aggregate_id]).to eq(old_aggregate.aggregate_id)
51
+ end
52
+
53
+ it "receives correct input on #save with 1 snapshot taken when enough events get fired" do
54
+ aggregate = aggregate_type.new
55
+ expect(event_store).to receive(:save)\
56
+ { |changes, context| expect(changes[0][:snapshot]).to_not be_nil }
57
+ (1..30).each { |x| aggregate.test_fire }
58
+ repository.save aggregate
59
+
60
+ aggregate = aggregate_s_45_type.new
61
+ expect(event_store).to receive(:save)\
62
+ { |changes, context| expect(changes[0][:snapshot]).to_not be_nil }
63
+ (1..45).each { |x| aggregate.test_fire }
64
+ repository.save aggregate
65
+ end
66
+
67
+ it "receives correct input on #save with 1 snapshot taken when enough events get fired, also test result" do
68
+ aggregate = aggregate_type.new
69
+ (1..30).each { |x| aggregate.test_fire }
70
+ repository.save aggregate
71
+
72
+ state = event_store.load_by aggregate.aggregate_id, command_context
73
+ expect(state[:aggregate_id]).to eq(aggregate.aggregate_id)
74
+ expect(state[:aggregate_type]).to eq(aggregate_type_str)
75
+ expect(state[:events].size).to eq(0)
76
+ expect(state[:snapshot][:data]).to_not be_nil
77
+ expect(state[:snapshot][:version]).to be(30)
78
+
79
+ aggregate = aggregate_s_45_type.new
80
+ (1..45).each { |x| aggregate.test_fire }
81
+ repository.save aggregate
82
+
83
+ state = event_store.load_by aggregate.aggregate_id, command_context
84
+ expect(state[:aggregate_id]).to eq(aggregate.aggregate_id)
85
+ expect(state[:aggregate_type]).to eq(aggregate_s_45_type_str)
86
+ expect(state[:events].size).to eq(0)
87
+ expect(state[:snapshot]).to_not be_nil
88
+ end
89
+
90
+ it "receives correct input on #save with no snapshot taken when not enough events get fired" do
91
+ aggregate = aggregate_type.new
92
+ expect(event_store).to receive(:save)\
93
+ { |changes, context| expect(changes[0][:snapshot]).to be_nil }
94
+ (1..29).each { |x| aggregate.test_fire }
95
+ repository.save aggregate
96
+
97
+ aggregate = aggregate_s_45_type.new
98
+ expect(event_store).to receive(:save)\
99
+ { |changes, context| expect(changes[0][:snapshot]).to be_nil }
100
+ (1..44).each { |x| aggregate.test_fire }
101
+ repository.save aggregate
102
+ end
103
+
104
+ it "receives correct input on #save with no snapshot taken when not enough events get fired, also test result" do
105
+ aggregate = aggregate_type.new
106
+ (1..29).each { |x| aggregate.test_fire }
107
+ repository.save aggregate
108
+
109
+ state = event_store.load_by aggregate.aggregate_id, command_context
110
+ expect(state[:aggregate_id]).to eq(aggregate.aggregate_id)
111
+ expect(state[:aggregate_type]).to eq(aggregate_type_str)
112
+ expect(state[:events].size).to eq(29)
113
+ expect(state[:snapshot]).to be_nil
114
+
115
+ aggregate = aggregate_s_45_type.new
116
+ (1..44).each { |x| aggregate.test_fire }
117
+ repository.save aggregate
118
+
119
+ state = event_store.load_by aggregate.aggregate_id, command_context
120
+ expect(state[:aggregate_id]).to eq(aggregate.aggregate_id)
121
+ expect(state[:aggregate_type]).to eq(aggregate_s_45_type_str)
122
+ expect(state[:events].size).to eq(44)
123
+ expect(state[:snapshot]).to be_nil
124
+ end
125
+
126
+ it "receives correct input on #save incrementally and eventually triggers a snapshot" do
127
+ aggregate = aggregate_type.new
128
+
129
+ expect(event_store).to receive(:save)\
130
+ { |changes, context| expect(changes[0][:snapshot]).to be_nil }
131
+ (1..15).each { |x| aggregate.test_fire }
132
+ repository.save aggregate
133
+
134
+ expect(event_store).to receive(:save)\
135
+ { |changes, context| expect(changes[0][:snapshot]).to_not be_nil }
136
+ (1..15).each { |x| aggregate.test_fire }
137
+ repository.save aggregate
138
+
139
+ aggregate = aggregate_s_45_type.new
140
+
141
+ expect(event_store).to receive(:save)\
142
+ { |changes, context| expect(changes[0][:snapshot]).to be_nil }
143
+ (1..30).each { |x| aggregate.test_fire }
144
+ repository.save aggregate
145
+
146
+ expect(event_store).to receive(:save)\
147
+ { |changes, context| expect(changes[0][:snapshot]).to_not be_nil }
148
+ (1..15).each { |x| aggregate.test_fire }
149
+ repository.save aggregate
150
+ end
151
+
152
+ it "receives correct input on #save incrementally and eventually triggers a snapshot, also test result" do
153
+ aggregate = aggregate_type.new
154
+ (1..15).each { |x| aggregate.test_fire }
155
+ repository.save aggregate
156
+ (1..15).each { |x| aggregate.test_fire }
157
+ repository.save aggregate
158
+
159
+ state = event_store.load_by aggregate.aggregate_id, command_context
160
+ expect(state[:aggregate_id]).to eq(aggregate.aggregate_id)
161
+ expect(state[:aggregate_type]).to eq(aggregate_type_str)
162
+ expect(state[:events].size).to eq(0)
163
+ expect(state[:snapshot][:data]).to_not be_nil
164
+ expect(state[:snapshot][:version]).to be(30)
165
+
166
+ aggregate = aggregate_s_45_type.new
167
+ (1..30).each { |x| aggregate.test_fire }
168
+ repository.save aggregate
169
+ (1..15).each { |x| aggregate.test_fire }
170
+ repository.save aggregate
171
+
172
+ state = event_store.load_by aggregate.aggregate_id, command_context
173
+ expect(state[:aggregate_id]).to eq(aggregate.aggregate_id)
174
+ expect(state[:aggregate_type]).to eq(aggregate_s_45_type_str)
175
+ expect(state[:events].size).to eq(0)
176
+ expect(state[:snapshot][:data]).to_not be_nil
177
+ expect(state[:snapshot][:version]).to be(45)
178
+ end
179
+
180
+ it "receives correct input on #save with 1 snapshot taken when more than enough events get fired" do
181
+ aggregate = aggregate_type.new
182
+
183
+ expect(event_store).to receive(:save)\
184
+ { |changes, context| expect(changes[0][:snapshot]).to_not be_nil }
185
+ (1..45).each { |x| aggregate.test_fire }
186
+ repository.save aggregate
187
+
188
+ aggregate = aggregate_s_45_type.new
189
+
190
+ expect(event_store).to receive(:save)\
191
+ { |changes, context| expect(changes[0][:snapshot]).to_not be_nil }
192
+ (1..60).each { |x| aggregate.test_fire }
193
+ repository.save aggregate
194
+ end
195
+
196
+ it "receives correct input on #save with 1 snapshot taken when more than enough events get fired, also test result" do
197
+ aggregate = aggregate_type.new
198
+ (1..45).each { |x| aggregate.test_fire }
199
+ repository.save aggregate
200
+
201
+ state = event_store.load_by aggregate.aggregate_id, command_context
202
+ expect(state[:aggregate_id]).to eq(aggregate.aggregate_id)
203
+ expect(state[:aggregate_type]).to eq(aggregate_type_str)
204
+ expect(state[:events].size).to eq(0)
205
+ expect(state[:snapshot][:data]).to_not be_nil
206
+ expect(state[:snapshot][:version]).to be(45)
207
+
208
+ aggregate = aggregate_s_45_type.new
209
+ (1..60).each { |x| aggregate.test_fire }
210
+ repository.save aggregate
211
+
212
+ state = event_store.load_by aggregate.aggregate_id, command_context
213
+ expect(state[:aggregate_id]).to eq(aggregate.aggregate_id)
214
+ expect(state[:aggregate_type]).to eq(aggregate_s_45_type_str)
215
+ expect(state[:events].size).to eq(0)
216
+ expect(state[:snapshot][:data]).to_not be_nil
217
+ expect(state[:snapshot][:version]).to be(60)
218
+ end
219
+
220
+ it "receives correct input on #save with 1 snapshot taken when enough events get fired, twice" do
221
+ aggregate = aggregate_type.new
222
+
223
+ expect(event_store).to receive(:save)\
224
+ { |changes, context| expect(changes[0][:snapshot]).to_not be_nil }
225
+ (1..30).each { |x| aggregate.test_fire }
226
+ repository.save aggregate
227
+
228
+ expect(event_store).to receive(:save)\
229
+ { |changes, context| expect(changes[0][:snapshot]).to_not be_nil }
230
+ (1..30).each { |x| aggregate.test_fire }
231
+ repository.save aggregate
232
+
233
+ aggregate = aggregate_s_45_type.new
234
+
235
+ expect(event_store).to receive(:save)\
236
+ { |changes, context| expect(changes[0][:snapshot]).to_not be_nil }
237
+ (1..45).each { |x| aggregate.test_fire }
238
+ repository.save aggregate
239
+
240
+ expect(event_store).to receive(:save)\
241
+ { |changes, context| expect(changes[0][:snapshot]).to_not be_nil }
242
+ (1..45).each { |x| aggregate.test_fire }
243
+ repository.save aggregate
244
+ end
245
+
246
+ it "receives correct input on #save with 1 snapshot taken when enough events get fired, twice, also test result" do
247
+ aggregate = aggregate_type.new
248
+ (1..30).each { |x| aggregate.test_fire }
249
+ repository.save aggregate
250
+ (1..30).each { |x| aggregate.test_fire }
251
+ repository.save aggregate
252
+
253
+ state = event_store.load_by aggregate.aggregate_id, command_context
254
+ expect(state[:aggregate_id]).to eq(aggregate.aggregate_id)
255
+ expect(state[:aggregate_type]).to eq(aggregate_type_str)
256
+ expect(state[:events].size).to eq(0)
257
+ expect(state[:snapshot][:data]).to_not be_nil
258
+ expect(state[:snapshot][:version]).to be(60)
259
+
260
+ aggregate = aggregate_s_45_type.new
261
+ (1..45).each { |x| aggregate.test_fire }
262
+ repository.save aggregate
263
+ (1..45).each { |x| aggregate.test_fire }
264
+ repository.save aggregate
265
+
266
+ state = event_store.load_by aggregate.aggregate_id, command_context
267
+ expect(state[:aggregate_id]).to eq(aggregate.aggregate_id)
268
+ expect(state[:aggregate_type]).to eq(aggregate_s_45_type_str)
269
+ expect(state[:events].size).to eq(0)
270
+ expect(state[:snapshot][:data]).to_not be_nil
271
+ expect(state[:snapshot][:version]).to be(90)
272
+ end
273
+
274
+ it "receives correct input on #save incrementally and eventually triggers two snapshots" do
275
+ aggregate = aggregate_type.new
276
+
277
+ expect(event_store).to receive(:save)\
278
+ { |changes, context| expect(changes[0][:snapshot]).to_not be_nil }
279
+ (1..30).each { |x| aggregate.test_fire }
280
+ repository.save aggregate
281
+
282
+ expect(event_store).to receive(:save)\
283
+ { |changes, context| expect(changes[0][:snapshot]).to be_nil }
284
+ (1..15).each { |x| aggregate.test_fire }
285
+ repository.save aggregate
286
+
287
+ expect(event_store).to receive(:save)\
288
+ { |changes, context| expect(changes[0][:snapshot]).to_not be_nil }
289
+ (1..15).each { |x| aggregate.test_fire }
290
+ repository.save aggregate
291
+
292
+ expect(event_store).to receive(:save)\
293
+ { |changes, context| expect(changes[0][:snapshot]).to be_nil }
294
+ (1..15).each { |x| aggregate.test_fire }
295
+ repository.save aggregate
296
+
297
+ aggregate = aggregate_s_45_type.new
298
+
299
+ expect(event_store).to receive(:save)\
300
+ { |changes, context| expect(changes[0][:snapshot]).to be_nil }
301
+ (1..30).each { |x| aggregate.test_fire }
302
+ repository.save aggregate
303
+
304
+ expect(event_store).to receive(:save)\
305
+ { |changes, context| expect(changes[0][:snapshot]).to_not be_nil }
306
+ (1..30).each { |x| aggregate.test_fire }
307
+ repository.save aggregate
308
+
309
+ expect(event_store).to receive(:save)\
310
+ { |changes, context| expect(changes[0][:snapshot]).to be_nil }
311
+ (1..30).each { |x| aggregate.test_fire }
312
+ repository.save aggregate
313
+
314
+ expect(event_store).to receive(:save)\
315
+ { |changes, context| expect(changes[0][:snapshot]).to_not be_nil }
316
+ (1..15).each { |x| aggregate.test_fire }
317
+ repository.save aggregate
318
+ end
319
+
320
+ it "receives correct input on #save incrementally and eventually triggers two snapshots, also test result" do
321
+ aggregate = aggregate_type.new
322
+ (1..30).each { |x| aggregate.test_fire }
323
+ repository.save aggregate
324
+ (1..15).each { |x| aggregate.test_fire }
325
+ repository.save aggregate
326
+ (1..15).each { |x| aggregate.test_fire }
327
+ repository.save aggregate
328
+ (1..15).each { |x| aggregate.test_fire }
329
+ repository.save aggregate
330
+
331
+ state = event_store.load_by aggregate.aggregate_id, command_context
332
+ expect(state[:aggregate_id]).to eq(aggregate.aggregate_id)
333
+ expect(state[:aggregate_type]).to eq(aggregate_type_str)
334
+ expect(state[:events].size).to eq(15)
335
+ expect(state[:snapshot][:data]).to_not be_nil
336
+ expect(state[:snapshot][:version]).to be(60)
337
+
338
+ aggregate = aggregate_s_45_type.new
339
+ (1..30).each { |x| aggregate.test_fire }
340
+ repository.save aggregate
341
+ (1..30).each { |x| aggregate.test_fire }
342
+ repository.save aggregate
343
+ (1..30).each { |x| aggregate.test_fire }
344
+ repository.save aggregate
345
+ (1..15).each { |x| aggregate.test_fire }
346
+ repository.save aggregate
347
+
348
+ state = event_store.load_by aggregate.aggregate_id, command_context
349
+ expect(state[:aggregate_id]).to eq(aggregate.aggregate_id)
350
+ expect(state[:aggregate_type]).to eq(aggregate_s_45_type_str)
351
+ expect(state[:events].size).to eq(0)
352
+ expect(state[:snapshot][:data]).to_not be_nil
353
+ expect(state[:snapshot][:version]).to be(105)
354
+ end
355
+
356
+ it 'raises concurrency error when two instances of the same aggregate try to compete with each other' do
357
+ # obtain two instances of the same aggregate
358
+ new_aggregate = aggregate_type.new
359
+ new_aggregate.test_fire
360
+ new_aggregate.test_fire_ag
361
+ repository.save new_aggregate
362
+ instance_1 = new_aggregate
363
+ instance_2 = repository.find_by new_aggregate.aggregate_id
364
+
365
+ # now both instances try to compete with each other
366
+ instance_1.test_fire
367
+ instance_2.test_fire
368
+
369
+ # only one instance of the two could be saved successfully
370
+ repository.save instance_1
371
+ expect(instance_1.version).to eq(instance_1.instance_variable_get(:@source_version))
372
+ expect{ repository.save instance_2 }.to raise_error(RubyCqrs::AggregateConcurrencyError)
373
+ expect(instance_2.version).to_not eq(instance_2.instance_variable_get(:@source_version))
374
+ end
375
+
376
+ it 'makes sure no state could be persisted if any error occured during the save process' do
377
+ # obtain two instances of the same aggregate
378
+ instance_1 = aggregate_type.new
379
+ instance_1.test_fire
380
+ instance_1.test_fire_ag
381
+ repository.save instance_1
382
+ instance_2 = repository.find_by instance_1.aggregate_id
383
+
384
+ # now both instances try to compete with each other
385
+ instance_1.test_fire
386
+ instance_2.test_fire
387
+
388
+ # instance 1 wins the save
389
+ repository.save instance_1
390
+
391
+ # instance 3 has done its work and ready to be persisted
392
+ instance_3 = aggregate_type.new
393
+ instance_3.test_fire
394
+
395
+ # when trying to save instance 2 and 3 together, instance 2 would trigger an error
396
+ # so both instance 2 and 3 could not be persisted
397
+ expect{ repository.save [ instance_3, instance_2 ] }.to\
398
+ raise_error(RubyCqrs::AggregateConcurrencyError)
399
+ expect(instance_1.version).to eq(instance_1.instance_variable_get(:@source_version))
400
+ expect(instance_2.version).to_not eq(instance_2.instance_variable_get(:@source_version))
401
+ expect(instance_3.version).to_not eq(instance_3.instance_variable_get(:@source_version))
402
+ end
403
+ end
404
+ end
@@ -0,0 +1,52 @@
1
+ require_relative('../spec_helper')
2
+ describe 'decoder & encoder' do
3
+ let(:unsupported_obj) { SomeDomain::FifthEvent.new }
4
+ let(:unsupported_obj_type) { SomeDomain::FifthEvent.name }
5
+ let(:supported_obj) { SomeDomain::THIRD_EVENT_INSTANCE }
6
+ let(:supported_obj_type) { SomeDomain::THIRD_EVENT_INSTANCE.class.name }
7
+
8
+ describe RubyCqrs::Data::Encodable do
9
+ describe '#try_encode' do
10
+ it 'encodes a supported object into string' do
11
+ encoded_message = supported_obj.try_encode
12
+ expect(encoded_message.class.name).to eq('String')
13
+ end
14
+
15
+ it 'raises an ObjectNotEncodableError when trying to encode an unsupported object' do
16
+ expect{ unsupported_obj.try_encode }.to raise_error(RubyCqrs::ObjectNotEncodableError)
17
+ end
18
+ end
19
+ end
20
+
21
+ describe RubyCqrs::Data::Decodable do
22
+ let(:decoder_type) { Class.new { include RubyCqrs::Data::Decodable } }
23
+ let(:decoder) { decoder_type.new }
24
+
25
+ describe '#try_decode' do
26
+ let(:unsupported_record) {
27
+ { :object_type => unsupported_obj_type,
28
+ :data => unsupported_obj } }
29
+ let(:supported_record) {
30
+ { :object_type => supported_obj_type,
31
+ :data => supported_obj.try_encode } }
32
+
33
+ it 'decodes a supported object type from string' do
34
+ decoded_object = decoder.try_decode(supported_record[:object_type],\
35
+ supported_record[:data])
36
+ expect(decoded_object.class.name).to eq(supported_obj_type)
37
+ # specific test value
38
+ expect(decoded_object.id).to eq(1)
39
+ expect(decoded_object.name).to eq('some dude')
40
+ expect(decoded_object.phone).to eq('13322244444')
41
+ expect(decoded_object.note).to eq('good luck')
42
+ end
43
+
44
+ it 'raises an ObjectNotDecodableError when trying to decode an unsupported object' do
45
+ expect {
46
+ decoder.try_decode unsupported_record[:object_type],\
47
+ unsupported_record[:data]
48
+ }.to raise_error(RubyCqrs::ObjectNotDecodableError)
49
+ end
50
+ end
51
+ end
52
+ end
metadata ADDED
@@ -0,0 +1,120 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: ruby_cqrs
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.2.0
5
+ platform: ruby
6
+ authors:
7
+ - Raven Chen
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2015-04-13 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: uuidtools
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - '='
18
+ - !ruby/object:Gem::Version
19
+ version: 2.1.5
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - '='
25
+ - !ruby/object:Gem::Version
26
+ version: 2.1.5
27
+ - !ruby/object:Gem::Dependency
28
+ name: activesupport
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - '='
32
+ - !ruby/object:Gem::Version
33
+ version: 4.2.1
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - '='
39
+ - !ruby/object:Gem::Version
40
+ version: 4.2.1
41
+ - !ruby/object:Gem::Dependency
42
+ name: beefcake
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - '='
46
+ - !ruby/object:Gem::Version
47
+ version: 1.0.0
48
+ type: :runtime
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - '='
53
+ - !ruby/object:Gem::Version
54
+ version: 1.0.0
55
+ description: a ruby implementation of cqrs, using event sourcing
56
+ email:
57
+ - ravenchen.cn@gmail.com
58
+ executables: []
59
+ extensions: []
60
+ extra_rdoc_files:
61
+ - README.md
62
+ files:
63
+ - License.txt
64
+ - README.md
65
+ - lib/ruby_cqrs.rb
66
+ - lib/ruby_cqrs/data/event_store.rb
67
+ - lib/ruby_cqrs/data/in_memory_event_store.rb
68
+ - lib/ruby_cqrs/data/serialization.rb
69
+ - lib/ruby_cqrs/domain/aggregate.rb
70
+ - lib/ruby_cqrs/domain/aggregate_repository.rb
71
+ - lib/ruby_cqrs/domain/event.rb
72
+ - lib/ruby_cqrs/domain/snapshot.rb
73
+ - lib/ruby_cqrs/domain/snapshotable.rb
74
+ - lib/ruby_cqrs/error.rb
75
+ - lib/ruby_cqrs/guid.rb
76
+ - lib/ruby_cqrs/version.rb
77
+ - spec/feature/basic_usage_spec.rb
78
+ - spec/feature/snapshot_spec.rb
79
+ - spec/fixture/typical_domain.rb
80
+ - spec/spec_helper.rb
81
+ - spec/support/matchers.rb
82
+ - spec/unit/aggregate_repository_spec.rb
83
+ - spec/unit/aggregate_spec.rb
84
+ - spec/unit/in_memory_event_store_spec.rb
85
+ - spec/unit/serialization_spec.rb
86
+ homepage: https://github.com/iravench/ruby_cqrs
87
+ licenses:
88
+ - MIT
89
+ metadata: {}
90
+ post_install_message:
91
+ rdoc_options:
92
+ - "--charset=UTF-8"
93
+ require_paths:
94
+ - lib
95
+ required_ruby_version: !ruby/object:Gem::Requirement
96
+ requirements:
97
+ - - ">="
98
+ - !ruby/object:Gem::Version
99
+ version: '0'
100
+ required_rubygems_version: !ruby/object:Gem::Requirement
101
+ requirements:
102
+ - - ">="
103
+ - !ruby/object:Gem::Version
104
+ version: '0'
105
+ requirements: []
106
+ rubyforge_project:
107
+ rubygems_version: 2.4.6
108
+ signing_key:
109
+ specification_version: 4
110
+ summary: ruby_cqrs-0.2.0
111
+ test_files:
112
+ - spec/feature/basic_usage_spec.rb
113
+ - spec/feature/snapshot_spec.rb
114
+ - spec/fixture/typical_domain.rb
115
+ - spec/spec_helper.rb
116
+ - spec/support/matchers.rb
117
+ - spec/unit/aggregate_repository_spec.rb
118
+ - spec/unit/aggregate_spec.rb
119
+ - spec/unit/in_memory_event_store_spec.rb
120
+ - spec/unit/serialization_spec.rb