staversion-0.2.2.0: test/Staversion/Internal/ExecSpec.hs
module Staversion.Internal.ExecSpec (main,spec) where
import Data.Either (isLeft)
import Data.IORef (readIORef)
import Data.List (isInfixOf)
import System.FilePath ((</>))
import Test.Hspec
import Staversion.Internal.BuildPlan (_setLTSDisambiguator)
import Staversion.Internal.Command (Command(..), defFormatConfig)
import Staversion.Internal.Exec
( processCommand,
_processCommandWithCustomBuildPlanManager
)
import Staversion.Internal.Query
( PackageName,
Query(..),
PackageSource(..),
ErrorMsg
)
import Staversion.Internal.Result
( Result(..),
ResultBody, ResultBody'(..),
ResultSource(..)
)
import Staversion.Internal.Log (defaultLogger, _mockLogger, Logger(loggerThreshold), LogLevel(..), LogEntry(..))
import Staversion.Internal.Cabal (Target(..))
import Staversion.Internal.Version (Version)
import Staversion.Internal.TestUtil (ver, simpleResultBody, verPairs)
main :: IO ()
main = hspec spec
spec :: Spec
spec = do
spec_processCommand_basic
spec_processCommand_disambiguates
spec_processCommand_error
spec_processCommand_basic :: Spec
spec_processCommand_basic = describe "processCommand" $ do
specify "QueryName, SourceStackage, hit" $ do
singleCase (SourceStackage "conpact_build_plan") (QueryName "drawille")
(Right $ simpleResultBody "drawille" [0,1,0,6])
specify "QueryName, SourceStackage, miss" $ do
singleCase (SourceStackage "conpact_build_plan") (QueryName "unknown")
(Right $ SimpleResultBody "unknown" Nothing)
specify "QueryName, SourceStackage, source not found" $ do
(logger, logs) <- _mockLogger
let src = SourceStackage "unknown"
query = QueryName "drawille"
comm = baseCommand { commSources = [src],
commQueries = [query],
commLogger = logger { loggerThreshold = Just LogInfo }
}
[got_ret] <- processCommand comm
(resultSourceQueried . resultIn) got_ret `shouldBe` src
(resultSourceReal . resultIn) got_ret `shouldBe` Nothing
resultFor got_ret `shouldBe` query
case resultBody got_ret of
Right _ -> expectationFailure "it should fail"
Left _ -> return ()
got_logs <- readIORef logs
let match :: LogEntry -> Bool
match (LogEntry level msg) = (level >= LogWarn)
&& ("unknown.yaml" `isInfixOf` msg)
&& ("not found" `isInfixOf` msg)
(length $ filter match got_logs) `shouldBe` 1
specify "QueryName, SourceStackage, full-mesh" $ do
let src2 = SourceStackage "lts-2.22_conpact"
src7 = SourceStackage "lts-7.0_conpact"
qc = QueryName "conduit"
qa = QueryName "aeson"
comm = baseCommand { commSources = [src2, src7], commQueries = [qc, qa] }
expected = [ Result { resultIn = ResultSource src2 (Just src2), resultFor = qc,
resultBody = Right $ simpleResultBody "conduit" [1,2,5]
},
Result { resultIn = ResultSource src2 (Just src2), resultFor = qa,
resultBody = Right $ simpleResultBody "aeson" [0,8,0,2]
},
Result { resultIn = ResultSource src7 (Just src7), resultFor = qc,
resultBody = Right $ simpleResultBody "conduit" [1,2,7]
},
Result { resultIn = ResultSource src7 (Just src7), resultFor = qa,
resultBody = Right $ simpleResultBody "aeson" [0,11,2,1]
}
]
processCommand comm `shouldReturn` expected
specify "QueryCabalfile, SourceStackage" $ do
let src = SourceStackage "lts-4.2"
cabal_file = ("test" </> "data" </> "foobar.cabal_test")
query = QueryCabalFile cabal_file
comm = baseCommand { commSources = [src], commQueries = [query] }
ret t vps = Result { resultIn = ResultSource src (Just src), resultFor = query,
resultBody = Right $ CabalResultBody cabal_file t vps
}
expected = [ ret TargetLibrary $ verPairs [ ("base", [4,8,2,0]),
("unordered-containers", [0,2,5,1])
],
-- no result for "executable" section because it has no build-depends field.
ret (TargetTestSuite "spec") $ verPairs [ ("base", [4,8,2,0]),
("staversion", []),
("text", [1,2,2,0]),
("filepath", [1,4,0,0]),
("bytestring", [0,10,6,0])
],
ret (TargetTestSuite "network-test") $ verPairs [ ("base", [4,8,2,0]),
("http-client", [0,4,26,2])
]
]
processCommand comm `shouldReturn` expected
singleCase :: PackageSource -> Query -> Either ErrorMsg ResultBody -> IO ()
singleCase src query exp_ret_vers = singleCase' src query (`shouldBe` exp_ret_vers)
singleCase' :: PackageSource -> Query -> (Either ErrorMsg ResultBody -> IO a) -> IO a
singleCase' src query checker = do
[got_ret] <- processCommand comm
(resultSourceQueried . resultIn) got_ret `shouldBe` src
let exp_source_real = either (const Nothing) (const $ Just $ src) $ resultBody got_ret
(resultSourceReal . resultIn) got_ret `shouldBe` exp_source_real
resultFor got_ret `shouldBe` query
checker $ resultBody got_ret
where
comm = baseCommand { commSources = [src],
commQueries = [query]
}
baseCommand :: Command
baseCommand = Command { commBuildPlanDir = "test" </> "data",
commLogger = defaultLogger { loggerThreshold = Nothing },
commSources = [],
commQueries = [],
commAllowNetwork = False,
commAggregator = Nothing,
commFormatConfig = defFormatConfig,
commStackCommand = "stack"
}
spec_processCommand_disambiguates :: Spec
spec_processCommand_disambiguates = describe "processCommand" $ do
it "disambiguates a partial resolver and sets resultReallyIn field" $ do
let comm = baseCommand { commSources = [SourceStackage "lts"],
commQueries = [QueryName "conduit"]
}
withMockDisam bp_man = do
_setLTSDisambiguator bp_man 4 2
return bp_man
[got_ret] <- _processCommandWithCustomBuildPlanManager withMockDisam comm
(resultSourceQueried . resultIn) got_ret `shouldBe` SourceStackage "lts"
(resultSourceReal . resultIn) got_ret `shouldBe` (Just $ SourceStackage "lts-4.2")
resultFor got_ret `shouldBe` QueryName "conduit"
resultBody got_ret `shouldBe` Right (simpleResultBody "conduit" [1,2,6,1])
spec_processCommand_error :: Spec
spec_processCommand_error = describe "processCommand" $ do
it "should continue processing after IO error in reading .cabal file" $ do
let src = SourceStackage "lts-4.2"
comm = baseCommand { commSources = [src],
commQueries = [ QueryCabalFile "this_does_not_exist.cabal",
QueryName "parsec"
]
}
[got_cabal, got_name] <- processCommand comm
resultFor got_cabal `shouldBe` QueryCabalFile "this_does_not_exist.cabal"
resultBody got_cabal `shouldSatisfy` isLeft
got_name `shouldBe` Result { resultIn = ResultSource src (Just src),
resultFor = QueryName "parsec",
resultBody = Right $ simpleResultBody "parsec" [3,1,9]
}