cabal init -i should sanitize suggested package name (fix #8404) (#8561)
[cabal.git] / cabal-install / tests / UnitTests / Distribution / Client / Init / Golden.hs
blob45c585f55ccd8c96e2ba8ea40a1d7cc7b3bbfe53
1 {-# LANGUAGE CPP #-}
2 {-# LANGUAGE LambdaCase #-}
3 module UnitTests.Distribution.Client.Init.Golden
4 ( tests
5 ) where
8 import Test.Tasty
9 import Test.Tasty.Golden
10 import Test.Tasty.HUnit
12 import qualified Data.ByteString.Lazy.Char8 as BS8
13 import Data.List.NonEmpty (fromList)
14 import Data.List.NonEmpty as NEL (NonEmpty, drop)
15 #if __GLASGOW_HASKELL__ < 804
16 import Data.Semigroup ((<>))
17 #endif
19 import Distribution.Client.Init.Types
20 import Distribution.Simple.PackageIndex hiding (fromList)
21 import Distribution.Verbosity
22 import Distribution.Client.Types.SourcePackageDb
23 import Distribution.Client.Init.Interactive.Command
24 import Distribution.Client.Init.Format
25 import Distribution.Fields.Pretty
26 import Distribution.Types.PackageName (PackageName)
27 import Distribution.Client.Init.FlagExtractors
28 import Distribution.Simple.Flag
29 import Distribution.CabalSpecVersion
31 import System.FilePath
33 import UnitTests.Distribution.Client.Init.Utils
34 import Distribution.Client.Init.Defaults
36 -- -------------------------------------------------------------------- --
37 -- golden test suite
39 -- | Golden executable tests.
41 -- We test target generation against a golden file in @tests/fixtures/init/@ for
42 -- executables, libraries, and test targets with the following:
44 -- * Empty flags, non-simple target gen, no special options
45 -- * Empty flags, simple target gen, no special options
46 -- * Empty flags, non-simple target gen, with generated comments (no minimal setting)
47 -- * Empty flags, non-simple target gen, with minimal setting (no generated comments)
48 -- * Empty flags, non-simple target gen, minimal and generated comments set.
50 -- Additionally, we test whole @.cabal@ file generation for every combination
51 -- of library, lib + tests, exe, exe + tests, exe + lib, exe + lib + tests
52 -- and so on against the same options.
54 tests
55 :: Verbosity
56 -> InitFlags
57 -> InstalledPackageIndex
58 -> SourcePackageDb
59 -> TestTree
60 tests v initFlags pkgIx srcDb = testGroup "golden"
61 [ goldenLibTests v pkgIx pkgDir pkgName
62 , goldenExeTests v pkgIx pkgDir pkgName
63 , goldenTestTests v pkgIx pkgDir pkgName
64 , goldenPkgDescTests v srcDb pkgDir pkgName
65 , goldenCabalTests v pkgIx srcDb
67 where
68 pkgDir = evalPrompt (getPackageDir initFlags)
69 $ fromList ["."]
70 pkgName = evalPrompt (packageNamePrompt srcDb initFlags)
71 $ fromList ["test-package", "test-package", "y"]
73 goldenPkgDescTests
74 :: Verbosity
75 -> SourcePackageDb
76 -> FilePath
77 -> PackageName
78 -> TestTree
79 goldenPkgDescTests v srcDb pkgDir pkgName = testGroup "package description golden tests"
80 [ goldenVsString "Empty flags, non-simple, no comments"
81 (goldenPkgDesc "pkg.golden") $
82 let opts = WriteOpts False False False v pkgDir Library pkgName defaultCabalVersion
83 in runPkgDesc opts emptyFlags pkgArgs
85 , goldenVsString "Empty flags, non-simple, with comments"
86 (goldenPkgDesc "pkg-with-comments.golden") $
87 let opts = WriteOpts False False False v pkgDir Library pkgName defaultCabalVersion
88 in runPkgDesc opts emptyFlags pkgArgs
90 , goldenVsString "Dummy flags, with comments"
91 (goldenPkgDesc "pkg-with-flags.golden") $
92 let opts = WriteOpts False False False v pkgDir Library pkgName defaultCabalVersion
93 in runPkgDesc opts dummyFlags pkgArgs
95 , goldenVsString "Dummy flags, old cabal version, with comments"
96 (goldenPkgDesc "pkg-old-cabal-with-flags.golden") $
97 let opts = WriteOpts False False False v pkgDir Library pkgName defaultCabalVersion
98 in runPkgDesc opts (dummyFlags {cabalVersion = Flag CabalSpecV2_0}) pkgArgs
100 where
101 runPkgDesc opts flags args = do
102 case _runPrompt (genPkgDescription flags srcDb) args of
103 Left e -> assertFailure $ show e
104 Right (pkg, _) -> mkStanza $ mkPkgDescription opts pkg
106 goldenExeTests
107 :: Verbosity
108 -> InstalledPackageIndex
109 -> FilePath
110 -> PackageName
111 -> TestTree
112 goldenExeTests v pkgIx pkgDir pkgName = testGroup "exe golden tests"
113 [ goldenVsString "Empty flags, not simple, no options, no comments"
114 (goldenExe "exe-no-comments.golden") $
115 let opts = WriteOpts False False True v pkgDir Executable pkgName defaultCabalVersion
116 in runGoldenExe opts exeArgs emptyFlags
118 , goldenVsString "Empty flags, not simple, with comments + no minimal"
119 (goldenExe "exe-with-comments.golden") $
120 let opts = WriteOpts False False False v pkgDir Executable pkgName defaultCabalVersion
121 in runGoldenExe opts exeArgs emptyFlags
123 , goldenVsString "Empty flags, not simple, with minimal + no comments"
124 (goldenExe "exe-minimal-no-comments.golden") $
125 let opts = WriteOpts False True True v pkgDir Executable pkgName defaultCabalVersion
126 in runGoldenExe opts exeArgs emptyFlags
128 , goldenVsString "Empty flags, not simple, with minimal + comments"
129 (goldenExe "exe-simple-minimal-with-comments.golden") $
130 let opts = WriteOpts False True False v pkgDir Executable pkgName defaultCabalVersion
131 in runGoldenExe opts exeArgs emptyFlags
133 , goldenVsString "Build tools flag, not simple, with comments + no minimal"
134 (goldenExe "exe-build-tools-with-comments.golden") $
135 let opts = WriteOpts False False False v pkgDir Executable pkgName defaultCabalVersion
136 in runGoldenExe opts exeArgs (emptyFlags {buildTools = Flag ["happy"]})
138 where
139 runGoldenExe opts args flags =
140 case _runPrompt (genExeTarget flags pkgIx) args of
141 Right (t, _) -> mkStanza [mkExeStanza opts $ t {_exeDependencies = mangleBaseDep t _exeDependencies}]
142 Left e -> assertFailure $ show e
144 goldenLibTests
145 :: Verbosity
146 -> InstalledPackageIndex
147 -> FilePath
148 -> PackageName
149 -> TestTree
150 goldenLibTests v pkgIx pkgDir pkgName = testGroup "lib golden tests"
151 [ goldenVsString "Empty flags, not simple, no options, no comments"
152 (goldenLib "lib-no-comments.golden") $
153 let opts = WriteOpts False False True v pkgDir Library pkgName defaultCabalVersion
154 in runGoldenLib opts libArgs emptyFlags
156 , goldenVsString "Empty flags, simple, no options, no comments"
157 (goldenLib "lib-simple-no-comments.golden") $
158 let opts = WriteOpts False False True v pkgDir Library pkgName defaultCabalVersion
159 in runGoldenLib opts libArgs emptyFlags
161 , goldenVsString "Empty flags, not simple, with comments + no minimal"
162 (goldenLib "lib-with-comments.golden") $
163 let opts = WriteOpts False False False v pkgDir Library pkgName defaultCabalVersion
164 in runGoldenLib opts libArgs emptyFlags
166 , goldenVsString "Empty flags, not simple, with minimal + no comments"
167 (goldenLib "lib-minimal-no-comments.golden") $
168 let opts = WriteOpts False True True v pkgDir Library pkgName defaultCabalVersion
169 in runGoldenLib opts libArgs emptyFlags
171 , goldenVsString "Empty flags, not simple, with minimal + comments"
172 (goldenLib "lib-simple-minimal-with-comments.golden") $
173 let opts = WriteOpts False True False v pkgDir Library pkgName defaultCabalVersion
174 in runGoldenLib opts libArgs emptyFlags
176 , goldenVsString "Build tools flag, not simple, with comments + no minimal"
177 (goldenLib "lib-build-tools-with-comments.golden") $
178 let opts = WriteOpts False False False v pkgDir Library pkgName defaultCabalVersion
179 in runGoldenLib opts libArgs (emptyFlags {buildTools = Flag ["happy"]})
181 where
182 runGoldenLib opts args flags =
183 case _runPrompt (genLibTarget flags pkgIx) args of
184 Right (t, _) -> mkStanza [mkLibStanza opts $ t {_libDependencies = mangleBaseDep t _libDependencies}]
185 Left e -> assertFailure $ show e
187 goldenTestTests
188 :: Verbosity
189 -> InstalledPackageIndex
190 -> FilePath
191 -> PackageName
192 -> TestTree
193 goldenTestTests v pkgIx pkgDir pkgName = testGroup "test golden tests"
194 [ goldenVsString "Empty flags, not simple, no options, no comments"
195 (goldenTest "test-no-comments.golden") $
196 let opts = WriteOpts False False True v pkgDir Library pkgName defaultCabalVersion
197 in runGoldenTest opts testArgs emptyFlags
199 , goldenVsString "Empty flags, not simple, with comments + no minimal"
200 (goldenTest "test-with-comments.golden") $
201 let opts = WriteOpts False False False v pkgDir Library pkgName defaultCabalVersion
202 in runGoldenTest opts testArgs emptyFlags
204 , goldenVsString "Empty flags, not simple, with minimal + no comments"
205 (goldenTest "test-minimal-no-comments.golden") $
206 let opts = WriteOpts False True True v pkgDir Library pkgName defaultCabalVersion
207 in runGoldenTest opts testArgs emptyFlags
209 , goldenVsString "Empty flags, not simple, with minimal + comments"
210 (goldenTest "test-simple-minimal-with-comments.golden") $
211 let opts = WriteOpts False True False v pkgDir Library pkgName defaultCabalVersion
212 in runGoldenTest opts testArgs emptyFlags
214 , goldenVsString "Build tools flag, not simple, with comments + no minimal"
215 (goldenTest "test-build-tools-with-comments.golden") $
216 let opts = WriteOpts False False False v pkgDir Library pkgName defaultCabalVersion
217 in runGoldenTest opts testArgs (emptyFlags {buildTools = Flag ["happy"]})
219 , goldenVsString "Standalone tests, empty flags, not simple, no options, no comments"
220 (goldenTest "standalone-test-no-comments.golden") $
221 let opts = WriteOpts False False True v pkgDir TestSuite pkgName defaultCabalVersion
222 in runGoldenTest opts testArgs emptyFlags
224 , goldenVsString "Standalone tests, empty flags, not simple, with comments + no minimal"
225 (goldenTest "standalone-test-with-comments.golden") $
226 let opts = WriteOpts False False False v pkgDir TestSuite pkgName defaultCabalVersion
227 in runGoldenTest opts testArgs emptyFlags
229 where
230 runGoldenTest opts args flags =
231 case _runPrompt (genTestTarget flags pkgIx) args of
232 Left e -> assertFailure $ show e
233 Right (Nothing, _) -> assertFailure
234 "goldenTestTests: Tests not enabled."
235 Right (Just t, _) -> mkStanza [mkTestStanza opts $ t {_testDependencies = mangleBaseDep t _testDependencies}]
237 -- | Full cabal file golden tests
238 goldenCabalTests
239 :: Verbosity
240 -> InstalledPackageIndex
241 -> SourcePackageDb
242 -> TestTree
243 goldenCabalTests v pkgIx srcDb = testGroup ".cabal file golden tests"
244 [ goldenVsString "Library and executable, empty flags, not simple, with comments + no minimal"
245 (goldenCabal "cabal-lib-and-exe-with-comments.golden") $
246 runGoldenTest (fullProjArgs "Y") emptyFlags
248 , goldenVsString "Library and executable, empty flags, not simple, no comments + no minimal"
249 (goldenCabal "cabal-lib-and-exe-no-comments.golden") $
250 runGoldenTest (fullProjArgs "N") emptyFlags
252 , goldenVsString "Library, empty flags, not simple, with comments + no minimal"
253 (goldenCabal "cabal-lib-with-comments.golden") $
254 runGoldenTest (libProjArgs "Y") emptyFlags
256 , goldenVsString "Library, empty flags, not simple, no comments + no minimal"
257 (goldenCabal "cabal-lib-no-comments.golden") $
258 runGoldenTest (libProjArgs "N") emptyFlags
260 , goldenVsString "Test suite, empty flags, not simple, with comments + no minimal"
261 (goldenCabal "cabal-test-suite-with-comments.golden") $
262 runGoldenTest (testProjArgs "Y") emptyFlags
264 , goldenVsString "Test suite, empty flags, not simple, no comments + no minimal"
265 (goldenCabal "cabal-test-suite-no-comments.golden") $
266 runGoldenTest (testProjArgs "N") emptyFlags
268 where
269 runGoldenTest args flags =
270 case _runPrompt (createProject v pkgIx srcDb flags) args of
271 Left e -> assertFailure $ show e
273 (Right (ProjectSettings opts pkgDesc (Just libTarget) (Just exeTarget) (Just testTarget), _)) -> do
274 let pkgFields = mkPkgDescription opts pkgDesc
275 commonStanza = mkCommonStanza opts
276 libStanza = mkLibStanza opts $ libTarget {_libDependencies = mangleBaseDep libTarget _libDependencies}
277 exeStanza = mkExeStanza opts $ exeTarget {_exeDependencies = mangleBaseDep exeTarget _exeDependencies}
278 testStanza = mkTestStanza opts $ testTarget {_testDependencies = mangleBaseDep testTarget _testDependencies}
280 mkStanza $ pkgFields ++ [commonStanza, libStanza, exeStanza, testStanza]
282 (Right (ProjectSettings opts pkgDesc (Just libTarget) Nothing (Just testTarget), _)) -> do
283 let pkgFields = mkPkgDescription opts pkgDesc
284 commonStanza = mkCommonStanza opts
285 libStanza = mkLibStanza opts $ libTarget {_libDependencies = mangleBaseDep libTarget _libDependencies}
286 testStanza = mkTestStanza opts $ testTarget {_testDependencies = mangleBaseDep testTarget _testDependencies}
288 mkStanza $ pkgFields ++ [commonStanza, libStanza, testStanza]
290 (Right (ProjectSettings opts pkgDesc Nothing Nothing (Just testTarget), _)) -> do
291 let pkgFields = mkPkgDescription opts pkgDesc
292 commonStanza = mkCommonStanza opts
293 testStanza = mkTestStanza opts $ testTarget {_testDependencies = mangleBaseDep testTarget _testDependencies}
295 mkStanza $ pkgFields ++ [commonStanza, testStanza]
297 (Right (ProjectSettings _ _ l e t, _)) -> assertFailure $
298 show l ++ "\n" ++ show e ++ "\n" ++ show t
301 -- -------------------------------------------------------------------- --
302 -- utils
304 mkStanza :: [PrettyField FieldAnnotation] -> IO BS8.ByteString
305 mkStanza fields = return . BS8.pack $ showFields'
306 annCommentLines postProcessFieldLines
307 4 fields
309 golden :: FilePath
310 golden = "tests" </> "fixtures" </> "init" </> "golden"
312 goldenExe :: FilePath -> FilePath
313 goldenExe file = golden </> "exe" </> file
315 goldenTest :: FilePath -> FilePath
316 goldenTest file = golden </> "test" </> file
318 goldenLib :: FilePath -> FilePath
319 goldenLib file = golden </> "lib" </> file
321 goldenCabal :: FilePath -> FilePath
322 goldenCabal file = golden </> "cabal" </> file
324 goldenPkgDesc :: FilePath -> FilePath
325 goldenPkgDesc file = golden </> "pkg-desc" </> file
327 libArgs :: NonEmpty String
328 libArgs = fromList ["1", "2"]
330 exeArgs :: NonEmpty String
331 exeArgs = fromList ["1", "2", "1"]
333 testArgs :: NonEmpty String
334 testArgs = fromList ["y", "1", "test", "1"]
336 pkgArgs :: NonEmpty String
337 pkgArgs = fromList
338 [ "5"
339 , "foo-package"
340 , "foo-package"
341 , "y"
342 , "0.1.0.0"
343 , "2"
344 , "git username"
345 , "foo-kmett"
346 , "git email"
347 , "foo-kmett@kmett.kmett"
348 , "home"
349 , "synopsis"
350 , "4"
353 testProjArgs :: String -> NonEmpty String
354 testProjArgs comments = fromList ["4", "n", "foo-package"]
355 <> pkgArgs
356 <> fromList (NEL.drop 1 testArgs)
357 <> fromList [comments]
359 libProjArgs :: String -> NonEmpty String
360 libProjArgs comments = fromList ["1", "n", "foo-package"]
361 <> pkgArgs
362 <> libArgs
363 <> testArgs
364 <> fromList [comments]
366 fullProjArgs :: String -> NonEmpty String
367 fullProjArgs comments = fromList ["3", "n", "foo-package"]
368 <> pkgArgs
369 <> libArgs
370 <> exeArgs
371 <> testArgs
372 <> fromList [comments]