Merge pull request #10709 from Kleidukos/cabal-3.14.1.1-release-notes
[cabal.git] / cabal-install / tests / UnitTests / Distribution / Client / Init / Golden.hs
blob2bc0fb5e3e8b090ee1a7e4af39a9d088d3c34b9f
1 {-# LANGUAGE CPP #-}
3 module UnitTests.Distribution.Client.Init.Golden
4 ( tests
5 ) where
7 import Test.Tasty
8 import Test.Tasty.Golden
9 import Test.Tasty.HUnit
11 import qualified Data.ByteString.Lazy.Char8 as BS8
12 import Data.List.NonEmpty (fromList)
13 import Data.List.NonEmpty as NEL (NonEmpty, drop)
14 #if __GLASGOW_HASKELL__ < 804
15 import Data.Semigroup ((<>))
16 #endif
18 import Distribution.CabalSpecVersion
19 import Distribution.Client.Init.FlagExtractors
20 import Distribution.Client.Init.Format
21 import Distribution.Client.Init.Interactive.Command
22 import Distribution.Client.Init.Types
23 import Distribution.Client.Types.SourcePackageDb
24 import Distribution.Fields.Pretty
25 import Distribution.Simple.Flag
26 import Distribution.Simple.PackageIndex hiding (fromList)
27 import Distribution.Types.PackageName (PackageName)
28 import Distribution.Verbosity
30 import System.FilePath
32 import Distribution.Client.Init.Defaults
33 import UnitTests.Distribution.Client.Init.Utils
35 -- -------------------------------------------------------------------- --
36 -- golden test suite
38 -- | Golden executable tests.
40 -- We test target generation against a golden file in @tests/fixtures/init/@ for
41 -- executables, libraries, and test targets with the following:
43 -- * Empty flags, non-simple target gen, no special options
44 -- * Empty flags, simple target gen, no special options
45 -- * Empty flags, non-simple target gen, with generated comments (no minimal setting)
46 -- * Empty flags, non-simple target gen, with minimal setting (no generated comments)
47 -- * Empty flags, non-simple target gen, minimal and generated comments set.
49 -- Additionally, we test whole @.cabal@ file generation for every combination
50 -- of library, lib + tests, exe, exe + tests, exe + lib, exe + lib + tests
51 -- and so on against the same options.
52 tests
53 :: Verbosity
54 -> InitFlags
55 -> InstalledPackageIndex
56 -> SourcePackageDb
57 -> TestTree
58 tests v initFlags pkgIx srcDb =
59 testGroup
60 "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 =
69 evalPrompt (getPackageDir initFlags) $
70 fromList ["."]
71 pkgName =
72 evalPrompt (packageNamePrompt srcDb initFlags) $
73 fromList ["test-package", "test-package", "y"]
75 goldenPkgDescTests
76 :: Verbosity
77 -> SourcePackageDb
78 -> FilePath
79 -> PackageName
80 -> TestTree
81 goldenPkgDescTests v srcDb pkgDir pkgName =
82 testGroup
83 "package description golden tests"
84 [ goldenVsString
85 "Empty flags, non-simple, no comments"
86 (goldenPkgDesc "pkg.golden")
87 $ let opts = WriteOpts False False False v pkgDir Library pkgName defaultCabalVersion
88 in runPkgDesc opts emptyFlags pkgArgs
89 , goldenVsString
90 "Empty flags, non-simple, with comments"
91 (goldenPkgDesc "pkg-with-comments.golden")
92 $ let opts = WriteOpts False False False v pkgDir Library pkgName defaultCabalVersion
93 in runPkgDesc opts emptyFlags pkgArgs
94 , goldenVsString
95 "Dummy flags, >= cabal version syntax, with comments"
96 (goldenPkgDesc "pkg-with-flags.golden")
97 $ let opts = WriteOpts False False False v pkgDir Library pkgName defaultCabalVersion
98 in runPkgDesc opts (dummyFlags{cabalVersion = Flag CabalSpecV1_0}) pkgArgs
99 , goldenVsString
100 "Dummy flags, old cabal version, with comments"
101 (goldenPkgDesc "pkg-old-cabal-with-flags.golden")
102 $ let opts = WriteOpts False False False v pkgDir Library pkgName defaultCabalVersion
103 in runPkgDesc opts (dummyFlags{cabalVersion = Flag CabalSpecV2_0}) pkgArgs
105 where
106 runPkgDesc opts flags args = do
107 case runPrompt (genPkgDescription flags srcDb) args of
108 Left e -> assertFailure $ show e
109 Right (pkg, _) -> mkStanza $ mkPkgDescription opts pkg
111 goldenExeTests
112 :: Verbosity
113 -> InstalledPackageIndex
114 -> FilePath
115 -> PackageName
116 -> TestTree
117 goldenExeTests v pkgIx pkgDir pkgName =
118 testGroup
119 "exe golden tests"
120 [ goldenVsString
121 "Empty flags, not simple, no options, no comments"
122 (goldenExe "exe-no-comments.golden")
123 $ let opts = WriteOpts False False True v pkgDir Executable pkgName defaultCabalVersion
124 in runGoldenExe opts exeArgs emptyFlags
125 , goldenVsString
126 "Empty flags, not simple, with comments + no minimal"
127 (goldenExe "exe-with-comments.golden")
128 $ let opts = WriteOpts False False False v pkgDir Executable pkgName defaultCabalVersion
129 in runGoldenExe opts exeArgs emptyFlags
130 , goldenVsString
131 "Empty flags, not simple, with minimal + no comments"
132 (goldenExe "exe-minimal-no-comments.golden")
133 $ let opts = WriteOpts False True True v pkgDir Executable pkgName defaultCabalVersion
134 in runGoldenExe opts exeArgs emptyFlags
135 , goldenVsString
136 "Empty flags, not simple, with minimal + comments"
137 (goldenExe "exe-simple-minimal-with-comments.golden")
138 $ let opts = WriteOpts False True False v pkgDir Executable pkgName defaultCabalVersion
139 in runGoldenExe opts exeArgs emptyFlags
140 , goldenVsString
141 "Build tools flag, not simple, with comments + no minimal"
142 (goldenExe "exe-build-tools-with-comments.golden")
143 $ let opts = WriteOpts False False False v pkgDir Executable pkgName defaultCabalVersion
144 in runGoldenExe opts exeArgs (emptyFlags{buildTools = Flag ["happy"]})
146 where
147 runGoldenExe opts args flags =
148 case runPrompt (genExeTarget flags pkgIx) args of
149 Right (t, _) -> mkStanza [mkExeStanza opts $ t{_exeDependencies = mangleBaseDep t _exeDependencies}]
150 Left e -> assertFailure $ show e
152 goldenLibTests
153 :: Verbosity
154 -> InstalledPackageIndex
155 -> FilePath
156 -> PackageName
157 -> TestTree
158 goldenLibTests v pkgIx pkgDir pkgName =
159 testGroup
160 "lib golden tests"
161 [ goldenVsString
162 "Empty flags, not simple, no options, no comments"
163 (goldenLib "lib-no-comments.golden")
164 $ let opts = WriteOpts False False True v pkgDir Library pkgName defaultCabalVersion
165 in runGoldenLib opts libArgs emptyFlags
166 , goldenVsString
167 "Empty flags, simple, no options, no comments"
168 (goldenLib "lib-simple-no-comments.golden")
169 $ let opts = WriteOpts False False True v pkgDir Library pkgName defaultCabalVersion
170 in runGoldenLib opts libArgs emptyFlags
171 , goldenVsString
172 "Empty flags, not simple, with comments + no minimal"
173 (goldenLib "lib-with-comments.golden")
174 $ let opts = WriteOpts False False False v pkgDir Library pkgName defaultCabalVersion
175 in runGoldenLib opts libArgs emptyFlags
176 , goldenVsString
177 "Empty flags, not simple, with minimal + no comments"
178 (goldenLib "lib-minimal-no-comments.golden")
179 $ let opts = WriteOpts False True True v pkgDir Library pkgName defaultCabalVersion
180 in runGoldenLib opts libArgs emptyFlags
181 , goldenVsString
182 "Empty flags, not simple, with minimal + comments"
183 (goldenLib "lib-simple-minimal-with-comments.golden")
184 $ let opts = WriteOpts False True False v pkgDir Library pkgName defaultCabalVersion
185 in runGoldenLib opts libArgs emptyFlags
186 , goldenVsString
187 "Build tools flag, not simple, with comments + no minimal"
188 (goldenLib "lib-build-tools-with-comments.golden")
189 $ let opts = WriteOpts False False False v pkgDir Library pkgName defaultCabalVersion
190 in runGoldenLib opts libArgs (emptyFlags{buildTools = Flag ["happy"]})
192 where
193 runGoldenLib opts args flags =
194 case runPrompt (genLibTarget flags pkgIx) args of
195 Right (t, _) -> mkStanza [mkLibStanza opts $ t{_libDependencies = mangleBaseDep t _libDependencies}]
196 Left e -> assertFailure $ show e
198 goldenTestTests
199 :: Verbosity
200 -> InstalledPackageIndex
201 -> FilePath
202 -> PackageName
203 -> TestTree
204 goldenTestTests v pkgIx pkgDir pkgName =
205 testGroup
206 "test golden tests"
207 [ goldenVsString
208 "Empty flags, not simple, no options, no comments"
209 (goldenTest "test-no-comments.golden")
210 $ let opts = WriteOpts False False True v pkgDir Library pkgName defaultCabalVersion
211 in runGoldenTest opts testArgs emptyFlags
212 , goldenVsString
213 "Empty flags, not simple, with comments + no minimal"
214 (goldenTest "test-with-comments.golden")
215 $ let opts = WriteOpts False False False v pkgDir Library pkgName defaultCabalVersion
216 in runGoldenTest opts testArgs emptyFlags
217 , goldenVsString
218 "Empty flags, not simple, with minimal + no comments"
219 (goldenTest "test-minimal-no-comments.golden")
220 $ let opts = WriteOpts False True True v pkgDir Library pkgName defaultCabalVersion
221 in runGoldenTest opts testArgs emptyFlags
222 , goldenVsString
223 "Empty flags, not simple, with minimal + comments"
224 (goldenTest "test-simple-minimal-with-comments.golden")
225 $ let opts = WriteOpts False True False v pkgDir Library pkgName defaultCabalVersion
226 in runGoldenTest opts testArgs emptyFlags
227 , goldenVsString
228 "Build tools flag, not simple, with comments + no minimal"
229 (goldenTest "test-build-tools-with-comments.golden")
230 $ let opts = WriteOpts False False False v pkgDir Library pkgName defaultCabalVersion
231 in runGoldenTest opts testArgs (emptyFlags{buildTools = Flag ["happy"]})
232 , goldenVsString
233 "Standalone tests, empty flags, not simple, no options, no comments"
234 (goldenTest "standalone-test-no-comments.golden")
235 $ let opts = WriteOpts False False True v pkgDir TestSuite pkgName defaultCabalVersion
236 in runGoldenTest opts testArgs emptyFlags
237 , goldenVsString
238 "Standalone tests, empty flags, not simple, with comments + no minimal"
239 (goldenTest "standalone-test-with-comments.golden")
240 $ let opts = WriteOpts False False False v pkgDir TestSuite pkgName defaultCabalVersion
241 in runGoldenTest opts testArgs emptyFlags
243 where
244 runGoldenTest opts args flags =
245 case runPrompt (genTestTarget flags pkgIx) args of
246 Left e -> assertFailure $ show e
247 Right (Nothing, _) ->
248 assertFailure
249 "goldenTestTests: Tests not enabled."
250 Right (Just t, _) -> mkStanza [mkTestStanza opts $ t{_testDependencies = mangleBaseDep t _testDependencies}]
252 -- | Full cabal file golden tests
253 goldenCabalTests
254 :: Verbosity
255 -> InstalledPackageIndex
256 -> SourcePackageDb
257 -> TestTree
258 goldenCabalTests v pkgIx srcDb =
259 testGroup
260 ".cabal file golden tests"
261 [ goldenVsString
262 "Library and executable, empty flags, not simple, with comments + no minimal"
263 (goldenCabal "cabal-lib-and-exe-with-comments.golden")
264 $ runGoldenTest (fullProjArgs "Y") emptyFlags
265 , goldenVsString
266 "Library and executable, empty flags, not simple, no comments + no minimal"
267 (goldenCabal "cabal-lib-and-exe-no-comments.golden")
268 $ runGoldenTest (fullProjArgs "N") emptyFlags
269 , goldenVsString
270 "Library, empty flags, not simple, with comments + no minimal"
271 (goldenCabal "cabal-lib-with-comments.golden")
272 $ runGoldenTest (libProjArgs "Y") emptyFlags
273 , goldenVsString
274 "Library, empty flags, not simple, no comments + no minimal"
275 (goldenCabal "cabal-lib-no-comments.golden")
276 $ runGoldenTest (libProjArgs "N") emptyFlags
277 , goldenVsString
278 "Test suite, empty flags, not simple, with comments + no minimal"
279 (goldenCabal "cabal-test-suite-with-comments.golden")
280 $ runGoldenTest (testProjArgs "Y") emptyFlags
281 , goldenVsString
282 "Test suite, empty flags, not simple, no comments + no minimal"
283 (goldenCabal "cabal-test-suite-no-comments.golden")
284 $ runGoldenTest (testProjArgs "N") emptyFlags
286 where
287 runGoldenTest args flags =
288 case runPrompt (createProject v pkgIx srcDb flags) args of
289 Left e -> assertFailure $ show e
290 (Right (ProjectSettings opts pkgDesc (Just libTarget) (Just exeTarget) (Just testTarget), _)) -> do
291 let pkgFields = mkPkgDescription opts pkgDesc
292 commonStanza = mkCommonStanza opts
293 libStanza = mkLibStanza opts $ libTarget{_libDependencies = mangleBaseDep libTarget _libDependencies}
294 exeStanza = mkExeStanza opts $ exeTarget{_exeDependencies = mangleBaseDep exeTarget _exeDependencies}
295 testStanza = mkTestStanza opts $ testTarget{_testDependencies = mangleBaseDep testTarget _testDependencies}
297 mkStanza $ pkgFields ++ [commonStanza, libStanza, exeStanza, testStanza]
298 (Right (ProjectSettings opts pkgDesc (Just libTarget) Nothing (Just testTarget), _)) -> do
299 let pkgFields = mkPkgDescription opts pkgDesc
300 commonStanza = mkCommonStanza opts
301 libStanza = mkLibStanza opts $ libTarget{_libDependencies = mangleBaseDep libTarget _libDependencies}
302 testStanza = mkTestStanza opts $ testTarget{_testDependencies = mangleBaseDep testTarget _testDependencies}
304 mkStanza $ pkgFields ++ [commonStanza, libStanza, testStanza]
305 (Right (ProjectSettings opts pkgDesc Nothing Nothing (Just testTarget), _)) -> do
306 let pkgFields = mkPkgDescription opts pkgDesc
307 commonStanza = mkCommonStanza opts
308 testStanza = mkTestStanza opts $ testTarget{_testDependencies = mangleBaseDep testTarget _testDependencies}
310 mkStanza $ pkgFields ++ [commonStanza, testStanza]
311 (Right (ProjectSettings _ _ l e t, _)) ->
312 assertFailure $
313 show l ++ "\n" ++ show e ++ "\n" ++ show t
315 -- -------------------------------------------------------------------- --
316 -- utils
318 mkStanza :: [PrettyField FieldAnnotation] -> IO BS8.ByteString
319 mkStanza fields =
320 return . BS8.pack $
321 showFields'
322 annCommentLines
323 postProcessFieldLines
325 fields
327 golden :: FilePath
328 golden = "tests" </> "fixtures" </> "init" </> "golden"
330 goldenExe :: FilePath -> FilePath
331 goldenExe file = golden </> "exe" </> file
333 goldenTest :: FilePath -> FilePath
334 goldenTest file = golden </> "test" </> file
336 goldenLib :: FilePath -> FilePath
337 goldenLib file = golden </> "lib" </> file
339 goldenCabal :: FilePath -> FilePath
340 goldenCabal file = golden </> "cabal" </> file
342 goldenPkgDesc :: FilePath -> FilePath
343 goldenPkgDesc file = golden </> "pkg-desc" </> file
345 libArgs :: NonEmpty String
346 libArgs = fromList ["1", "2"]
348 exeArgs :: NonEmpty String
349 exeArgs = fromList ["1", "2", "1"]
351 testArgs :: NonEmpty String
352 testArgs = fromList ["y", "1", "test", "1"]
354 pkgArgs :: NonEmpty String
355 pkgArgs =
356 fromList
357 [ "5"
358 , "foo-package"
359 , "foo-package"
360 , "y"
361 , "0.1.0.0"
362 , "2"
363 , "git username"
364 , "foo-kmett"
365 , "git email"
366 , "foo-kmett@kmett.kmett"
367 , "home"
368 , "synopsis"
369 , "4"
372 testProjArgs :: String -> NonEmpty String
373 testProjArgs comments =
374 fromList ["4", "test-dir", "[]", "foo-package"]
375 <> pkgArgs
376 <> fromList (NEL.drop 1 testArgs)
377 <> fromList [comments]
379 libProjArgs :: String -> NonEmpty String
380 libProjArgs comments =
381 fromList ["1", "test-dir", "[]", "foo-package"]
382 <> pkgArgs
383 <> libArgs
384 <> testArgs
385 <> fromList [comments]
387 fullProjArgs :: String -> NonEmpty String
388 fullProjArgs comments =
389 fromList ["3", "test-dir", "[]", "foo-package"]
390 <> pkgArgs
391 <> libArgs
392 <> exeArgs
393 <> testArgs
394 <> fromList [comments]