-
-
Notifications
You must be signed in to change notification settings - Fork 22
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Browse files
Browse the repository at this point in the history
* Add tests (mainly) * Add Changelog * Remove unnecessary changes (store handle in env) * fix formatting * fix more formatting (test) * PR fixes * Update test/Test/Iris/Interactive/Question.hs Co-authored-by: Dmitrii Kovanikov <[email protected]> * test recactoring and changelog fixed --------- Co-authored-by: Dmitrii Kovanikov <[email protected]>
- Loading branch information
1 parent
ba68943
commit 1d8b3f2
Showing
8 changed files
with
202 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
{- | | ||
Module : Iris.Interactive | ||
Copyright : (c) 2023 Dmitrii Kovanikov | ||
SPDX-License-Identifier : MPL-2.0 | ||
Maintainer : Dmitrii Kovanikov <[email protected]> | ||
Stability : Experimental | ||
Portability : Portable | ||
Functions to handle interactive mode. | ||
@since x.x.x.x | ||
-} | ||
module Iris.Interactive ( | ||
-- $question | ||
module Iris.Interactive.Question, | ||
) where | ||
|
||
import Iris.Interactive.Question | ||
|
||
{- $question | ||
Asking Questions and receiving an answer: | ||
-} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,118 @@ | ||
{-# LANGUAGE FlexibleContexts #-} | ||
|
||
{- | | ||
Module : Iris.Interactive.Question | ||
Copyright : (c) 2023 Dmitrii Kovanikov | ||
SPDX-License-Identifier : MPL-2.0 | ||
Maintainer : Dmitrii Kovanikov <[email protected]> | ||
Stability : Experimental | ||
Portability : Portable | ||
Asking Questions. Receiving answers. | ||
@since x.x.x.x | ||
-} | ||
module Iris.Interactive.Question ( | ||
yesno, | ||
YesNo (..), | ||
parseYesNo, | ||
) where | ||
|
||
import Control.Monad.IO.Class (MonadIO (..)) | ||
import Control.Monad.Reader (MonadReader) | ||
|
||
import Data.Text (Text) | ||
import qualified Data.Text as Text | ||
import qualified Data.Text.IO as Text | ||
import System.IO (hFlush, stdout) | ||
|
||
import Iris.Cli.Interactive (InteractiveMode (..)) | ||
import Iris.Env (CliEnv (..), asksCliEnv) | ||
|
||
{- | ||
@since x.x.x.x | ||
-} | ||
parseYesNo :: Text -> Maybe YesNo | ||
parseYesNo t = case Text.toUpper . Text.strip $ t of | ||
"Y" -> Just Yes | ||
"YES" -> Just Yes | ||
"YS" -> Just Yes | ||
"N" -> Just No | ||
"NO" -> Just No | ||
_ -> Nothing | ||
|
||
{- | Parsed as Yes: "Y", "YES", "YS" (lower- or uppercase) | ||
Parsed as No: "N", "NO" (lower- or uppercase) | ||
@since x.x.x.x | ||
-} | ||
data YesNo | ||
= No | ||
| Yes | ||
deriving stock | ||
( Show | ||
-- ^ @since x.x.x.x | ||
, Eq | ||
-- ^ @since x.x.x.x | ||
, Ord | ||
-- ^ @since x.x.x.x | ||
, Enum | ||
-- ^ @since x.x.x.x | ||
, Bounded | ||
-- ^ @since x.x.x.x | ||
) | ||
|
||
{- | Ask a yes/no question to stdout, read the reply from terminal, return an Answer. | ||
In case of running non-interactively, return the provided default | ||
Example usage: | ||
@ | ||
app :: App () | ||
app = do | ||
answer <- Iris.yesno "Would you like to proceed?" Iris.Yes | ||
case answer of | ||
Iris.Yes -> proceed | ||
Iris.No -> Iris.outLn "Aborting" | ||
\$ ./irisapp | ||
Would you like to proceed? (yes/no) | ||
I don't understand your answer: '' | ||
Please, answer yes or no (or y, or n) | ||
Would you like to proceed? (yes/no) ne | ||
I don't understand your answer: 'ne' | ||
Please, answer yes or no (or y, or n) | ||
Would you like to proceed? (yes/no) NO | ||
Aborting | ||
@ | ||
@since x.x.x.x | ||
-} | ||
yesno | ||
:: (MonadIO m, MonadReader (CliEnv cmd appEnv) m) | ||
=> Text | ||
-- ^ Question Text | ||
-> YesNo | ||
-- ^ Default answer when @--no-input@ is provided | ||
-> m YesNo | ||
yesno question defaultAnswer = do | ||
interactiveMode <- asksCliEnv cliEnvInteractiveMode | ||
case interactiveMode of | ||
NonInteractive -> pure defaultAnswer | ||
Interactive -> liftIO loop | ||
where | ||
loop :: IO YesNo | ||
loop = do | ||
Text.putStr $ question <> " (yes/no) " | ||
hFlush stdout | ||
input <- Text.getLine | ||
case parseYesNo input of | ||
Just answer -> pure answer | ||
Nothing -> do | ||
Text.putStrLn $ "I don't understand your answer: '" <> input <> "'" | ||
Text.putStrLn "Please, answer yes or no (or y, or n)" | ||
loop |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
module Test.Iris.Interactive (interactiveSpec) where | ||
|
||
import Test.Hspec (Spec, describe) | ||
|
||
import Test.Iris.Interactive.Question (questionSpec) | ||
|
||
interactiveSpec :: Spec | ||
interactiveSpec = describe "Interactive" $ do | ||
questionSpec |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
module Test.Iris.Interactive.Question (questionSpec) where | ||
|
||
import Control.Monad (forM_) | ||
import Data.Text (Text) | ||
import qualified Data.Text as Text | ||
import Test.Hspec (Spec, SpecWith, describe, it, shouldBe) | ||
|
||
import Iris.Interactive.Question ( | ||
-- under test | ||
YesNo (..), | ||
parseYesNo, | ||
) | ||
|
||
yesAnswers :: [Text] | ||
yesAnswers = "y" : "Y" : [y <> e <> s | y <- ["y", "Y"], e <- ["e", "E", ""], s <- ["s", "S"]] | ||
|
||
questionSpec :: Spec | ||
questionSpec = | ||
describe "Question - parse YesNo" $ do | ||
checkElements yesAnswers (Just Yes) | ||
checkElements ["n", "N", "NO", "no", "No", "nO"] (Just No) | ||
checkElements ["a", "ye", "NOone", "yesterday", "oui"] Nothing | ||
it "Empty string parses to Nothing" $ | ||
parseYesNo "" `shouldBe` Nothing | ||
|
||
checkElements | ||
:: [Text] | ||
-> Maybe YesNo | ||
-> SpecWith () | ||
checkElements values expected = do | ||
describe ("should parse to " ++ show expected) $ | ||
forM_ values $ \strValue -> | ||
it (Text.unpack strValue) $ | ||
parseYesNo strValue `shouldBe` expected |