{-# LANGUAGE FlexibleContexts #-} {-# LANGUAGE OverloadedStrings #-} {-# LANGUAGE RecordWildCards #-} {-# LANGUAGE TemplateHaskell #-} module Stack.BuildPlanSpec where import Stack.BuildPlan import Control.Monad.Logger import Control.Exception hiding (try) import Control.Monad.Catch (try) import Data.Monoid import qualified Data.Map as Map import qualified Data.Set as Set import Prelude -- Fix redundant import warnings import System.Directory import System.Environment import System.IO.Temp (withSystemTempDirectory) import Test.Hspec import Stack.Config import Stack.Types.BuildPlan import Stack.Types.PackageName import Stack.Types.Version import Stack.Types.Config import Stack.Types.Compiler import Stack.Types.StackT setup :: IO () setup = unsetEnv "STACK_YAML" main :: IO () main = hspec spec spec :: Spec spec = beforeAll setup $ do let logLevel = LevelDebug let loadConfig' = runStackT () logLevel True False ColorAuto False (loadConfig mempty Nothing SYLDefault) let loadBuildConfigRest = runStackT () logLevel True False ColorAuto False let inTempDir action = do currentDirectory <- getCurrentDirectory withSystemTempDirectory "Stack_BuildPlanSpec" $ \tempDir -> do let enterDir = setCurrentDirectory tempDir let exitDir = setCurrentDirectory currentDirectory bracket_ enterDir exitDir action it "finds missing transitive dependencies #159" $ inTempDir $ do -- Note: this test is somewhat fragile, depending on packages on -- Hackage remaining in a certain state. If it fails, confirm that -- github still depends on failure. writeFile "stack.yaml" "resolver: lts-2.9" LoadConfig{..} <- loadConfig' bconfig <- loadBuildConfigRest (lcLoadBuildConfig Nothing) runStackT bconfig logLevel True False ColorAuto False $ do mbp <- loadMiniBuildPlan $ LTS 2 9 eres <- try $ resolveBuildPlan mbp (const False) (Map.fromList [ ($(mkPackageName "github"), Set.empty) ]) case eres of Left (UnknownPackages _ unknown _) -> do case Map.lookup $(mkPackageName "github") unknown of Nothing -> error "doesn't list github as unknown" Just _ -> return () {- Currently not implemented, see: https://github.com/fpco/stack/issues/159#issuecomment-107809418 case Map.lookup $(mkPackageName "failure") unknown of Nothing -> error "failure not listed" Just _ -> return () -} _ -> error $ "Unexpected result from resolveBuildPlan: " ++ show eres return () describe "shadowMiniBuildPlan" $ do let version = $(mkVersion "1.0.0") -- unimportant for this test pn = either throw id . parsePackageNameFromString mkMPI deps = MiniPackageInfo { mpiVersion = version , mpiFlags = Map.empty , mpiGhcOptions = [] , mpiPackageDeps = Set.fromList $ map pn $ words deps , mpiToolDeps = Set.empty , mpiExes = Set.empty , mpiHasLibrary = True , mpiGitSHA1 = Nothing } go x y = (pn x, mkMPI y) resourcet = go "resourcet" "" conduit = go "conduit" "resourcet" conduitExtra = go "conduit-extra" "conduit" text = go "text" "" attoparsec = go "attoparsec" "text" aeson = go "aeson" "text attoparsec" mkMBP pkgs = MiniBuildPlan { mbpCompilerVersion = GhcVersion version , mbpPackages = Map.fromList pkgs } mbpAll = mkMBP [resourcet, conduit, conduitExtra, text, attoparsec, aeson] test name input shadowed output extra = it name $ const $ shadowMiniBuildPlan input (Set.fromList $ map pn $ words shadowed) `shouldBe` (output, Map.fromList extra) test "no shadowing" mbpAll "" mbpAll [] test "shadow something that isn't there" mbpAll "does-not-exist" mbpAll [] test "shadow a leaf" mbpAll "conduit-extra" (mkMBP [resourcet, conduit, text, attoparsec, aeson]) [] test "shadow direct dep" mbpAll "conduit" (mkMBP [resourcet, text, attoparsec, aeson]) [conduitExtra] test "shadow deep dep" mbpAll "resourcet" (mkMBP [text, attoparsec, aeson]) [conduit, conduitExtra] test "shadow deep dep and leaf" mbpAll "resourcet aeson" (mkMBP [text, attoparsec]) [conduit, conduitExtra] test "shadow deep dep and direct dep" mbpAll "resourcet conduit" (mkMBP [text, attoparsec, aeson]) [conduitExtra]