commit
cee2b3a5bb
2
elm.json
2
elm.json
|
@ -6,6 +6,7 @@
|
|||
"version": "2.0.0",
|
||||
"exposed-modules": [
|
||||
"Matrix",
|
||||
"Matrix.Event",
|
||||
"Matrix.Settings",
|
||||
"Internal.Config.Default",
|
||||
"Internal.Config.Leaks",
|
||||
|
@ -19,6 +20,7 @@
|
|||
"Internal.Values.Context",
|
||||
"Internal.Values.Envelope",
|
||||
"Internal.Values.Event",
|
||||
"Internal.Values.Settings",
|
||||
"Internal.Values.Vault",
|
||||
"Types"
|
||||
],
|
||||
|
|
|
@ -46,6 +46,7 @@ import Internal.Config.Default as Default
|
|||
import Internal.Tools.Decode as D
|
||||
import Internal.Tools.Encode as E
|
||||
import Internal.Values.Context as Context exposing (Context)
|
||||
import Internal.Values.Settings as Settings
|
||||
import Json.Decode as D
|
||||
import Json.Encode as E
|
||||
|
||||
|
@ -55,26 +56,19 @@ need the same values. The Envelope type wraps settings, tokens and values around
|
|||
each data type so they can all enjoy those values without needing to explicitly
|
||||
define them in their type.
|
||||
-}
|
||||
type Envelope a
|
||||
= Envelope
|
||||
{ content : a
|
||||
, context : Context
|
||||
, settings : Settings
|
||||
}
|
||||
type alias Envelope a =
|
||||
{ content : a
|
||||
, context : Context
|
||||
, settings : Settings
|
||||
}
|
||||
|
||||
|
||||
{-| Custom settings that can be manipulated by the user. These serve as a
|
||||
configuration for how the Elm SDK should behave.
|
||||
|
||||
Custom settings are always part of the Envelope, allowing all functions to
|
||||
behave under the user's preferred settings.
|
||||
|
||||
{-| Settings value from
|
||||
[Internal.Values.Settings](Internal-Values-Settings#Settings). Can be used to
|
||||
manipulate the Matrix Vault.
|
||||
-}
|
||||
type alias Settings =
|
||||
{ currentVersion : String
|
||||
, deviceName : String
|
||||
, syncTime : Int
|
||||
}
|
||||
Settings.Settings
|
||||
|
||||
|
||||
{-| Decode an enveloped type from a JSON value. The decoder also imports any
|
||||
|
@ -82,67 +76,25 @@ potential tokens, values and settings included in the JSON.
|
|||
-}
|
||||
decoder : D.Decoder a -> D.Decoder (Envelope a)
|
||||
decoder xDecoder =
|
||||
D.map3 (\a b c -> Envelope { content = a, context = b, settings = c })
|
||||
D.map3 Envelope
|
||||
(D.field "content" xDecoder)
|
||||
(D.field "context" Context.decoder)
|
||||
(D.field "settings" decoderSettings)
|
||||
|
||||
|
||||
{-| Decode settings from a JSON value.
|
||||
-}
|
||||
decoderSettings : D.Decoder Settings
|
||||
decoderSettings =
|
||||
D.map3 Settings
|
||||
(D.opFieldWithDefault "currentVersion" Default.currentVersion D.string)
|
||||
(D.opFieldWithDefault "deviceName" Default.deviceName D.string)
|
||||
(D.opFieldWithDefault "syncTime" Default.syncTime D.int)
|
||||
(D.field "settings" Settings.decoder)
|
||||
|
||||
|
||||
{-| Encode an enveloped type into a JSON value. The function encodes all
|
||||
non-standard settings, tokens and values.
|
||||
-}
|
||||
encode : (a -> E.Value) -> Envelope a -> E.Value
|
||||
encode encodeX (Envelope data) =
|
||||
encode encodeX data =
|
||||
E.object
|
||||
[ ( "content", encodeX data.content )
|
||||
, ( "context", Context.encode data.context )
|
||||
, ( "settings", encodeSettings data.settings )
|
||||
, ( "settings", Settings.encode data.settings )
|
||||
, ( "version", E.string Default.currentVersion )
|
||||
]
|
||||
|
||||
|
||||
{-| Encode the settings into a JSON value.
|
||||
-}
|
||||
encodeSettings : Settings -> E.Value
|
||||
encodeSettings settings =
|
||||
let
|
||||
differentFrom : b -> b -> Maybe b
|
||||
differentFrom defaultValue currentValue =
|
||||
if currentValue == defaultValue then
|
||||
Nothing
|
||||
|
||||
else
|
||||
Just currentValue
|
||||
in
|
||||
E.maybeObject
|
||||
[ ( "currentVersion"
|
||||
, settings.currentVersion
|
||||
|> differentFrom Default.currentVersion
|
||||
|> Maybe.map E.string
|
||||
)
|
||||
, ( "deviceName"
|
||||
, settings.deviceName
|
||||
|> differentFrom Default.deviceName
|
||||
|> Maybe.map E.string
|
||||
)
|
||||
, ( "syncTime"
|
||||
, settings.syncTime
|
||||
|> differentFrom Default.syncTime
|
||||
|> Maybe.map E.int
|
||||
)
|
||||
]
|
||||
|
||||
|
||||
{-| Map a function, then get its content. This is useful for getting information
|
||||
from a data type inside an Envelope.
|
||||
|
||||
|
@ -155,7 +107,7 @@ from a data type inside an Envelope.
|
|||
|
||||
-}
|
||||
extract : (a -> b) -> Envelope a -> b
|
||||
extract f (Envelope data) =
|
||||
extract f data =
|
||||
f data.content
|
||||
|
||||
|
||||
|
@ -165,7 +117,7 @@ This can be helpful if you have a UI that displays custom settings to a user.
|
|||
|
||||
-}
|
||||
extractSettings : (Settings -> b) -> Envelope a -> b
|
||||
extractSettings f (Envelope data) =
|
||||
extractSettings f data =
|
||||
f data.settings
|
||||
|
||||
|
||||
|
@ -186,15 +138,10 @@ from the [Internal.Config.Default](Internal-Config-Default) module.
|
|||
-}
|
||||
init : a -> Envelope a
|
||||
init x =
|
||||
Envelope
|
||||
{ content = x
|
||||
, context = Context.init
|
||||
, settings =
|
||||
{ currentVersion = Default.currentVersion
|
||||
, deviceName = Default.deviceName
|
||||
, syncTime = Default.syncTime
|
||||
}
|
||||
}
|
||||
{ content = x
|
||||
, context = Context.init
|
||||
, settings = Settings.init
|
||||
}
|
||||
|
||||
|
||||
{-| Map a function on the content of the Envelope.
|
||||
|
@ -208,23 +155,18 @@ init x =
|
|||
|
||||
-}
|
||||
map : (a -> b) -> Envelope a -> Envelope b
|
||||
map f (Envelope data) =
|
||||
Envelope
|
||||
{ content = f data.content
|
||||
, context = data.context
|
||||
, settings = data.settings
|
||||
}
|
||||
map f data =
|
||||
{ content = f data.content
|
||||
, context = data.context
|
||||
, settings = data.settings
|
||||
}
|
||||
|
||||
|
||||
{-| Update the Context in the Envelope.
|
||||
-}
|
||||
mapContext : (Context -> Context) -> Envelope a -> Envelope a
|
||||
mapContext f (Envelope data) =
|
||||
Envelope
|
||||
{ content = data.content
|
||||
, context = f data.context
|
||||
, settings = data.settings
|
||||
}
|
||||
mapContext f data =
|
||||
{ data | context = f data.context }
|
||||
|
||||
|
||||
{-| Map the contents of a function, where the result is wrapped in a `List`
|
||||
|
@ -279,23 +221,19 @@ mapMaybe f =
|
|||
|
||||
-}
|
||||
mapSettings : (Settings -> Settings) -> Envelope a -> Envelope a
|
||||
mapSettings f (Envelope data) =
|
||||
Envelope
|
||||
{ content = data.content
|
||||
, context = data.context
|
||||
, settings = f data.settings
|
||||
}
|
||||
mapSettings f data =
|
||||
{ data | settings = f data.settings }
|
||||
|
||||
|
||||
toList : Envelope (List a) -> List (Envelope a)
|
||||
toList (Envelope data) =
|
||||
toList data =
|
||||
List.map
|
||||
(\content -> map (always content) (Envelope data))
|
||||
(\content -> map (always content) data)
|
||||
data.content
|
||||
|
||||
|
||||
toMaybe : Envelope (Maybe a) -> Maybe (Envelope a)
|
||||
toMaybe (Envelope data) =
|
||||
toMaybe data =
|
||||
Maybe.map
|
||||
(\content -> map (always content) (Envelope data))
|
||||
(\content -> map (always content) data)
|
||||
data.content
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
module Internal.Values.Event exposing
|
||||
( Event
|
||||
, UnsignedData, age, prevContent, redactedBecause, transactionId
|
||||
, UnsignedData(..), age, prevContent, redactedBecause, transactionId
|
||||
, encode, decoder
|
||||
)
|
||||
|
||||
|
@ -122,7 +122,9 @@ encodeUnsignedData (UnsignedData data) =
|
|||
]
|
||||
|
||||
|
||||
{-| Get the old content, if the event has changed or it has been edited.
|
||||
{-| Determine the previous `content` value for this event. This field is only a
|
||||
`Just value` if the event is a state event, and the Matrix Vault has permission
|
||||
to see the previous content.
|
||||
-}
|
||||
prevContent : Event -> Maybe E.Value
|
||||
prevContent event =
|
||||
|
|
|
@ -0,0 +1,93 @@
|
|||
module Internal.Values.Settings exposing
|
||||
( Settings, init
|
||||
, encode, decoder
|
||||
)
|
||||
|
||||
{-|
|
||||
|
||||
|
||||
# Settings
|
||||
|
||||
The Settings module exposes a data type to configure settings in the enveloped
|
||||
data types.
|
||||
|
||||
@docs Settings, init
|
||||
|
||||
|
||||
## JSON coders
|
||||
|
||||
@docs encode, decoder
|
||||
|
||||
-}
|
||||
|
||||
import Internal.Config.Default as Default
|
||||
import Internal.Tools.Decode as D
|
||||
import Internal.Tools.Encode as E
|
||||
import Json.Decode as D
|
||||
import Json.Encode as E
|
||||
|
||||
|
||||
{-| Custom settings that can be manipulated by the user. These serve as a
|
||||
configuration for how the Elm SDK should behave.
|
||||
|
||||
Custom settings are always part of the Envelope, allowing all functions to
|
||||
behave under the user's preferred settings.
|
||||
|
||||
-}
|
||||
type alias Settings =
|
||||
{ currentVersion : String
|
||||
, deviceName : String
|
||||
, syncTime : Int
|
||||
}
|
||||
|
||||
|
||||
{-| Decode settings from a JSON value.
|
||||
-}
|
||||
decoder : D.Decoder Settings
|
||||
decoder =
|
||||
D.map3 Settings
|
||||
(D.opFieldWithDefault "currentVersion" Default.currentVersion D.string)
|
||||
(D.opFieldWithDefault "deviceName" Default.deviceName D.string)
|
||||
(D.opFieldWithDefault "syncTime" Default.syncTime D.int)
|
||||
|
||||
|
||||
{-| Encode the settings into a JSON value.
|
||||
-}
|
||||
encode : Settings -> E.Value
|
||||
encode settings =
|
||||
let
|
||||
differentFrom : b -> b -> Maybe b
|
||||
differentFrom defaultValue currentValue =
|
||||
if currentValue == defaultValue then
|
||||
Nothing
|
||||
|
||||
else
|
||||
Just currentValue
|
||||
in
|
||||
E.maybeObject
|
||||
[ ( "currentVersion"
|
||||
, settings.currentVersion
|
||||
|> differentFrom Default.currentVersion
|
||||
|> Maybe.map E.string
|
||||
)
|
||||
, ( "deviceName"
|
||||
, settings.deviceName
|
||||
|> differentFrom Default.deviceName
|
||||
|> Maybe.map E.string
|
||||
)
|
||||
, ( "syncTime"
|
||||
, settings.syncTime
|
||||
|> differentFrom Default.syncTime
|
||||
|> Maybe.map E.int
|
||||
)
|
||||
]
|
||||
|
||||
|
||||
{-| Create a new Settings module based on default values
|
||||
-}
|
||||
init : Settings
|
||||
init =
|
||||
{ currentVersion = Default.currentVersion
|
||||
, deviceName = Default.deviceName
|
||||
, syncTime = Default.syncTime
|
||||
}
|
|
@ -6,10 +6,8 @@ module Internal.Values.Vault exposing (Vault)
|
|||
|
||||
-}
|
||||
|
||||
import Internal.Values.Envelope as Envelope
|
||||
|
||||
|
||||
{-| This is the Vault type.
|
||||
-}
|
||||
type alias Vault =
|
||||
Envelope.Envelope {}
|
||||
()
|
||||
|
|
|
@ -0,0 +1,143 @@
|
|||
module Matrix.Event exposing
|
||||
( Event, content, eventType, stateKey
|
||||
, eventId, roomId, sender, originServerTs
|
||||
, previousContent, redactedBecause
|
||||
)
|
||||
|
||||
{-|
|
||||
|
||||
|
||||
# Matrix Events
|
||||
|
||||
This module contains all the functions necessary to view and manipulate Matrix
|
||||
events.
|
||||
|
||||
|
||||
## Event
|
||||
|
||||
@docs Event, content, eventType, stateKey
|
||||
|
||||
|
||||
## Metadata
|
||||
|
||||
@docs eventId, roomId, sender, originServerTs
|
||||
|
||||
|
||||
## Optional data
|
||||
|
||||
Occasionally, the Event might bring some extra information. Given how this
|
||||
information isn't always applicable, it doesn't always exist.
|
||||
|
||||
@docs previousContent, redactedBecause
|
||||
|
||||
-}
|
||||
|
||||
import Internal.Values.Envelope as Envelope
|
||||
import Internal.Values.Event as Internal
|
||||
import Json.Encode
|
||||
import Time
|
||||
import Types exposing (Event(..))
|
||||
|
||||
|
||||
{-| In Matrix, the primary form of communication is to send JSON values to one
|
||||
another. These JSON values, together with their metadata, are bundled into Event
|
||||
types. They contain information like:
|
||||
|
||||
- Who sent the JSON value
|
||||
- How they intend you to decode it
|
||||
- When they sent it
|
||||
- In what room they sent it
|
||||
|
||||
-}
|
||||
type alias Event =
|
||||
Types.Event
|
||||
|
||||
|
||||
{-| Receive the body of an Event, as created by the user that sent it.
|
||||
-}
|
||||
content : Event -> Json.Encode.Value
|
||||
content (Event event) =
|
||||
Envelope.extract .content event
|
||||
|
||||
|
||||
{-| Determine the globally unique identifier for an event.
|
||||
-}
|
||||
eventId : Event -> String
|
||||
eventId (Event event) =
|
||||
Envelope.extract .eventId event
|
||||
|
||||
|
||||
{-| To give a hint what the event's [content](#content) might look like, users
|
||||
can use this eventType value to hint at how the JSON might be decoded.
|
||||
|
||||
Standard examples of event types are `m.room.message`, `m.room.member` and
|
||||
`me.noordstar.game.chess.move`.
|
||||
|
||||
-}
|
||||
eventType : Event -> String
|
||||
eventType (Event event) =
|
||||
Envelope.extract .eventType event
|
||||
|
||||
|
||||
{-| Determine the timestamp of at what time the event was originally received by
|
||||
the original homeserver.
|
||||
|
||||
Generally, this timestamp offers a relatively accurate indicator of when a
|
||||
message was sent. However, this number isn't completely reliable! The timestamp
|
||||
can be far in the past due to long network lag, and a (malicious) homeserver can
|
||||
spoof this number to make it seem like something was sent ridiculously far in
|
||||
the past - or even in the future.
|
||||
|
||||
-}
|
||||
originServerTs : Event -> Time.Posix
|
||||
originServerTs (Event event) =
|
||||
Envelope.extract .originServerTs event
|
||||
|
||||
|
||||
{-| Determine the previous `content` value for this event. This field is only a
|
||||
`Just value` if the event is a state event, and the Matrix Vault has permission
|
||||
to see the previous content.
|
||||
-}
|
||||
previousContent : Event -> Maybe Json.Encode.Value
|
||||
previousContent (Event event) =
|
||||
Envelope.extract Internal.prevContent event
|
||||
|
||||
|
||||
{-| If the event has been redacted, the homeserver can display the event that
|
||||
redacted it here.
|
||||
-}
|
||||
redactedBecause : Event -> Maybe Event
|
||||
redactedBecause (Event event) =
|
||||
Envelope.mapMaybe Internal.redactedBecause event
|
||||
|> Maybe.map Event
|
||||
|
||||
|
||||
{-| Unique id assigned to the Matrix room. You can use this room id to reference
|
||||
or look up rooms.
|
||||
-}
|
||||
roomId : Event -> String
|
||||
roomId (Event event) =
|
||||
Envelope.extract .roomId event
|
||||
|
||||
|
||||
{-| Determine the fully-qualified ID of the user who sent an event.
|
||||
-}
|
||||
sender : Event -> String
|
||||
sender (Event event) =
|
||||
Envelope.extract .sender event
|
||||
|
||||
|
||||
{-| Determine an event's state key.
|
||||
|
||||
It is present if, and only if, the event is a _state_ event. The key makes the
|
||||
piece of state unique in the room. Note that it is often `Just ""`. If it is not
|
||||
present, its value is `Nothing`.
|
||||
|
||||
State keys starting with an `@` are reserved for referencing user IDs, such as
|
||||
room members. With the exception of a few events, state events set with a given
|
||||
user'd ID as the state key can only be set by that user.
|
||||
|
||||
-}
|
||||
stateKey : Event -> Maybe String
|
||||
stateKey (Event event) =
|
||||
Envelope.extract .stateKey event
|
|
@ -1,4 +1,4 @@
|
|||
module Types exposing (Vault(..))
|
||||
module Types exposing (Vault(..), Event(..))
|
||||
|
||||
{-| The Elm SDK uses a lot of records and values that are easy to manipulate.
|
||||
Yet, the [Elm design guidelines](https://package.elm-lang.org/help/design-guidelines#keep-tags-and-record-constructors-secret)
|
||||
|
@ -12,14 +12,22 @@ access their content directly.
|
|||
The opaque types are placed in a central module so all exposed modules can
|
||||
safely access all exposed data types without risking to create circular imports.
|
||||
|
||||
@docs Vault
|
||||
@docs Vault, Event
|
||||
|
||||
-}
|
||||
|
||||
import Internal.Values.Envelope as Envelope
|
||||
import Internal.Values.Event as Event
|
||||
import Internal.Values.Vault as Vault
|
||||
|
||||
|
||||
{-| Opaque type for Matrix Event
|
||||
-}
|
||||
type Event
|
||||
= Event (Envelope.Envelope Event.Event)
|
||||
|
||||
|
||||
{-| Opaque type for Matrix Vault
|
||||
-}
|
||||
type Vault
|
||||
= Vault Vault.Vault
|
||||
= Vault (Envelope.Envelope Vault.Vault)
|
||||
|
|
|
@ -0,0 +1,35 @@
|
|||
module Test.Matrix.Settings exposing (..)
|
||||
|
||||
import Expect
|
||||
import Fuzz
|
||||
import Matrix.Settings
|
||||
import Test exposing (..)
|
||||
import Test.Types as TestTypes
|
||||
|
||||
|
||||
settings : Test
|
||||
settings =
|
||||
describe "Exposed Matrix.Settings"
|
||||
[ describe "Set values"
|
||||
[ fuzz2 TestTypes.vault
|
||||
Fuzz.string
|
||||
"Set device name"
|
||||
(\vault name ->
|
||||
vault
|
||||
|> Matrix.Settings.setDeviceName name
|
||||
|> Matrix.Settings.getDeviceName
|
||||
|> Expect.equal name
|
||||
)
|
||||
, fuzz2 TestTypes.vault
|
||||
Fuzz.int
|
||||
"Set sync time"
|
||||
(\vault sync ->
|
||||
vault
|
||||
|> Matrix.Settings.setSyncTime sync
|
||||
|> Matrix.Settings.getSyncTime
|
||||
|> Expect.equal sync
|
||||
)
|
||||
]
|
||||
|
||||
-- , describe "Read values" []
|
||||
]
|
|
@ -1,4 +1,4 @@
|
|||
module Iddict exposing (..)
|
||||
module Test.Tools.Iddict exposing (..)
|
||||
|
||||
import Expect
|
||||
import Fuzz exposing (Fuzzer)
|
|
@ -0,0 +1,66 @@
|
|||
module Test.Tools.Timestamp exposing (..)
|
||||
|
||||
import Expect
|
||||
import Fuzz exposing (Fuzzer)
|
||||
import Internal.Tools.Timestamp as Timestamp exposing (Timestamp)
|
||||
import Json.Decode as D
|
||||
import Json.Encode as E
|
||||
import Test exposing (..)
|
||||
import Time
|
||||
|
||||
|
||||
fuzzer : Fuzzer Timestamp
|
||||
fuzzer =
|
||||
Fuzz.map Time.millisToPosix Fuzz.int
|
||||
|
||||
|
||||
suite : Test
|
||||
suite =
|
||||
describe "Timestamp"
|
||||
[ describe "JSON"
|
||||
[ fuzz2 fuzzer
|
||||
Fuzz.int
|
||||
"JSON encode -> JSON decode"
|
||||
(\time indent ->
|
||||
time
|
||||
|> Timestamp.encode
|
||||
|> E.encode indent
|
||||
|> D.decodeString Timestamp.decoder
|
||||
|> Expect.equal (Ok time)
|
||||
)
|
||||
, fuzz fuzzer
|
||||
"JSON decode -> millis"
|
||||
(\time ->
|
||||
time
|
||||
|> Timestamp.encode
|
||||
|> D.decodeValue D.int
|
||||
|> Expect.equal (Ok <| Time.posixToMillis time)
|
||||
)
|
||||
, fuzz Fuzz.int
|
||||
"JSON decode -> time"
|
||||
(\n ->
|
||||
n
|
||||
|> E.int
|
||||
|> D.decodeValue Timestamp.decoder
|
||||
|> Expect.equal (Ok <| Time.millisToPosix n)
|
||||
)
|
||||
]
|
||||
, describe "Identity"
|
||||
[ fuzz fuzzer
|
||||
"Posix -> int -> Posix"
|
||||
(\time ->
|
||||
time
|
||||
|> Time.posixToMillis
|
||||
|> Time.millisToPosix
|
||||
|> Expect.equal time
|
||||
)
|
||||
, fuzz Fuzz.int
|
||||
"int -> Posix -> int"
|
||||
(\n ->
|
||||
n
|
||||
|> Time.millisToPosix
|
||||
|> Time.posixToMillis
|
||||
|> Expect.equal n
|
||||
)
|
||||
]
|
||||
]
|
|
@ -0,0 +1,17 @@
|
|||
module Test.Types exposing (..)
|
||||
|
||||
import Fuzz exposing (Fuzzer)
|
||||
import Test.Values.Envelope as TestEnvelope
|
||||
import Test.Values.Event as TestEvent
|
||||
import Test.Values.Vault as TestVault
|
||||
import Types exposing (..)
|
||||
|
||||
|
||||
event : Fuzzer Event
|
||||
event =
|
||||
Fuzz.map Event (TestEnvelope.fuzzer TestEvent.fuzzer)
|
||||
|
||||
|
||||
vault : Fuzzer Vault
|
||||
vault =
|
||||
Fuzz.map Vault (TestEnvelope.fuzzer TestVault.vault)
|
|
@ -1,4 +1,4 @@
|
|||
module Context exposing (..)
|
||||
module Test.Values.Context exposing (..)
|
||||
|
||||
import Expect
|
||||
import Fuzz exposing (Fuzzer)
|
|
@ -0,0 +1,65 @@
|
|||
module Test.Values.Envelope exposing (..)
|
||||
|
||||
import Expect
|
||||
import Fuzz exposing (Fuzzer)
|
||||
import Internal.Config.Default as Default
|
||||
import Internal.Values.Envelope as Envelope exposing (Envelope)
|
||||
import Json.Decode as D
|
||||
import Json.Encode as E
|
||||
import Test exposing (..)
|
||||
import Test.Values.Context as TestContext
|
||||
import Test.Values.Settings as TestSettings
|
||||
|
||||
|
||||
fuzzer : Fuzzer a -> Fuzzer (Envelope a)
|
||||
fuzzer fuz =
|
||||
Fuzz.map3 Envelope
|
||||
fuz
|
||||
TestContext.fuzzer
|
||||
TestSettings.fuzzer
|
||||
|
||||
|
||||
suite : Test
|
||||
suite =
|
||||
describe "Envelope value"
|
||||
[ describe "init"
|
||||
[ describe "Default settings"
|
||||
[ fuzz Fuzz.string
|
||||
"currentVersion"
|
||||
(\s ->
|
||||
s
|
||||
|> Envelope.init
|
||||
|> Envelope.extractSettings .currentVersion
|
||||
|> Expect.equal Default.currentVersion
|
||||
)
|
||||
, fuzz Fuzz.string
|
||||
"deviceName"
|
||||
(\s ->
|
||||
s
|
||||
|> Envelope.init
|
||||
|> Envelope.extractSettings .deviceName
|
||||
|> Expect.equal Default.deviceName
|
||||
)
|
||||
, fuzz Fuzz.string
|
||||
"syncTime"
|
||||
(\s ->
|
||||
s
|
||||
|> Envelope.init
|
||||
|> Envelope.extractSettings .syncTime
|
||||
|> Expect.equal Default.syncTime
|
||||
)
|
||||
]
|
||||
]
|
||||
, describe "JSON"
|
||||
[ fuzz2 (fuzzer Fuzz.string)
|
||||
Fuzz.int
|
||||
"JSON encode -> JSON decode"
|
||||
(\envelope indent ->
|
||||
envelope
|
||||
|> Envelope.encode E.string
|
||||
|> E.encode indent
|
||||
|> D.decodeString (Envelope.decoder D.string)
|
||||
|> Expect.equal (Ok envelope)
|
||||
)
|
||||
]
|
||||
]
|
|
@ -0,0 +1,50 @@
|
|||
module Test.Values.Event exposing (..)
|
||||
|
||||
import Fuzz exposing (Fuzzer)
|
||||
import Internal.Values.Event as Event exposing (Event)
|
||||
import Json.Encode as E
|
||||
import Test exposing (..)
|
||||
import Test.Tools.Timestamp as TestTimestamp
|
||||
|
||||
|
||||
fuzzer : Fuzzer Event
|
||||
fuzzer =
|
||||
Fuzz.map8 Event
|
||||
valueFuzzer
|
||||
Fuzz.string
|
||||
TestTimestamp.fuzzer
|
||||
Fuzz.string
|
||||
Fuzz.string
|
||||
(Fuzz.maybe Fuzz.string)
|
||||
Fuzz.string
|
||||
(Fuzz.maybe unsignedDataFuzzer)
|
||||
|
||||
|
||||
unsignedDataFuzzer : Fuzzer Event.UnsignedData
|
||||
unsignedDataFuzzer =
|
||||
Fuzz.map4
|
||||
(\age prev redact trans ->
|
||||
Event.UnsignedData
|
||||
{ age = age
|
||||
, prevContent = prev
|
||||
, redactedBecause = redact
|
||||
, transactionId = trans
|
||||
}
|
||||
)
|
||||
(Fuzz.maybe Fuzz.int)
|
||||
(Fuzz.maybe valueFuzzer)
|
||||
(Fuzz.maybe <| Fuzz.lazy (\_ -> fuzzer))
|
||||
(Fuzz.maybe Fuzz.string)
|
||||
|
||||
|
||||
{-| Example values that can be used for arbitrary JSON values
|
||||
-}
|
||||
valueFuzzer : Fuzzer E.Value
|
||||
valueFuzzer =
|
||||
Fuzz.oneOf
|
||||
[ Fuzz.map E.int Fuzz.int
|
||||
, Fuzz.map E.string Fuzz.string
|
||||
, Fuzz.map (E.list E.int) (Fuzz.list Fuzz.int)
|
||||
, Fuzz.map (E.list E.string) (Fuzz.list Fuzz.string)
|
||||
, Fuzz.map Event.encode (Fuzz.lazy (\_ -> fuzzer))
|
||||
]
|
|
@ -0,0 +1,80 @@
|
|||
module Test.Values.Settings exposing (..)
|
||||
|
||||
import Expect
|
||||
import Fuzz exposing (Fuzzer)
|
||||
import Internal.Config.Default as Default
|
||||
import Internal.Values.Settings as Settings exposing (Settings)
|
||||
import Json.Decode as D
|
||||
import Json.Encode as E
|
||||
import Test exposing (..)
|
||||
|
||||
|
||||
fuzzer : Fuzzer Settings
|
||||
fuzzer =
|
||||
Fuzz.map3 Settings
|
||||
(Fuzz.oneOf
|
||||
[ Fuzz.constant Default.currentVersion
|
||||
, Fuzz.string
|
||||
]
|
||||
)
|
||||
(Fuzz.oneOf
|
||||
[ Fuzz.constant Default.deviceName
|
||||
, Fuzz.string
|
||||
]
|
||||
)
|
||||
(Fuzz.oneOf
|
||||
[ Fuzz.constant Default.syncTime
|
||||
, Fuzz.int
|
||||
]
|
||||
)
|
||||
|
||||
|
||||
suite : Test
|
||||
suite =
|
||||
describe "Settings"
|
||||
[ describe "init"
|
||||
[ test "Current version"
|
||||
(Settings.init
|
||||
|> .currentVersion
|
||||
|> Expect.equal Default.currentVersion
|
||||
|> always
|
||||
)
|
||||
, test "Device name"
|
||||
(Settings.init
|
||||
|> .deviceName
|
||||
|> Expect.equal Default.deviceName
|
||||
|> always
|
||||
)
|
||||
, test "Sync time"
|
||||
(Settings.init
|
||||
|> .syncTime
|
||||
|> Expect.equal Default.syncTime
|
||||
|> always
|
||||
)
|
||||
, test "JSON encode init is {}"
|
||||
(Settings.init
|
||||
|> Settings.encode
|
||||
|> E.encode 0
|
||||
|> Expect.equal "{}"
|
||||
|> always
|
||||
)
|
||||
, test "JSON decode {} is init"
|
||||
("{}"
|
||||
|> D.decodeString Settings.decoder
|
||||
|> Expect.equal (Ok Settings.init)
|
||||
|> always
|
||||
)
|
||||
]
|
||||
, describe "JSON"
|
||||
[ fuzz2 fuzzer
|
||||
Fuzz.int
|
||||
"JSON encode -> JSON decode -> identical"
|
||||
(\settings indent ->
|
||||
settings
|
||||
|> Settings.encode
|
||||
|> E.encode indent
|
||||
|> D.decodeString Settings.decoder
|
||||
|> Expect.equal (Ok settings)
|
||||
)
|
||||
]
|
||||
]
|
|
@ -0,0 +1,10 @@
|
|||
module Test.Values.Vault exposing (..)
|
||||
|
||||
import Fuzz exposing (Fuzzer)
|
||||
import Internal.Values.Vault exposing (Vault)
|
||||
import Test exposing (..)
|
||||
|
||||
|
||||
vault : Fuzzer Vault
|
||||
vault =
|
||||
Fuzz.unit
|
|
@ -1,53 +0,0 @@
|
|||
module Vault exposing (..)
|
||||
|
||||
import Expect
|
||||
import Fuzz exposing (Fuzzer)
|
||||
import Internal.Config.Default as Default
|
||||
import Internal.Values.Envelope as Envelope
|
||||
import Matrix
|
||||
import Matrix.Settings
|
||||
import Test exposing (..)
|
||||
import Types
|
||||
|
||||
|
||||
fuzzer : Fuzzer Matrix.Vault
|
||||
fuzzer =
|
||||
Fuzz.constant <| Types.Vault <| Envelope.init {}
|
||||
|
||||
|
||||
settings : Test
|
||||
settings =
|
||||
describe "Edit settings"
|
||||
[ fuzz fuzzer
|
||||
"Default device name"
|
||||
(\vault ->
|
||||
vault
|
||||
|> Matrix.Settings.getDeviceName
|
||||
|> Expect.equal Default.deviceName
|
||||
)
|
||||
, fuzz2 fuzzer
|
||||
Fuzz.string
|
||||
"Set device name"
|
||||
(\vault name ->
|
||||
vault
|
||||
|> Matrix.Settings.setDeviceName name
|
||||
|> Matrix.Settings.getDeviceName
|
||||
|> Expect.equal name
|
||||
)
|
||||
, fuzz fuzzer
|
||||
"Default sync time"
|
||||
(\vault ->
|
||||
vault
|
||||
|> Matrix.Settings.getSyncTime
|
||||
|> Expect.equal Default.syncTime
|
||||
)
|
||||
, fuzz2 fuzzer
|
||||
Fuzz.int
|
||||
"Set sync time"
|
||||
(\vault sync ->
|
||||
vault
|
||||
|> Matrix.Settings.setSyncTime sync
|
||||
|> Matrix.Settings.getSyncTime
|
||||
|> Expect.equal sync
|
||||
)
|
||||
]
|
Loading…
Reference in New Issue