Skip to content

Commit 2ee5327

Browse files
committed
Add tests for cabal status
1 parent ee7cd24 commit 2ee5327

28 files changed

+446
-0
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
cabal-version: 2.4
2+
name: InvalidDep
3+
version: 0.1.0.0
4+
5+
executable Inv
6+
main-is: Main.hs
7+
hs-source-dirs: src
8+
build-depends: another-framework
9+
default-language: Haskell2010
10+
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
packages: ./
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
name: another-framework
2+
version: 0.8.1.1
3+
build-type: Simple
4+
cabal-version: >= 1.10
5+
6+
library
7+
build-depends: base <3 && >=3
8+
default-language: Haskell2010
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
module Main where
2+
3+
main :: IO ()
4+
main = putStr "Test"
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
# cabal v2-update
2+
Downloading the latest package list from test-local-repo
3+
# cabal status
4+
Resolving dependencies...
5+
Error: cabal: Could not resolve dependencies:
6+
[__0] trying: InvalidDep-0.1.0.0 (user goal)
7+
[__1] trying: another-framework-0.8.1.1 (dependency of InvalidDep)
8+
[__2] next goal: base (dependency of another-framework)
9+
[__2] rejecting: base-<VERSION>/installed-<HASH> (conflict: another-framework => base<3 && >=3)
10+
[__2] fail (backjumping, conflict set: another-framework, base)
11+
After searching the rest of the dependency tree exhaustively, these were the goals I've had most trouble fulfilling: another-framework (3), InvalidDep (2), base (2)
12+
# cabal status
13+
Resolving dependencies...
14+
Error: cabal: Could not resolve dependencies:
15+
[__0] trying: InvalidDep-0.1.0.0 (user goal)
16+
[__1] trying: another-framework-0.8.1.1 (dependency of InvalidDep)
17+
[__2] next goal: base (dependency of another-framework)
18+
[__2] rejecting: base-<VERSION>/installed-<HASH> (conflict: another-framework => base<3 && >=3)
19+
[__2] fail (backjumping, conflict set: another-framework, base)
20+
After searching the rest of the dependency tree exhaustively, these were the goals I've had most trouble fulfilling: another-framework (3), InvalidDep (2), base (2)
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
{-# LANGUAGE OverloadedStrings #-}
2+
import Test.Cabal.Prelude
3+
import Test.Cabal.DecodeShowBuildInfo
4+
5+
main = cabalTest $ withRepo "repo" $ do
6+
-- no build plan available
7+
r <- fails $ cabal' "status" ["--output-format=json", "--target", "src/Main.hs"]
8+
assertOutputContains "Could not resolve dependencies" r
9+
-- TODO: should this actually work?
10+
r <- fails $ cabal' "status" ["--output-format=json", "--compiler"]
11+
assertOutputContains "Could not resolve dependencies" r
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
cabal-version: 2.4
2+
name: Simple
3+
version: 0.1.0.0
4+
5+
library
6+
exposed-modules:
7+
MyLib
8+
MyLib2
9+
10+
build-depends: base
11+
hs-source-dirs: src
12+
default-language: Haskell2010
13+
14+
library unbuildable
15+
exposed-modules: Unbuildable
16+
hs-source-dirs: src
17+
build-depends: base
18+
default-language: Haskell2010
19+
buildable: False
20+
21+
library compilefail
22+
exposed-modules: Fails
23+
hs-source-dirs: src
24+
build-depends: base
25+
default-language: Haskell2010
26+
27+
executable Simple
28+
main-is: Main.hs
29+
30+
-- Module that belongs to multiple components
31+
other-modules: MyLib
32+
hs-source-dirs: src, exe
33+
build-depends: base
34+
default-language: Haskell2010
35+
36+
-- Just some simple config to test 'exes' meta command
37+
executable Simple2
38+
main-is: Main2.hs
39+
40+
-- Module that belongs to multiple components
41+
other-modules: MyLib
42+
hs-source-dirs: src, exe
43+
build-depends: base
44+
default-language: Haskell2010
45+
46+
test-suite Tests
47+
type: exitcode-stdio-1.0
48+
main-is: Main.hs
49+
hs-source-dirs: test
50+
build-depends: base
51+
52+
benchmark Benchs
53+
type: exitcode-stdio-1.0
54+
main-is: Bench.hs
55+
hs-source-dirs: test
56+
build-depends: base
57+
58+
foreign-library myforeignlib
59+
type: native-shared
60+
61+
if os(windows)
62+
options: standalone
63+
64+
other-modules:
65+
MyForeignLib.AnotherVal
66+
MyForeignLib.Hello
67+
MyForeignLib.SomeBindings
68+
69+
build-depends: base
70+
hs-source-dirs: flibsrc
71+
c-sources: csrc/MyForeignLibWrapper.c
72+
default-language: Haskell2010
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
module Bench where
2+
3+
main = putStr "Benchmarks!"
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
packages: ./
2+
3+
tests: True
4+
executables: True
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
# cabal status
2+
Warning: <ROOT>/cabal.project: Unrecognized field 'executables' on line 4
3+
Resolving dependencies...
4+
{"cabal-version":"3.9","compiler":{"flavour":"ghc","compiler-id":"ghc-<GHCVER>","path":"<GHCPATH>"}}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
import Test.Cabal.Prelude
2+
import Test.Cabal.DecodeShowBuildInfo
3+
import Data.Maybe
4+
5+
main = cabalTest $ do
6+
r <- cabal' "status" ["--output-format=json", "--compiler"]
7+
statusInfo <- withJsonOutput r
8+
assertBool "Must contain compiler information" (isJust $ siCompiler statusInfo)
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
#include <stdlib.h>
2+
#include <stdbool.h>
3+
#include "HsFFI.h"
4+
5+
bool myForeignLibInit(void){
6+
int argc = 2;
7+
char *argv[] = { "+RTS", "-A32m", NULL };
8+
char **pargv = argv;
9+
10+
// Initialize Haskell runtime
11+
hs_init(&argc, &pargv);
12+
13+
// do any other initialization here and
14+
// return false if there was a problem
15+
return true;
16+
}
17+
18+
void myForeignLibExit(void){
19+
hs_exit();
20+
}
21+
22+
int cFoo2() {
23+
return 1234;
24+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
module Main where
2+
3+
main :: IO ()
4+
main = putStrLn "Test"
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
module Main where
2+
3+
main :: IO ()
4+
main = putStrLn "Test"
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
module MyForeignLib.AnotherVal where
2+
3+
anotherVal = 189
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
-- | Module with single foreign export
2+
module MyForeignLib.Hello (sayHi) where
3+
4+
import MyForeignLib.SomeBindings
5+
import MyForeignLib.AnotherVal
6+
7+
foreign export ccall sayHi :: IO ()
8+
9+
-- | Say hi!
10+
sayHi :: IO ()
11+
sayHi = putStrLn $
12+
"Hi from a foreign library! Foo has value " ++ show valueOfFoo
13+
++ " and anotherVal has value " ++ show anotherVal
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
-- | Module that needs the hsc2hs preprocessor
2+
module MyForeignLib.SomeBindings where
3+
4+
#define FOO 1
5+
6+
#ifdef FOO
7+
-- | Value guarded by a CPP flag
8+
valueOfFoo :: Int
9+
valueOfFoo = 5678
10+
#endif
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
# cabal status
2+
Warning: <ROOT>/cabal.project: Unrecognized field 'executables' on line 4
3+
Resolving dependencies...
4+
{"cabal-version":"3.9","targets":[{"target":"src/Main.hs","unit-id":null}]}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
import Test.Cabal.Prelude
2+
3+
main = cabalTest $ do
4+
-- Make sure plan.json is generated, even if no target is resolved
5+
cabal "status" ["--output-format=json", "--target", "src/Main.hs"]
6+
withPlan $ do
7+
pure ()
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
# cabal status
2+
Error: cabal: The status command requires the flag '--output-format'.
3+
# cabal status
4+
Resolving dependencies...
5+
{"cabal-version":"3.9","targets":[{"target":"exe/Main.hs","unit-id":"Simple-0.1.0.0-inplace-Simple"}]}
6+
# cabal status
7+
{"cabal-version":"3.9","targets":[{"target":"exe/Main.hs","unit-id":"Simple-0.1.0.0-inplace-Simple"},{"target":"exe/Main2.hs","unit-id":"Simple-0.1.0.0-inplace-Simple2"}]}
8+
# cabal status
9+
{"cabal-version":"3.9","targets":[{"target":"src/MyLib.hs","unit-id":null}]}
10+
# cabal status
11+
{"cabal-version":"3.9","targets":[{"target":"src/MyLib2.hs","unit-id":null}]}
12+
# cabal status
13+
{"cabal-version":"3.9","targets":[{"target":"bench/Bench.hs","unit-id":null}]}
14+
# cabal status
15+
{"cabal-version":"3.9","targets":[{"target":"test/Main.hs","unit-id":null}]}
16+
# cabal status
17+
{"cabal-version":"3.9","targets":[{"target":"flibsrc/MyForeignLib/AnotherVal.hs","unit-id":"Simple-0.1.0.0-inplace-myforeignlib"},{"target":"flibsrc/MyForeignLib/Hello.hs","unit-id":"Simple-0.1.0.0-inplace-myforeignlib"},{"target":"flibsrc/MyForeignLib/SomeBindings.hsc","unit-id":"Simple-0.1.0.0-inplace-myforeignlib"},{"target":"csrc/MyForeignLibWrapper.c","unit-id":null}]}
18+
# cabal status
19+
{"cabal-version":"3.9","targets":[{"target":"Benchs","unit-id":"Simple-0.1.0.0-inplace-Benchs"}]}
20+
# cabal status
21+
{"cabal-version":"3.9","targets":[{"target":"all","unit-id":"Simple-0.1.0.0-inplace"},{"target":"all","unit-id":"Simple-0.1.0.0-inplace-Simple"},{"target":"all","unit-id":"Simple-0.1.0.0-inplace-Simple2"},{"target":"all","unit-id":"Simple-0.1.0.0-inplace-myforeignlib"}]}
22+
# cabal status
23+
{"cabal-version":"3.9","targets":[{"target":"exes","unit-id":"Simple-0.1.0.0-inplace-Simple"},{"target":"exes","unit-id":"Simple-0.1.0.0-inplace-Simple2"}]}
24+
# cabal status
25+
{"cabal-version":"3.9","targets":[{"target":"tests","unit-id":"Simple-0.1.0.0-inplace-Tests"}]}
26+
# cabal status
27+
{"cabal-version":"3.9","targets":[{"target":"benchmarks","unit-id":"Simple-0.1.0.0-inplace-Benchs"}]}
28+
# cabal status
29+
{"cabal-version":"3.9","targets":[{"target":"executables","unit-id":"Simple-0.1.0.0-inplace-Simple"},{"target":"executables","unit-id":"Simple-0.1.0.0-inplace-Simple2"}]}
30+
# cabal status
31+
{"cabal-version":"3.9","targets":[{"target":"Main2.hs","unit-id":null}]}
32+
# cabal status
33+
{"cabal-version":"3.9","targets":[{"target":"Main3.hs","unit-id":null},{"target":"src/MyLib2.hs","unit-id":null},{"target":"Main3.hs","unit-id":null}]}
34+
# cabal status
35+
{"cabal-version":"3.9","targets":[{"target":"Lib.hs","unit-id":null}]}
36+
# cabal status
37+
{"cabal-version":"3.9","compiler":{"flavour":"ghc","compiler-id":"ghc-<GHCVER>","path":"<GHCPATH>"},"targets":[{"target":"Lib.hs","unit-id":null}]}
38+
# cabal status
39+
{"cabal-version":"3.9","targets":[{"target":"Lib2.hs","unit-id":null}]}
40+
# cabal status
41+
{"cabal-version":"3.9","compiler":{"flavour":"ghc","compiler-id":"ghc-<GHCVER>","path":"<GHCPATH>"},"targets":[{"target":"Lib.hs","unit-id":null}]}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
import Test.Cabal.Prelude
2+
import Test.Cabal.DecodeShowBuildInfo
3+
import Data.Maybe (isJust)
4+
import Data.List (sort, nub)
5+
6+
main = cabalTest $ do
7+
-- output-format flag is missing but required, must fail
8+
r <- fails $ cabal' "status" ["--target", "Main.hs"]
9+
assertOutputContains "The status command requires the flag '--output-format'." r
10+
11+
-- Simple file target tests
12+
runStatusWithTargets ["exe/Main.hs"]$ \si -> do
13+
resolveOnce "exe/Main.hs" si
14+
runStatusWithTargets ["exe/Main.hs", "exe/Main2.hs"] $ \si -> do
15+
resolveOnce "exe/Main.hs" si
16+
resolveOnce "exe/Main2.hs" si
17+
runStatusWithTargets ["src/MyLib.hs"] $ \si -> do
18+
rts <- resolve "src/MyLib.hs" si
19+
assertEqual "Ambiguous component" 3 (length rts)
20+
runStatusWithTargets ["src/MyLib2.hs"] $ \si -> do
21+
resolveOnce "src/MyLib2.hs" si
22+
runStatusWithTargets ["bench/Bench.hs"] $ \si -> do
23+
resolveOnce "bench/Bench.hs" si
24+
runStatusWithTargets ["test/Main.hs"]$ \si -> do
25+
resolveOnce "test/Main.hs" si
26+
runStatusWithTargets ["flibsrc/MyForeignLib/AnotherVal.hs",
27+
"flibsrc/MyForeignLib/Hello.hs",
28+
"flibsrc/MyForeignLib/SomeBindings.hsc",
29+
"csrc/MyForeignLibWrapper.c"
30+
]$ \si -> do
31+
resolveOnce "flibsrc/MyForeignLib/AnotherVal.hs" si
32+
resolveOnce "flibsrc/MyForeignLib/Hello.hs" si
33+
resolveOnce "flibsrc/MyForeignLib/SomeBindings.hsc" si
34+
unresolvable "csrc/MyForeignLibWrapper.c" si
35+
runStatusWithTargets ["lib:Simple", "exe:Simple", "Simple:exe:Simple"] $ \si -> do
36+
resolveOnce "lib:Simple" si
37+
resolveOnce "exe:Simple" si
38+
resolveOnce "Simple:exe:Simple" si
39+
-- pkgs syntax tests
40+
runStatusWithTargets ["Benchs"] $ \si -> do
41+
resolveOnce "Benchs" si
42+
-- meta targets
43+
runStatusWithTargets ["all"] $ \si -> do
44+
rts <- resolve "all" si
45+
assertEqual "Seven components" 7 (length rts)
46+
runStatusWithTargets ["exes"] $ \si -> do
47+
rts <- resolve "exes" si
48+
assertEqual "Two executables" 2 (length rts)
49+
runStatusWithTargets ["tests"] $ \si -> do
50+
resolveOnce "tests" si
51+
runStatusWithTargets ["benchmarks"] $ \si -> do
52+
resolveOnce "benchmarks" si
53+
54+
-- unknown target selectors
55+
runStatusWithTargets ["executables"] $ \si ->
56+
unresolvable "executables" si
57+
runStatusWithTargets ["Main2.hs"] $ \si ->
58+
unresolvable "Main2.hs" si
59+
60+
-- partially works, Main3.hs isn't known while `src/MyLib2.hs` is.
61+
runStatusWithTargets ["Main3.hs", "src/MyLib2.hs"] $ \si -> do
62+
unresolvable "Main3.hs" si
63+
resolveOnce "src/MyLib2.hs" si
64+
65+
-- component fails to compile, still works
66+
runStatusWithTargets ["src/Fails.hs"] $ \si -> do
67+
resolveOnce "src/Fails.hs" si
68+
cabal "status" ["--output-format=json", "--compiler", "--target", "Fails.hs"]
69+
-- unbuildable target, resolves to 'null'
70+
runStatusWithTargets ["src/Unbuildable.hs"] $ \si -> do
71+
unresolvable "src/Unbuildable.hs" si
72+
cabal "status" ["--output-format=json", "--compiler", "--target", "src/Unbuildable"]
73+
where
74+
runStatusWithTargets :: [String] -> (StatusInformation -> TestM a) -> TestM a
75+
runStatusWithTargets targets act = do
76+
r <- cabal' "status" $ ["--output-format=json"] ++ concatMap (\t -> ["--target", t]) targets
77+
statusInfo <- withJsonOutput r
78+
act statusInfo
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
module Fails where
2+
3+
-- fails to compile intentionally
4+
foo =
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
module MyLib (someFunc) where
2+
3+
someFunc :: IO ()
4+
someFunc = putStrLn "someFunc"
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
module MyLib2 (someFunc) where
2+
3+
someFunc :: IO ()
4+
someFunc = putStrLn "someFunc"
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
module Unbuildable (someFunc) where
2+
3+
someFunc :: IO ()
4+
someFunc = putStrLn "someFunc"
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
module Bench where
2+
3+
main = putStr "Tests!"

0 commit comments

Comments
 (0)