ruby_event_store 2.1.0 → 2.4.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 +4 -4
- data/lib/ruby_event_store/batch_enumerator.rb +3 -3
- data/lib/ruby_event_store/broker.rb +5 -4
- data/lib/ruby_event_store/client.rb +81 -48
- data/lib/ruby_event_store/composed_dispatcher.rb +1 -3
- data/lib/ruby_event_store/correlated_commands.rb +4 -15
- data/lib/ruby_event_store/errors.rb +11 -10
- data/lib/ruby_event_store/event.rb +9 -14
- data/lib/ruby_event_store/expected_version.rb +3 -7
- data/lib/ruby_event_store/in_memory_repository.rb +100 -37
- data/lib/ruby_event_store/instrumented_dispatcher.rb +11 -2
- data/lib/ruby_event_store/instrumented_repository.rb +13 -8
- data/lib/ruby_event_store/link_by_metadata.rb +4 -21
- data/lib/ruby_event_store/mappers/default.rb +6 -4
- data/lib/ruby_event_store/mappers/encryption_key.rb +7 -16
- data/lib/ruby_event_store/mappers/encryption_mapper.rb +6 -6
- data/lib/ruby_event_store/mappers/forgotten_data.rb +1 -1
- data/lib/ruby_event_store/mappers/in_memory_encryption_key_repository.rb +1 -1
- data/lib/ruby_event_store/mappers/null_mapper.rb +0 -1
- data/lib/ruby_event_store/mappers/pipeline.rb +3 -10
- data/lib/ruby_event_store/mappers/pipeline_mapper.rb +1 -0
- data/lib/ruby_event_store/mappers/transformation/domain_event.rb +22 -12
- data/lib/ruby_event_store/mappers/transformation/encryption.rb +21 -25
- data/lib/ruby_event_store/mappers/transformation/event_class_remapper.rb +6 -5
- data/lib/ruby_event_store/mappers/transformation/stringify_metadata_keys.rb +6 -5
- data/lib/ruby_event_store/mappers/transformation/symbolize_metadata_keys.rb +6 -5
- data/lib/ruby_event_store/mappers/transformation/upcast.rb +2 -6
- data/lib/ruby_event_store/metadata.rb +46 -17
- data/lib/ruby_event_store/projection.rb +12 -20
- data/lib/ruby_event_store/record.rb +14 -26
- data/lib/ruby_event_store/serialized_record.rb +14 -26
- data/lib/ruby_event_store/serializers/yaml.rb +17 -0
- data/lib/ruby_event_store/spec/broker_lint.rb +38 -28
- data/lib/ruby_event_store/spec/event_lint.rb +10 -10
- data/lib/ruby_event_store/spec/event_repository_lint.rb +746 -730
- data/lib/ruby_event_store/spec/mapper_lint.rb +2 -2
- data/lib/ruby_event_store/spec/subscriptions_lint.rb +58 -68
- data/lib/ruby_event_store/specification.rb +20 -16
- data/lib/ruby_event_store/specification_reader.rb +2 -3
- data/lib/ruby_event_store/specification_result.rb +52 -46
- data/lib/ruby_event_store/stream.rb +3 -7
- data/lib/ruby_event_store/subscriptions.rb +17 -17
- data/lib/ruby_event_store/transform_keys.rb +1 -1
- data/lib/ruby_event_store/version.rb +1 -1
- data/lib/ruby_event_store.rb +44 -43
- metadata +6 -4
@@ -2,88 +2,58 @@ module RubyEventStore
|
|
2
2
|
# @private
|
3
3
|
class SRecord
|
4
4
|
def self.new(
|
5
|
-
event_id:
|
6
|
-
data:
|
7
|
-
metadata:
|
8
|
-
event_type:
|
9
|
-
timestamp:
|
10
|
-
valid_at:
|
5
|
+
event_id: SecureRandom.uuid,
|
6
|
+
data: {},
|
7
|
+
metadata: {},
|
8
|
+
event_type: "SRecordTestEvent",
|
9
|
+
timestamp: Time.new.utc,
|
10
|
+
valid_at: nil
|
11
11
|
)
|
12
12
|
Record.new(
|
13
|
-
event_id:
|
14
|
-
data:
|
15
|
-
metadata:
|
13
|
+
event_id: event_id,
|
14
|
+
data: data,
|
15
|
+
metadata: metadata,
|
16
16
|
event_type: event_type,
|
17
|
-
timestamp:
|
18
|
-
valid_at:
|
17
|
+
timestamp: timestamp.round(TIMESTAMP_PRECISION),
|
18
|
+
valid_at: (valid_at || timestamp).round(TIMESTAMP_PRECISION)
|
19
19
|
)
|
20
20
|
end
|
21
21
|
end
|
22
22
|
|
23
23
|
# @private
|
24
24
|
Type1 = Class.new(RubyEventStore::Event)
|
25
|
+
|
25
26
|
# @private
|
26
27
|
Type2 = Class.new(RubyEventStore::Event)
|
27
|
-
# @private
|
28
|
-
Type3 = Class.new(RubyEventStore::Event)
|
29
28
|
|
30
29
|
# @private
|
31
|
-
|
32
|
-
def supports_concurrent_auto?
|
33
|
-
true
|
34
|
-
end
|
35
|
-
|
36
|
-
def supports_concurrent_any?
|
37
|
-
true
|
38
|
-
end
|
39
|
-
|
40
|
-
def supports_binary?
|
41
|
-
true
|
42
|
-
end
|
43
|
-
|
44
|
-
def supports_upsert?
|
45
|
-
true
|
46
|
-
end
|
47
|
-
|
48
|
-
def has_connection_pooling?
|
49
|
-
false
|
50
|
-
end
|
51
|
-
|
52
|
-
def connection_pool_size
|
53
|
-
end
|
54
|
-
|
55
|
-
def cleanup_concurrency_test
|
56
|
-
end
|
57
|
-
|
58
|
-
def rescuable_concurrency_test_errors
|
59
|
-
[]
|
60
|
-
end
|
61
|
-
end
|
30
|
+
Type3 = Class.new(RubyEventStore::Event)
|
62
31
|
end
|
63
32
|
|
64
33
|
module RubyEventStore
|
65
|
-
::RSpec.shared_examples :event_repository do
|
66
|
-
let(:
|
34
|
+
::RSpec.shared_examples :event_repository do |mk_repository, helper|
|
35
|
+
let(:repository) { mk_repository.call }
|
67
36
|
let(:specification) { Specification.new(SpecificationReader.new(repository, Mappers::NullMapper.new)) }
|
68
37
|
let(:global_stream) { Stream.new(GLOBAL_STREAM) }
|
69
|
-
let(:stream)
|
70
|
-
let(:stream_flow)
|
71
|
-
let(:stream_other)
|
72
|
-
let(:stream_test)
|
73
|
-
let(:version_none)
|
74
|
-
let(:version_auto)
|
75
|
-
let(:version_any)
|
76
|
-
let(:version_0)
|
77
|
-
let(:version_1)
|
78
|
-
let(:version_2)
|
79
|
-
let(:version_3)
|
80
|
-
|
81
|
-
def verify_conncurency_assumptions
|
38
|
+
let(:stream) { Stream.new(SecureRandom.uuid) }
|
39
|
+
let(:stream_flow) { Stream.new("flow") }
|
40
|
+
let(:stream_other) { Stream.new("other") }
|
41
|
+
let(:stream_test) { Stream.new("test") }
|
42
|
+
let(:version_none) { ExpectedVersion.none }
|
43
|
+
let(:version_auto) { ExpectedVersion.auto }
|
44
|
+
let(:version_any) { ExpectedVersion.any }
|
45
|
+
let(:version_0) { ExpectedVersion.new(0) }
|
46
|
+
let(:version_1) { ExpectedVersion.new(1) }
|
47
|
+
let(:version_2) { ExpectedVersion.new(2) }
|
48
|
+
let(:version_3) { ExpectedVersion.new(3) }
|
49
|
+
|
50
|
+
def verify_conncurency_assumptions(helper)
|
82
51
|
return unless helper.has_connection_pooling?
|
83
|
-
expect(helper.connection_pool_size).to eq(5)
|
52
|
+
expect(helper.connection_pool_size).to eq(5),
|
53
|
+
"expected connection pool of size 5, got #{helper.connection_pool_size}"
|
84
54
|
end
|
85
55
|
|
86
|
-
def read_events(scope, stream = nil, from: nil, to: nil, count: nil)
|
56
|
+
def read_events(repository, scope, stream = nil, from: nil, to: nil, count: nil)
|
87
57
|
scope = scope.stream(stream.name) if stream
|
88
58
|
scope = scope.from(from) if from
|
89
59
|
scope = scope.to(to) if to
|
@@ -91,25 +61,25 @@ module RubyEventStore
|
|
91
61
|
repository.read(scope.result).to_a
|
92
62
|
end
|
93
63
|
|
94
|
-
def read_events_forward(
|
95
|
-
read_events(specification, stream, from: from, to: to, count: count)
|
64
|
+
def read_events_forward(repository, stream = nil, from: nil, to: nil, count: nil)
|
65
|
+
read_events(repository, specification, stream, from: from, to: to, count: count)
|
96
66
|
end
|
97
67
|
|
98
|
-
def read_events_backward(
|
99
|
-
read_events(specification.backward, stream, from: from, to: to, count: count)
|
68
|
+
def read_events_backward(repository, stream = nil, from: nil, to: nil, count: nil)
|
69
|
+
read_events(repository, specification.backward, stream, from: from, to: to, count: count)
|
100
70
|
end
|
101
71
|
|
102
|
-
it
|
72
|
+
it "just created is empty" do
|
103
73
|
expect(read_events_forward(repository)).to be_empty
|
104
74
|
end
|
105
75
|
|
106
|
-
specify
|
76
|
+
specify "append_to_stream returns self" do
|
107
77
|
repository
|
108
78
|
.append_to_stream([event = SRecord.new], stream, version_none)
|
109
79
|
.append_to_stream([event = SRecord.new], stream, version_0)
|
110
80
|
end
|
111
81
|
|
112
|
-
specify
|
82
|
+
specify "link_to_stream returns self" do
|
113
83
|
event0 = SRecord.new
|
114
84
|
event1 = SRecord.new
|
115
85
|
repository
|
@@ -118,14 +88,14 @@ module RubyEventStore
|
|
118
88
|
.link_to_stream([event1.event_id], stream_flow, version_0)
|
119
89
|
end
|
120
90
|
|
121
|
-
specify
|
91
|
+
specify "adds an initial event to a new stream" do
|
122
92
|
repository.append_to_stream([event = SRecord.new], stream, version_none)
|
123
93
|
expect(read_events_forward(repository).first).to eq(event)
|
124
94
|
expect(read_events_forward(repository, stream).first).to eq(event)
|
125
95
|
expect(read_events_forward(repository, stream_other)).to be_empty
|
126
96
|
end
|
127
97
|
|
128
|
-
specify
|
98
|
+
specify "links an initial event to a new stream" do
|
129
99
|
repository
|
130
100
|
.append_to_stream([event = SRecord.new], stream, version_none)
|
131
101
|
.link_to_stream([event.event_id], stream_flow, version_none)
|
@@ -136,476 +106,350 @@ module RubyEventStore
|
|
136
106
|
expect(read_events_forward(repository, stream_other)).to be_empty
|
137
107
|
end
|
138
108
|
|
139
|
-
specify
|
140
|
-
repository.append_to_stream([
|
141
|
-
event0 = SRecord.new,
|
142
|
-
event1 = SRecord.new,
|
143
|
-
], stream, version_none)
|
109
|
+
specify "adds multiple initial events to a new stream" do
|
110
|
+
repository.append_to_stream([event0 = SRecord.new, event1 = SRecord.new], stream, version_none)
|
144
111
|
expect(read_events_forward(repository, count: 2)).to eq([event0, event1])
|
145
112
|
expect(read_events_forward(repository, stream)).to eq([event0, event1])
|
146
113
|
end
|
147
114
|
|
148
|
-
specify
|
149
|
-
repository
|
150
|
-
event0 = SRecord.new,
|
151
|
-
event1
|
152
|
-
], stream, version_none).link_to_stream([
|
153
|
-
event0.event_id,
|
154
|
-
event1.event_id,
|
155
|
-
], stream_flow, version_none)
|
115
|
+
specify "links multiple initial events to a new stream" do
|
116
|
+
repository
|
117
|
+
.append_to_stream([event0 = SRecord.new, event1 = SRecord.new], stream, version_none)
|
118
|
+
.link_to_stream([event0.event_id, event1.event_id], stream_flow, version_none)
|
156
119
|
expect(read_events_forward(repository, count: 2)).to eq([event0, event1])
|
157
120
|
expect(read_events_forward(repository, stream_flow)).to eq([event0, event1])
|
158
121
|
end
|
159
122
|
|
160
|
-
specify
|
161
|
-
repository.append_to_stream([
|
162
|
-
|
163
|
-
event1 = SRecord.new,
|
164
|
-
], stream, version_none)
|
165
|
-
repository.append_to_stream([
|
166
|
-
event2 = SRecord.new,
|
167
|
-
event3 = SRecord.new,
|
168
|
-
], stream, version_1)
|
123
|
+
specify "correct expected version on second write" do
|
124
|
+
repository.append_to_stream([event0 = SRecord.new, event1 = SRecord.new], stream, version_none)
|
125
|
+
repository.append_to_stream([event2 = SRecord.new, event3 = SRecord.new], stream, version_1)
|
169
126
|
expect(read_events_forward(repository, count: 4)).to eq([event0, event1, event2, event3])
|
170
127
|
expect(read_events_forward(repository, stream)).to eq([event0, event1, event2, event3])
|
171
128
|
end
|
172
129
|
|
173
|
-
specify
|
174
|
-
repository
|
175
|
-
event0 = SRecord.new,
|
176
|
-
|
177
|
-
|
178
|
-
event2 = SRecord.new,
|
179
|
-
event3 = SRecord.new,
|
180
|
-
], stream_flow, version_none).link_to_stream([
|
181
|
-
event0.event_id,
|
182
|
-
event1.event_id,
|
183
|
-
], stream_flow, version_1)
|
130
|
+
specify "correct expected version on second link" do
|
131
|
+
repository
|
132
|
+
.append_to_stream([event0 = SRecord.new, event1 = SRecord.new], stream, version_none)
|
133
|
+
.append_to_stream([event2 = SRecord.new, event3 = SRecord.new], stream_flow, version_none)
|
134
|
+
.link_to_stream([event0.event_id, event1.event_id], stream_flow, version_1)
|
184
135
|
expect(read_events_forward(repository, count: 4)).to eq([event0, event1, event2, event3])
|
185
136
|
expect(read_events_forward(repository, stream_flow)).to eq([event2, event3, event0, event1])
|
186
137
|
end
|
187
138
|
|
188
|
-
specify
|
189
|
-
repository.append_to_stream([
|
190
|
-
event0 = SRecord.new,
|
191
|
-
event1 = SRecord.new,
|
192
|
-
], stream, version_none)
|
139
|
+
specify "incorrect expected version on second write" do
|
140
|
+
repository.append_to_stream([event0 = SRecord.new, event1 = SRecord.new], stream, version_none)
|
193
141
|
expect do
|
194
|
-
repository.append_to_stream([
|
195
|
-
event2 = SRecord.new,
|
196
|
-
event3 = SRecord.new,
|
197
|
-
], stream, version_0)
|
142
|
+
repository.append_to_stream([event2 = SRecord.new, event3 = SRecord.new], stream, version_0)
|
198
143
|
end.to raise_error(WrongExpectedEventVersion)
|
199
144
|
|
200
145
|
expect(read_events_forward(repository, count: 4)).to eq([event0, event1])
|
201
146
|
expect(read_events_forward(repository, stream)).to eq([event0, event1])
|
202
147
|
end
|
203
148
|
|
204
|
-
specify
|
205
|
-
repository.append_to_stream([
|
206
|
-
|
207
|
-
|
208
|
-
|
209
|
-
|
210
|
-
event2 = SRecord.new,
|
211
|
-
event3 = SRecord.new,
|
212
|
-
], stream_other, version_none)
|
213
|
-
expect do
|
214
|
-
repository.link_to_stream([
|
215
|
-
event2.event_id,
|
216
|
-
event3.event_id,
|
217
|
-
], stream, version_0)
|
218
|
-
end.to raise_error(WrongExpectedEventVersion)
|
149
|
+
specify "incorrect expected version on second link" do
|
150
|
+
repository.append_to_stream([event0 = SRecord.new, event1 = SRecord.new], stream, version_none)
|
151
|
+
repository.append_to_stream([event2 = SRecord.new, event3 = SRecord.new], stream_other, version_none)
|
152
|
+
expect { repository.link_to_stream([event2.event_id, event3.event_id], stream, version_0) }.to raise_error(
|
153
|
+
WrongExpectedEventVersion
|
154
|
+
)
|
219
155
|
|
220
156
|
expect(read_events_forward(repository, count: 4)).to eq([event0, event1, event2, event3])
|
221
157
|
expect(read_events_forward(repository, stream)).to eq([event0, event1])
|
222
158
|
end
|
223
159
|
|
224
|
-
specify
|
225
|
-
repository.append_to_stream([
|
226
|
-
|
227
|
-
|
228
|
-
|
229
|
-
repository.append_to_stream([
|
230
|
-
eventB = SRecord.new,
|
231
|
-
], stream, version_none)
|
232
|
-
end.to raise_error(WrongExpectedEventVersion)
|
160
|
+
specify ":none on first and subsequent write" do
|
161
|
+
repository.append_to_stream([eventA = SRecord.new], stream, version_none)
|
162
|
+
expect { repository.append_to_stream([eventB = SRecord.new], stream, version_none) }.to raise_error(
|
163
|
+
WrongExpectedEventVersion
|
164
|
+
)
|
233
165
|
expect(read_events_forward(repository, count: 1)).to eq([eventA])
|
234
166
|
expect(read_events_forward(repository, stream)).to eq([eventA])
|
235
167
|
end
|
236
168
|
|
237
|
-
specify
|
238
|
-
repository.append_to_stream([
|
239
|
-
eventA = SRecord.new,
|
240
|
-
eventB = SRecord.new,
|
241
|
-
], stream, version_none)
|
169
|
+
specify ":none on first and subsequent link" do
|
170
|
+
repository.append_to_stream([eventA = SRecord.new, eventB = SRecord.new], stream, version_none)
|
242
171
|
|
243
172
|
repository.link_to_stream([eventA.event_id], stream_flow, version_none)
|
244
|
-
expect
|
245
|
-
|
246
|
-
|
173
|
+
expect { repository.link_to_stream([eventB.event_id], stream_flow, version_none) }.to raise_error(
|
174
|
+
WrongExpectedEventVersion
|
175
|
+
)
|
247
176
|
|
248
177
|
expect(read_events_forward(repository, count: 1)).to eq([eventA])
|
249
178
|
expect(read_events_forward(repository, stream_flow)).to eq([eventA])
|
250
179
|
end
|
251
180
|
|
252
|
-
specify
|
253
|
-
repository.append_to_stream([
|
254
|
-
|
255
|
-
event1 = SRecord.new,
|
256
|
-
], stream, version_any)
|
257
|
-
repository.append_to_stream([
|
258
|
-
event2 = SRecord.new,
|
259
|
-
event3 = SRecord.new,
|
260
|
-
], stream, version_any)
|
181
|
+
specify ":any allows stream with best-effort order and no guarantee" do
|
182
|
+
repository.append_to_stream([event0 = SRecord.new, event1 = SRecord.new], stream, version_any)
|
183
|
+
repository.append_to_stream([event2 = SRecord.new, event3 = SRecord.new], stream, version_any)
|
261
184
|
expect(read_events_forward(repository, count: 4).to_set).to eq(Set.new([event0, event1, event2, event3]))
|
262
185
|
expect(read_events_forward(repository, stream).to_set).to eq(Set.new([event0, event1, event2, event3]))
|
263
186
|
end
|
264
187
|
|
265
|
-
specify
|
266
|
-
repository.append_to_stream(
|
267
|
-
event0 = SRecord.new,
|
268
|
-
|
269
|
-
|
270
|
-
|
271
|
-
], stream, version_any)
|
188
|
+
specify ":any allows linking in stream with best-effort order and no guarantee" do
|
189
|
+
repository.append_to_stream(
|
190
|
+
[event0 = SRecord.new, event1 = SRecord.new, event2 = SRecord.new, event3 = SRecord.new],
|
191
|
+
stream,
|
192
|
+
version_any
|
193
|
+
)
|
272
194
|
|
273
|
-
repository.link_to_stream([
|
274
|
-
|
275
|
-
], stream_flow, version_any)
|
276
|
-
repository.link_to_stream([
|
277
|
-
event2.event_id, event3.event_id,
|
278
|
-
], stream_flow, version_any)
|
195
|
+
repository.link_to_stream([event0.event_id, event1.event_id], stream_flow, version_any)
|
196
|
+
repository.link_to_stream([event2.event_id, event3.event_id], stream_flow, version_any)
|
279
197
|
|
280
198
|
expect(read_events_forward(repository, count: 4).to_set).to eq(Set.new([event0, event1, event2, event3]))
|
281
199
|
expect(read_events_forward(repository, stream_flow).to_set).to eq(Set.new([event0, event1, event2, event3]))
|
282
200
|
end
|
283
201
|
|
284
|
-
specify
|
285
|
-
repository.append_to_stream(
|
286
|
-
eventA = SRecord.new,
|
287
|
-
|
288
|
-
|
289
|
-
|
290
|
-
repository.append_to_stream([
|
291
|
-
|
292
|
-
event1 = SRecord.new,
|
293
|
-
], stream, version_auto)
|
294
|
-
repository.append_to_stream([
|
295
|
-
event2 = SRecord.new,
|
296
|
-
event3 = SRecord.new,
|
297
|
-
], stream, version_1)
|
298
|
-
end
|
299
|
-
|
300
|
-
specify ':auto queries for last position in given stream when linking' do
|
301
|
-
repository.append_to_stream([
|
302
|
-
eventA = SRecord.new,
|
303
|
-
eventB = SRecord.new,
|
304
|
-
eventC = SRecord.new,
|
305
|
-
], stream_other, version_auto)
|
306
|
-
repository.append_to_stream([
|
307
|
-
event0 = SRecord.new,
|
308
|
-
event1 = SRecord.new,
|
309
|
-
], stream, version_auto)
|
310
|
-
repository.link_to_stream([
|
311
|
-
eventA.event_id,
|
312
|
-
eventB.event_id,
|
313
|
-
eventC.event_id,
|
314
|
-
], stream, version_1)
|
315
|
-
end
|
316
|
-
|
317
|
-
specify ':auto starts from 0' do
|
318
|
-
repository.append_to_stream([
|
319
|
-
event0 = SRecord.new,
|
320
|
-
], stream, version_auto)
|
321
|
-
expect do
|
322
|
-
repository.append_to_stream([
|
323
|
-
event1 = SRecord.new,
|
324
|
-
], stream, version_none)
|
325
|
-
end.to raise_error(WrongExpectedEventVersion)
|
202
|
+
specify ":auto queries for last position in given stream" do
|
203
|
+
repository.append_to_stream(
|
204
|
+
[eventA = SRecord.new, eventB = SRecord.new, eventC = SRecord.new],
|
205
|
+
stream_other,
|
206
|
+
version_auto
|
207
|
+
)
|
208
|
+
repository.append_to_stream([event0 = SRecord.new, event1 = SRecord.new], stream, version_auto)
|
209
|
+
repository.append_to_stream([event2 = SRecord.new, event3 = SRecord.new], stream, version_1)
|
326
210
|
end
|
327
211
|
|
328
|
-
specify
|
329
|
-
repository.append_to_stream(
|
330
|
-
|
331
|
-
|
332
|
-
|
333
|
-
|
334
|
-
], stream, version_auto)
|
335
|
-
|
336
|
-
|
337
|
-
|
338
|
-
|
339
|
-
|
212
|
+
specify ":auto queries for last position in given stream when linking" do
|
213
|
+
repository.append_to_stream(
|
214
|
+
[eventA = SRecord.new, eventB = SRecord.new, eventC = SRecord.new],
|
215
|
+
stream_other,
|
216
|
+
version_auto
|
217
|
+
)
|
218
|
+
repository.append_to_stream([event0 = SRecord.new, event1 = SRecord.new], stream, version_auto)
|
219
|
+
repository.link_to_stream([eventA.event_id, eventB.event_id, eventC.event_id], stream, version_1)
|
220
|
+
end
|
221
|
+
|
222
|
+
specify ":auto starts from 0" do
|
223
|
+
repository.append_to_stream([event0 = SRecord.new], stream, version_auto)
|
224
|
+
expect { repository.append_to_stream([event1 = SRecord.new], stream, version_none) }.to raise_error(
|
225
|
+
WrongExpectedEventVersion
|
226
|
+
)
|
227
|
+
end
|
228
|
+
|
229
|
+
specify ":auto linking starts from 0" do
|
230
|
+
repository.append_to_stream([event0 = SRecord.new], stream_other, version_auto)
|
231
|
+
repository.link_to_stream([event0.event_id], stream, version_auto)
|
232
|
+
expect { repository.append_to_stream([event1 = SRecord.new], stream, version_none) }.to raise_error(
|
233
|
+
WrongExpectedEventVersion
|
234
|
+
)
|
340
235
|
end
|
341
236
|
|
342
|
-
specify
|
237
|
+
specify ":auto queries for last position and follows in incremental way" do
|
343
238
|
# It is expected that there is higher level lock
|
344
239
|
# So this query is safe from race conditions
|
345
|
-
repository.append_to_stream([
|
346
|
-
|
347
|
-
|
348
|
-
], stream, version_auto)
|
349
|
-
repository.append_to_stream([
|
350
|
-
event2 = SRecord.new,
|
351
|
-
event3 = SRecord.new,
|
352
|
-
], stream, version_auto)
|
353
|
-
expect(read_events_forward(repository, count: 4)).to eq([
|
354
|
-
event0, event1,
|
355
|
-
event2, event3
|
356
|
-
])
|
240
|
+
repository.append_to_stream([event0 = SRecord.new, event1 = SRecord.new], stream, version_auto)
|
241
|
+
repository.append_to_stream([event2 = SRecord.new, event3 = SRecord.new], stream, version_auto)
|
242
|
+
expect(read_events_forward(repository, count: 4)).to eq([event0, event1, event2, event3])
|
357
243
|
expect(read_events_forward(repository, stream)).to eq([event0, event1, event2, event3])
|
358
244
|
end
|
359
245
|
|
360
|
-
specify
|
361
|
-
repository.append_to_stream(
|
362
|
-
event0 = SRecord.new,
|
363
|
-
|
364
|
-
|
365
|
-
|
366
|
-
],
|
367
|
-
repository.link_to_stream([
|
368
|
-
|
369
|
-
], stream_flow, version_auto)
|
370
|
-
repository.link_to_stream([
|
371
|
-
event2.event_id, event3.event_id,
|
372
|
-
], stream_flow, version_auto)
|
373
|
-
expect(read_events_forward(repository, count: 4)).to eq([
|
374
|
-
event0, event1,
|
375
|
-
event2, event3
|
376
|
-
])
|
246
|
+
specify ":auto queries for last position and follows in incremental way when linking" do
|
247
|
+
repository.append_to_stream(
|
248
|
+
[event0 = SRecord.new, event1 = SRecord.new, event2 = SRecord.new, event3 = SRecord.new],
|
249
|
+
stream,
|
250
|
+
version_auto
|
251
|
+
)
|
252
|
+
repository.link_to_stream([event0.event_id, event1.event_id], stream_flow, version_auto)
|
253
|
+
repository.link_to_stream([event2.event_id, event3.event_id], stream_flow, version_auto)
|
254
|
+
expect(read_events_forward(repository, count: 4)).to eq([event0, event1, event2, event3])
|
377
255
|
expect(read_events_forward(repository, stream_flow)).to eq([event0, event1, event2, event3])
|
378
256
|
end
|
379
257
|
|
380
|
-
specify
|
381
|
-
repository.append_to_stream([
|
382
|
-
|
383
|
-
event1 = SRecord.new,
|
384
|
-
], stream, version_auto)
|
385
|
-
repository.append_to_stream([
|
386
|
-
event2 = SRecord.new,
|
387
|
-
event3 = SRecord.new,
|
388
|
-
], stream, version_1)
|
258
|
+
specify ":auto is compatible with manual expectation" do
|
259
|
+
repository.append_to_stream([event0 = SRecord.new, event1 = SRecord.new], stream, version_auto)
|
260
|
+
repository.append_to_stream([event2 = SRecord.new, event3 = SRecord.new], stream, version_1)
|
389
261
|
expect(read_events_forward(repository, count: 4)).to eq([event0, event1, event2, event3])
|
390
262
|
expect(read_events_forward(repository, stream)).to eq([event0, event1, event2, event3])
|
391
263
|
end
|
392
264
|
|
393
|
-
specify
|
394
|
-
repository.append_to_stream([
|
395
|
-
|
396
|
-
|
397
|
-
|
398
|
-
repository.
|
399
|
-
|
400
|
-
|
401
|
-
|
402
|
-
|
403
|
-
],
|
404
|
-
expect(read_events_forward(repository, count: 4)).to eq([event0, event1,])
|
405
|
-
expect(read_events_forward(repository, stream_flow)).to eq([event0, event1,])
|
406
|
-
end
|
407
|
-
|
408
|
-
specify 'manual is compatible with auto expectation' do
|
409
|
-
repository.append_to_stream([
|
410
|
-
event0 = SRecord.new,
|
411
|
-
event1 = SRecord.new,
|
412
|
-
], stream, version_none)
|
413
|
-
repository.append_to_stream([
|
414
|
-
event2 = SRecord.new,
|
415
|
-
event3 = SRecord.new,
|
416
|
-
], stream, version_auto)
|
265
|
+
specify ":auto is compatible with manual expectation when linking" do
|
266
|
+
repository.append_to_stream([event0 = SRecord.new, event1 = SRecord.new], stream, version_auto)
|
267
|
+
repository.link_to_stream([event0.event_id], stream_flow, version_auto)
|
268
|
+
repository.link_to_stream([event1.event_id], stream_flow, version_0)
|
269
|
+
expect(read_events_forward(repository, count: 4)).to eq([event0, event1])
|
270
|
+
expect(read_events_forward(repository, stream_flow)).to eq([event0, event1])
|
271
|
+
end
|
272
|
+
|
273
|
+
specify "manual is compatible with auto expectation" do
|
274
|
+
repository.append_to_stream([event0 = SRecord.new, event1 = SRecord.new], stream, version_none)
|
275
|
+
repository.append_to_stream([event2 = SRecord.new, event3 = SRecord.new], stream, version_auto)
|
417
276
|
expect(read_events_forward(repository, count: 4)).to eq([event0, event1, event2, event3])
|
418
277
|
expect(read_events_forward(repository, stream)).to eq([event0, event1, event2, event3])
|
419
278
|
end
|
420
279
|
|
421
|
-
specify
|
422
|
-
repository.append_to_stream([
|
423
|
-
|
424
|
-
|
425
|
-
], stream, version_auto)
|
426
|
-
repository.link_to_stream([
|
427
|
-
event0.event_id,
|
428
|
-
], stream_flow, version_none)
|
429
|
-
repository.link_to_stream([
|
430
|
-
event1.event_id,
|
431
|
-
], stream_flow, version_auto)
|
280
|
+
specify "manual is compatible with auto expectation when linking" do
|
281
|
+
repository.append_to_stream([event0 = SRecord.new, event1 = SRecord.new], stream, version_auto)
|
282
|
+
repository.link_to_stream([event0.event_id], stream_flow, version_none)
|
283
|
+
repository.link_to_stream([event1.event_id], stream_flow, version_auto)
|
432
284
|
expect(read_events_forward(repository, count: 4)).to eq([event0, event1])
|
433
285
|
expect(read_events_forward(repository, stream_flow)).to eq([event0, event1])
|
434
286
|
end
|
435
287
|
|
436
|
-
specify
|
288
|
+
specify "unlimited concurrency for :any - everything should succeed", timeout: 10, mutant: false do
|
437
289
|
skip unless helper.supports_concurrent_any?
|
438
|
-
verify_conncurency_assumptions
|
290
|
+
verify_conncurency_assumptions(helper)
|
439
291
|
begin
|
440
292
|
concurrency_level = 4
|
441
|
-
fail_occurred
|
442
|
-
wait_for_it
|
293
|
+
fail_occurred = false
|
294
|
+
wait_for_it = true
|
443
295
|
|
444
|
-
threads =
|
445
|
-
|
446
|
-
|
447
|
-
|
448
|
-
|
449
|
-
|
450
|
-
|
451
|
-
SRecord.new(event_id: eid),
|
452
|
-
|
296
|
+
threads =
|
297
|
+
concurrency_level.times.map do |i|
|
298
|
+
Thread.new do
|
299
|
+
true while wait_for_it
|
300
|
+
begin
|
301
|
+
100.times do |j|
|
302
|
+
eid = "0000000#{i}-#{sprintf("%04d", j)}-0000-0000-000000000000"
|
303
|
+
repository.append_to_stream([SRecord.new(event_id: eid)], stream, version_any)
|
304
|
+
end
|
305
|
+
rescue WrongExpectedEventVersion
|
306
|
+
fail_occurred = true
|
453
307
|
end
|
454
|
-
rescue WrongExpectedEventVersion
|
455
|
-
fail_occurred = true
|
456
308
|
end
|
457
309
|
end
|
458
|
-
end
|
459
310
|
wait_for_it = false
|
460
311
|
threads.each(&:join)
|
461
312
|
expect(fail_occurred).to eq(false)
|
462
313
|
expect(read_events_forward(repository, stream).size).to eq(400)
|
463
314
|
events_in_stream = read_events_forward(repository, stream)
|
464
315
|
expect(events_in_stream.size).to eq(400)
|
465
|
-
events0 = events_in_stream.select
|
466
|
-
|
467
|
-
end
|
468
|
-
expect(events0).to eq(events0.sort_by{|ev| ev.event_id })
|
469
|
-
ensure
|
470
|
-
helper.cleanup_concurrency_test
|
316
|
+
events0 = events_in_stream.select { |ev| ev.event_id.start_with?("0-") }
|
317
|
+
expect(events0).to eq(events0.sort_by { |ev| ev.event_id })
|
471
318
|
end
|
472
319
|
end
|
473
320
|
|
474
|
-
specify
|
321
|
+
specify "unlimited concurrency for :any - everything should succeed when linking", timeout: 10, mutant: false do
|
475
322
|
skip unless helper.supports_concurrent_any?
|
476
|
-
verify_conncurency_assumptions
|
323
|
+
verify_conncurency_assumptions(helper)
|
477
324
|
begin
|
478
325
|
concurrency_level = 4
|
479
|
-
fail_occurred
|
480
|
-
wait_for_it
|
326
|
+
fail_occurred = false
|
327
|
+
wait_for_it = true
|
481
328
|
|
482
329
|
concurrency_level.times.map do |i|
|
483
330
|
100.times do |j|
|
484
331
|
eid = "0000000#{i}-#{sprintf("%04d", j)}-0000-0000-000000000000"
|
485
|
-
repository.append_to_stream([
|
486
|
-
SRecord.new(event_id: eid),
|
487
|
-
], stream, version_any)
|
332
|
+
repository.append_to_stream([SRecord.new(event_id: eid)], stream, version_any)
|
488
333
|
end
|
489
334
|
end
|
490
335
|
|
491
|
-
threads =
|
492
|
-
|
493
|
-
|
494
|
-
|
495
|
-
|
496
|
-
|
497
|
-
|
336
|
+
threads =
|
337
|
+
concurrency_level.times.map do |i|
|
338
|
+
Thread.new do
|
339
|
+
true while wait_for_it
|
340
|
+
begin
|
341
|
+
100.times do |j|
|
342
|
+
eid = "0000000#{i}-#{sprintf("%04d", j)}-0000-0000-000000000000"
|
343
|
+
repository.link_to_stream([eid], stream_flow, version_any)
|
344
|
+
end
|
345
|
+
rescue WrongExpectedEventVersion
|
346
|
+
fail_occurred = true
|
498
347
|
end
|
499
|
-
rescue WrongExpectedEventVersion
|
500
|
-
fail_occurred = true
|
501
348
|
end
|
502
349
|
end
|
503
|
-
end
|
504
350
|
wait_for_it = false
|
505
351
|
threads.each(&:join)
|
506
352
|
expect(fail_occurred).to eq(false)
|
507
353
|
expect(read_events_forward(repository, stream_flow).size).to eq(400)
|
508
354
|
events_in_stream = read_events_forward(repository, stream_flow)
|
509
355
|
expect(events_in_stream.size).to eq(400)
|
510
|
-
events0 = events_in_stream.select
|
511
|
-
|
512
|
-
end
|
513
|
-
expect(events0).to eq(events0.sort_by{|ev| ev.event_id })
|
514
|
-
ensure
|
515
|
-
helper.cleanup_concurrency_test
|
356
|
+
events0 = events_in_stream.select { |ev| ev.event_id.start_with?("0-") }
|
357
|
+
expect(events0).to eq(events0.sort_by { |ev| ev.event_id })
|
516
358
|
end
|
517
359
|
end
|
518
360
|
|
519
|
-
specify
|
361
|
+
specify "limited concurrency for :auto - some operations will fail without outside lock, stream is ordered",
|
362
|
+
mutant: false do
|
520
363
|
skip unless helper.supports_concurrent_auto?
|
521
|
-
verify_conncurency_assumptions
|
364
|
+
verify_conncurency_assumptions(helper)
|
522
365
|
begin
|
523
366
|
concurrency_level = 4
|
524
367
|
|
525
368
|
fail_occurred = 0
|
526
|
-
wait_for_it
|
369
|
+
wait_for_it = true
|
527
370
|
|
528
|
-
threads =
|
529
|
-
|
530
|
-
|
531
|
-
|
532
|
-
|
533
|
-
|
534
|
-
|
535
|
-
SRecord.new(event_id: eid),
|
536
|
-
|
537
|
-
|
538
|
-
|
539
|
-
|
371
|
+
threads =
|
372
|
+
concurrency_level.times.map do |i|
|
373
|
+
Thread.new do
|
374
|
+
true while wait_for_it
|
375
|
+
100.times do |j|
|
376
|
+
begin
|
377
|
+
eid = "0000000#{i}-#{sprintf("%04d", j)}-0000-0000-000000000000"
|
378
|
+
repository.append_to_stream([SRecord.new(event_id: eid)], stream, version_auto)
|
379
|
+
sleep(rand(concurrency_level) / 1000.0)
|
380
|
+
rescue WrongExpectedEventVersion
|
381
|
+
fail_occurred += 1
|
382
|
+
end
|
540
383
|
end
|
541
384
|
end
|
542
385
|
end
|
543
|
-
end
|
544
386
|
wait_for_it = false
|
545
387
|
threads.each(&:join)
|
546
388
|
expect(fail_occurred).to be > 0
|
547
389
|
events_in_stream = read_events_forward(repository, stream)
|
548
390
|
expect(events_in_stream.size).to be < 400
|
549
391
|
expect(events_in_stream.size).to be >= 100
|
550
|
-
events0 = events_in_stream.select
|
551
|
-
|
552
|
-
|
553
|
-
|
554
|
-
|
555
|
-
|
556
|
-
|
392
|
+
events0 = events_in_stream.select { |ev| ev.event_id.start_with?("0-") }
|
393
|
+
expect(events0).to eq(events0.sort_by { |ev| ev.event_id })
|
394
|
+
|
395
|
+
positions =
|
396
|
+
repository
|
397
|
+
.read(specification.stream(stream.name).result)
|
398
|
+
.map { |r| repository.position_in_stream(r.event_id, stream) }
|
399
|
+
expect(positions).to eq((0...positions.size).to_a)
|
557
400
|
end
|
558
401
|
end
|
559
402
|
|
560
|
-
specify
|
403
|
+
specify "limited concurrency for :auto - some operations will fail without outside lock, stream is ordered",
|
404
|
+
mutant: false do
|
561
405
|
skip unless helper.supports_concurrent_auto?
|
562
|
-
verify_conncurency_assumptions
|
406
|
+
verify_conncurency_assumptions(helper)
|
563
407
|
begin
|
564
408
|
concurrency_level = 4
|
565
409
|
|
566
410
|
concurrency_level.times.map do |i|
|
567
411
|
100.times do |j|
|
568
412
|
eid = "0000000#{i}-#{sprintf("%04d", j)}-0000-0000-000000000000"
|
569
|
-
repository.append_to_stream([
|
570
|
-
SRecord.new(event_id: eid),
|
571
|
-
], stream_other, version_any)
|
413
|
+
repository.append_to_stream([SRecord.new(event_id: eid)], stream_other, version_any)
|
572
414
|
end
|
573
415
|
end
|
574
416
|
|
575
417
|
fail_occurred = 0
|
576
|
-
wait_for_it
|
418
|
+
wait_for_it = true
|
577
419
|
|
578
|
-
threads =
|
579
|
-
|
580
|
-
|
581
|
-
|
582
|
-
|
583
|
-
|
584
|
-
|
585
|
-
|
586
|
-
|
587
|
-
|
420
|
+
threads =
|
421
|
+
concurrency_level.times.map do |i|
|
422
|
+
Thread.new do
|
423
|
+
true while wait_for_it
|
424
|
+
100.times do |j|
|
425
|
+
begin
|
426
|
+
eid = "0000000#{i}-#{sprintf("%04d", j)}-0000-0000-000000000000"
|
427
|
+
repository.link_to_stream([eid], stream, version_auto)
|
428
|
+
sleep(rand(concurrency_level) / 1000.0)
|
429
|
+
rescue WrongExpectedEventVersion
|
430
|
+
fail_occurred += 1
|
431
|
+
end
|
588
432
|
end
|
589
433
|
end
|
590
434
|
end
|
591
|
-
end
|
592
435
|
wait_for_it = false
|
593
436
|
threads.each(&:join)
|
594
437
|
expect(fail_occurred).to be > 0
|
595
438
|
events_in_stream = read_events_forward(repository, stream)
|
596
439
|
expect(events_in_stream.size).to be < 400
|
597
440
|
expect(events_in_stream.size).to be >= 100
|
598
|
-
events0 = events_in_stream.select
|
599
|
-
|
600
|
-
|
601
|
-
|
602
|
-
|
603
|
-
|
604
|
-
|
441
|
+
events0 = events_in_stream.select { |ev| ev.event_id.start_with?("0-") }
|
442
|
+
expect(events0).to eq(events0.sort_by { |ev| ev.event_id })
|
443
|
+
|
444
|
+
positions =
|
445
|
+
repository
|
446
|
+
.read(specification.stream(stream.name).result)
|
447
|
+
.map { |r| repository.position_in_stream(r.event_id, stream) }
|
448
|
+
expect(positions).to eq((0...positions.size).to_a)
|
605
449
|
end
|
606
450
|
end
|
607
451
|
|
608
|
-
it
|
452
|
+
it "appended event is stored in given stream" do
|
609
453
|
expected_event = SRecord.new
|
610
454
|
repository.append_to_stream([expected_event], stream, version_any)
|
611
455
|
expect(read_events_forward(repository, count: 1).first).to eq(expected_event)
|
@@ -613,25 +457,22 @@ module RubyEventStore
|
|
613
457
|
expect(read_events_forward(repository, stream_other)).to be_empty
|
614
458
|
end
|
615
459
|
|
616
|
-
it
|
460
|
+
it "data attributes are retrieved" do
|
617
461
|
event = SRecord.new(data: { "order_id" => 3 })
|
618
462
|
repository.append_to_stream([event], stream, version_any)
|
619
463
|
retrieved_event = read_events_forward(repository, count: 1).first
|
620
464
|
expect(retrieved_event.data).to eq({ "order_id" => 3 })
|
621
465
|
end
|
622
466
|
|
623
|
-
it
|
467
|
+
it "metadata attributes are retrieved" do
|
624
468
|
event = SRecord.new(metadata: { "request_id" => 3 })
|
625
469
|
repository.append_to_stream([event], stream, version_any)
|
626
470
|
retrieved_event = read_events_forward(repository, count: 1).first
|
627
471
|
expect(retrieved_event.metadata).to eq({ "request_id" => 3 })
|
628
472
|
end
|
629
473
|
|
630
|
-
it
|
631
|
-
event = SRecord.new(
|
632
|
-
data: { "order_id" => 3 },
|
633
|
-
metadata: { "request_id" => 4},
|
634
|
-
)
|
474
|
+
it "data and metadata attributes are retrieved when linking" do
|
475
|
+
event = SRecord.new(data: { "order_id" => 3 }, metadata: { "request_id" => 4 })
|
635
476
|
repository
|
636
477
|
.append_to_stream([event], stream, version_any)
|
637
478
|
.link_to_stream([event.event_id], stream_flow, version_any)
|
@@ -641,17 +482,17 @@ module RubyEventStore
|
|
641
482
|
expect(event).to eq(retrieved_event)
|
642
483
|
end
|
643
484
|
|
644
|
-
it
|
485
|
+
it "does not have deleted streams" do
|
645
486
|
repository.append_to_stream([e1 = SRecord.new], stream, version_none)
|
646
487
|
repository.append_to_stream([e2 = SRecord.new], stream_other, version_none)
|
647
488
|
|
648
489
|
repository.delete_stream(stream)
|
649
490
|
expect(read_events_forward(repository, stream)).to be_empty
|
650
491
|
expect(read_events_forward(repository, stream_other)).to eq([e2])
|
651
|
-
expect(read_events_forward(repository, count: 10)).to eq([e1,e2])
|
492
|
+
expect(read_events_forward(repository, count: 10)).to eq([e1, e2])
|
652
493
|
end
|
653
494
|
|
654
|
-
it
|
495
|
+
it "does not have deleted streams with linked events" do
|
655
496
|
repository
|
656
497
|
.append_to_stream([e1 = SRecord.new], stream, version_none)
|
657
498
|
.link_to_stream([e1.event_id], stream_flow, version_none)
|
@@ -661,51 +502,152 @@ module RubyEventStore
|
|
661
502
|
expect(read_events_forward(repository, count: 10)).to eq([e1])
|
662
503
|
end
|
663
504
|
|
664
|
-
it
|
665
|
-
just_an_id =
|
505
|
+
it "has or has not domain event" do
|
506
|
+
just_an_id = "d5c134c2-db65-4e87-b6ea-d196f8f1a292"
|
666
507
|
repository.append_to_stream([SRecord.new(event_id: just_an_id)], stream, version_none)
|
667
508
|
|
668
509
|
expect(repository.has_event?(just_an_id)).to be_truthy
|
669
510
|
expect(repository.has_event?(just_an_id.clone)).to be_truthy
|
670
|
-
expect(repository.has_event?(
|
511
|
+
expect(repository.has_event?("any other id")).to be false
|
671
512
|
|
672
513
|
repository.delete_stream(stream)
|
673
514
|
expect(repository.has_event?(just_an_id)).to be_truthy
|
674
515
|
expect(repository.has_event?(just_an_id.clone)).to be_truthy
|
675
516
|
end
|
676
517
|
|
677
|
-
it
|
678
|
-
|
679
|
-
repository.append_to_stream([
|
518
|
+
it "#position_in_stream happy path" do
|
519
|
+
skip unless helper.supports_position_queries?
|
520
|
+
repository.append_to_stream([event0 = SRecord.new, event1 = SRecord.new], stream, version_auto)
|
680
521
|
|
681
|
-
expect(repository.
|
682
|
-
expect(repository.
|
522
|
+
expect(repository.position_in_stream(event0.event_id, stream)).to eq(0)
|
523
|
+
expect(repository.position_in_stream(event1.event_id, stream)).to eq(1)
|
683
524
|
end
|
684
525
|
|
685
|
-
it
|
686
|
-
|
687
|
-
|
688
|
-
|
689
|
-
|
526
|
+
it "#position_in_stream happy path with linking" do
|
527
|
+
skip unless helper.supports_position_queries?
|
528
|
+
repository.append_to_stream([event0 = SRecord.new, event1 = SRecord.new], stream, version_auto)
|
529
|
+
repository.link_to_stream([event1.event_id, event0.event_id], stream_other, version_auto)
|
530
|
+
|
531
|
+
expect(repository.position_in_stream(event0.event_id, stream)).to eq(0)
|
532
|
+
expect(repository.position_in_stream(event1.event_id, stream)).to eq(1)
|
533
|
+
expect(repository.position_in_stream(event1.event_id, stream_other)).to eq(0)
|
534
|
+
expect(repository.position_in_stream(event0.event_id, stream_other)).to eq(1)
|
535
|
+
end
|
536
|
+
|
537
|
+
it "#position_in_stream when event is not in the stream" do
|
538
|
+
skip unless helper.supports_position_queries?
|
539
|
+
just_an_id = "d5c134c2-db65-4e87-b6ea-d196f8f1a292"
|
540
|
+
|
541
|
+
expect { repository.position_in_stream(just_an_id, stream) }.to raise_error(EventNotFoundInStream)
|
542
|
+
end
|
543
|
+
|
544
|
+
it "#position_in_stream when event is published without position" do
|
545
|
+
skip unless helper.supports_position_queries?
|
546
|
+
repository.append_to_stream([event0 = SRecord.new], stream, version_any)
|
547
|
+
|
548
|
+
expect(repository.position_in_stream(event0.event_id, stream)).to eq(nil)
|
549
|
+
end
|
550
|
+
|
551
|
+
it "#global_position happy path" do
|
552
|
+
skip unless helper.supports_position_queries?
|
553
|
+
repository.append_to_stream([event0 = SRecord.new, event1 = SRecord.new], stream, version_any)
|
554
|
+
|
555
|
+
expect(repository.global_position(event0.event_id)).to eq(0)
|
556
|
+
expect(repository.global_position(event1.event_id)).to eq(1)
|
557
|
+
end
|
558
|
+
|
559
|
+
it "#global_position for not existing event" do
|
560
|
+
skip unless helper.supports_position_queries?
|
561
|
+
just_an_id = "d5c134c2-db65-4e87-b6ea-d196f8f1a292"
|
562
|
+
|
563
|
+
expect { repository.global_position(just_an_id) }.to raise_error do |err|
|
564
|
+
expect(err).to be_a(EventNotFound)
|
565
|
+
expect(err.event_id).to eq(just_an_id)
|
566
|
+
end
|
567
|
+
end
|
568
|
+
|
569
|
+
it "#event_in_stream? when event does not exist" do
|
570
|
+
skip unless helper.supports_event_in_stream_query?
|
571
|
+
repository.append_to_stream([SRecord.new], stream, version_any)
|
572
|
+
just_an_id = "d5c134c2-db65-4e87-b6ea-d196f8f1a292"
|
573
|
+
|
574
|
+
expect(repository.event_in_stream?(just_an_id, stream)).to eq(false)
|
575
|
+
end
|
576
|
+
|
577
|
+
it "#event_in_stream? when event published into stream" do
|
578
|
+
skip unless helper.supports_event_in_stream_query?
|
579
|
+
repository.append_to_stream([event0 = SRecord.new], stream, version_any)
|
580
|
+
|
581
|
+
expect(repository.event_in_stream?(event0.event_id, stream)).to eq(true)
|
582
|
+
end
|
583
|
+
|
584
|
+
it "#event_in_stream? when event not linked into stream" do
|
585
|
+
skip unless helper.supports_event_in_stream_query?
|
586
|
+
repository.append_to_stream([SRecord.new], stream_flow, version_any)
|
587
|
+
repository.append_to_stream([event1 = SRecord.new], stream, version_any)
|
588
|
+
|
589
|
+
expect(repository.event_in_stream?(event1.event_id, stream_flow)).to eq(false)
|
590
|
+
end
|
591
|
+
|
592
|
+
it "#event_in_stream? when event linked into stream" do
|
593
|
+
skip unless helper.supports_event_in_stream_query?
|
594
|
+
repository.append_to_stream([event0 = SRecord.new], stream, version_any)
|
595
|
+
repository.link_to_stream([event0.event_id], stream_flow, version_any)
|
596
|
+
|
597
|
+
expect(repository.event_in_stream?(event0.event_id, stream_flow)).to eq(true)
|
598
|
+
end
|
599
|
+
|
600
|
+
it "#event_in_stream? when stream is empty" do
|
601
|
+
skip unless helper.supports_event_in_stream_query?
|
602
|
+
just_an_id = "d5c134c2-db65-4e87-b6ea-d196f8f1a292"
|
603
|
+
|
604
|
+
expect(repository.event_in_stream?(just_an_id, stream)).to eq(false)
|
605
|
+
end
|
606
|
+
|
607
|
+
it "knows last event in stream" do
|
608
|
+
repository.append_to_stream(
|
609
|
+
[a = SRecord.new(event_id: "00000000-0000-0000-0000-000000000001")],
|
690
610
|
stream,
|
691
611
|
version_none
|
692
|
-
)
|
612
|
+
)
|
613
|
+
repository.append_to_stream(
|
614
|
+
[b = SRecord.new(event_id: "00000000-0000-0000-0000-000000000002")],
|
615
|
+
stream,
|
616
|
+
version_0
|
617
|
+
)
|
618
|
+
|
619
|
+
expect(repository.last_stream_event(stream)).to eq(b)
|
620
|
+
expect(repository.last_stream_event(stream_other)).to be_nil
|
621
|
+
end
|
622
|
+
|
623
|
+
it "knows last event in stream when linked" do
|
624
|
+
repository
|
625
|
+
.append_to_stream(
|
626
|
+
[
|
627
|
+
e0 = SRecord.new(event_id: "00000000-0000-0000-0000-000000000001"),
|
628
|
+
e1 = SRecord.new(event_id: "00000000-0000-0000-0000-000000000002")
|
629
|
+
],
|
630
|
+
stream,
|
631
|
+
version_none
|
632
|
+
)
|
633
|
+
.link_to_stream([e1.event_id, e0.event_id], stream_flow, version_none)
|
693
634
|
expect(repository.last_stream_event(stream_flow)).to eq(e0)
|
694
635
|
end
|
695
636
|
|
696
|
-
it
|
697
|
-
events =
|
698
|
-
|
699
|
-
|
700
|
-
|
701
|
-
|
702
|
-
|
703
|
-
|
704
|
-
|
705
|
-
|
706
|
-
|
707
|
-
|
708
|
-
|
637
|
+
it "reads batch of events from stream forward & backward" do
|
638
|
+
events =
|
639
|
+
%w[
|
640
|
+
96c920b1-cdd0-40f4-907c-861b9fff7d02
|
641
|
+
56404f79-0ba0-4aa0-8524-dc3436368ca0
|
642
|
+
6a54dd21-f9d8-4857-a195-f5588d9e406c
|
643
|
+
0e50a9cd-f981-4e39-93d5-697fc7285b98
|
644
|
+
d85589bc-b993-41d4-812f-fc631d9185d5
|
645
|
+
96bdacda-77dd-4d7d-973d-cbdaa5842855
|
646
|
+
94688199-e6b7-4180-bf8e-825b6808e6cc
|
647
|
+
68fab040-741e-4bc2-9cca-5b8855b0ca19
|
648
|
+
ab60114c-011d-4d58-ab31-7ba65d99975e
|
649
|
+
868cac42-3d19-4b39-84e8-cd32d65c2445
|
650
|
+
].map { |id| SRecord.new(event_id: id) }
|
709
651
|
repository.append_to_stream([SRecord.new], stream_other, version_none)
|
710
652
|
events.each.with_index do |event, index|
|
711
653
|
repository.append_to_stream([event], stream, ExpectedVersion.new(index - 1))
|
@@ -722,25 +664,30 @@ module RubyEventStore
|
|
722
664
|
|
723
665
|
expect(read_events_backward(repository, stream, count: 3)).to eq(events.last(3).reverse)
|
724
666
|
expect(read_events_backward(repository, stream, count: 100)).to eq(events.reverse)
|
725
|
-
expect(read_events_backward(repository, stream, from: events[4].event_id, count: 4)).to eq(
|
726
|
-
|
667
|
+
expect(read_events_backward(repository, stream, from: events[4].event_id, count: 4)).to eq(
|
668
|
+
events.first(4).reverse
|
669
|
+
)
|
670
|
+
expect(read_events_backward(repository, stream, from: events[4].event_id, count: 100)).to eq(
|
671
|
+
events.first(4).reverse
|
672
|
+
)
|
727
673
|
expect(read_events_backward(repository, stream, to: events[4].event_id, count: 4)).to eq(events.last(4).reverse)
|
728
674
|
expect(read_events_backward(repository, stream, to: events[4].event_id, count: 100)).to eq(events.last(5).reverse)
|
729
675
|
end
|
730
676
|
|
731
|
-
it
|
732
|
-
events =
|
733
|
-
|
734
|
-
|
735
|
-
|
736
|
-
|
737
|
-
|
738
|
-
|
739
|
-
|
740
|
-
|
741
|
-
|
742
|
-
|
743
|
-
|
677
|
+
it "reads batch of linked events from stream forward & backward" do
|
678
|
+
events =
|
679
|
+
%w[
|
680
|
+
96c920b1-cdd0-40f4-907c-861b9fff7d02
|
681
|
+
56404f79-0ba0-4aa0-8524-dc3436368ca0
|
682
|
+
6a54dd21-f9d8-4857-a195-f5588d9e406c
|
683
|
+
0e50a9cd-f981-4e39-93d5-697fc7285b98
|
684
|
+
d85589bc-b993-41d4-812f-fc631d9185d5
|
685
|
+
96bdacda-77dd-4d7d-973d-cbdaa5842855
|
686
|
+
94688199-e6b7-4180-bf8e-825b6808e6cc
|
687
|
+
68fab040-741e-4bc2-9cca-5b8855b0ca19
|
688
|
+
ab60114c-011d-4d58-ab31-7ba65d99975e
|
689
|
+
868cac42-3d19-4b39-84e8-cd32d65c2445
|
690
|
+
].map { |id| SRecord.new(event_id: id) }
|
744
691
|
repository.append_to_stream([SRecord.new], stream_other, version_none)
|
745
692
|
events.each.with_index do |event, index|
|
746
693
|
repository
|
@@ -758,60 +705,67 @@ module RubyEventStore
|
|
758
705
|
|
759
706
|
expect(read_events_backward(repository, stream_flow, count: 3)).to eq(events.last(3).reverse)
|
760
707
|
expect(read_events_backward(repository, stream_flow, count: 100)).to eq(events.reverse)
|
761
|
-
expect(read_events_backward(repository, stream_flow, from: events[4].event_id, count: 4)).to eq(
|
762
|
-
|
763
|
-
|
764
|
-
expect(read_events_backward(repository, stream_flow,
|
708
|
+
expect(read_events_backward(repository, stream_flow, from: events[4].event_id, count: 4)).to eq(
|
709
|
+
events.first(4).reverse
|
710
|
+
)
|
711
|
+
expect(read_events_backward(repository, stream_flow, from: events[4].event_id, count: 100)).to eq(
|
712
|
+
events.first(4).reverse
|
713
|
+
)
|
714
|
+
expect(read_events_backward(repository, stream_flow, to: events[4].event_id, count: 4)).to eq(
|
715
|
+
events[6..9].reverse
|
716
|
+
)
|
717
|
+
expect(read_events_backward(repository, stream_flow, to: events[4].event_id, count: 100)).to eq(
|
718
|
+
events[5..9].reverse
|
719
|
+
)
|
765
720
|
end
|
766
721
|
|
767
|
-
it
|
722
|
+
it "reads all stream events forward & backward" do
|
768
723
|
s1 = stream
|
769
724
|
s2 = stream_other
|
770
725
|
repository
|
771
|
-
.append_to_stream([a = SRecord.new(event_id:
|
772
|
-
.append_to_stream([b = SRecord.new(event_id:
|
773
|
-
.append_to_stream([c = SRecord.new(event_id:
|
774
|
-
.append_to_stream([d = SRecord.new(event_id:
|
775
|
-
.append_to_stream([e = SRecord.new(event_id:
|
726
|
+
.append_to_stream([a = SRecord.new(event_id: "7010d298-ab69-4bb1-9251-f3466b5d1282")], s1, version_none)
|
727
|
+
.append_to_stream([b = SRecord.new(event_id: "34f88aca-aaba-4ca0-9256-8017b47528c5")], s2, version_none)
|
728
|
+
.append_to_stream([c = SRecord.new(event_id: "8e61c864-ceae-4684-8726-97c34eb8fc4f")], s1, version_0)
|
729
|
+
.append_to_stream([d = SRecord.new(event_id: "30963ed9-6349-450b-ac9b-8ea50115b3bd")], s2, version_0)
|
730
|
+
.append_to_stream([e = SRecord.new(event_id: "5bdc58b7-e8a7-4621-afd6-ccb828d72457")], s2, version_1)
|
776
731
|
|
777
|
-
expect(read_events_forward(repository, s1)).to eq [a,c]
|
778
|
-
expect(read_events_backward(repository, s1)).to eq [c,a]
|
732
|
+
expect(read_events_forward(repository, s1)).to eq [a, c]
|
733
|
+
expect(read_events_backward(repository, s1)).to eq [c, a]
|
779
734
|
end
|
780
735
|
|
781
|
-
it
|
736
|
+
it "reads all stream linked events forward & backward" do
|
782
737
|
s1, fs1, fs2 = stream, stream_flow, stream_other
|
783
738
|
repository
|
784
|
-
.append_to_stream([a = SRecord.new(event_id:
|
785
|
-
.append_to_stream([b = SRecord.new(event_id:
|
786
|
-
.append_to_stream([c = SRecord.new(event_id:
|
787
|
-
.append_to_stream([d = SRecord.new(event_id:
|
788
|
-
.append_to_stream([e = SRecord.new(event_id:
|
789
|
-
.link_to_stream([
|
790
|
-
.link_to_stream([
|
791
|
-
.link_to_stream([
|
792
|
-
.link_to_stream([
|
793
|
-
.link_to_stream([
|
794
|
-
|
795
|
-
expect(read_events_forward(repository, fs1)).to eq [a,c]
|
796
|
-
expect(read_events_backward(repository, fs1)).to eq [c,a]
|
797
|
-
end
|
798
|
-
|
799
|
-
it
|
800
|
-
events =
|
801
|
-
|
802
|
-
|
803
|
-
|
804
|
-
|
805
|
-
|
806
|
-
|
807
|
-
|
808
|
-
|
809
|
-
|
810
|
-
|
811
|
-
|
812
|
-
|
813
|
-
|
814
|
-
end
|
739
|
+
.append_to_stream([a = SRecord.new(event_id: "7010d298-ab69-4bb1-9251-f3466b5d1282")], s1, version_none)
|
740
|
+
.append_to_stream([b = SRecord.new(event_id: "34f88aca-aaba-4ca0-9256-8017b47528c5")], s1, version_0)
|
741
|
+
.append_to_stream([c = SRecord.new(event_id: "8e61c864-ceae-4684-8726-97c34eb8fc4f")], s1, version_1)
|
742
|
+
.append_to_stream([d = SRecord.new(event_id: "30963ed9-6349-450b-ac9b-8ea50115b3bd")], s1, version_2)
|
743
|
+
.append_to_stream([e = SRecord.new(event_id: "5bdc58b7-e8a7-4621-afd6-ccb828d72457")], s1, version_3)
|
744
|
+
.link_to_stream(["7010d298-ab69-4bb1-9251-f3466b5d1282"], fs1, version_none)
|
745
|
+
.link_to_stream(["34f88aca-aaba-4ca0-9256-8017b47528c5"], fs2, version_none)
|
746
|
+
.link_to_stream(["8e61c864-ceae-4684-8726-97c34eb8fc4f"], fs1, version_0)
|
747
|
+
.link_to_stream(["30963ed9-6349-450b-ac9b-8ea50115b3bd"], fs2, version_0)
|
748
|
+
.link_to_stream(["5bdc58b7-e8a7-4621-afd6-ccb828d72457"], fs2, version_1)
|
749
|
+
|
750
|
+
expect(read_events_forward(repository, fs1)).to eq [a, c]
|
751
|
+
expect(read_events_backward(repository, fs1)).to eq [c, a]
|
752
|
+
end
|
753
|
+
|
754
|
+
it "reads batch of events from all streams forward & backward" do
|
755
|
+
events =
|
756
|
+
%w[
|
757
|
+
96c920b1-cdd0-40f4-907c-861b9fff7d02
|
758
|
+
56404f79-0ba0-4aa0-8524-dc3436368ca0
|
759
|
+
6a54dd21-f9d8-4857-a195-f5588d9e406c
|
760
|
+
0e50a9cd-f981-4e39-93d5-697fc7285b98
|
761
|
+
d85589bc-b993-41d4-812f-fc631d9185d5
|
762
|
+
96bdacda-77dd-4d7d-973d-cbdaa5842855
|
763
|
+
94688199-e6b7-4180-bf8e-825b6808e6cc
|
764
|
+
68fab040-741e-4bc2-9cca-5b8855b0ca19
|
765
|
+
ab60114c-011d-4d58-ab31-7ba65d99975e
|
766
|
+
868cac42-3d19-4b39-84e8-cd32d65c2445
|
767
|
+
].map { |id| SRecord.new(event_id: id) }
|
768
|
+
events.each { |ev| repository.append_to_stream([ev], Stream.new(SecureRandom.uuid), version_none) }
|
815
769
|
|
816
770
|
expect(read_events_forward(repository, count: 3)).to eq(events.first(3))
|
817
771
|
expect(read_events_forward(repository, count: 100)).to eq(events)
|
@@ -828,19 +782,20 @@ module RubyEventStore
|
|
828
782
|
expect(read_events_backward(repository, to: events[4].event_id, count: 100)).to eq(events.last(5).reverse)
|
829
783
|
end
|
830
784
|
|
831
|
-
it
|
832
|
-
events =
|
833
|
-
|
834
|
-
|
835
|
-
|
836
|
-
|
837
|
-
|
838
|
-
|
839
|
-
|
840
|
-
|
841
|
-
|
842
|
-
|
843
|
-
|
785
|
+
it "linked events do not affect reading from all streams - no duplicates" do
|
786
|
+
events =
|
787
|
+
%w[
|
788
|
+
96c920b1-cdd0-40f4-907c-861b9fff7d02
|
789
|
+
56404f79-0ba0-4aa0-8524-dc3436368ca0
|
790
|
+
6a54dd21-f9d8-4857-a195-f5588d9e406c
|
791
|
+
0e50a9cd-f981-4e39-93d5-697fc7285b98
|
792
|
+
d85589bc-b993-41d4-812f-fc631d9185d5
|
793
|
+
96bdacda-77dd-4d7d-973d-cbdaa5842855
|
794
|
+
94688199-e6b7-4180-bf8e-825b6808e6cc
|
795
|
+
68fab040-741e-4bc2-9cca-5b8855b0ca19
|
796
|
+
ab60114c-011d-4d58-ab31-7ba65d99975e
|
797
|
+
868cac42-3d19-4b39-84e8-cd32d65c2445
|
798
|
+
].map { |id| SRecord.new(event_id: id) }
|
844
799
|
events.each do |ev|
|
845
800
|
repository
|
846
801
|
.append_to_stream([ev], Stream.new(SecureRandom.uuid), version_none)
|
@@ -862,46 +817,44 @@ module RubyEventStore
|
|
862
817
|
expect(read_events_backward(repository, to: events[4].event_id, count: 100)).to eq(events.last(5).reverse)
|
863
818
|
end
|
864
819
|
|
865
|
-
it
|
866
|
-
events =
|
867
|
-
96c920b1-cdd0-40f4-907c-861b9fff7d02
|
868
|
-
|
869
|
-
|
820
|
+
it "reads events different uuid object but same content" do
|
821
|
+
events =
|
822
|
+
%w[96c920b1-cdd0-40f4-907c-861b9fff7d02 56404f79-0ba0-4aa0-8524-dc3436368ca0].map do |id|
|
823
|
+
SRecord.new(event_id: id)
|
824
|
+
end
|
870
825
|
repository.append_to_stream([events.first], stream, version_none)
|
871
|
-
repository.append_to_stream([events.last],
|
826
|
+
repository.append_to_stream([events.last], stream, version_0)
|
872
827
|
|
873
828
|
expect(read_events_forward(repository, from: "96c920b1-cdd0-40f4-907c-861b9fff7d02")).to eq([events.last])
|
874
829
|
expect(read_events_backward(repository, from: "56404f79-0ba0-4aa0-8524-dc3436368ca0")).to eq([events.first])
|
875
|
-
expect(read_events_forward(repository, to: "56404f79-0ba0-4aa0-8524-dc3436368ca0", count: 1)).to eq(
|
876
|
-
|
830
|
+
expect(read_events_forward(repository, to: "56404f79-0ba0-4aa0-8524-dc3436368ca0", count: 1)).to eq(
|
831
|
+
[events.first]
|
832
|
+
)
|
833
|
+
expect(read_events_backward(repository, to: "96c920b1-cdd0-40f4-907c-861b9fff7d02", count: 1)).to eq(
|
834
|
+
[events.last]
|
835
|
+
)
|
877
836
|
|
878
837
|
expect(read_events_forward(repository, stream, from: "96c920b1-cdd0-40f4-907c-861b9fff7d02")).to eq([events.last])
|
879
|
-
expect(read_events_backward(repository, stream, from: "56404f79-0ba0-4aa0-8524-dc3436368ca0")).to eq(
|
880
|
-
|
881
|
-
|
838
|
+
expect(read_events_backward(repository, stream, from: "56404f79-0ba0-4aa0-8524-dc3436368ca0")).to eq(
|
839
|
+
[events.first]
|
840
|
+
)
|
841
|
+
expect(read_events_forward(repository, stream, to: "56404f79-0ba0-4aa0-8524-dc3436368ca0", count: 1)).to eq(
|
842
|
+
[events.first]
|
843
|
+
)
|
844
|
+
expect(read_events_backward(repository, stream, to: "96c920b1-cdd0-40f4-907c-861b9fff7d02", count: 1)).to eq(
|
845
|
+
[events.last]
|
846
|
+
)
|
882
847
|
end
|
883
848
|
|
884
|
-
it
|
885
|
-
repository.append_to_stream(
|
886
|
-
[SRecord.new(event_id: "a1b49edb-7636-416f-874a-88f94b859bef")],
|
887
|
-
stream,
|
888
|
-
version_none
|
889
|
-
)
|
849
|
+
it "does not allow same event twice in a stream" do
|
850
|
+
repository.append_to_stream([SRecord.new(event_id: "a1b49edb-7636-416f-874a-88f94b859bef")], stream, version_none)
|
890
851
|
expect do
|
891
|
-
repository.append_to_stream(
|
892
|
-
[SRecord.new(event_id: "a1b49edb-7636-416f-874a-88f94b859bef")],
|
893
|
-
stream,
|
894
|
-
version_0
|
895
|
-
)
|
852
|
+
repository.append_to_stream([SRecord.new(event_id: "a1b49edb-7636-416f-874a-88f94b859bef")], stream, version_0)
|
896
853
|
end.to raise_error(EventDuplicatedInStream)
|
897
854
|
end
|
898
855
|
|
899
|
-
it
|
900
|
-
repository.append_to_stream(
|
901
|
-
[SRecord.new(event_id: "a1b49edb-7636-416f-874a-88f94b859bef")],
|
902
|
-
stream,
|
903
|
-
version_none
|
904
|
-
)
|
856
|
+
it "does not allow same event twice" do
|
857
|
+
repository.append_to_stream([SRecord.new(event_id: "a1b49edb-7636-416f-874a-88f94b859bef")], stream, version_none)
|
905
858
|
expect do
|
906
859
|
repository.append_to_stream(
|
907
860
|
[SRecord.new(event_id: "a1b49edb-7636-416f-874a-88f94b859bef")],
|
@@ -911,18 +864,16 @@ module RubyEventStore
|
|
911
864
|
end.to raise_error(EventDuplicatedInStream)
|
912
865
|
end
|
913
866
|
|
914
|
-
it
|
915
|
-
repository
|
916
|
-
[SRecord.new(event_id: "a1b49edb-7636-416f-874a-88f94b859bef")],
|
917
|
-
|
918
|
-
version_none
|
919
|
-
).link_to_stream(["a1b49edb-7636-416f-874a-88f94b859bef"], stream_flow, version_none)
|
867
|
+
it "does not allow linking same event twice in a stream" do
|
868
|
+
repository
|
869
|
+
.append_to_stream([SRecord.new(event_id: "a1b49edb-7636-416f-874a-88f94b859bef")], stream, version_none)
|
870
|
+
.link_to_stream(["a1b49edb-7636-416f-874a-88f94b859bef"], stream_flow, version_none)
|
920
871
|
expect do
|
921
872
|
repository.link_to_stream(["a1b49edb-7636-416f-874a-88f94b859bef"], stream_flow, version_0)
|
922
873
|
end.to raise_error(EventDuplicatedInStream)
|
923
874
|
end
|
924
875
|
|
925
|
-
it
|
876
|
+
it "allows appending to GLOBAL_STREAM explicitly" do
|
926
877
|
event = SRecord.new(event_id: "df8b2ba3-4e2c-4888-8d14-4364855fa80e")
|
927
878
|
repository.append_to_stream([event], global_stream, version_any)
|
928
879
|
|
@@ -934,65 +885,53 @@ module RubyEventStore
|
|
934
885
|
|
935
886
|
expect do
|
936
887
|
repository.append_to_stream(
|
937
|
-
[SRecord.new(event_id:
|
888
|
+
[SRecord.new(event_id: "9bedf448-e4d0-41a3-a8cd-f94aec7aa763")],
|
938
889
|
stream,
|
939
890
|
version_none
|
940
891
|
)
|
941
892
|
end.to raise_error(WrongExpectedEventVersion)
|
942
|
-
expect(repository.has_event?(
|
893
|
+
expect(repository.has_event?("9bedf448-e4d0-41a3-a8cd-f94aec7aa763")).to be false
|
943
894
|
end
|
944
895
|
|
945
|
-
specify
|
896
|
+
specify "linking non-existent event" do
|
946
897
|
expect do
|
947
|
-
repository.link_to_stream([
|
898
|
+
repository.link_to_stream(["72922e65-1b32-4e97-8023-03ae81dd3a27"], stream_flow, version_none)
|
948
899
|
end.to raise_error do |err|
|
949
900
|
expect(err).to be_a(EventNotFound)
|
950
|
-
expect(err.event_id).to eq(
|
951
|
-
expect(err.message).to eq(
|
901
|
+
expect(err.event_id).to eq("72922e65-1b32-4e97-8023-03ae81dd3a27")
|
902
|
+
expect(err.message).to eq("Event not found: 72922e65-1b32-4e97-8023-03ae81dd3a27")
|
952
903
|
end
|
953
904
|
end
|
954
905
|
|
955
|
-
specify
|
906
|
+
specify "read returns enumerator" do
|
956
907
|
expect(repository.read(specification.result)).to be_kind_of(Enumerator)
|
957
908
|
end
|
958
909
|
|
959
|
-
specify
|
910
|
+
specify "can store arbitrary binary data" do
|
960
911
|
skip unless helper.supports_binary?
|
961
912
|
binary = "\xB0"
|
962
913
|
expect(binary.valid_encoding?).to eq(false)
|
963
914
|
binary.force_encoding("binary")
|
964
915
|
expect(binary.valid_encoding?).to eq(true)
|
965
916
|
|
966
|
-
repository.append_to_stream(
|
967
|
-
[event = SRecord.new(data: binary, metadata: binary)],
|
968
|
-
stream,
|
969
|
-
version_none
|
970
|
-
)
|
917
|
+
repository.append_to_stream([event = SRecord.new(data: binary, metadata: binary)], stream, version_none)
|
971
918
|
end
|
972
919
|
|
973
920
|
specify do
|
974
921
|
expect(repository.read(specification.in_batches.result)).to be_kind_of(Enumerator)
|
922
|
+
expect(repository.read(specification.in_batches.as_at.result)).to be_kind_of(Enumerator)
|
923
|
+
expect(repository.read(specification.in_batches.as_of.result)).to be_kind_of(Enumerator)
|
975
924
|
events = Array.new(10) { SRecord.new }
|
976
|
-
repository.append_to_stream(
|
977
|
-
events,
|
978
|
-
Stream.new("Dummy"),
|
979
|
-
ExpectedVersion.none
|
980
|
-
)
|
925
|
+
repository.append_to_stream(events, Stream.new("Dummy"), ExpectedVersion.none)
|
981
926
|
expect(repository.read(specification.in_batches.result)).to be_kind_of(Enumerator)
|
927
|
+
expect(repository.read(specification.in_batches.as_at.result)).to be_kind_of(Enumerator)
|
928
|
+
expect(repository.read(specification.in_batches.as_of.result)).to be_kind_of(Enumerator)
|
982
929
|
end
|
983
930
|
|
984
931
|
specify do
|
985
932
|
events = Array.new(400) { SRecord.new }
|
986
|
-
repository.append_to_stream(
|
987
|
-
|
988
|
-
Stream.new("Foo"),
|
989
|
-
ExpectedVersion.none
|
990
|
-
)
|
991
|
-
repository.append_to_stream(
|
992
|
-
events[0...200],
|
993
|
-
Stream.new("Dummy"),
|
994
|
-
ExpectedVersion.none
|
995
|
-
)
|
933
|
+
repository.append_to_stream(events[200...400], Stream.new("Foo"), ExpectedVersion.none)
|
934
|
+
repository.append_to_stream(events[0...200], Stream.new("Dummy"), ExpectedVersion.none)
|
996
935
|
|
997
936
|
batches = repository.read(specification.stream("Dummy").in_batches.result).to_a
|
998
937
|
expect(batches.size).to eq(2)
|
@@ -1002,11 +941,7 @@ module RubyEventStore
|
|
1002
941
|
|
1003
942
|
specify do
|
1004
943
|
events = Array.new(200) { SRecord.new }
|
1005
|
-
repository.append_to_stream(
|
1006
|
-
events,
|
1007
|
-
Stream.new(GLOBAL_STREAM),
|
1008
|
-
ExpectedVersion.any
|
1009
|
-
)
|
944
|
+
repository.append_to_stream(events, Stream.new(GLOBAL_STREAM), ExpectedVersion.any)
|
1010
945
|
|
1011
946
|
batches = repository.read(specification.in_batches.result).to_a
|
1012
947
|
expect(batches.size).to eq(2)
|
@@ -1016,22 +951,14 @@ module RubyEventStore
|
|
1016
951
|
|
1017
952
|
specify do
|
1018
953
|
events = Array.new(200) { SRecord.new }
|
1019
|
-
repository.append_to_stream(
|
1020
|
-
events,
|
1021
|
-
Stream.new(GLOBAL_STREAM),
|
1022
|
-
ExpectedVersion.any
|
1023
|
-
)
|
954
|
+
repository.append_to_stream(events, Stream.new(GLOBAL_STREAM), ExpectedVersion.any)
|
1024
955
|
|
1025
956
|
expect(repository.read(specification.in_batches(200).result).to_a.size).to eq(1)
|
1026
957
|
end
|
1027
958
|
|
1028
959
|
specify do
|
1029
960
|
events = Array.new(200) { SRecord.new }
|
1030
|
-
repository.append_to_stream(
|
1031
|
-
events,
|
1032
|
-
Stream.new(GLOBAL_STREAM),
|
1033
|
-
ExpectedVersion.any
|
1034
|
-
)
|
961
|
+
repository.append_to_stream(events, Stream.new(GLOBAL_STREAM), ExpectedVersion.any)
|
1035
962
|
|
1036
963
|
batches = repository.read(specification.limit(199).in_batches.result).to_a
|
1037
964
|
expect(batches.size).to eq(2)
|
@@ -1043,11 +970,7 @@ module RubyEventStore
|
|
1043
970
|
|
1044
971
|
specify do
|
1045
972
|
events = Array.new(200) { SRecord.new }
|
1046
|
-
repository.append_to_stream(
|
1047
|
-
events,
|
1048
|
-
Stream.new(GLOBAL_STREAM),
|
1049
|
-
ExpectedVersion.any
|
1050
|
-
)
|
973
|
+
repository.append_to_stream(events, Stream.new(GLOBAL_STREAM), ExpectedVersion.any)
|
1051
974
|
|
1052
975
|
batches = repository.read(specification.limit(99).in_batches.result).to_a
|
1053
976
|
expect(batches.size).to eq(1)
|
@@ -1057,11 +980,7 @@ module RubyEventStore
|
|
1057
980
|
|
1058
981
|
specify do
|
1059
982
|
events = Array.new(200) { SRecord.new }
|
1060
|
-
repository.append_to_stream(
|
1061
|
-
events,
|
1062
|
-
Stream.new(GLOBAL_STREAM),
|
1063
|
-
ExpectedVersion.any
|
1064
|
-
)
|
983
|
+
repository.append_to_stream(events, Stream.new(GLOBAL_STREAM), ExpectedVersion.any)
|
1065
984
|
|
1066
985
|
batches = repository.read(specification.backward.limit(99).in_batches.result).to_a
|
1067
986
|
expect(batches.size).to eq(1)
|
@@ -1071,11 +990,7 @@ module RubyEventStore
|
|
1071
990
|
|
1072
991
|
specify do
|
1073
992
|
events = Array.new(200) { SRecord.new }
|
1074
|
-
repository.append_to_stream(
|
1075
|
-
events,
|
1076
|
-
Stream.new(GLOBAL_STREAM),
|
1077
|
-
ExpectedVersion.any
|
1078
|
-
)
|
993
|
+
repository.append_to_stream(events, Stream.new(GLOBAL_STREAM), ExpectedVersion.any)
|
1079
994
|
|
1080
995
|
batches = repository.read(specification.from(events[100].event_id).limit(99).in_batches.result).to_a
|
1081
996
|
expect(batches.size).to eq(1)
|
@@ -1088,11 +1003,7 @@ module RubyEventStore
|
|
1088
1003
|
expect(repository.read(specification.read_last.result)).to be_nil
|
1089
1004
|
|
1090
1005
|
events = Array.new(5) { SRecord.new }
|
1091
|
-
repository.append_to_stream(
|
1092
|
-
events,
|
1093
|
-
Stream.new(GLOBAL_STREAM),
|
1094
|
-
ExpectedVersion.any
|
1095
|
-
)
|
1006
|
+
repository.append_to_stream(events, Stream.new(GLOBAL_STREAM), ExpectedVersion.any)
|
1096
1007
|
|
1097
1008
|
expect(repository.read(specification.stream("Any").read_first.result)).to be_nil
|
1098
1009
|
expect(repository.read(specification.stream("Any").read_last.result)).to be_nil
|
@@ -1132,33 +1043,70 @@ module RubyEventStore
|
|
1132
1043
|
specify "changes events" do
|
1133
1044
|
skip unless helper.supports_upsert?
|
1134
1045
|
events = Array.new(5) { SRecord.new }
|
1135
|
-
repository.append_to_stream(
|
1136
|
-
|
1137
|
-
|
1138
|
-
|
1046
|
+
repository.append_to_stream(events[0..2], Stream.new("whatever"), ExpectedVersion.any)
|
1047
|
+
repository.append_to_stream(events[3..4], Stream.new("elo"), ExpectedVersion.any)
|
1048
|
+
repository.update_messages(
|
1049
|
+
[
|
1050
|
+
a =
|
1051
|
+
SRecord.new(
|
1052
|
+
event_id: events[0].event_id.clone,
|
1053
|
+
data: events[0].data,
|
1054
|
+
metadata: events[0].metadata,
|
1055
|
+
event_type: events[0].event_type,
|
1056
|
+
timestamp: events[0].timestamp
|
1057
|
+
),
|
1058
|
+
b =
|
1059
|
+
SRecord.new(
|
1060
|
+
event_id: events[1].event_id.dup,
|
1061
|
+
data: {
|
1062
|
+
"test" => 1
|
1063
|
+
},
|
1064
|
+
metadata: events[1].metadata,
|
1065
|
+
event_type: events[1].event_type,
|
1066
|
+
timestamp: events[1].timestamp
|
1067
|
+
),
|
1068
|
+
c =
|
1069
|
+
SRecord.new(
|
1070
|
+
event_id: events[2].event_id,
|
1071
|
+
data: events[2].data,
|
1072
|
+
metadata: {
|
1073
|
+
"test" => 2
|
1074
|
+
},
|
1075
|
+
event_type: events[2].event_type,
|
1076
|
+
timestamp: events[2].timestamp
|
1077
|
+
),
|
1078
|
+
d =
|
1079
|
+
SRecord.new(
|
1080
|
+
event_id: events[3].event_id.clone,
|
1081
|
+
data: events[3].data,
|
1082
|
+
metadata: events[3].metadata,
|
1083
|
+
event_type: "event_type3",
|
1084
|
+
timestamp: events[3].timestamp
|
1085
|
+
),
|
1086
|
+
e =
|
1087
|
+
SRecord.new(
|
1088
|
+
event_id: events[4].event_id.dup,
|
1089
|
+
data: {
|
1090
|
+
"test" => 4
|
1091
|
+
},
|
1092
|
+
metadata: {
|
1093
|
+
"test" => 42
|
1094
|
+
},
|
1095
|
+
event_type: "event_type4",
|
1096
|
+
timestamp: events[4].timestamp
|
1097
|
+
)
|
1098
|
+
]
|
1139
1099
|
)
|
1140
|
-
|
1141
|
-
|
1142
|
-
|
1143
|
-
|
1144
|
-
)
|
1145
|
-
repository.update_messages([
|
1146
|
-
a = SRecord.new(event_id: events[0].event_id.clone, data: events[0].data, metadata: events[0].metadata, event_type: events[0].event_type, timestamp: events[0].timestamp),
|
1147
|
-
b = SRecord.new(event_id: events[1].event_id.dup, data: { "test" => 1 }, metadata: events[1].metadata, event_type: events[1].event_type, timestamp: events[1].timestamp),
|
1148
|
-
c = SRecord.new(event_id: events[2].event_id, data: events[2].data, metadata: { "test" => 2 }, event_type: events[2].event_type, timestamp: events[2].timestamp),
|
1149
|
-
d = SRecord.new(event_id: events[3].event_id.clone, data: events[3].data, metadata: events[3].metadata, event_type: "event_type3", timestamp: events[3].timestamp),
|
1150
|
-
e = SRecord.new(event_id: events[4].event_id.dup, data: { "test" => 4 }, metadata: { "test" => 42 }, event_type: "event_type4", timestamp: events[4].timestamp),
|
1151
|
-
])
|
1152
|
-
|
1153
|
-
expect(repository.read(specification.result).to_a).to eq([a,b,c,d,e])
|
1154
|
-
expect(repository.read(specification.stream("whatever").result).to_a).to eq([a,b,c])
|
1155
|
-
expect(repository.read(specification.stream("elo").result).to_a).to eq([d,e])
|
1100
|
+
|
1101
|
+
expect(repository.read(specification.result).to_a).to eq([a, b, c, d, e])
|
1102
|
+
expect(repository.read(specification.stream("whatever").result).to_a).to eq([a, b, c])
|
1103
|
+
expect(repository.read(specification.stream("elo").result).to_a).to eq([d, e])
|
1156
1104
|
end
|
1157
1105
|
|
1158
1106
|
specify "cannot change unexisting event" do
|
1159
1107
|
skip unless helper.supports_upsert?
|
1160
1108
|
e = SRecord.new
|
1161
|
-
expect{ repository.update_messages([e]) }.to raise_error do |err|
|
1109
|
+
expect { repository.update_messages([e]) }.to raise_error do |err|
|
1162
1110
|
expect(err).to be_a(EventNotFound)
|
1163
1111
|
expect(err.event_id).to eq(e.event_id)
|
1164
1112
|
expect(err.message).to eq("Event not found: #{e.event_id}")
|
@@ -1175,51 +1123,63 @@ module RubyEventStore
|
|
1175
1123
|
end
|
1176
1124
|
|
1177
1125
|
specify do
|
1178
|
-
event_1 = SRecord.new(event_id:
|
1179
|
-
event_2 = SRecord.new(event_id:
|
1180
|
-
event_3 = SRecord.new(event_id:
|
1181
|
-
stream_a = Stream.new(
|
1182
|
-
stream_b = Stream.new(
|
1183
|
-
stream_c = Stream.new(
|
1126
|
+
event_1 = SRecord.new(event_id: "8a6f053e-3ce2-4c82-a55b-4d02c66ae6ea")
|
1127
|
+
event_2 = SRecord.new(event_id: "8cee1139-4f96-483a-a175-2b947283c3c7")
|
1128
|
+
event_3 = SRecord.new(event_id: "d345f86d-b903-4d78-803f-38990c078d9e")
|
1129
|
+
stream_a = Stream.new("Stream A")
|
1130
|
+
stream_b = Stream.new("Stream B")
|
1131
|
+
stream_c = Stream.new("Stream C")
|
1184
1132
|
repository.append_to_stream([event_1, event_2], stream_a, version_any)
|
1185
1133
|
repository.append_to_stream([event_3], stream_b, version_any)
|
1186
1134
|
repository.link_to_stream([event_1.event_id], stream_c, version_none)
|
1187
1135
|
|
1188
|
-
expect(repository.streams_of(
|
1189
|
-
expect(repository.streams_of(
|
1190
|
-
expect(repository.streams_of(
|
1191
|
-
expect(repository.streams_of(
|
1136
|
+
expect(repository.streams_of("8a6f053e-3ce2-4c82-a55b-4d02c66ae6ea")).to eq [stream_a, stream_c]
|
1137
|
+
expect(repository.streams_of("8cee1139-4f96-483a-a175-2b947283c3c7")).to eq [stream_a]
|
1138
|
+
expect(repository.streams_of("d345f86d-b903-4d78-803f-38990c078d9e")).to eq [stream_b]
|
1139
|
+
expect(repository.streams_of("d10c8fe9-2163-418d-ba47-88c9a1f9391b")).to eq []
|
1192
1140
|
end
|
1193
1141
|
|
1194
1142
|
specify do
|
1195
|
-
e1 = SRecord.new(event_id:
|
1196
|
-
e2 = SRecord.new(event_id:
|
1197
|
-
e3 = SRecord.new(event_id:
|
1198
|
-
stream = Stream.new(
|
1143
|
+
e1 = SRecord.new(event_id: "8a6f053e-3ce2-4c82-a55b-4d02c66ae6ea")
|
1144
|
+
e2 = SRecord.new(event_id: "8cee1139-4f96-483a-a175-2b947283c3c7")
|
1145
|
+
e3 = SRecord.new(event_id: "d345f86d-b903-4d78-803f-38990c078d9e")
|
1146
|
+
stream = Stream.new("Stream A")
|
1199
1147
|
repository.append_to_stream([e1, e2, e3], stream, version_any)
|
1200
1148
|
|
1201
|
-
expect(repository.read(specification.with_id([
|
1202
|
-
|
1203
|
-
|
1204
|
-
expect(repository.read(specification.with_id([
|
1205
|
-
|
1206
|
-
|
1207
|
-
expect(repository.read(specification.with_id([
|
1208
|
-
|
1209
|
-
|
1210
|
-
expect(
|
1211
|
-
|
1212
|
-
|
1213
|
-
|
1214
|
-
|
1215
|
-
|
1216
|
-
|
1217
|
-
|
1218
|
-
|
1219
|
-
|
1220
|
-
expect(
|
1221
|
-
|
1222
|
-
|
1149
|
+
expect(repository.read(specification.with_id(["8a6f053e-3ce2-4c82-a55b-4d02c66ae6ea"]).read_first.result)).to eq(
|
1150
|
+
e1
|
1151
|
+
)
|
1152
|
+
expect(repository.read(specification.with_id(["d345f86d-b903-4d78-803f-38990c078d9e"]).read_first.result)).to eq(
|
1153
|
+
e3
|
1154
|
+
)
|
1155
|
+
expect(repository.read(specification.with_id(["c31b327c-0da1-4178-a3cd-d2f6bb5d0688"]).read_first.result)).to eq(
|
1156
|
+
nil
|
1157
|
+
)
|
1158
|
+
expect(
|
1159
|
+
repository.read(
|
1160
|
+
specification
|
1161
|
+
.with_id(%w[8a6f053e-3ce2-4c82-a55b-4d02c66ae6ea d345f86d-b903-4d78-803f-38990c078d9e])
|
1162
|
+
.in_batches
|
1163
|
+
.result
|
1164
|
+
).to_a[
|
1165
|
+
0
|
1166
|
+
]
|
1167
|
+
).to eq([e1, e3])
|
1168
|
+
expect(
|
1169
|
+
repository.read(
|
1170
|
+
specification.stream("Stream A").with_id(["8cee1139-4f96-483a-a175-2b947283c3c7"]).read_first.result
|
1171
|
+
)
|
1172
|
+
).to eq(e2)
|
1173
|
+
expect(
|
1174
|
+
repository.read(
|
1175
|
+
specification.stream("Stream B").with_id(["8cee1139-4f96-483a-a175-2b947283c3c7"]).read_first.result
|
1176
|
+
)
|
1177
|
+
).to eq(nil)
|
1178
|
+
expect(
|
1179
|
+
repository.read(
|
1180
|
+
specification.stream("Stream B").with_id(["c31b327c-0da1-4178-a3cd-d2f6bb5d0688"]).read_first.result
|
1181
|
+
)
|
1182
|
+
).to eq(nil)
|
1223
1183
|
expect(repository.read(specification.with_id([]).result).to_a).to eq([])
|
1224
1184
|
end
|
1225
1185
|
|
@@ -1227,23 +1187,21 @@ module RubyEventStore
|
|
1227
1187
|
e1 = SRecord.new(event_type: Type1.to_s)
|
1228
1188
|
e2 = SRecord.new(event_type: Type2.to_s)
|
1229
1189
|
e3 = SRecord.new(event_type: Type1.to_s)
|
1230
|
-
stream = Stream.new(
|
1190
|
+
stream = Stream.new("Stream A")
|
1231
1191
|
repository.append_to_stream([e1, e2, e3], stream, version_any)
|
1232
1192
|
|
1233
|
-
expect(repository.read(specification.of_type([Type1]).result).to_a).to eq([e1,e3])
|
1193
|
+
expect(repository.read(specification.of_type([Type1]).result).to_a).to eq([e1, e3])
|
1234
1194
|
expect(repository.read(specification.of_type([Type2]).result).to_a).to eq([e2])
|
1235
1195
|
expect(repository.read(specification.of_type([Type3]).result).to_a).to eq([])
|
1236
|
-
expect(repository.read(specification.of_type([Type1, Type2, Type3]).result).to_a).to eq([e1,e2,e3])
|
1196
|
+
expect(repository.read(specification.of_type([Type1, Type2, Type3]).result).to_a).to eq([e1, e2, e3])
|
1237
1197
|
end
|
1238
1198
|
|
1239
1199
|
specify do
|
1240
|
-
stream = Stream.new(
|
1241
|
-
dummy
|
1200
|
+
stream = Stream.new("Stream A")
|
1201
|
+
dummy = Stream.new("Dummy")
|
1242
1202
|
|
1243
1203
|
expect(repository.count(specification.result)).to eq(0)
|
1244
|
-
(1..3).each
|
1245
|
-
repository.append_to_stream([SRecord.new(event_type: Type1.to_s)], stream, version_any)
|
1246
|
-
end
|
1204
|
+
(1..3).each { repository.append_to_stream([SRecord.new(event_type: Type1.to_s)], stream, version_any) }
|
1247
1205
|
expect(repository.count(specification.result)).to eq(3)
|
1248
1206
|
event_id = SecureRandom.uuid
|
1249
1207
|
repository.append_to_stream([SRecord.new(event_type: Type1.to_s, event_id: event_id)], dummy, version_any)
|
@@ -1256,8 +1214,8 @@ module RubyEventStore
|
|
1256
1214
|
expect(repository.count(specification.with_id([not_existing_uuid]).result)).to eq(0)
|
1257
1215
|
|
1258
1216
|
expect(repository.count(specification.stream(stream.name).result)).to eq(3)
|
1259
|
-
expect(repository.count(specification.stream(
|
1260
|
-
expect(repository.count(specification.stream(
|
1217
|
+
expect(repository.count(specification.stream("Dummy").result)).to eq(1)
|
1218
|
+
expect(repository.count(specification.stream("not-existing-stream").result)).to eq(0)
|
1261
1219
|
|
1262
1220
|
repository.append_to_stream([SRecord.new(event_type: Type1.to_s)], dummy, version_any)
|
1263
1221
|
expect(repository.count(specification.from(event_id).result)).to eq(1)
|
@@ -1277,118 +1235,176 @@ module RubyEventStore
|
|
1277
1235
|
expect(repository.count(specification.stream(stream.name).of_type([Type3]).result)).to eq(0)
|
1278
1236
|
end
|
1279
1237
|
|
1280
|
-
specify
|
1281
|
-
time = Time.utc(2020, 9, 11, 12, 26, 0,
|
1238
|
+
specify "timestamp precision" do
|
1239
|
+
time = Time.utc(2020, 9, 11, 12, 26, 0, 123_456)
|
1282
1240
|
repository.append_to_stream([SRecord.new(timestamp: time)], stream, version_none)
|
1283
1241
|
event = read_events_forward(repository, count: 1).first
|
1284
1242
|
|
1285
1243
|
expect(event.timestamp).to eq(time)
|
1286
1244
|
end
|
1287
1245
|
|
1288
|
-
specify
|
1289
|
-
event_1 = SRecord.new(event_id:
|
1290
|
-
event_2 = SRecord.new(event_id:
|
1291
|
-
event_3 = SRecord.new(event_id:
|
1292
|
-
repository.append_to_stream([event_1, event_2, event_3], Stream.new(
|
1246
|
+
specify "fetching records older than specified date in stream" do
|
1247
|
+
event_1 = SRecord.new(event_id: "8a6f053e-3ce2-4c82-a55b-4d02c66ae6ea", timestamp: Time.utc(2020, 1, 1))
|
1248
|
+
event_2 = SRecord.new(event_id: "8cee1139-4f96-483a-a175-2b947283c3c7", timestamp: Time.utc(2020, 1, 2))
|
1249
|
+
event_3 = SRecord.new(event_id: "d345f86d-b903-4d78-803f-38990c078d9e", timestamp: Time.utc(2020, 1, 3))
|
1250
|
+
repository.append_to_stream([event_1, event_2, event_3], Stream.new("whatever"), version_any)
|
1293
1251
|
|
1294
|
-
expect(repository.read(specification.stream(
|
1252
|
+
expect(repository.read(specification.stream("whatever").older_than(Time.utc(2020, 1, 2)).result).to_a).to eq(
|
1253
|
+
[event_1]
|
1254
|
+
)
|
1295
1255
|
end
|
1296
1256
|
|
1297
|
-
specify
|
1298
|
-
event_1 = SRecord.new(event_id:
|
1299
|
-
event_2 = SRecord.new(event_id:
|
1300
|
-
event_3 = SRecord.new(event_id:
|
1301
|
-
repository.append_to_stream([event_1, event_2, event_3], Stream.new(
|
1257
|
+
specify "fetching records older than or equal to specified date in stream" do
|
1258
|
+
event_1 = SRecord.new(event_id: "8a6f053e-3ce2-4c82-a55b-4d02c66ae6ea", timestamp: Time.utc(2020, 1, 1))
|
1259
|
+
event_2 = SRecord.new(event_id: "8cee1139-4f96-483a-a175-2b947283c3c7", timestamp: Time.utc(2020, 1, 2))
|
1260
|
+
event_3 = SRecord.new(event_id: "d345f86d-b903-4d78-803f-38990c078d9e", timestamp: Time.utc(2020, 1, 3))
|
1261
|
+
repository.append_to_stream([event_1, event_2, event_3], Stream.new("whatever"), version_any)
|
1302
1262
|
|
1303
|
-
expect(
|
1263
|
+
expect(
|
1264
|
+
repository.read(specification.stream("whatever").older_than_or_equal(Time.utc(2020, 1, 2)).result).to_a
|
1265
|
+
).to eq([event_1, event_2])
|
1304
1266
|
end
|
1305
1267
|
|
1306
|
-
specify
|
1307
|
-
event_1 = SRecord.new(event_id:
|
1308
|
-
event_2 = SRecord.new(event_id:
|
1309
|
-
event_3 = SRecord.new(event_id:
|
1310
|
-
repository.append_to_stream([event_1, event_2, event_3], Stream.new(
|
1268
|
+
specify "fetching records newer than specified date in stream" do
|
1269
|
+
event_1 = SRecord.new(event_id: "8a6f053e-3ce2-4c82-a55b-4d02c66ae6ea", timestamp: Time.utc(2020, 1, 1))
|
1270
|
+
event_2 = SRecord.new(event_id: "8cee1139-4f96-483a-a175-2b947283c3c7", timestamp: Time.utc(2020, 1, 2))
|
1271
|
+
event_3 = SRecord.new(event_id: "d345f86d-b903-4d78-803f-38990c078d9e", timestamp: Time.utc(2020, 1, 3))
|
1272
|
+
repository.append_to_stream([event_1, event_2, event_3], Stream.new("whatever"), version_any)
|
1311
1273
|
|
1312
|
-
expect(repository.read(specification.stream(
|
1274
|
+
expect(repository.read(specification.stream("whatever").newer_than(Time.utc(2020, 1, 2)).result).to_a).to eq(
|
1275
|
+
[event_3]
|
1276
|
+
)
|
1313
1277
|
end
|
1314
1278
|
|
1315
|
-
specify
|
1316
|
-
event_1 = SRecord.new(event_id:
|
1317
|
-
event_2 = SRecord.new(event_id:
|
1318
|
-
event_3 = SRecord.new(event_id:
|
1319
|
-
repository.append_to_stream([event_1, event_2, event_3], Stream.new(
|
1279
|
+
specify "fetching records newer than or equal to specified date in stream" do
|
1280
|
+
event_1 = SRecord.new(event_id: "8a6f053e-3ce2-4c82-a55b-4d02c66ae6ea", timestamp: Time.utc(2020, 1, 1))
|
1281
|
+
event_2 = SRecord.new(event_id: "8cee1139-4f96-483a-a175-2b947283c3c7", timestamp: Time.utc(2020, 1, 2))
|
1282
|
+
event_3 = SRecord.new(event_id: "d345f86d-b903-4d78-803f-38990c078d9e", timestamp: Time.utc(2020, 1, 3))
|
1283
|
+
repository.append_to_stream([event_1, event_2, event_3], Stream.new("whatever"), version_any)
|
1320
1284
|
|
1321
|
-
expect(
|
1285
|
+
expect(
|
1286
|
+
repository.read(specification.stream("whatever").newer_than_or_equal(Time.utc(2020, 1, 2)).result).to_a
|
1287
|
+
).to eq([event_2, event_3])
|
1322
1288
|
end
|
1323
1289
|
|
1324
|
-
specify
|
1325
|
-
event_1 = SRecord.new(event_id:
|
1326
|
-
event_2 = SRecord.new(event_id:
|
1327
|
-
event_3 = SRecord.new(event_id:
|
1328
|
-
repository.append_to_stream([event_1, event_2, event_3], Stream.new(
|
1290
|
+
specify "fetching records older than specified date" do
|
1291
|
+
event_1 = SRecord.new(event_id: "8a6f053e-3ce2-4c82-a55b-4d02c66ae6ea", timestamp: Time.utc(2020, 1, 1))
|
1292
|
+
event_2 = SRecord.new(event_id: "8cee1139-4f96-483a-a175-2b947283c3c7", timestamp: Time.utc(2020, 1, 2))
|
1293
|
+
event_3 = SRecord.new(event_id: "d345f86d-b903-4d78-803f-38990c078d9e", timestamp: Time.utc(2020, 1, 3))
|
1294
|
+
repository.append_to_stream([event_1, event_2, event_3], Stream.new("whatever"), version_any)
|
1329
1295
|
|
1330
1296
|
expect(repository.read(specification.older_than(Time.utc(2020, 1, 2)).result).to_a).to eq([event_1])
|
1331
1297
|
end
|
1332
1298
|
|
1333
|
-
specify
|
1334
|
-
event_1 = SRecord.new(event_id:
|
1335
|
-
event_2 = SRecord.new(event_id:
|
1336
|
-
event_3 = SRecord.new(event_id:
|
1337
|
-
repository.append_to_stream([event_1, event_2, event_3], Stream.new(
|
1299
|
+
specify "fetching records older than or equal to specified date" do
|
1300
|
+
event_1 = SRecord.new(event_id: "8a6f053e-3ce2-4c82-a55b-4d02c66ae6ea", timestamp: Time.utc(2020, 1, 1))
|
1301
|
+
event_2 = SRecord.new(event_id: "8cee1139-4f96-483a-a175-2b947283c3c7", timestamp: Time.utc(2020, 1, 2))
|
1302
|
+
event_3 = SRecord.new(event_id: "d345f86d-b903-4d78-803f-38990c078d9e", timestamp: Time.utc(2020, 1, 3))
|
1303
|
+
repository.append_to_stream([event_1, event_2, event_3], Stream.new("whatever"), version_any)
|
1338
1304
|
|
1339
|
-
expect(repository.read(specification.older_than_or_equal(Time.utc(2020, 1, 2)).result).to_a).to eq(
|
1305
|
+
expect(repository.read(specification.older_than_or_equal(Time.utc(2020, 1, 2)).result).to_a).to eq(
|
1306
|
+
[event_1, event_2]
|
1307
|
+
)
|
1340
1308
|
end
|
1341
1309
|
|
1342
|
-
specify
|
1343
|
-
event_1 = SRecord.new(event_id:
|
1344
|
-
event_2 = SRecord.new(event_id:
|
1345
|
-
event_3 = SRecord.new(event_id:
|
1346
|
-
repository.append_to_stream([event_1, event_2, event_3], Stream.new(
|
1310
|
+
specify "fetching records newer than specified date" do
|
1311
|
+
event_1 = SRecord.new(event_id: "8a6f053e-3ce2-4c82-a55b-4d02c66ae6ea", timestamp: Time.utc(2020, 1, 1))
|
1312
|
+
event_2 = SRecord.new(event_id: "8cee1139-4f96-483a-a175-2b947283c3c7", timestamp: Time.utc(2020, 1, 2))
|
1313
|
+
event_3 = SRecord.new(event_id: "d345f86d-b903-4d78-803f-38990c078d9e", timestamp: Time.utc(2020, 1, 3))
|
1314
|
+
repository.append_to_stream([event_1, event_2, event_3], Stream.new("whatever"), version_any)
|
1347
1315
|
|
1348
1316
|
expect(repository.read(specification.newer_than(Time.utc(2020, 1, 2)).result).to_a).to eq([event_3])
|
1349
1317
|
end
|
1350
1318
|
|
1351
|
-
specify
|
1352
|
-
event_1 = SRecord.new(event_id:
|
1353
|
-
event_2 = SRecord.new(event_id:
|
1354
|
-
event_3 = SRecord.new(event_id:
|
1355
|
-
repository.append_to_stream([event_1, event_2, event_3], Stream.new(
|
1319
|
+
specify "fetching records newer than or equal to specified date" do
|
1320
|
+
event_1 = SRecord.new(event_id: "8a6f053e-3ce2-4c82-a55b-4d02c66ae6ea", timestamp: Time.utc(2020, 1, 1))
|
1321
|
+
event_2 = SRecord.new(event_id: "8cee1139-4f96-483a-a175-2b947283c3c7", timestamp: Time.utc(2020, 1, 2))
|
1322
|
+
event_3 = SRecord.new(event_id: "d345f86d-b903-4d78-803f-38990c078d9e", timestamp: Time.utc(2020, 1, 3))
|
1323
|
+
repository.append_to_stream([event_1, event_2, event_3], Stream.new("whatever"), version_any)
|
1356
1324
|
|
1357
|
-
expect(repository.read(specification.newer_than_or_equal(Time.utc(2020, 1, 2)).result).to_a).to eq(
|
1325
|
+
expect(repository.read(specification.newer_than_or_equal(Time.utc(2020, 1, 2)).result).to_a).to eq(
|
1326
|
+
[event_2, event_3]
|
1327
|
+
)
|
1358
1328
|
end
|
1359
1329
|
|
1360
|
-
specify
|
1361
|
-
event_1 = SRecord.new(event_id:
|
1362
|
-
event_2 = SRecord.new(event_id:
|
1363
|
-
event_3 = SRecord.new(event_id:
|
1364
|
-
repository.append_to_stream([event_1, event_2, event_3], Stream.new(
|
1330
|
+
specify "fetching records from disjoint periods" do
|
1331
|
+
event_1 = SRecord.new(event_id: "8a6f053e-3ce2-4c82-a55b-4d02c66ae6ea", timestamp: Time.utc(2020, 1, 1))
|
1332
|
+
event_2 = SRecord.new(event_id: "8cee1139-4f96-483a-a175-2b947283c3c7", timestamp: Time.utc(2020, 1, 2))
|
1333
|
+
event_3 = SRecord.new(event_id: "d345f86d-b903-4d78-803f-38990c078d9e", timestamp: Time.utc(2020, 1, 3))
|
1334
|
+
repository.append_to_stream([event_1, event_2, event_3], Stream.new("whatever"), version_any)
|
1365
1335
|
|
1366
|
-
expect(
|
1336
|
+
expect(
|
1337
|
+
repository.read(specification.older_than(Time.utc(2020, 1, 2)).newer_than(Time.utc(2020, 1, 2)).result).to_a
|
1338
|
+
).to eq([])
|
1367
1339
|
end
|
1368
1340
|
|
1369
|
-
specify
|
1370
|
-
event_1 = SRecord.new(event_id:
|
1371
|
-
event_2 = SRecord.new(event_id:
|
1372
|
-
event_3 = SRecord.new(event_id:
|
1373
|
-
repository.append_to_stream([event_1, event_2, event_3], Stream.new(
|
1341
|
+
specify "fetching records within time range" do
|
1342
|
+
event_1 = SRecord.new(event_id: "8a6f053e-3ce2-4c82-a55b-4d02c66ae6ea", timestamp: Time.utc(2020, 1, 1))
|
1343
|
+
event_2 = SRecord.new(event_id: "8cee1139-4f96-483a-a175-2b947283c3c7", timestamp: Time.utc(2020, 1, 2))
|
1344
|
+
event_3 = SRecord.new(event_id: "d345f86d-b903-4d78-803f-38990c078d9e", timestamp: Time.utc(2020, 1, 3))
|
1345
|
+
repository.append_to_stream([event_1, event_2, event_3], Stream.new("whatever"), version_any)
|
1374
1346
|
|
1375
|
-
expect(repository.read(specification.between(Time.utc(2020, 1, 1)...Time.utc(2020, 1, 3)).result).to_a).to eq(
|
1347
|
+
expect(repository.read(specification.between(Time.utc(2020, 1, 1)...Time.utc(2020, 1, 3)).result).to_a).to eq(
|
1348
|
+
[event_1, event_2]
|
1349
|
+
)
|
1376
1350
|
end
|
1377
1351
|
|
1378
1352
|
specify "time order is respected" do
|
1379
|
-
repository.append_to_stream(
|
1380
|
-
|
1381
|
-
SRecord.new(
|
1382
|
-
|
1353
|
+
repository.append_to_stream(
|
1354
|
+
[
|
1355
|
+
SRecord.new(
|
1356
|
+
event_id: e1 = SecureRandom.uuid,
|
1357
|
+
timestamp: Time.new(2020, 1, 1),
|
1358
|
+
valid_at: Time.new(2020, 1, 9)
|
1359
|
+
),
|
1360
|
+
SRecord.new(
|
1361
|
+
event_id: e2 = SecureRandom.uuid,
|
1362
|
+
timestamp: Time.new(2020, 1, 3),
|
1363
|
+
valid_at: Time.new(2020, 1, 6)
|
1364
|
+
),
|
1365
|
+
SRecord.new(event_id: e3 = SecureRandom.uuid, timestamp: Time.new(2020, 1, 2), valid_at: Time.new(2020, 1, 3))
|
1383
1366
|
],
|
1384
1367
|
Stream.new("Dummy"),
|
1385
1368
|
ExpectedVersion.any
|
1386
1369
|
)
|
1387
|
-
expect(repository.read(specification.result)
|
1388
|
-
expect(repository.read(specification.as_at.result)
|
1389
|
-
expect(repository.read(specification.as_at.backward.result)
|
1390
|
-
expect(repository.read(specification.as_of.result)
|
1391
|
-
expect(repository.read(specification.as_of.backward.result)
|
1370
|
+
expect(repository.read(specification.result)).to eq_ids([e1, e2, e3])
|
1371
|
+
expect(repository.read(specification.as_at.result)).to eq_ids([e1, e3, e2])
|
1372
|
+
expect(repository.read(specification.as_at.backward.result)).to eq_ids([e2, e3, e1])
|
1373
|
+
expect(repository.read(specification.as_of.result)).to eq_ids([e3, e2, e1])
|
1374
|
+
expect(repository.read(specification.as_of.backward.result)).to eq_ids([e1, e2, e3])
|
1375
|
+
end
|
1376
|
+
|
1377
|
+
specify "time order is respected with batches" do
|
1378
|
+
repository.append_to_stream(
|
1379
|
+
[
|
1380
|
+
SRecord.new(
|
1381
|
+
event_id: e1 = SecureRandom.uuid,
|
1382
|
+
timestamp: Time.new(2020, 1, 1),
|
1383
|
+
valid_at: Time.new(2020, 1, 9)
|
1384
|
+
),
|
1385
|
+
SRecord.new(
|
1386
|
+
event_id: e2 = SecureRandom.uuid,
|
1387
|
+
timestamp: Time.new(2020, 1, 3),
|
1388
|
+
valid_at: Time.new(2020, 1, 6)
|
1389
|
+
),
|
1390
|
+
SRecord.new(event_id: e3 = SecureRandom.uuid, timestamp: Time.new(2020, 1, 2), valid_at: Time.new(2020, 1, 3))
|
1391
|
+
],
|
1392
|
+
Stream.new("Dummy"),
|
1393
|
+
ExpectedVersion.any
|
1394
|
+
)
|
1395
|
+
expect(repository.read(specification.in_batches.result).to_a.flatten).to eq_ids([e1, e2, e3])
|
1396
|
+
expect(repository.read(specification.in_batches.as_at.result).to_a.flatten).to eq_ids([e1, e3, e2])
|
1397
|
+
expect(repository.read(specification.in_batches.as_at.backward.result).to_a.flatten).to eq_ids([e2, e3, e1])
|
1398
|
+
expect(repository.read(specification.in_batches.as_of.result).to_a.flatten).to eq_ids([e3, e2, e1])
|
1399
|
+
expect(repository.read(specification.in_batches.as_of.backward.result).to_a.flatten).to eq_ids([e1, e2, e3])
|
1400
|
+
end
|
1401
|
+
end
|
1402
|
+
|
1403
|
+
::RSpec::Matchers.define :eq_ids do |expected_ids|
|
1404
|
+
match do |enum|
|
1405
|
+
@actual = enum.map(&:event_id)
|
1406
|
+
expected_ids == @actual
|
1392
1407
|
end
|
1408
|
+
diffable
|
1393
1409
|
end
|
1394
1410
|
end
|