From 3e54ea9cbe0719e43d75f9cb2d949ba1e4ea5abe Mon Sep 17 00:00:00 2001 From: Bram Date: Sun, 24 Dec 2023 01:26:06 +0100 Subject: [PATCH] Add separate Settings module --- elm.json | 3 +- src/Internal/Values/Settings.elm | 93 ++++++++++++++++++++++++++++++++ tests/Test/Values/Settings.elm | 80 +++++++++++++++++++++++++++ 3 files changed, 174 insertions(+), 2 deletions(-) create mode 100644 src/Internal/Values/Settings.elm create mode 100644 tests/Test/Values/Settings.elm diff --git a/elm.json b/elm.json index 72bead6..ac0cd72 100644 --- a/elm.json +++ b/elm.json @@ -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" ], diff --git a/src/Internal/Values/Settings.elm b/src/Internal/Values/Settings.elm new file mode 100644 index 0000000..f9a266a --- /dev/null +++ b/src/Internal/Values/Settings.elm @@ -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 + } diff --git a/tests/Test/Values/Settings.elm b/tests/Test/Values/Settings.elm new file mode 100644 index 0000000..8edf86c --- /dev/null +++ b/tests/Test/Values/Settings.elm @@ -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) + ) + ] + ]