packages feed

stan-0.0.0.0: test/Test/Stan/Cli.hs

module Test.Stan.Cli
    ( cliSpec
    ) where

import Hedgehog (forAll, (===))
import Options.Applicative (ParserResult (Success), execParserPure)
import Test.Hspec (Spec, describe, it, shouldBe)
import Test.Hspec.Hedgehog (hedgehog)
import Trial (fiasco, trialToMaybe, withTag)

import Stan.Cli (StanArgs (..), StanCommand (..), stanCliParser, stanParserPrefs)
import Stan.Config (Check (..), CheckFilter (..), CheckType (..), Config, ConfigP (..),
                    PartialConfig, Scope (..), configToCliCommand, finaliseConfig)
import Stan.Core.Id (Id (..))
import Test.Stan.Gen (Property, genCheck, genConfig, genId, genScope)


cliSpec :: Spec
cliSpec = describe "CLI configuration tests" $ do
    it "execParserPure . configToCliCommand ≡ pure" cliConfigRoundtripProperty
    it "Converts Config to CLI command and parses it back" $
        case execParserPure stanParserPrefs stanCliParser (stanCommand configExample) of
            Success (Stan StanArgs{..}) -> stanArgsConfig `shouldBe` partialConfigExample
            _failure                    -> fail "Toml-To-CLI doesn't match the original config"

  where
    configExample :: Config
    configExample = ConfigP
        { configChecks = checks
        , configRemoved = []
        , configIgnored = []
        }

    partialConfigExample :: PartialConfig
    partialConfigExample = ConfigP
        { configChecks = withTag "CLI" $ pure checks
        , configRemoved = withTag "CLI" $ fiasco "No CLI option specified for: remove"
        , configIgnored = withTag "CLI" $ fiasco "No CLI option specified for: ignore"
        }

    checks :: [Check]
    checks =
        [ Check Exclude CheckAll (ScopeDirectory "test/")
        , Check Include CheckAll ScopeAll
        , Check Exclude (CheckInspection $ Id "STAN-0002") ScopeAll
        , Check
            Exclude
            (CheckInspection $ Id "STAN-0001")
            (ScopeFile "src/MyFile.hs")
        ]

cliConfigRoundtripProperty :: Property
cliConfigRoundtripProperty = hedgehog $ do
    check <- forAll genCheck
    scope <- forAll genScope
    obs   <- forAll genId
    -- we need to have a non-empty list as empty list is Fiasco for CLI.
    config <- forAll $ genConfig <&> \c -> c
        { configChecks  = check : configChecks c
        , configRemoved = scope : configRemoved c
        , configIgnored = obs : configIgnored c
        }
    case execParserPure stanParserPrefs stanCliParser (stanCommand config) of
        Success (Stan StanArgs{..}) ->
            trialToMaybe (finaliseConfig stanArgsConfig) === Just config
        _failure -> fail $ "Toml-To-CLI doesn't match the original config:\n"
            <> toString (configToCliCommand config)

stanCommand :: Config -> [String]
stanCommand = filter (/= "\\") . drop 1 . map toString . words . configToCliCommand