ruby_event_store 2.2.0 → 2.4.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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 +75 -46
- 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 +23 -13
- 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 +745 -741
- data/lib/ruby_event_store/spec/mapper_lint.rb +2 -2
- data/lib/ruby_event_store/spec/subscriptions_lint.rb +58 -57
- 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 +14 -15
- 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,40 +885,36 @@ 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
|
@@ -975,29 +922,16 @@ module RubyEventStore
|
|
975
922
|
expect(repository.read(specification.in_batches.as_at.result)).to be_kind_of(Enumerator)
|
976
923
|
expect(repository.read(specification.in_batches.as_of.result)).to be_kind_of(Enumerator)
|
977
924
|
events = Array.new(10) { SRecord.new }
|
978
|
-
repository.append_to_stream(
|
979
|
-
events,
|
980
|
-
Stream.new("Dummy"),
|
981
|
-
ExpectedVersion.none
|
982
|
-
)
|
925
|
+
repository.append_to_stream(events, Stream.new("Dummy"), ExpectedVersion.none)
|
983
926
|
expect(repository.read(specification.in_batches.result)).to be_kind_of(Enumerator)
|
984
927
|
expect(repository.read(specification.in_batches.as_at.result)).to be_kind_of(Enumerator)
|
985
928
|
expect(repository.read(specification.in_batches.as_of.result)).to be_kind_of(Enumerator)
|
986
|
-
|
987
929
|
end
|
988
930
|
|
989
931
|
specify do
|
990
932
|
events = Array.new(400) { SRecord.new }
|
991
|
-
repository.append_to_stream(
|
992
|
-
|
993
|
-
Stream.new("Foo"),
|
994
|
-
ExpectedVersion.none
|
995
|
-
)
|
996
|
-
repository.append_to_stream(
|
997
|
-
events[0...200],
|
998
|
-
Stream.new("Dummy"),
|
999
|
-
ExpectedVersion.none
|
1000
|
-
)
|
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)
|
1001
935
|
|
1002
936
|
batches = repository.read(specification.stream("Dummy").in_batches.result).to_a
|
1003
937
|
expect(batches.size).to eq(2)
|
@@ -1007,11 +941,7 @@ module RubyEventStore
|
|
1007
941
|
|
1008
942
|
specify do
|
1009
943
|
events = Array.new(200) { SRecord.new }
|
1010
|
-
repository.append_to_stream(
|
1011
|
-
events,
|
1012
|
-
Stream.new(GLOBAL_STREAM),
|
1013
|
-
ExpectedVersion.any
|
1014
|
-
)
|
944
|
+
repository.append_to_stream(events, Stream.new(GLOBAL_STREAM), ExpectedVersion.any)
|
1015
945
|
|
1016
946
|
batches = repository.read(specification.in_batches.result).to_a
|
1017
947
|
expect(batches.size).to eq(2)
|
@@ -1021,22 +951,14 @@ module RubyEventStore
|
|
1021
951
|
|
1022
952
|
specify do
|
1023
953
|
events = Array.new(200) { SRecord.new }
|
1024
|
-
repository.append_to_stream(
|
1025
|
-
events,
|
1026
|
-
Stream.new(GLOBAL_STREAM),
|
1027
|
-
ExpectedVersion.any
|
1028
|
-
)
|
954
|
+
repository.append_to_stream(events, Stream.new(GLOBAL_STREAM), ExpectedVersion.any)
|
1029
955
|
|
1030
956
|
expect(repository.read(specification.in_batches(200).result).to_a.size).to eq(1)
|
1031
957
|
end
|
1032
958
|
|
1033
959
|
specify do
|
1034
960
|
events = Array.new(200) { SRecord.new }
|
1035
|
-
repository.append_to_stream(
|
1036
|
-
events,
|
1037
|
-
Stream.new(GLOBAL_STREAM),
|
1038
|
-
ExpectedVersion.any
|
1039
|
-
)
|
961
|
+
repository.append_to_stream(events, Stream.new(GLOBAL_STREAM), ExpectedVersion.any)
|
1040
962
|
|
1041
963
|
batches = repository.read(specification.limit(199).in_batches.result).to_a
|
1042
964
|
expect(batches.size).to eq(2)
|
@@ -1048,11 +970,7 @@ module RubyEventStore
|
|
1048
970
|
|
1049
971
|
specify do
|
1050
972
|
events = Array.new(200) { SRecord.new }
|
1051
|
-
repository.append_to_stream(
|
1052
|
-
events,
|
1053
|
-
Stream.new(GLOBAL_STREAM),
|
1054
|
-
ExpectedVersion.any
|
1055
|
-
)
|
973
|
+
repository.append_to_stream(events, Stream.new(GLOBAL_STREAM), ExpectedVersion.any)
|
1056
974
|
|
1057
975
|
batches = repository.read(specification.limit(99).in_batches.result).to_a
|
1058
976
|
expect(batches.size).to eq(1)
|
@@ -1062,11 +980,7 @@ module RubyEventStore
|
|
1062
980
|
|
1063
981
|
specify do
|
1064
982
|
events = Array.new(200) { SRecord.new }
|
1065
|
-
repository.append_to_stream(
|
1066
|
-
events,
|
1067
|
-
Stream.new(GLOBAL_STREAM),
|
1068
|
-
ExpectedVersion.any
|
1069
|
-
)
|
983
|
+
repository.append_to_stream(events, Stream.new(GLOBAL_STREAM), ExpectedVersion.any)
|
1070
984
|
|
1071
985
|
batches = repository.read(specification.backward.limit(99).in_batches.result).to_a
|
1072
986
|
expect(batches.size).to eq(1)
|
@@ -1076,11 +990,7 @@ module RubyEventStore
|
|
1076
990
|
|
1077
991
|
specify do
|
1078
992
|
events = Array.new(200) { SRecord.new }
|
1079
|
-
repository.append_to_stream(
|
1080
|
-
events,
|
1081
|
-
Stream.new(GLOBAL_STREAM),
|
1082
|
-
ExpectedVersion.any
|
1083
|
-
)
|
993
|
+
repository.append_to_stream(events, Stream.new(GLOBAL_STREAM), ExpectedVersion.any)
|
1084
994
|
|
1085
995
|
batches = repository.read(specification.from(events[100].event_id).limit(99).in_batches.result).to_a
|
1086
996
|
expect(batches.size).to eq(1)
|
@@ -1093,11 +1003,7 @@ module RubyEventStore
|
|
1093
1003
|
expect(repository.read(specification.read_last.result)).to be_nil
|
1094
1004
|
|
1095
1005
|
events = Array.new(5) { SRecord.new }
|
1096
|
-
repository.append_to_stream(
|
1097
|
-
events,
|
1098
|
-
Stream.new(GLOBAL_STREAM),
|
1099
|
-
ExpectedVersion.any
|
1100
|
-
)
|
1006
|
+
repository.append_to_stream(events, Stream.new(GLOBAL_STREAM), ExpectedVersion.any)
|
1101
1007
|
|
1102
1008
|
expect(repository.read(specification.stream("Any").read_first.result)).to be_nil
|
1103
1009
|
expect(repository.read(specification.stream("Any").read_last.result)).to be_nil
|
@@ -1137,33 +1043,70 @@ module RubyEventStore
|
|
1137
1043
|
specify "changes events" do
|
1138
1044
|
skip unless helper.supports_upsert?
|
1139
1045
|
events = Array.new(5) { SRecord.new }
|
1140
|
-
repository.append_to_stream(
|
1141
|
-
|
1142
|
-
|
1143
|
-
|
1144
|
-
|
1145
|
-
|
1146
|
-
|
1147
|
-
|
1148
|
-
|
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
|
+
]
|
1149
1099
|
)
|
1150
|
-
|
1151
|
-
|
1152
|
-
|
1153
|
-
|
1154
|
-
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),
|
1155
|
-
e = SRecord.new(event_id: events[4].event_id.dup, data: { "test" => 4 }, metadata: { "test" => 42 }, event_type: "event_type4", timestamp: events[4].timestamp),
|
1156
|
-
])
|
1157
|
-
|
1158
|
-
expect(repository.read(specification.result).to_a).to eq([a,b,c,d,e])
|
1159
|
-
expect(repository.read(specification.stream("whatever").result).to_a).to eq([a,b,c])
|
1160
|
-
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])
|
1161
1104
|
end
|
1162
1105
|
|
1163
1106
|
specify "cannot change unexisting event" do
|
1164
1107
|
skip unless helper.supports_upsert?
|
1165
1108
|
e = SRecord.new
|
1166
|
-
expect{ repository.update_messages([e]) }.to raise_error do |err|
|
1109
|
+
expect { repository.update_messages([e]) }.to raise_error do |err|
|
1167
1110
|
expect(err).to be_a(EventNotFound)
|
1168
1111
|
expect(err.event_id).to eq(e.event_id)
|
1169
1112
|
expect(err.message).to eq("Event not found: #{e.event_id}")
|
@@ -1180,51 +1123,63 @@ module RubyEventStore
|
|
1180
1123
|
end
|
1181
1124
|
|
1182
1125
|
specify do
|
1183
|
-
event_1 = SRecord.new(event_id:
|
1184
|
-
event_2 = SRecord.new(event_id:
|
1185
|
-
event_3 = SRecord.new(event_id:
|
1186
|
-
stream_a = Stream.new(
|
1187
|
-
stream_b = Stream.new(
|
1188
|
-
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")
|
1189
1132
|
repository.append_to_stream([event_1, event_2], stream_a, version_any)
|
1190
1133
|
repository.append_to_stream([event_3], stream_b, version_any)
|
1191
1134
|
repository.link_to_stream([event_1.event_id], stream_c, version_none)
|
1192
1135
|
|
1193
|
-
expect(repository.streams_of(
|
1194
|
-
expect(repository.streams_of(
|
1195
|
-
expect(repository.streams_of(
|
1196
|
-
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 []
|
1197
1140
|
end
|
1198
1141
|
|
1199
1142
|
specify do
|
1200
|
-
e1 = SRecord.new(event_id:
|
1201
|
-
e2 = SRecord.new(event_id:
|
1202
|
-
e3 = SRecord.new(event_id:
|
1203
|
-
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")
|
1204
1147
|
repository.append_to_stream([e1, e2, e3], stream, version_any)
|
1205
1148
|
|
1206
|
-
expect(repository.read(specification.with_id([
|
1207
|
-
|
1208
|
-
|
1209
|
-
expect(repository.read(specification.with_id([
|
1210
|
-
|
1211
|
-
|
1212
|
-
expect(repository.read(specification.with_id([
|
1213
|
-
|
1214
|
-
|
1215
|
-
expect(
|
1216
|
-
|
1217
|
-
|
1218
|
-
|
1219
|
-
|
1220
|
-
|
1221
|
-
|
1222
|
-
|
1223
|
-
|
1224
|
-
|
1225
|
-
expect(
|
1226
|
-
|
1227
|
-
|
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)
|
1228
1183
|
expect(repository.read(specification.with_id([]).result).to_a).to eq([])
|
1229
1184
|
end
|
1230
1185
|
|
@@ -1232,23 +1187,21 @@ module RubyEventStore
|
|
1232
1187
|
e1 = SRecord.new(event_type: Type1.to_s)
|
1233
1188
|
e2 = SRecord.new(event_type: Type2.to_s)
|
1234
1189
|
e3 = SRecord.new(event_type: Type1.to_s)
|
1235
|
-
stream = Stream.new(
|
1190
|
+
stream = Stream.new("Stream A")
|
1236
1191
|
repository.append_to_stream([e1, e2, e3], stream, version_any)
|
1237
1192
|
|
1238
|
-
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])
|
1239
1194
|
expect(repository.read(specification.of_type([Type2]).result).to_a).to eq([e2])
|
1240
1195
|
expect(repository.read(specification.of_type([Type3]).result).to_a).to eq([])
|
1241
|
-
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])
|
1242
1197
|
end
|
1243
1198
|
|
1244
1199
|
specify do
|
1245
|
-
stream = Stream.new(
|
1246
|
-
dummy
|
1200
|
+
stream = Stream.new("Stream A")
|
1201
|
+
dummy = Stream.new("Dummy")
|
1247
1202
|
|
1248
1203
|
expect(repository.count(specification.result)).to eq(0)
|
1249
|
-
(1..3).each
|
1250
|
-
repository.append_to_stream([SRecord.new(event_type: Type1.to_s)], stream, version_any)
|
1251
|
-
end
|
1204
|
+
(1..3).each { repository.append_to_stream([SRecord.new(event_type: Type1.to_s)], stream, version_any) }
|
1252
1205
|
expect(repository.count(specification.result)).to eq(3)
|
1253
1206
|
event_id = SecureRandom.uuid
|
1254
1207
|
repository.append_to_stream([SRecord.new(event_type: Type1.to_s, event_id: event_id)], dummy, version_any)
|
@@ -1261,8 +1214,8 @@ module RubyEventStore
|
|
1261
1214
|
expect(repository.count(specification.with_id([not_existing_uuid]).result)).to eq(0)
|
1262
1215
|
|
1263
1216
|
expect(repository.count(specification.stream(stream.name).result)).to eq(3)
|
1264
|
-
expect(repository.count(specification.stream(
|
1265
|
-
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)
|
1266
1219
|
|
1267
1220
|
repository.append_to_stream([SRecord.new(event_type: Type1.to_s)], dummy, version_any)
|
1268
1221
|
expect(repository.count(specification.from(event_id).result)).to eq(1)
|
@@ -1282,134 +1235,185 @@ module RubyEventStore
|
|
1282
1235
|
expect(repository.count(specification.stream(stream.name).of_type([Type3]).result)).to eq(0)
|
1283
1236
|
end
|
1284
1237
|
|
1285
|
-
specify
|
1286
|
-
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)
|
1287
1240
|
repository.append_to_stream([SRecord.new(timestamp: time)], stream, version_none)
|
1288
1241
|
event = read_events_forward(repository, count: 1).first
|
1289
1242
|
|
1290
1243
|
expect(event.timestamp).to eq(time)
|
1291
1244
|
end
|
1292
1245
|
|
1293
|
-
specify
|
1294
|
-
event_1 = SRecord.new(event_id:
|
1295
|
-
event_2 = SRecord.new(event_id:
|
1296
|
-
event_3 = SRecord.new(event_id:
|
1297
|
-
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)
|
1298
1251
|
|
1299
|
-
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
|
+
)
|
1300
1255
|
end
|
1301
1256
|
|
1302
|
-
specify
|
1303
|
-
event_1 = SRecord.new(event_id:
|
1304
|
-
event_2 = SRecord.new(event_id:
|
1305
|
-
event_3 = SRecord.new(event_id:
|
1306
|
-
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)
|
1307
1262
|
|
1308
|
-
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])
|
1309
1266
|
end
|
1310
1267
|
|
1311
|
-
specify
|
1312
|
-
event_1 = SRecord.new(event_id:
|
1313
|
-
event_2 = SRecord.new(event_id:
|
1314
|
-
event_3 = SRecord.new(event_id:
|
1315
|
-
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)
|
1316
1273
|
|
1317
|
-
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
|
+
)
|
1318
1277
|
end
|
1319
1278
|
|
1320
|
-
specify
|
1321
|
-
event_1 = SRecord.new(event_id:
|
1322
|
-
event_2 = SRecord.new(event_id:
|
1323
|
-
event_3 = SRecord.new(event_id:
|
1324
|
-
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)
|
1325
1284
|
|
1326
|
-
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])
|
1327
1288
|
end
|
1328
1289
|
|
1329
|
-
specify
|
1330
|
-
event_1 = SRecord.new(event_id:
|
1331
|
-
event_2 = SRecord.new(event_id:
|
1332
|
-
event_3 = SRecord.new(event_id:
|
1333
|
-
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)
|
1334
1295
|
|
1335
1296
|
expect(repository.read(specification.older_than(Time.utc(2020, 1, 2)).result).to_a).to eq([event_1])
|
1336
1297
|
end
|
1337
1298
|
|
1338
|
-
specify
|
1339
|
-
event_1 = SRecord.new(event_id:
|
1340
|
-
event_2 = SRecord.new(event_id:
|
1341
|
-
event_3 = SRecord.new(event_id:
|
1342
|
-
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)
|
1343
1304
|
|
1344
|
-
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
|
+
)
|
1345
1308
|
end
|
1346
1309
|
|
1347
|
-
specify
|
1348
|
-
event_1 = SRecord.new(event_id:
|
1349
|
-
event_2 = SRecord.new(event_id:
|
1350
|
-
event_3 = SRecord.new(event_id:
|
1351
|
-
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)
|
1352
1315
|
|
1353
1316
|
expect(repository.read(specification.newer_than(Time.utc(2020, 1, 2)).result).to_a).to eq([event_3])
|
1354
1317
|
end
|
1355
1318
|
|
1356
|
-
specify
|
1357
|
-
event_1 = SRecord.new(event_id:
|
1358
|
-
event_2 = SRecord.new(event_id:
|
1359
|
-
event_3 = SRecord.new(event_id:
|
1360
|
-
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)
|
1361
1324
|
|
1362
|
-
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
|
+
)
|
1363
1328
|
end
|
1364
1329
|
|
1365
|
-
specify
|
1366
|
-
event_1 = SRecord.new(event_id:
|
1367
|
-
event_2 = SRecord.new(event_id:
|
1368
|
-
event_3 = SRecord.new(event_id:
|
1369
|
-
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)
|
1370
1335
|
|
1371
|
-
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([])
|
1372
1339
|
end
|
1373
1340
|
|
1374
|
-
specify
|
1375
|
-
event_1 = SRecord.new(event_id:
|
1376
|
-
event_2 = SRecord.new(event_id:
|
1377
|
-
event_3 = SRecord.new(event_id:
|
1378
|
-
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)
|
1379
1346
|
|
1380
|
-
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
|
+
)
|
1381
1350
|
end
|
1382
1351
|
|
1383
1352
|
specify "time order is respected" do
|
1384
|
-
repository.append_to_stream(
|
1385
|
-
|
1386
|
-
SRecord.new(
|
1387
|
-
|
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))
|
1388
1366
|
],
|
1389
1367
|
Stream.new("Dummy"),
|
1390
1368
|
ExpectedVersion.any
|
1391
1369
|
)
|
1392
|
-
expect(repository.read(specification.result)
|
1393
|
-
expect(repository.read(specification.as_at.result)
|
1394
|
-
expect(repository.read(specification.as_at.backward.result)
|
1395
|
-
expect(repository.read(specification.as_of.result)
|
1396
|
-
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])
|
1397
1375
|
end
|
1398
1376
|
|
1399
1377
|
specify "time order is respected with batches" do
|
1400
|
-
repository.append_to_stream(
|
1401
|
-
|
1402
|
-
|
1403
|
-
|
1404
|
-
|
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
|
+
],
|
1405
1392
|
Stream.new("Dummy"),
|
1406
1393
|
ExpectedVersion.any
|
1407
1394
|
)
|
1408
|
-
expect(repository.read(specification.in_batches.result).to_a.flatten
|
1409
|
-
expect(repository.read(specification.in_batches.as_at.result).to_a.flatten
|
1410
|
-
expect(repository.read(specification.in_batches.as_at.backward.result).to_a.flatten
|
1411
|
-
expect(repository.read(specification.in_batches.as_of.result).to_a.flatten
|
1412
|
-
expect(repository.read(specification.in_batches.as_of.backward.result).to_a.flatten
|
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
|
+
|
1402
|
+
specify "appending empty list of commits should be a no-op" do
|
1403
|
+
repository.append_to_stream(
|
1404
|
+
[],
|
1405
|
+
RubyEventStore::Stream.new(RubyEventStore::GLOBAL_STREAM),
|
1406
|
+
RubyEventStore::ExpectedVersion.any
|
1407
|
+
)
|
1408
|
+
expect(repository.read(specification.result).count).to eq(0)
|
1409
|
+
end
|
1410
|
+
end
|
1411
|
+
|
1412
|
+
::RSpec::Matchers.define :eq_ids do |expected_ids|
|
1413
|
+
match do |enum|
|
1414
|
+
@actual = enum.map(&:event_id)
|
1415
|
+
expected_ids == @actual
|
1413
1416
|
end
|
1417
|
+
diffable
|
1414
1418
|
end
|
1415
1419
|
end
|