elm-format
parent
3983ab0de2
commit
db6573180b
5
elm.json
5
elm.json
|
@ -10,12 +10,14 @@
|
|||
"Internal.Config.Log",
|
||||
"Internal.Config.Phantom",
|
||||
"Internal.Config.Text",
|
||||
"Internal.Filter.Timeline",
|
||||
"Internal.Tools.DecodeExtra",
|
||||
"Internal.Tools.EncodeExtra",
|
||||
"Internal.Tools.Hashdict",
|
||||
"Internal.Tools.Iddict",
|
||||
"Internal.Tools.Json",
|
||||
"Internal.Tools.Mashdict",
|
||||
"Internal.Tools.RationalOrder",
|
||||
"Internal.Tools.Timestamp",
|
||||
"Internal.Tools.VersionControl",
|
||||
"Internal.Values.Context",
|
||||
|
@ -27,7 +29,8 @@
|
|||
"Internal.Values.Vault",
|
||||
"Matrix",
|
||||
"Matrix.Event",
|
||||
"Matrix.Settings"
|
||||
"Matrix.Settings",
|
||||
"Types"
|
||||
],
|
||||
"elm-version": "0.19.0 <= v < 0.20.0",
|
||||
"dependencies": {
|
||||
|
|
|
@ -485,18 +485,16 @@ leakingValueFound leaking_value =
|
|||
"Found leaking value : " ++ leaking_value
|
||||
|
||||
|
||||
{-|
|
||||
-}
|
||||
{-| -}
|
||||
logs : { keyIsNotAnInt : String -> String }
|
||||
logs =
|
||||
{ keyIsNotAnInt =
|
||||
(\key ->
|
||||
\key ->
|
||||
String.concat
|
||||
[ "Encountered a key `"
|
||||
, key
|
||||
, "` that cannot be converted to an Int"
|
||||
]
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -161,22 +161,26 @@ and (Filter f1) (Filter f2) =
|
|||
else
|
||||
stdAnd
|
||||
|
||||
|
||||
{-| Define how to encode and decode a Timeline Filter to and from a JSON value.
|
||||
-}
|
||||
coder : Json.Coder Filter
|
||||
coder =
|
||||
Json.object4
|
||||
{ name = Text.docs.timelineFilter.name
|
||||
, description = Text.docs.timelineFilter.description
|
||||
, init =
|
||||
(\a b c d ->
|
||||
\a b c d ->
|
||||
Filter
|
||||
{ senders = a, sendersAllowOthers = b
|
||||
, types = c, typesAllowOthers = d
|
||||
{ senders = a
|
||||
, sendersAllowOthers = b
|
||||
, types = c
|
||||
, typesAllowOthers = d
|
||||
}
|
||||
)
|
||||
}
|
||||
(Json.field.optional.withDefault
|
||||
{ fieldName = "senders"
|
||||
, toField = (\(Filter f) -> f.senders)
|
||||
, toField = \(Filter f) -> f.senders
|
||||
, description = Text.fields.timelineFilter.senders
|
||||
, coder = Json.set Json.string
|
||||
, default = ( Set.empty, [] )
|
||||
|
@ -185,14 +189,14 @@ coder =
|
|||
)
|
||||
(Json.field.required
|
||||
{ fieldName = "sendersAllowOthers"
|
||||
, toField = (\(Filter f) -> f.sendersAllowOthers)
|
||||
, toField = \(Filter f) -> f.sendersAllowOthers
|
||||
, description = Text.fields.timelineFilter.sendersAllowOthers
|
||||
, coder = Json.bool
|
||||
}
|
||||
)
|
||||
(Json.field.optional.withDefault
|
||||
{ fieldName = "types"
|
||||
, toField = (\(Filter f) -> f.types)
|
||||
, toField = \(Filter f) -> f.types
|
||||
, description = Text.fields.timelineFilter.types
|
||||
, coder = Json.set Json.string
|
||||
, default = ( Set.empty, [] )
|
||||
|
@ -201,12 +205,13 @@ coder =
|
|||
)
|
||||
(Json.field.required
|
||||
{ fieldName = "typesAllowOthers"
|
||||
, toField = (\(Filter f) -> f.typesAllowOthers)
|
||||
, toField = \(Filter f) -> f.typesAllowOthers
|
||||
, description = Text.fields.timelineFilter.typesAllowOthers
|
||||
, coder = Json.bool
|
||||
}
|
||||
)
|
||||
|
||||
|
||||
{-| Decode a Filter from a JSON value.
|
||||
-}
|
||||
decoder : Json.Decoder Filter
|
||||
|
|
|
@ -53,6 +53,7 @@ type Iddict a
|
|||
, dict : Dict Int a
|
||||
}
|
||||
|
||||
|
||||
{-| Define how an Iddict can be encoded and decoded to and from a JSON value.
|
||||
-}
|
||||
coder : Json.Coder a -> Json.Coder (Iddict a)
|
||||
|
@ -61,7 +62,7 @@ coder x =
|
|||
{ name = Text.docs.iddict.name
|
||||
, description = Text.docs.iddict.description
|
||||
, init =
|
||||
(\c d ->
|
||||
\c d ->
|
||||
Iddict
|
||||
{ cursor =
|
||||
Dict.keys d
|
||||
|
@ -72,11 +73,10 @@ coder x =
|
|||
|> max c
|
||||
, dict = d
|
||||
}
|
||||
)
|
||||
}
|
||||
(Json.field.optional.withDefault
|
||||
{ fieldName = "cursor"
|
||||
, toField = (\(Iddict i) -> i.cursor)
|
||||
, toField = \(Iddict i) -> i.cursor
|
||||
, description = Text.fields.iddict.cursor
|
||||
, coder = Json.int
|
||||
, default = ( 0, [] )
|
||||
|
@ -85,12 +85,13 @@ coder x =
|
|||
)
|
||||
(Json.field.required
|
||||
{ fieldName = "dict"
|
||||
, toField = (\(Iddict i) -> i.dict)
|
||||
, toField = \(Iddict i) -> i.dict
|
||||
, description = Text.fields.iddict.dict
|
||||
, coder = Json.fastIntDict x
|
||||
}
|
||||
)
|
||||
|
||||
|
||||
{-| Decode an id-dict from a JSON value.
|
||||
-}
|
||||
decoder : Json.Coder a -> Json.Decoder (Iddict a)
|
||||
|
|
|
@ -294,6 +294,7 @@ fastDict (Coder old) =
|
|||
, docs = DocsDict old.docs
|
||||
}
|
||||
|
||||
|
||||
{-| Define a fast dict where the keys are integers, not strings.
|
||||
-}
|
||||
fastIntDict : Coder value -> Coder (FastDict.Dict Int value)
|
||||
|
@ -335,6 +336,7 @@ fastIntDict (Coder old) =
|
|||
, docs = DocsIntDict old.docs
|
||||
}
|
||||
|
||||
|
||||
{-| Create a new field using any of the three provided options.
|
||||
|
||||
For example, suppose we are creating a `Field String User` to represent the
|
||||
|
@ -509,12 +511,13 @@ list (Coder old) =
|
|||
, docs = DocsList old.docs
|
||||
}
|
||||
|
||||
|
||||
{-| Define a list that has at least one value
|
||||
-}
|
||||
listWithOne : Coder a -> Coder ( a, List a )
|
||||
listWithOne (Coder old) =
|
||||
Coder
|
||||
{ encoder = (\(h, t) -> E.list old.encoder (h :: t))
|
||||
{ encoder = \( h, t ) -> E.list old.encoder (h :: t)
|
||||
, decoder =
|
||||
old.decoder
|
||||
|> D.list
|
||||
|
@ -1170,6 +1173,7 @@ set (Coder data) =
|
|||
, docs = DocsSet data.docs
|
||||
}
|
||||
|
||||
|
||||
{-| Define a slow dict from the `elm/core` library.
|
||||
-}
|
||||
slowDict : Coder value -> Coder (SlowDict.Dict String value)
|
||||
|
|
|
@ -2,7 +2,7 @@ module Internal.Values.Timeline exposing
|
|||
( Batch, Timeline
|
||||
, empty, singleton
|
||||
, mostRecentEvents, mostRecentEventsFrom
|
||||
, insert, addSync
|
||||
, addSync, insert
|
||||
, coder, encode, decoder
|
||||
)
|
||||
|
||||
|
@ -67,11 +67,11 @@ events!
|
|||
-}
|
||||
|
||||
import FastDict as Dict exposing (Dict)
|
||||
import Internal.Config.Text as Text
|
||||
import Internal.Filter.Timeline as Filter exposing (Filter)
|
||||
import Internal.Tools.Hashdict as Hashdict exposing (Hashdict)
|
||||
import Internal.Tools.Iddict as Iddict exposing (Iddict)
|
||||
import Internal.Tools.Json as Json
|
||||
import Internal.Config.Text as Text
|
||||
import Recursion
|
||||
import Recursion.Traverse
|
||||
import Set exposing (Set)
|
||||
|
@ -82,6 +82,7 @@ that require an insertion, generally require this data type.
|
|||
|
||||
If the `start` value is `Nothing`, it is either the start of the timeline or the
|
||||
start of the timeline part that the user is allowed to view.
|
||||
|
||||
-}
|
||||
type alias Batch =
|
||||
{ events : List String
|
||||
|
@ -167,6 +168,7 @@ type Timeline
|
|||
type alias TokenValue =
|
||||
String
|
||||
|
||||
|
||||
{-| Add a new batch as a sync
|
||||
-}
|
||||
addSync : Batch -> Timeline -> Timeline
|
||||
|
@ -175,15 +177,18 @@ addSync batch timeline =
|
|||
( Timeline t, { start, end } ) ->
|
||||
let
|
||||
old : ITokenPTR
|
||||
old = t.mostRecentBatch
|
||||
old =
|
||||
t.mostRecentBatch
|
||||
in
|
||||
case Timeline { t | mostRecentBatch = end } of
|
||||
tl ->
|
||||
if old == start then
|
||||
tl
|
||||
|
||||
else
|
||||
connectITokenToIToken old start tl
|
||||
|
||||
|
||||
{-| Define how a Timeline can be encoded and decoded to and from a JSON value.
|
||||
-}
|
||||
coder : Json.Coder Timeline
|
||||
|
@ -192,30 +197,32 @@ coder =
|
|||
{ name = Text.docs.timeline.name
|
||||
, description = Text.docs.timeline.description
|
||||
, init =
|
||||
(\a b c d e ->
|
||||
\a b c d e ->
|
||||
Timeline
|
||||
{ batches = a, events = b, filledBatches = c
|
||||
, mostRecentBatch = d, tokens = e
|
||||
{ batches = a
|
||||
, events = b
|
||||
, filledBatches = c
|
||||
, mostRecentBatch = d
|
||||
, tokens = e
|
||||
}
|
||||
)
|
||||
}
|
||||
(Json.field.required
|
||||
{ fieldName = "batches"
|
||||
, toField = (\(Timeline t) -> t.batches)
|
||||
, toField = \(Timeline t) -> t.batches
|
||||
, description = Text.fields.timeline.batches
|
||||
, coder = Iddict.coder coderIBatch
|
||||
}
|
||||
)
|
||||
(Json.field.required
|
||||
{ fieldName = "events"
|
||||
, toField = (\(Timeline t) -> t.events)
|
||||
, toField = \(Timeline t) -> t.events
|
||||
, description = Text.fields.timeline.events
|
||||
, coder = Json.fastDict (Json.listWithOne coderIBatchPTR)
|
||||
}
|
||||
)
|
||||
(Json.field.optional.withDefault
|
||||
{ fieldName = "filledBatches"
|
||||
, toField = (\(Timeline t) -> t.filledBatches)
|
||||
, toField = \(Timeline t) -> t.filledBatches
|
||||
, description = Text.fields.timeline.filledBatches
|
||||
, coder = Json.int
|
||||
, default = ( 0, [] )
|
||||
|
@ -224,19 +231,20 @@ coder =
|
|||
)
|
||||
(Json.field.required
|
||||
{ fieldName = "mostRecentBatch"
|
||||
, toField = (\(Timeline t) -> t.mostRecentBatch)
|
||||
, toField = \(Timeline t) -> t.mostRecentBatch
|
||||
, description = Text.fields.timeline.mostRecentBatch
|
||||
, coder = coderITokenPTR
|
||||
}
|
||||
)
|
||||
(Json.field.required
|
||||
{ fieldName = "tokens"
|
||||
, toField = (\(Timeline t) -> t.tokens)
|
||||
, toField = \(Timeline t) -> t.tokens
|
||||
, description = Text.fields.timeline.tokens
|
||||
, coder = Hashdict.coder .name coderIToken
|
||||
}
|
||||
)
|
||||
|
||||
|
||||
{-| Define how to encode and decode a IBatch to and from a JSON value.
|
||||
-}
|
||||
coderIBatch : Json.Coder IBatch
|
||||
|
@ -275,6 +283,7 @@ coderIBatch =
|
|||
}
|
||||
)
|
||||
|
||||
|
||||
{-| Define how to encode and decode a IBatchPTR to and from a JSON value.
|
||||
-}
|
||||
coderIBatchPTR : Json.Coder IBatchPTR
|
||||
|
@ -282,15 +291,18 @@ coderIBatchPTR =
|
|||
Json.map
|
||||
{ name = Text.docs.itoken.name
|
||||
, description = Text.docs.itoken.description
|
||||
, back = (\(IBatchPTR value) -> value)
|
||||
, back = \(IBatchPTR value) -> value
|
||||
, forth = IBatchPTR
|
||||
}
|
||||
coderIBatchPTRValue
|
||||
|
||||
|
||||
{-| Define how to encode and decode a IBatchPTRValue to and from a JSON value.
|
||||
-}
|
||||
coderIBatchPTRValue : Json.Coder IBatchPTRValue
|
||||
coderIBatchPTRValue = Json.int
|
||||
coderIBatchPTRValue =
|
||||
Json.int
|
||||
|
||||
|
||||
{-| Define how to encode and decode a IToken to and from a JSON value.
|
||||
-}
|
||||
|
@ -345,6 +357,7 @@ coderIToken =
|
|||
}
|
||||
)
|
||||
|
||||
|
||||
{-| Define how to encode and decode a ITokenPTR to and from a JSON value.
|
||||
-}
|
||||
coderITokenPTR : Json.Coder ITokenPTR
|
||||
|
@ -354,34 +367,37 @@ coderITokenPTR =
|
|||
{ name = Text.mappings.itokenPTR.name
|
||||
, description = Text.mappings.itokenPTR.description
|
||||
, back =
|
||||
(\itokenptr ->
|
||||
\itokenptr ->
|
||||
case itokenptr of
|
||||
ITokenPTR name ->
|
||||
Just name
|
||||
|
||||
StartOfTimeline ->
|
||||
Nothing
|
||||
)
|
||||
, forth =
|
||||
(\value ->
|
||||
\value ->
|
||||
case value of
|
||||
Just name ->
|
||||
ITokenPTR name
|
||||
|
||||
Nothing ->
|
||||
StartOfTimeline
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
{-| Define how to encode and decode a ITokenPTRValue to and from a JSON value.
|
||||
-}
|
||||
coderITokenPTRValue : Json.Coder ITokenPTRValue
|
||||
coderITokenPTRValue = Json.string
|
||||
coderITokenPTRValue =
|
||||
Json.string
|
||||
|
||||
|
||||
{-| Define how to encode and decode a TokenValue to and from a JSON value.
|
||||
-}
|
||||
coderTokenValue : Json.Coder TokenValue
|
||||
coderTokenValue = Json.string
|
||||
coderTokenValue =
|
||||
Json.string
|
||||
|
||||
|
||||
{-| Append a token at the end of a batch.
|
||||
-}
|
||||
|
@ -454,10 +470,13 @@ connectITokenToIToken pointer1 pointer2 (Timeline tl) =
|
|||
( _, _ ) ->
|
||||
Timeline tl
|
||||
|
||||
|
||||
{-| Timeline JSON decoder that helps decode a Timeline from JSON.
|
||||
-}
|
||||
decoder : Json.Decoder Timeline
|
||||
decoder = Json.decode coder
|
||||
decoder =
|
||||
Json.decode coder
|
||||
|
||||
|
||||
{-| Create a new empty timeline.
|
||||
-}
|
||||
|
@ -471,10 +490,13 @@ empty =
|
|||
, tokens = Hashdict.empty .name
|
||||
}
|
||||
|
||||
|
||||
{-| Directly encode a Timeline into a JSON value.
|
||||
-}
|
||||
encode : Json.Encoder Timeline
|
||||
encode = Json.encode coder
|
||||
encode =
|
||||
Json.encode coder
|
||||
|
||||
|
||||
{-| Get an IBatch from the Timeline.
|
||||
-}
|
||||
|
@ -608,6 +630,7 @@ mostRecentEvents : Filter -> Timeline -> List (List String)
|
|||
mostRecentEvents filter (Timeline timeline) =
|
||||
mostRecentFrom filter (Timeline timeline) timeline.mostRecentBatch
|
||||
|
||||
|
||||
{-| Instead of finding the most recent events from the latest sync, users can
|
||||
also find the most recent events given a token value.
|
||||
-}
|
||||
|
|
|
@ -3,11 +3,11 @@ module Test.Values.Timeline exposing (..)
|
|||
import Expect
|
||||
import Fuzz exposing (Fuzzer)
|
||||
import Internal.Filter.Timeline as Filter exposing (Filter)
|
||||
import Internal.Tools.Json as Json
|
||||
import Internal.Values.Timeline as Timeline exposing (Batch, Timeline)
|
||||
import Json.Decode as D
|
||||
import Test exposing (..)
|
||||
import Test.Filter.Timeline as TestFilter
|
||||
import Internal.Tools.Json as Json
|
||||
|
||||
|
||||
fuzzer : Fuzzer Timeline
|
||||
|
@ -216,7 +216,9 @@ suite =
|
|||
|> Timeline.mostRecentEventsFrom filter "token_4"
|
||||
|> Expect.equal [ [ "d", "e", "f" ] ]
|
||||
)
|
||||
, fuzz3 TestFilter.fuzzer (Fuzz.list Fuzz.string) (Fuzz.pair (Fuzz.list Fuzz.string) (Fuzz.list Fuzz.string))
|
||||
, fuzz3 TestFilter.fuzzer
|
||||
(Fuzz.list Fuzz.string)
|
||||
(Fuzz.pair (Fuzz.list Fuzz.string) (Fuzz.list Fuzz.string))
|
||||
"Gaps can be bridged"
|
||||
(\filter l1 ( l2, l3 ) ->
|
||||
Timeline.empty
|
||||
|
@ -243,7 +245,8 @@ suite =
|
|||
)
|
||||
]
|
||||
, describe "JSON"
|
||||
[ fuzz fuzzer "Encode + Decode gives same output"
|
||||
[ fuzz fuzzer
|
||||
"Encode + Decode gives same output"
|
||||
(\timeline ->
|
||||
timeline
|
||||
|> Json.encode Timeline.coder
|
||||
|
@ -254,7 +257,8 @@ suite =
|
|||
)
|
||||
]
|
||||
, describe "Weird loops"
|
||||
[ fuzz TestFilter.fuzzer "Weird loops stop looping"
|
||||
[ fuzz TestFilter.fuzzer
|
||||
"Weird loops stop looping"
|
||||
(\filter ->
|
||||
Timeline.empty
|
||||
|> Timeline.insert
|
||||
|
@ -283,7 +287,8 @@ suite =
|
|||
)
|
||||
]
|
||||
, describe "Sync"
|
||||
[ fuzz TestFilter.fuzzer "Sync fills gaps"
|
||||
[ fuzz TestFilter.fuzzer
|
||||
"Sync fills gaps"
|
||||
(\filter ->
|
||||
Timeline.empty
|
||||
|> Timeline.addSync
|
||||
|
@ -307,7 +312,8 @@ suite =
|
|||
|> Timeline.mostRecentEvents filter
|
||||
|> Expect.equal [ [ "a", "b", "c", "d", "e", "f", "g", "h" ] ]
|
||||
)
|
||||
, fuzz TestFilter.fuzzer "Sync doesn't fill open gaps"
|
||||
, fuzz TestFilter.fuzzer
|
||||
"Sync doesn't fill open gaps"
|
||||
(\filter ->
|
||||
Timeline.empty
|
||||
|> Timeline.addSync
|
||||
|
@ -325,11 +331,15 @@ suite =
|
|||
|> Timeline.mostRecentEvents filter
|
||||
|> Expect.equal [ [ "f", "g", "h" ] ]
|
||||
)
|
||||
, fuzz3 (Fuzz.pair Fuzz.string Fuzz.string) fuzzer TestFilter.fuzzer "Getting /sync is the same as getting from the token"
|
||||
, fuzz3 (Fuzz.pair Fuzz.string Fuzz.string)
|
||||
fuzzer
|
||||
TestFilter.fuzzer
|
||||
"Getting /sync is the same as getting from the token"
|
||||
(\( start, end ) timeline filter ->
|
||||
let
|
||||
t : Timeline
|
||||
t = Timeline.addSync
|
||||
t =
|
||||
Timeline.addSync
|
||||
{ events = [ "a", "b", "c" ]
|
||||
, filter = filter
|
||||
, start = Just start
|
||||
|
@ -341,7 +351,8 @@ suite =
|
|||
(Timeline.mostRecentEvents filter t)
|
||||
(Timeline.mostRecentEventsFrom filter end t)
|
||||
)
|
||||
, fuzz TestFilter.fuzzer "Weird loops stop looping"
|
||||
, fuzz TestFilter.fuzzer
|
||||
"Weird loops stop looping"
|
||||
(\filter ->
|
||||
Timeline.empty
|
||||
|> Timeline.insert
|
||||
|
|
Loading…
Reference in New Issue