@@ -5,123 +5,84 @@ open Propulsion.Streams
5
5
open Swensen.Unquote
6
6
open Xunit
7
7
8
- module FsCodec301 = // Not yet merged, https://github.com/jet/FsCodec/pull/123
9
- open FsCodec
10
- open System
11
- /// <summary>An Event or Unfold that's been read from a Store and hence has a defined <c>Index</c> on the Event Timeline.</summary>
12
- [<NoComparison; NoEquality>]
13
- type TimelineEvent2 < 'Format >( index , eventType , data , meta , eventId , correlationId , causationId , timestamp , isUnfold , context , size ) =
14
-
15
- static member Create ( index , eventType , data , ? meta , ? eventId , ? correlationId , ? causationId , ? timestamp , ? isUnfold , ? context , ? size ): ITimelineEvent < 'Format > =
16
- let isUnfold = defaultArg isUnfold false
17
- let meta = match meta with Some x -> x | None -> Unchecked.defaultof<_>
18
- let eventId = match eventId with Some x -> x | None -> Guid.Empty
19
- let ts = match timestamp with Some ts -> ts | None -> DateTimeOffset.UtcNow
20
- let size = defaultArg size 0
21
- TimelineEvent2( index, eventType, data, meta, eventId, Option.toObj correlationId, Option.toObj causationId, ts, isUnfold, Option.toObj context, size) :> _
22
-
23
- static member Create ( index , inner : IEventData < 'Format >, ? isUnfold , ? context , ? size ): ITimelineEvent < 'Format > =
24
- let isUnfold = defaultArg isUnfold false
25
- let size = defaultArg size 0
26
- TimelineEvent2( index, inner.EventType, inner.Data, inner.Meta, inner.EventId, inner.CorrelationId, inner.CausationId, inner.Timestamp, isUnfold, Option.toObj context, size) :> _
27
-
28
- override _.ToString () =
29
- let t = if isUnfold then " Unfold" else " Event"
30
- $" {t} {eventType} @{index} {context}"
31
- interface ITimelineEvent< 'Format> with
32
- member _.Index = index
33
- member _.IsUnfold = isUnfold
34
- member _.Context = context
35
- member _.Size = size
36
- member _.EventType = eventType
37
- member _.Data = data
38
- member _.Meta = meta
39
- member _.EventId = eventId
40
- member _.CorrelationId = correlationId
41
- member _.CausationId = causationId
42
- member _.Timestamp = timestamp
43
- open FsCodec301
44
-
45
8
let canonicalTime = System.DateTimeOffset.UtcNow
46
9
47
10
let mk_ p c seg uc : FsCodec.ITimelineEvent < string >[] =
48
- let mk id et isUnfold = TimelineEvent2 .Create( id, et, null , timestamp = canonicalTime, isUnfold = isUnfold, context = seg)
11
+ let mk id et isUnfold = FsCodec.Core.TimelineEvent .Create( id, et, null , timestamp = canonicalTime, isUnfold = isUnfold, context = seg)
49
12
[| for x in 0 .. c-1 -> mk ( p + int64 x) ( p + int64 x |> string) false
50
13
for u in 0 .. uc-1 -> mk ( p + int64 c) $" {p+int64 c}u{u}" true |]
51
14
let mk p c = mk_ p c 0 0
52
- let merge = StreamSpan.merge
53
15
let isSame = LanguagePrimitives.PhysicalEquality
54
- let dropBeforeIndex = StreamSpan.dropBeforeIndex
55
16
let is ( xs : FsCodec.ITimelineEvent < string >[][]) ( res : FsCodec.ITimelineEvent < string >[][]) =
56
17
( xs, res) ||> Seq.forall2 ( fun x y -> ( Array.isEmpty x && Array.isEmpty y)
57
18
|| x[ 0 ]. Index = y[ 0 ]. Index && ( x, y) ||> Seq.forall2 ( fun x y -> x.EventType = y.EventType))
58
19
59
20
let [<Fact>] nothing () =
60
- let r = merge 0 L [| mk 0 L 0 ; mk 0 L 0 |]
21
+ let r = StreamSpan. merge 0 L [| mk 0 L 0 ; mk 0 L 0 |]
61
22
test <@ isSame null r @>
62
23
63
24
let [<Fact>] synced () =
64
- let r = merge 1 L [| mk 0 L 1 ; mk 0 L 0 |]
25
+ let r = StreamSpan. merge 1 L [| mk 0 L 1 ; mk 0 L 0 |]
65
26
test <@ isSame null r @>
66
27
67
28
let [<Fact>] ``no overlap`` () =
68
- let r = merge 0 L [| mk 0 L 1 ; mk 2 L 2 |]
29
+ let r = StreamSpan. merge 0 L [| mk 0 L 1 ; mk 2 L 2 |]
69
30
test <@ r |> is [| mk 0 L 1 ; mk 2 L 2 |] @>
70
31
71
32
let [<Fact>] overlap () =
72
- let r = merge 0 L [| mk 0 L 1 ; mk 0 L 2 |]
33
+ let r = StreamSpan. merge 0 L [| mk 0 L 1 ; mk 0 L 2 |]
73
34
test <@ r |> is [| mk 0 L 2 |] @>
74
35
75
36
let [<Fact>] ``remove nulls`` () =
76
- let r = merge 1 L [| mk 0 L 1 ; mk 0 L 2 |]
37
+ let r = StreamSpan. merge 1 L [| mk 0 L 1 ; mk 0 L 2 |]
77
38
test <@ r |> is [| mk 1 L 1 |] @>
78
39
79
40
let [<Fact>] adjacent () =
80
- let r = merge 0 L [| mk 0 L 1 ; mk 1 L 2 |]
41
+ let r = StreamSpan. merge 0 L [| mk 0 L 1 ; mk 1 L 2 |]
81
42
test <@ r |> is [| mk 0 L 3 |] @>
82
43
83
44
let [<Fact>] ``adjacent to min`` () =
84
- let r = Array.map ( dropBeforeIndex 2 L) [| mk 0 L 1 ; mk 1 L 2 |]
45
+ let r = Array.map ( StreamSpan.dropBefore 2 L) [| mk 0 L 1 ; mk 1 L 2 |]
85
46
test <@ r |> is [| [||]; mk 2 L 1 |] @>
86
47
87
48
let [<Fact>] ``adjacent to min merge`` () =
88
- let r = merge 2 L [| mk 0 L 1 ; mk 1 L 2 |]
49
+ let r = StreamSpan. merge 2 L [| mk 0 L 1 ; mk 1 L 2 |]
89
50
test <@ r |> is [| mk 2 L 1 |] @>
90
51
91
52
let [<Fact>] ``adjacent to min no overlap`` () =
92
- let r = merge 2 L [| mk 0 L 1 ; mk 2 L 1 |]
53
+ let r = StreamSpan. merge 2 L [| mk 0 L 1 ; mk 2 L 1 |]
93
54
test <@ r |> is [| mk 2 L 1 |] @>
94
55
95
56
let [<Fact>] ``adjacent trim`` () =
96
- let r = Array.map ( dropBeforeIndex 1 L) [| mk 0 L 2 ; mk 2 L 2 |]
57
+ let r = Array.map ( StreamSpan.dropBefore 1 L) [| mk 0 L 2 ; mk 2 L 2 |]
97
58
test <@ r |> is [| mk 1 L 1 ; mk 2 L 2 |] @>
98
59
99
60
let [<Fact>] ``adjacent trim merge`` () =
100
- let r = merge 1 L [| mk 0 L 2 ; mk 2 L 2 |]
61
+ let r = StreamSpan. merge 1 L [| mk 0 L 2 ; mk 2 L 2 |]
101
62
test <@ r |> is [| mk 1 L 3 |] @>
102
63
103
64
let [<Fact>] ``adjacent trim append`` () =
104
- let r = Array.map ( dropBeforeIndex 1 L) [| mk 0 L 2 ; mk 2 L 2 ; mk 5 L 1 |]
65
+ let r = Array.map ( StreamSpan.dropBefore 1 L) [| mk 0 L 2 ; mk 2 L 2 ; mk 5 L 1 |]
105
66
test <@ r |> is [| mk 1 L 1 ; mk 2 L 2 ; mk 5 L 1 |] @>
106
67
107
68
let [<Fact>] ``adjacent trim append merge`` () =
108
- let r = merge 1 L [| mk 0 L 2 ; mk 2 L 2 ; mk 5 L 1 |]
69
+ let r = StreamSpan. merge 1 L [| mk 0 L 2 ; mk 2 L 2 ; mk 5 L 1 |]
109
70
test <@ r |> is [| mk 1 L 3 ; mk 5 L 1 |] @>
110
71
111
72
let [<Fact>] ``mixed adjacent trim append`` () =
112
- let r = Array.map ( dropBeforeIndex 1 L) [| mk 0 L 2 ; mk 5 L 1 ; mk 2 L 2 |]
73
+ let r = Array.map ( StreamSpan.dropBefore 1 L) [| mk 0 L 2 ; mk 5 L 1 ; mk 2 L 2 |]
113
74
test <@ r |> is [| mk 1 L 1 ; mk 5 L 1 ; mk 2 L 2 |] @>
114
75
115
76
let [<Fact>] ``mixed adjacent trim append merge`` () =
116
- let r = merge 1 L [| mk 0 L 2 ; mk 5 L 1 ; mk 2 L 2 |]
77
+ let r = StreamSpan. merge 1 L [| mk 0 L 2 ; mk 5 L 1 ; mk 2 L 2 |]
117
78
test <@ r |> is [| mk 1 L 3 ; mk 5 L 1 |] @>
118
79
119
80
let [<Fact>] fail () =
120
- let r = merge 11614 L [| null ; mk 11614 L 1 |]
81
+ let r = StreamSpan. merge 11614 L [| null ; mk 11614 L 1 |]
121
82
test <@ r |> is [| mk 11614 L 1 |] @>
122
83
123
84
let [<Fact>] ``fail 2`` () =
124
- let r = merge 11613 L [| mk 11614 L 1 ; null |]
85
+ let r = StreamSpan. merge 11613 L [| mk 11614 L 1 ; null |]
125
86
test <@ r |> is [| mk 11614 L 1 |] @>
126
87
127
88
let (= ==) ( xs: 't seq) ( ys: 't seq) = ( xs, ys) ||> Seq.forall2 isSame
@@ -137,7 +98,7 @@ let [<FsCheck.Xunit.Property(MaxTest = 1000)>] ``merges retain freshest unfolds,
137
98
yield mk_ pos events seg unfolds
138
99
pos <- pos + int64 events
139
100
seg <- seg + 1 |]
140
- let res = merge 0 L input
101
+ let res = StreamSpan. merge 0 L input
141
102
// The only way to end up with a null output is by sending either no spans, or all empties
142
103
if res = null then
143
104
test <@ input |> Array.forall Array.isEmpty @>
@@ -165,7 +126,7 @@ let [<FsCheck.Xunit.Property(MaxTest = 1000)>] ``merges retain freshest unfolds,
165
126
| _ -> true @>
166
127
167
128
// resulting span sequence must be monotonic, with a gap of at least 1 in the Index ranges per span
168
- test <@ res |> Seq.pairwise |> Seq.forall ( fun ( x , y ) -> StreamSpan.nextIndex x < StreamSpan.index y) @>
129
+ test <@ res |> Seq.pairwise |> Seq.forall ( fun ( x , y ) -> StreamSpan.next x < StreamSpan.index y) @>
169
130
170
131
let others = res |> Array.take ( res.Length - 1 )
171
132
// Only the last span can have unfolds
0 commit comments