Add separate Settings module

3-event
Bram 2023-12-24 01:26:06 +01:00
parent 5ac3e7eb6a
commit 3e54ea9cbe
3 changed files with 174 additions and 2 deletions

View File

@ -6,7 +6,6 @@
"version": "2.0.0",
"exposed-modules": [
"Matrix",
"Matrix.Event",
"Matrix.Settings",
"Internal.Config.Default",
"Internal.Config.Leaks",
@ -19,7 +18,7 @@
"Internal.Tools.VersionControl",
"Internal.Values.Context",
"Internal.Values.Envelope",
"Internal.Values.Event",
"Internal.Values.Settings",
"Internal.Values.Vault",
"Types"
],

View File

@ -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
}

View File

@ -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)
)
]
]