Complete Timeline by fixing bugs

pull/17/head
Bram 2024-02-15 13:15:19 +01:00
parent 10c7075bef
commit 7acae258ed
2 changed files with 172 additions and 44 deletions

View File

@ -1,9 +1,8 @@
module Internal.Values.Timeline exposing module Internal.Values.Timeline exposing
( Batch, Timeline ( Batch, Timeline
, empty, singleton , empty, singleton
, mostRecentEvents , mostRecentEvents, mostRecentEventsFrom
, insert , insert
, encode, decoder
) )
{-| {-|
@ -52,7 +51,7 @@ events!
## Query ## Query
@docs mostRecentEvents @docs mostRecentEvents, mostRecentEventsFrom
## Manipulate ## Manipulate
@ -381,14 +380,19 @@ invokeIToken value (Timeline tl) =
-} -}
mostRecentEvents : Filter -> Timeline -> List (List String) mostRecentEvents : Filter -> Timeline -> List (List String)
mostRecentEvents filter (Timeline timeline) = mostRecentEvents filter (Timeline timeline) =
mostRecentEventsFrom filter (Timeline timeline) timeline.mostRecentBatch mostRecentFrom filter (Timeline timeline) timeline.mostRecentBatch
mostRecentEventsFrom : Filter -> ITokenPTRValue -> Timeline -> List (List String)
mostRecentEventsFrom filter tokenName timeline =
mostRecentFrom filter timeline (ITokenPTR tokenName)
{-| Under a given filter, starting from a given ITokenPTR, find the most recent {-| Under a given filter, starting from a given ITokenPTR, find the most recent
events. events.
-} -}
mostRecentEventsFrom : Filter -> Timeline -> ITokenPTR -> List (List String) mostRecentFrom : Filter -> Timeline -> ITokenPTR -> List (List String)
mostRecentEventsFrom filter timeline ptr = mostRecentFrom filter timeline ptr =
Recursion.runRecursion Recursion.runRecursion
(\p -> (\p ->
case getITokenFromPTR p.ptr timeline of case getITokenFromPTR p.ptr timeline of
@ -409,12 +413,18 @@ mostRecentEventsFrom filter timeline ptr =
Recursion.recurseThen Recursion.recurseThen
{ ptr = ibatch.start, visited = Set.insert token.name p.visited } { ptr = ibatch.start, visited = Set.insert token.name p.visited }
(\optionalTimelines -> (\optionalTimelines ->
optionalTimelines case optionalTimelines of
|> List.map [] ->
(\outTimeline -> List.singleton ibatch.events
List.append outTimeline ibatch.events |> Recursion.base
)
|> Recursion.base _ :: _ ->
optionalTimelines
|> List.map
(\outTimeline ->
List.append outTimeline ibatch.events
)
|> Recursion.base
) )
) )
|> Recursion.map List.concat |> Recursion.map List.concat
@ -443,4 +453,4 @@ most recent batch, as if created by a sync.
-} -}
singleton : Batch -> Timeline singleton : Batch -> Timeline
singleton b = singleton b =
addSync b empty insert b empty

View File

@ -21,7 +21,7 @@ fuzzer =
List.foldl List.foldl
(\b ( s, f ) -> (\b ( s, f ) ->
( b.end ( b.end
, f >> Timeline.addSync { b | start = Just s, filter = globalFilter } , f >> Timeline.insert { b | start = Just s, filter = globalFilter }
) )
) )
( start, identity ) ( start, identity )
@ -59,41 +59,159 @@ fuzzerBatch =
Fuzz.string Fuzz.string
isEqual : Timeline -> Timeline -> Expect.Expectation
isEqual t1 t2 =
Expect.equal
(E.encode 0 <| Timeline.encode t1)
(E.encode 0 <| Timeline.encode t2)
suite : Test suite : Test
suite = suite =
describe "Timeline" describe "Timeline"
[ describe "empty" [ describe "most recent events with filters"
[ fuzz fuzzerBatch [ fuzz TestFilter.fuzzer
"singleton = empty + sync" "Events are returned properly"
(\batch -> (\filter ->
isEqual Timeline.empty
(Timeline.singleton batch) |> Timeline.insert
(Timeline.addSync batch Timeline.empty) { events = [ "a", "b", "c" ]
, filter = filter
, start = Just "token_1"
, end = "token_2"
}
|> Timeline.insert
{ events = [ "d", "e", "f" ]
, filter = filter
, start = Just "token_2"
, end = "token_3"
}
|> Timeline.mostRecentEventsFrom filter "token_3"
|> Expect.equal
[ [ "a", "b", "c", "d", "e", "f" ] ]
) )
] , fuzz2 TestFilter.fuzzer
, describe "JSON" TestFilter.fuzzer
[ fuzz fuzzer "Sub-events get the same results"
"encode -> decode is same" (\f1 f2 ->
(\timeline -> let
timeline subFilter =
|> Timeline.encode Filter.and f1 f2
|> E.encode 0 in
|> D.decodeString Timeline.decoder Timeline.empty
|> (\t -> |> Timeline.insert
case t of { events = [ "a", "b", "c" ]
Ok v -> , filter = f1
isEqual v timeline , start = Just "token_1"
, end = "token_2"
Err e -> }
Expect.fail (D.errorToString e) |> Timeline.insert
{ events = [ "d", "e", "f" ]
, filter = f1
, start = Just "token_2"
, end = "token_3"
}
|> Timeline.mostRecentEventsFrom subFilter "token_3"
|> Expect.equal
[ [ "a", "b", "c", "d", "e", "f" ] ]
)
, fuzz2 TestFilter.fuzzer
TestFilter.fuzzer
"ONLY same result if sub-filter"
(\f1 f2 ->
Timeline.empty
|> Timeline.insert
{ events = [ "a", "b", "c" ]
, filter = f1
, start = Just "token_1"
, end = "token_2"
}
|> Timeline.insert
{ events = [ "d", "e", "f" ]
, filter = f1
, start = Just "token_2"
, end = "token_3"
}
|> Timeline.mostRecentEventsFrom f2 "token_3"
|> (\events ->
Expect.equal
(Filter.subsetOf f1 f2)
(events == [ [ "a", "b", "c", "d", "e", "f" ] ])
) )
) )
] ]
, describe "Forks in the road"
[ fuzz2 TestFilter.fuzzer
TestFilter.fuzzer
"Two options returned"
(\f1 f2 ->
let
subFilter =
Filter.and f1 f2
in
Timeline.empty
|> Timeline.insert
{ events = [ "a", "b", "c" ]
, filter = f1
, start = Just "token_1"
, end = "token_2"
}
|> Timeline.insert
{ events = [ "d", "e", "f" ]
, filter = f2
, start = Just "token_3"
, end = "token_2"
}
|> Timeline.insert
{ events = [ "g", "h", "i" ]
, filter = subFilter
, start = Just "token_2"
, end = "token_4"
}
|> Timeline.mostRecentEventsFrom subFilter "token_4"
|> Expect.equal
[ [ "a", "b", "c", "g", "h", "i" ]
, [ "d", "e", "f", "g", "h", "i" ]
]
)
]
, describe "Gaps"
[ fuzz TestFilter.fuzzer
"Gap leaves behind old events"
(\filter ->
Timeline.empty
|> Timeline.insert
{ events = [ "a", "b", "c" ]
, filter = filter
, start = Just "token_1"
, end = "token_2"
}
|> Timeline.insert
{ events = [ "d", "e", "f" ]
, filter = filter
, start = Just "token_3"
, end = "token_4"
}
|> Timeline.mostRecentEventsFrom filter "token_4"
|> Expect.equal [ [ "d", "e", "f" ] ]
)
, fuzz TestFilter.fuzzer
"Gap can be bridged"
(\filter ->
Timeline.empty
|> Timeline.insert
{ events = [ "a", "b", "c" ]
, filter = filter
, start = Just "token_1"
, end = "token_2"
}
|> Timeline.insert
{ events = [ "d", "e", "f" ]
, filter = filter
, start = Just "token_3"
, end = "token_4"
}
|> Timeline.insert
{ events = [ "g", "h" ]
, filter = filter
, start = Just "token_2"
, end = "token_3"
}
|> Timeline.mostRecentEventsFrom filter "token_4"
|> Expect.equal [ [ "a", "b", "c", "g", "h", "d", "e", "f" ] ]
)
]
] ]