{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE OverloadedLists #-}
module Helpers
( module Exports,
checkExprsSuccess,
checkExprsError,
pureCatalog,
getResource,
getAttribute,
renderToString,
withStdlibFunction,
)
where
import qualified Data.HashMap.Strict as HM
import qualified Data.Maybe.Strict as S
import qualified Data.Vector as Vector
import Puppet.Interpreter as Exports
import Puppet.Parser as Exports
import Puppet.Runner as Exports hiding (getCatalog)
import Test.Hspec as Exports
import XPrelude as Exports
-- | Given a raw text input to be parsed, compute the manifest in a pure setting.
-- The 'InterpreterWriter' might be useful for debugging purpose.
pureCatalog :: Text -> Either String (FinalCatalog, InterpreterWriter)
pureCatalog = runExcept . fmap (\s -> (s ^. _1, s ^. _6)) . compileCatalog
where
compileCatalog :: Text -> Except String (FinalCatalog, EdgeMap, FinalCatalog, [Resource], InterpreterState, InterpreterWriter)
compileCatalog input = do
statements <- either (throwError . show) pure (runPuppetParser mempty input)
let nodename = "pure"
top_node = [((TopNode, nodename), NodeDeclaration (NodeDecl (NodeName nodename) statements S.Nothing (initialPPos mempty)))]
(res, finalState, logs) = pureEval top_node (computeCatalog nodename)
(catalog, em, exported, defResources) <- either (throwError . show) pure res
pure (catalog, em, exported, defResources, finalState, logs)
getResource :: (MonadFail m) => RIdentifier -> FinalCatalog -> m Resource
getResource resid catalog = maybe (fail ("Unknown resource " <> renderToString resid)) pure (HM.lookup resid catalog)
getAttribute :: (MonadFail m) => Text -> Resource -> m PValue
getAttribute att res =
case res ^? rattributes . ix att of
Nothing -> fail ("Unknown attribute: " <> toS att)
Just x -> return x
withStdlibFunction :: Text -> (([PValue] -> InterpreterMonad PValue) -> Spec) -> Spec
withStdlibFunction fname testsuite =
case stdlibFunctions ^? ix fname of
Just f -> testsuite f
Nothing -> panic ("Don't know this function: " <> fname)
checkExprsSuccess :: Text -> [Expression] -> Text -> Expectation
checkExprsSuccess fname args res =
case evalExprs fname args of
Left rr -> expectationFailure (show rr)
Right res' -> res' `shouldBe` res
checkExprsError :: Text -> [Expression] -> String -> Expectation
checkExprsError fname args msg =
case evalExprs fname args of
Left rr -> show rr `shouldContain` msg
Right r -> expectationFailure ("Should have errored, received this instead: " <> show r)
evalExprs :: Text -> [Expression] -> Either PrettyError Text
evalExprs fname =
dummyEval . resolveValue . UFunctionCall fname . Vector.fromList >=> \case
PString s -> return s
v -> Left ("Expected a string, not " <> PrettyError (pretty v))
renderToString :: (Pretty a) => a -> String
renderToString d = displayS (renderCompact (pretty d)) ""