Hoe kan ik / lift / inject aangepaste monade stack met HSpec integreren?

stemmen
1

Context

Ik heb een aantal monadische functies voor een tolk dat ik probeer om te testen met HSpec. Ze lopen met de volgende monade stack:

type AppState = StateT InterpreterState (ExceptT Events IO)
type AppReturn a = Either Events (a, PState)

runApp :: AppState a -> IO (AppReturn a)
runApp f = runExceptT (runStateT f new)

Hier is een voorbeeld van een eenvoudige één:

mustEvalExpr :: Expr -> S.AppState (S.Value)
mustEvalExpr e = do
    val <- evalExpr e
    case val of
        Just val' -> return val'
        Nothing   -> throw $ S.CannotEval e

Het probleem is dat HSpec heeft zijn eigen context ( IO ()), dus ik heb te vertalen tussen de twee contexten.

huidige aanpak

Ik gebruik HSpec, en ik schreef een transformator functie om een krijgen runAppcontext vanuit de HSpec context.

-- imports omitted

extract :: S.AppReturn a -> a
extract st = case st of
    Right (a, _) -> a
    Left ev      -> throw ev

run :: (S.AppReturn a -> b) -> S.AppState a -> IO b
run extractor fn = do
    state <- S.runApp fn
    return $ extractor state

Dus mijn Specziet er als volgt:

spec :: Spec
spec = do
    describe mustEvalExpr $ do
        let badExpr = D.VarExpr $ D.Id doesntExist
            goodExpr = D.IntExpr 1
            val = S.IntValue 1

        it should evaluate and return expression if its a Just $ do
            (run extract $ do
                I.mustEvalExpr goodExpr
                ) >>= (`shouldBe` val)

        it should throw error if it gets a Nothing $ do
            (run extract $ do
                I.mustEvalExpr badExpr
                ) `shouldThrow` anyException

Vraag

Is dit het beste wat ik kan doen? Ik voel me als run extract $ dois prima, en ik denk dat het is goed om expliciet te zijn als de dingen ingewikkeld.

Maar ik vroeg me af of er een manier waarop ik kan worden geïntegreerd met HSpec was, of dat er een best-practice voor dit probleem dat niet aangepaste code nodig heeft?

De vraag is gesteld op 19/03/2020 om 21:58
bron van user
In andere talen...                            

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more