marvin-0.2.1: test/IntegrationSpec.hs
import Control.Lens
import Control.Monad.Extra
import Data.Aeson.Lens
import Data.Maybe
import Data.Text (Text)
import Data.Yaml
import System.Directory
import System.Environment
import System.FilePath
import System.Info.Extra
import System.IO.Temp
import System.Process
import Test.Hspec
stackBuildArgs :: [String]
stackBuildArgs
| isMac = ["--extra-lib-dirs=/usr/local/opt/icu4c/lib", "--extra-include-dirs=/usr/local/opt/icu4c/include"]
| otherwise = []
copyDirectory :: FilePath -> FilePath -> IO ()
copyDirectory source target = do
createDirectoryIfMissing True target
(dirs, files) <- getDirectoryContents source >>=
partitionM (doesDirectoryExist . (source </>))
. filter (\a -> not $ a == "." || a == "..")
mapM_ (copyFile <$> (source </>) <*> (target </>)) files
mapM_ (copyDirectory <$> (source </>) <*> (target </>)) dirs
-- | In the .travis.yml file I pass the stack yaml as STACK_YAML env variable.
-- This is necessary as the extra-deps are different for some lts versions
-- However the yaml file in STACK_YAML cannot be used by the integration tests,
-- as they require both marvins source directory as well as their own to be
-- recorded in the `packages` key.
-- This function reads the stack.yaml, modifies the `packages` section and
-- writes a new stack.yaml to the target path which the tests pass to stack via
-- then `--stack-yaml` command line parameter
getAndModifyStackYaml :: FilePath -> IO ()
getAndModifyStackYaml targetPath = do
path <- fromMaybe "test/resources/stack.yaml" <$> lookupEnv "STACK_YAML"
Just yamlFile <- decodeFile path
encodeFile targetPath $ (yamlFile :: Value) & key "packages" .~ packageObject
where
packageObject = toJSON [".", ".." :: Text]
getResolver :: IO String
getResolver = fromMaybe "lts" <$> lookupEnv "STACK_RESOLVER"
-- | This test is used to make sure the initializer produces a compileable project
runInitAndCompileResult :: IO ()
runInitAndCompileResult =
withTempDirectory "." ".test" $ \dir -> do
getAndModifyStackYaml (dir </> "stack.yaml")
withCurrentDirectory dir $ do
resolver <- getResolver
callProcess "stack"
[ "exec"
, "--resolver", resolver
, "--stack-yaml", "stack.yaml"
, "--", "marvin-init"
, "-a", "shell"
, "testbot"]
callProcess "stack" $
[ "build"
, "--stack-yaml", "stack.yaml"
, "--resolver", resolver
] ++ stackBuildArgs
compileIntegration :: IO ()
compileIntegration =
withTempDirectory "." ".test" $ \dir -> do
resolver <- getResolver
copyDirectory "test/integration" dir
getAndModifyStackYaml (dir </> "stack.yaml")
withCurrentDirectory dir $ callProcess "stack" $
[ "build"
, "--stack-yaml", "stack.yaml"
, "--resolver", resolver
] ++ stackBuildArgs
main :: IO ()
main = hspec $ do
describe "the integration test" $
it "compiles the integration test suite" $
compileIntegration `shouldReturn` ()
describe "initializer" $
it "produces a compileable project" $
runInitAndCompileResult `shouldReturn` ()