From 408e0f0f82af4823bd598903a10950924f2f5daf Mon Sep 17 00:00:00 2001 From: Jonathan Lamothe Date: Fri, 26 Jul 2024 20:35:54 -0400 Subject: [PATCH] implemented `editStateL` --- hamming.cabal | 2 + src/Hamming/App/Types.hs | 21 +++++++-- test/Hamming/App/Types/AppModeSpec.hs | 66 +++++++++++++++++++++++++++ test/Hamming/App/TypesSpec.hs | 32 +++++++++++++ test/Hamming/AppSpec.hs | 4 +- 5 files changed, 121 insertions(+), 4 deletions(-) create mode 100644 test/Hamming/App/Types/AppModeSpec.hs create mode 100644 test/Hamming/App/TypesSpec.hs diff --git a/hamming.cabal b/hamming.cabal index c3bfecc..2e90d74 100644 --- a/hamming.cabal +++ b/hamming.cabal @@ -67,6 +67,8 @@ test-suite hamming-test type: exitcode-stdio-1.0 main-is: Spec.hs other-modules: + Hamming.App.Types.AppModeSpec + Hamming.App.TypesSpec Hamming.App.Widgets.InternalSpec Hamming.App.WidgetsSpec Hamming.AppSpec diff --git a/src/Hamming/App/Types.hs b/src/Hamming/App/Types.hs index edabd0d..909d427 100644 --- a/src/Hamming/App/Types.hs +++ b/src/Hamming/App/Types.hs @@ -24,7 +24,7 @@ License along with this program. If not, see |-} -{-# LANGUAGE TemplateHaskell #-} +{-# LANGUAGE LambdaCase, TemplateHaskell #-} module Hamming.App.Types ( -- * Application state data @@ -35,6 +35,8 @@ module Hamming.App.Types ( hammingCode, -- ** AppMode AppMode (..), + -- *** Lenses + editStateL, -- ** EditState, EditState (..), -- *** Lenses @@ -52,18 +54,20 @@ module Hamming.App.Types ( import Brick.Types (BrickEvent, EventM) import Data.Word (Word16) +import Lens.Micro (Lens', lens) import Lens.Micro.TH (makeLenses) -- | The main state of the application data AppState = AppState { _appMode :: AppMode , _hammingCode :: Word16 - } + } deriving (Eq, Show) -- | The application's main mode data AppMode = DisplayMode | EditMode EditState + deriving (Eq, Show) -- | The state of the editor data EditState = EditState @@ -71,7 +75,7 @@ data EditState = EditState -- ^ The selected row number , _colNum :: Int -- ^ The selected column - } + } deriving (Eq, Show) -- | Identifies a resource type ResName = () @@ -90,6 +94,17 @@ concat <$> mapM makeLenses , ''EditState ] +editStateL :: Lens' AppMode (Maybe EditState) +editStateL = lens + ( \case + DisplayMode -> Nothing + EditMode s -> Just s + ) + ( const $ \case + Just s -> EditMode s + Nothing -> DisplayMode + ) + -- | Initial application state initialState :: AppState initialState = AppState DisplayMode 0 diff --git a/test/Hamming/App/Types/AppModeSpec.hs b/test/Hamming/App/Types/AppModeSpec.hs new file mode 100644 index 0000000..2090d59 --- /dev/null +++ b/test/Hamming/App/Types/AppModeSpec.hs @@ -0,0 +1,66 @@ +{- + +hamming +Copyright (C) Jonathan Lamothe + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU Affero General Public License as +published by the Free Software Foundation, either version 3 of the +License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Affero General Public License for more details. + +You should have received a copy of the GNU Affero General Public +License along with this program. If not, see +. + +-} + +module Hamming.App.Types.AppModeSpec (spec) where + +import Lens.Micro ((^.), (&), (.~)) +import Test.Hspec (Spec, context, describe, it, shouldBe) + +import Hamming.App.Types + +spec :: Spec +spec = describe "AppMode" + editStateLSpec + +editStateLSpec :: Spec +editStateLSpec = describe "editStateL" $ do + eslSetterSpec + eslGetterSpec + +eslSetterSpec :: Spec +eslSetterSpec = context "setter" $ mapM_ + ( \(desc, mode, val, expected) -> context desc $ let + actual = mode & editStateL .~ val + in it ("should be " ++ show expected) $ + actual `shouldBe` expected + ) + [ ( "set from display", DisplayMode, Just s1, EditMode s1 ) + , ( "clear from display", DisplayMode, Nothing, DisplayMode ) + , ( "set from edit", EditMode s1, Just s2, EditMode s2 ) + , ( "clear from edit", EditMode s1, Nothing, DisplayMode ) + ] + where + s1 = EditState 2 3 + s2 = EditState 3 5 + +eslGetterSpec :: Spec +eslGetterSpec = context "getter" $ mapM_ + ( \(desc, mode, expected) -> context desc $ let + actual = mode^.editStateL + in it ("should be " ++ show expected) $ + actual `shouldBe` expected + ) + [ ( "no editor", DisplayMode, Nothing ) + , ( "with editor", EditMode s, Just s ) + ] + where s = EditState 2 3 + +--jl diff --git a/test/Hamming/App/TypesSpec.hs b/test/Hamming/App/TypesSpec.hs new file mode 100644 index 0000000..bf91b2a --- /dev/null +++ b/test/Hamming/App/TypesSpec.hs @@ -0,0 +1,32 @@ +{- + +hamming +Copyright (C) Jonathan Lamothe + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU Affero General Public License as +published by the Free Software Foundation, either version 3 of the +License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Affero General Public License for more details. + +You should have received a copy of the GNU Affero General Public +License along with this program. If not, see +. + +-} + +module Hamming.App.TypesSpec (spec) where + +import Test.Hspec (Spec, describe) + +import qualified Hamming.App.Types.AppModeSpec as AppMode + +spec :: Spec +spec = describe "Types" + AppMode.spec + +--jl diff --git a/test/Hamming/AppSpec.hs b/test/Hamming/AppSpec.hs index 74747af..a285cdf 100644 --- a/test/Hamming/AppSpec.hs +++ b/test/Hamming/AppSpec.hs @@ -23,10 +23,12 @@ module Hamming.AppSpec (spec) where import Test.Hspec (Spec, describe) +import qualified Hamming.App.TypesSpec as Types import qualified Hamming.App.WidgetsSpec as Widgets spec :: Spec -spec = describe "App" +spec = describe "App" $ do + Types.spec Widgets.spec --jl