cabal-install-3.16.0.0: tests/UnitTests/Distribution/Client/Init/Golden.hs
{-# LANGUAGE CPP #-}
module UnitTests.Distribution.Client.Init.Golden
( tests
) where
import Test.Tasty
import Test.Tasty.Golden
import Test.Tasty.HUnit
import qualified Data.ByteString.Lazy.Char8 as BS8
import Data.List.NonEmpty (fromList)
import Data.List.NonEmpty as NEL (NonEmpty, drop)
#if __GLASGOW_HASKELL__ < 804
import Data.Semigroup ((<>))
#endif
import Distribution.CabalSpecVersion
import Distribution.Client.Init.FlagExtractors
import Distribution.Client.Init.Format
import Distribution.Client.Init.Interactive.Command
import Distribution.Client.Init.Types
import Distribution.Client.Types.SourcePackageDb
import Distribution.Fields.Pretty
import Distribution.Simple.Flag
import Distribution.Simple.PackageIndex hiding (fromList)
import Distribution.Types.PackageName (PackageName)
import Distribution.Verbosity
import System.FilePath
import Distribution.Client.Init.Defaults
import UnitTests.Distribution.Client.Init.Utils
-- -------------------------------------------------------------------- --
-- golden test suite
-- | Golden executable tests.
--
-- We test target generation against a golden file in @tests/fixtures/init/@ for
-- executables, libraries, and test targets with the following:
--
-- * Empty flags, non-simple target gen, no special options
-- * Empty flags, simple target gen, no special options
-- * Empty flags, non-simple target gen, with generated comments (no minimal setting)
-- * Empty flags, non-simple target gen, with minimal setting (no generated comments)
-- * Empty flags, non-simple target gen, minimal and generated comments set.
--
-- Additionally, we test whole @.cabal@ file generation for every combination
-- of library, lib + tests, exe, exe + tests, exe + lib, exe + lib + tests
-- and so on against the same options.
tests
:: Verbosity
-> InitFlags
-> InstalledPackageIndex
-> SourcePackageDb
-> TestTree
tests v initFlags pkgIx srcDb =
testGroup
"golden"
[ goldenLibTests v pkgIx pkgDir pkgName
, goldenExeTests v pkgIx pkgDir pkgName
, goldenTestTests v pkgIx pkgDir pkgName
, goldenPkgDescTests v srcDb pkgDir pkgName
, goldenCabalTests v pkgIx srcDb
]
where
pkgDir =
evalPrompt (getPackageDir initFlags) $
fromList ["."]
pkgName =
evalPrompt (packageNamePrompt srcDb initFlags) $
fromList ["test-package", "test-package", "y"]
goldenPkgDescTests
:: Verbosity
-> SourcePackageDb
-> FilePath
-> PackageName
-> TestTree
goldenPkgDescTests v srcDb pkgDir pkgName =
testGroup
"package description golden tests"
[ goldenVsString
"Empty flags, non-simple, no comments"
(goldenPkgDesc "pkg.golden")
$ let opts = WriteOpts False False False v pkgDir Library pkgName defaultCabalVersion
in runPkgDesc opts emptyFlags pkgArgs
, goldenVsString
"Empty flags, non-simple, with comments"
(goldenPkgDesc "pkg-with-comments.golden")
$ let opts = WriteOpts False False False v pkgDir Library pkgName defaultCabalVersion
in runPkgDesc opts emptyFlags pkgArgs
, goldenVsString
"Dummy flags, >= cabal version syntax, with comments"
(goldenPkgDesc "pkg-with-flags.golden")
$ let opts = WriteOpts False False False v pkgDir Library pkgName defaultCabalVersion
in runPkgDesc opts (dummyFlags{cabalVersion = Flag CabalSpecV1_0}) pkgArgs
, goldenVsString
"Dummy flags, old cabal version, with comments"
(goldenPkgDesc "pkg-old-cabal-with-flags.golden")
$ let opts = WriteOpts False False False v pkgDir Library pkgName defaultCabalVersion
in runPkgDesc opts (dummyFlags{cabalVersion = Flag CabalSpecV2_0}) pkgArgs
]
where
runPkgDesc opts flags args = do
case runPrompt (genPkgDescription flags srcDb) args of
Left e -> assertFailure $ show e
Right (pkg, _) -> mkStanza $ mkPkgDescription opts pkg
goldenExeTests
:: Verbosity
-> InstalledPackageIndex
-> FilePath
-> PackageName
-> TestTree
goldenExeTests v pkgIx pkgDir pkgName =
testGroup
"exe golden tests"
[ goldenVsString
"Empty flags, not simple, no options, no comments"
(goldenExe "exe-no-comments.golden")
$ let opts = WriteOpts False False True v pkgDir Executable pkgName defaultCabalVersion
in runGoldenExe opts exeArgs emptyFlags
, goldenVsString
"Empty flags, not simple, with comments + no minimal"
(goldenExe "exe-with-comments.golden")
$ let opts = WriteOpts False False False v pkgDir Executable pkgName defaultCabalVersion
in runGoldenExe opts exeArgs emptyFlags
, goldenVsString
"Empty flags, not simple, with minimal + no comments"
(goldenExe "exe-minimal-no-comments.golden")
$ let opts = WriteOpts False True True v pkgDir Executable pkgName defaultCabalVersion
in runGoldenExe opts exeArgs emptyFlags
, goldenVsString
"Empty flags, not simple, with minimal + comments"
(goldenExe "exe-simple-minimal-with-comments.golden")
$ let opts = WriteOpts False True False v pkgDir Executable pkgName defaultCabalVersion
in runGoldenExe opts exeArgs emptyFlags
, goldenVsString
"Build tools flag, not simple, with comments + no minimal"
(goldenExe "exe-build-tools-with-comments.golden")
$ let opts = WriteOpts False False False v pkgDir Executable pkgName defaultCabalVersion
in runGoldenExe opts exeArgs (emptyFlags{buildTools = Flag ["happy"]})
]
where
runGoldenExe opts args flags =
case runPrompt (genExeTarget flags pkgIx) args of
Right (t, _) -> mkStanza [mkExeStanza opts $ t{_exeDependencies = mangleBaseDep t _exeDependencies}]
Left e -> assertFailure $ show e
goldenLibTests
:: Verbosity
-> InstalledPackageIndex
-> FilePath
-> PackageName
-> TestTree
goldenLibTests v pkgIx pkgDir pkgName =
testGroup
"lib golden tests"
[ goldenVsString
"Empty flags, not simple, no options, no comments"
(goldenLib "lib-no-comments.golden")
$ let opts = WriteOpts False False True v pkgDir Library pkgName defaultCabalVersion
in runGoldenLib opts libArgs emptyFlags
, goldenVsString
"Empty flags, simple, no options, no comments"
(goldenLib "lib-simple-no-comments.golden")
$ let opts = WriteOpts False False True v pkgDir Library pkgName defaultCabalVersion
in runGoldenLib opts libArgs emptyFlags
, goldenVsString
"Empty flags, not simple, with comments + no minimal"
(goldenLib "lib-with-comments.golden")
$ let opts = WriteOpts False False False v pkgDir Library pkgName defaultCabalVersion
in runGoldenLib opts libArgs emptyFlags
, goldenVsString
"Empty flags, not simple, with minimal + no comments"
(goldenLib "lib-minimal-no-comments.golden")
$ let opts = WriteOpts False True True v pkgDir Library pkgName defaultCabalVersion
in runGoldenLib opts libArgs emptyFlags
, goldenVsString
"Empty flags, not simple, with minimal + comments"
(goldenLib "lib-simple-minimal-with-comments.golden")
$ let opts = WriteOpts False True False v pkgDir Library pkgName defaultCabalVersion
in runGoldenLib opts libArgs emptyFlags
, goldenVsString
"Build tools flag, not simple, with comments + no minimal"
(goldenLib "lib-build-tools-with-comments.golden")
$ let opts = WriteOpts False False False v pkgDir Library pkgName defaultCabalVersion
in runGoldenLib opts libArgs (emptyFlags{buildTools = Flag ["happy"]})
]
where
runGoldenLib opts args flags =
case runPrompt (genLibTarget flags pkgIx) args of
Right (t, _) -> mkStanza [mkLibStanza opts $ t{_libDependencies = mangleBaseDep t _libDependencies}]
Left e -> assertFailure $ show e
goldenTestTests
:: Verbosity
-> InstalledPackageIndex
-> FilePath
-> PackageName
-> TestTree
goldenTestTests v pkgIx pkgDir pkgName =
testGroup
"test golden tests"
[ goldenVsString
"Empty flags, not simple, no options, no comments"
(goldenTest "test-no-comments.golden")
$ let opts = WriteOpts False False True v pkgDir Library pkgName defaultCabalVersion
in runGoldenTest opts testArgs emptyFlags
, goldenVsString
"Empty flags, not simple, with comments + no minimal"
(goldenTest "test-with-comments.golden")
$ let opts = WriteOpts False False False v pkgDir Library pkgName defaultCabalVersion
in runGoldenTest opts testArgs emptyFlags
, goldenVsString
"Empty flags, not simple, with minimal + no comments"
(goldenTest "test-minimal-no-comments.golden")
$ let opts = WriteOpts False True True v pkgDir Library pkgName defaultCabalVersion
in runGoldenTest opts testArgs emptyFlags
, goldenVsString
"Empty flags, not simple, with minimal + comments"
(goldenTest "test-simple-minimal-with-comments.golden")
$ let opts = WriteOpts False True False v pkgDir Library pkgName defaultCabalVersion
in runGoldenTest opts testArgs emptyFlags
, goldenVsString
"Build tools flag, not simple, with comments + no minimal"
(goldenTest "test-build-tools-with-comments.golden")
$ let opts = WriteOpts False False False v pkgDir Library pkgName defaultCabalVersion
in runGoldenTest opts testArgs (emptyFlags{buildTools = Flag ["happy"]})
, goldenVsString
"Standalone tests, empty flags, not simple, no options, no comments"
(goldenTest "standalone-test-no-comments.golden")
$ let opts = WriteOpts False False True v pkgDir TestSuite pkgName defaultCabalVersion
in runGoldenTest opts testArgs emptyFlags
, goldenVsString
"Standalone tests, empty flags, not simple, with comments + no minimal"
(goldenTest "standalone-test-with-comments.golden")
$ let opts = WriteOpts False False False v pkgDir TestSuite pkgName defaultCabalVersion
in runGoldenTest opts testArgs emptyFlags
]
where
runGoldenTest opts args flags =
case runPrompt (genTestTarget flags pkgIx) args of
Left e -> assertFailure $ show e
Right (Nothing, _) ->
assertFailure
"goldenTestTests: Tests not enabled."
Right (Just t, _) -> mkStanza [mkTestStanza opts $ t{_testDependencies = mangleBaseDep t _testDependencies}]
-- | Full cabal file golden tests
goldenCabalTests
:: Verbosity
-> InstalledPackageIndex
-> SourcePackageDb
-> TestTree
goldenCabalTests v pkgIx srcDb =
testGroup
".cabal file golden tests"
[ goldenVsString
"Library and executable, empty flags, not simple, with comments + no minimal"
(goldenCabal "cabal-lib-and-exe-with-comments.golden")
$ runGoldenTest (fullProjArgs "Y") emptyFlags
, goldenVsString
"Library and executable, empty flags, not simple, no comments + no minimal"
(goldenCabal "cabal-lib-and-exe-no-comments.golden")
$ runGoldenTest (fullProjArgs "N") emptyFlags
, goldenVsString
"Library, empty flags, not simple, with comments + no minimal"
(goldenCabal "cabal-lib-with-comments.golden")
$ runGoldenTest (libProjArgs "Y") emptyFlags
, goldenVsString
"Library, empty flags, not simple, no comments + no minimal"
(goldenCabal "cabal-lib-no-comments.golden")
$ runGoldenTest (libProjArgs "N") emptyFlags
, goldenVsString
"Test suite, empty flags, not simple, with comments + no minimal"
(goldenCabal "cabal-test-suite-with-comments.golden")
$ runGoldenTest (testProjArgs "Y") emptyFlags
, goldenVsString
"Test suite, empty flags, not simple, no comments + no minimal"
(goldenCabal "cabal-test-suite-no-comments.golden")
$ runGoldenTest (testProjArgs "N") emptyFlags
]
where
runGoldenTest args flags =
case runPrompt (createProject v pkgIx srcDb flags) args of
Left e -> assertFailure $ show e
(Right (ProjectSettings opts pkgDesc (Just libTarget) (Just exeTarget) (Just testTarget), _)) -> do
let pkgFields = mkPkgDescription opts pkgDesc
commonStanza = mkCommonStanza opts
libStanza = mkLibStanza opts $ libTarget{_libDependencies = mangleBaseDep libTarget _libDependencies}
exeStanza = mkExeStanza opts $ exeTarget{_exeDependencies = mangleBaseDep exeTarget _exeDependencies}
testStanza = mkTestStanza opts $ testTarget{_testDependencies = mangleBaseDep testTarget _testDependencies}
mkStanza $ pkgFields ++ [commonStanza, libStanza, exeStanza, testStanza]
(Right (ProjectSettings opts pkgDesc (Just libTarget) Nothing (Just testTarget), _)) -> do
let pkgFields = mkPkgDescription opts pkgDesc
commonStanza = mkCommonStanza opts
libStanza = mkLibStanza opts $ libTarget{_libDependencies = mangleBaseDep libTarget _libDependencies}
testStanza = mkTestStanza opts $ testTarget{_testDependencies = mangleBaseDep testTarget _testDependencies}
mkStanza $ pkgFields ++ [commonStanza, libStanza, testStanza]
(Right (ProjectSettings opts pkgDesc Nothing Nothing (Just testTarget), _)) -> do
let pkgFields = mkPkgDescription opts pkgDesc
commonStanza = mkCommonStanza opts
testStanza = mkTestStanza opts $ testTarget{_testDependencies = mangleBaseDep testTarget _testDependencies}
mkStanza $ pkgFields ++ [commonStanza, testStanza]
(Right (ProjectSettings _ _ l e t, _)) ->
assertFailure $
show l ++ "\n" ++ show e ++ "\n" ++ show t
-- -------------------------------------------------------------------- --
-- utils
mkStanza :: [PrettyField FieldAnnotation] -> IO BS8.ByteString
mkStanza fields =
return . BS8.pack $
showFields'
annCommentLines
postProcessFieldLines
4
fields
golden :: FilePath
golden = "tests" </> "fixtures" </> "init" </> "golden"
goldenExe :: FilePath -> FilePath
goldenExe file = golden </> "exe" </> file
goldenTest :: FilePath -> FilePath
goldenTest file = golden </> "test" </> file
goldenLib :: FilePath -> FilePath
goldenLib file = golden </> "lib" </> file
goldenCabal :: FilePath -> FilePath
goldenCabal file = golden </> "cabal" </> file
goldenPkgDesc :: FilePath -> FilePath
goldenPkgDesc file = golden </> "pkg-desc" </> file
libArgs :: NonEmpty String
libArgs = fromList ["1", "2"]
exeArgs :: NonEmpty String
exeArgs = fromList ["1", "2", "1"]
testArgs :: NonEmpty String
testArgs = fromList ["y", "1", "test", "1"]
pkgArgs :: NonEmpty String
pkgArgs =
fromList
[ "5"
, "foo-package"
, "foo-package"
, "y"
, "0.1.0.0"
, "2"
, "git username"
, "foo-kmett"
, "git email"
, "foo-kmett@kmett.kmett"
, "home"
, "synopsis"
, "4"
]
testProjArgs :: String -> NonEmpty String
testProjArgs comments =
fromList ["4", "test-dir", "[]", "foo-package"]
<> pkgArgs
<> fromList (NEL.drop 1 testArgs)
<> fromList [comments]
libProjArgs :: String -> NonEmpty String
libProjArgs comments =
fromList ["1", "test-dir", "[]", "foo-package"]
<> pkgArgs
<> libArgs
<> testArgs
<> fromList [comments]
fullProjArgs :: String -> NonEmpty String
fullProjArgs comments =
fromList ["3", "test-dir", "[]", "foo-package"]
<> pkgArgs
<> libArgs
<> exeArgs
<> testArgs
<> fromList [comments]