1module UnitTests.Distribution.Client.Init.FileCreators (
2  tests
3  ) where
4
5import Distribution.Client.Init.FileCreators
6  ( generateCabalFile )
7
8import Test.Tasty
9import Test.Tasty.Golden (goldenVsString)
10
11import System.FilePath
12  ( (</>) )
13import qualified Data.ByteString.Lazy as BS
14import qualified Data.ByteString.Lazy.Char8 as BS8
15
16import Distribution.Client.Init.Types
17  ( InitFlags(..), PackageType(..), defaultInitFlags )
18import Distribution.Simple.Setup
19  ( Flag(..) )
20
21import Distribution.CabalSpecVersion
22  ( CabalSpecVersion(CabalSpecV2_4) )
23import Distribution.Types.Dependency
24  ( Dependency, mkDependency, mainLibSet )
25import Distribution.Types.PackageName
26  ( mkPackageName )
27import Distribution.Types.VersionRange
28  ( majorBoundVersion )
29import Distribution.Types.Version
30  ( mkVersion )
31import qualified Distribution.ModuleName as ModuleName
32  ( fromString )
33import qualified Distribution.SPDX as SPDX
34import Language.Haskell.Extension ( Language(..) )
35
36tests :: [TestTree]
37tests = [ testGroup "cabal init goldens"
38          [ checkCabalFileGolden exeFlags "exe-only-golden.cabal"
39          , checkCabalFileGolden libAndExeFlags "lib-and-exe-golden.cabal"
40          , checkCabalFileGolden libExeAndTestFlags "lib-exe-and-test-golden.cabal"
41          , checkCabalFileGolden libExeAndTestWithCommentsFlags "lib-exe-and-test-with-comments-golden.cabal"
42          ]
43        ]
44
45checkCabalFileGolden :: InitFlags -> FilePath -> TestTree
46checkCabalFileGolden flags goldenFileName =
47  goldenVsString goldenFileName goldenFilePath generatedCabalFile
48  where
49    goldenFilePath :: FilePath
50    goldenFilePath = "tests" </> "fixtures" </> "init" </> goldenFileName
51
52    generatedCabalFile :: IO BS.ByteString
53    generatedCabalFile = pure . BS8.pack $ generateCabalFile goldenFileName flags
54
55-- ==================================================
56-- Base flags to set common InitFlags values.
57
58baseFlags :: InitFlags
59baseFlags = defaultInitFlags {
60  -- Values common to all (or most) test flags.
61    packageName = Flag (mkPackageName "foo")
62  , noComments = Flag False
63  , minimal = Flag True
64  , version = Flag (mkVersion [3,2,1])
65  , synopsis = Flag "The foo package"
66  , homepage = Flag "https://github.com/foo/foo"
67  , license = Flag SPDX.NONE
68  , author = Flag "me"
69  , email = Flag "me@me.me"
70  , category = Flag (Left "SomeCat")
71  , cabalVersion = Flag CabalSpecV2_4
72  , extraSrc = Just ["CHANGELOG.md"]
73  , interactive = Flag False
74  , otherModules = Nothing
75  , otherExts = Nothing
76  , language = Flag Haskell2010
77  , buildTools = Nothing
78  , dependencies = Just testDependencies
79  , quiet = Flag True
80  , packageDir = NoFlag
81  , simpleProject = Flag False
82  , initHcPath = NoFlag
83  , overwrite = NoFlag
84
85  -- Commonly overridden values in test InitFlags.
86  -- It is fine to provide the same value in an overridden InitFlags
87  -- to make it clear what that particular test case is differentiating
88  -- from others.
89  , packageType = Flag Executable
90  , mainIs = Flag "Main.hs"
91  , applicationDirs = Just ["app"]
92  , sourceDirs = Nothing
93  , exposedModules = Nothing
94  , initializeTestSuite = Flag False
95  , testDirs = Nothing
96  }
97
98
99-- ==================================================
100-- Simple exe.
101
102exeFlags :: InitFlags
103exeFlags = baseFlags {
104  -- Create an executable only, with main living in app/Main.hs.
105    packageType = Flag Executable
106  , mainIs = Flag "Main.hs"
107  , applicationDirs = Just ["app"]
108  }
109
110
111-- ==================================================
112-- Simple lib and exe (as created by `cabal init --libandexe`).
113--
114-- Specifically, having 'exposedModules = Just ["MyLib"]' is a special
115-- case which results in the executable depending on the library from
116-- the same package, i.e. 'build-depends = foo' with no version
117-- constraints.
118
119libAndExeFlags :: InitFlags
120libAndExeFlags = baseFlags {
121  -- Create a library and executable
122    packageType = Flag LibraryAndExecutable
123
124  -- Main living in app/Main.hs.
125  , mainIs = Flag "Main.hs"
126  , applicationDirs = Just ["app"]
127
128  -- Library sources live in src/ and expose the module MyLib.
129  , sourceDirs = Just ["src"]
130  , exposedModules = Just (map ModuleName.fromString ["MyLib"])
131  }
132
133
134-- ==================================================
135-- Lib, exe, and test suite
136
137libExeAndTestFlags :: InitFlags
138libExeAndTestFlags = baseFlags {
139  -- Create a library and executable
140    packageType = Flag LibraryAndExecutable
141
142  -- Main living in app/Main.hs.
143  , mainIs = Flag "Main.hs"
144  , applicationDirs = Just ["app"]
145
146  -- Library sources live in src/ and expose the modules A and B.
147  , sourceDirs = Just ["src"]
148  , exposedModules = Just (map ModuleName.fromString ["A", "B"])
149
150  -- Create a test suite living in tests/
151  , initializeTestSuite = Flag True
152  , testDirs = Just ["tests"]
153  }
154
155-- ==================================================
156-- Lib, exe, and test suite with comments.
157
158libExeAndTestWithCommentsFlags :: InitFlags
159libExeAndTestWithCommentsFlags = libExeAndTestFlags {
160    minimal = Flag False
161  , noComments = Flag False
162  , quiet = Flag False
163  }
164
165
166
167-- ==================================================
168-- Test dependency.
169
170testDependencies :: [Dependency]
171testDependencies =
172  [ mkDependency
173      (mkPackageName "base")
174      (majorBoundVersion (mkVersion [4,13,0,0]))
175      mainLibSet
176  , mkDependency
177      (mkPackageName "containers")
178      (majorBoundVersion (mkVersion [5,7,0,0]))
179      mainLibSet
180  , mkDependency
181      (mkPackageName "unordered-containers")
182      (majorBoundVersion (mkVersion [2,7,0,0]))
183      mainLibSet
184  ]
185