Skip to content

Commit e5a68bc

Browse files
committed
WIP: add tests for cabal status
1 parent ee7cd24 commit e5a68bc

27 files changed

+388
-0
lines changed
Lines changed: 10 additions & 0 deletions
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+
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
packages: ./
Lines changed: 8 additions & 0 deletions
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
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
module Main where
2+
3+
main :: IO ()
4+
main = putStr "Test"
Lines changed: 20 additions & 0 deletions
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)
Lines changed: 11 additions & 0 deletions
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
Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
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: MyLib2
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+
buildable: False
27+
28+
executable Simple
29+
main-is: Main.hs
30+
31+
-- Module that belongs to multiple components
32+
other-modules: MyLib
33+
hs-source-dirs: src exe
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+
default-language: Haskell2010
44+
45+
test-suite Tests
46+
type: exitcode-stdio-1.0
47+
main-is: Main.hs
48+
hs-source-dirs: test
49+
build-depends: base
50+
51+
benchmark Benchs
52+
type: exitcode-stdio-1.0
53+
main-is: Main.hs
54+
hs-source-dirs: test
55+
build-depends: base
56+
57+
foreign-library myforeignlib
58+
type: native-shared
59+
60+
if os(windows)
61+
options: standalone
62+
63+
other-modules: MyForeignLib.Hello
64+
MyForeignLib.SomeBindings
65+
MyForeignLib.AnotherVal
66+
build-depends: base
67+
hs-source-dirs: flibsrc
68+
c-sources: csrc/MyForeignLibWrapper.c
69+
default-language: Haskell2010
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
module Bench where
2+
3+
main = putStr "Benchmarks!"
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
packages: ./
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
# cabal status
2+
Resolving dependencies...
3+
{"cabal-version":"3.9","compiler":{"flavour":"ghc","compiler-id":"ghc-<GHCVER>","path":"<GHCPATH>"}}
Lines changed: 8 additions & 0 deletions
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)
Lines changed: 24 additions & 0 deletions
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+
}
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
module Main where
2+
3+
main :: IO ()
4+
main = putStrLn "Test"
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
module Main where
2+
3+
main :: IO ()
4+
main = putStrLn "Test"
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
module MyForeignLib.AnotherVal where
2+
3+
anotherVal = 189
Lines changed: 13 additions & 0 deletions
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
Lines changed: 10 additions & 0 deletions
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
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
# cabal status
2+
Resolving dependencies...
3+
{"cabal-version":"3.9","targets":[{"target":"src/Main.hs","unit-id":null}]}
Lines changed: 7 additions & 0 deletions
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 ()
Lines changed: 41 additions & 0 deletions
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}]}
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
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"]
13+
runStatusWithTargets ["exe/Main.hs", "exe/Main2.hs"] -- multiple targets
14+
runStatusWithTargets ["src/MyLib.hs"] -- belongs to multiple components
15+
runStatusWithTargets ["src/MyLib2.hs"]
16+
runStatusWithTargets ["bench/Bench.hs"]
17+
runStatusWithTargets ["test/Main.hs"]
18+
runStatusWithTargets ["flibsrc/MyForeignLib/AnotherVal.hs",
19+
"flibsrc/MyForeignLib/Hello.hs",
20+
"flibsrc/MyForeignLib/SomeBindings.hsc",
21+
"csrc/MyForeignLibWrapper.c"
22+
]
23+
-- TODO: this should not fail, that's a bug!
24+
-- runStatusWithTargets ["lib:Simple", "exe:Simple", "Simple:exe:Simple"]
25+
-- pkgs syntax twsts
26+
runStatusWithTargets ["Benchs"]
27+
28+
-- meta targets
29+
runStatusWithTargets ["all"]
30+
runStatusWithTargets ["exes"]
31+
runStatusWithTargets ["tests"]
32+
runStatusWithTargets ["benchmarks"]
33+
34+
-- unknown target selectors
35+
runStatusWithTargets ["executables"]
36+
runStatusWithTargets ["Main2.hs"]
37+
38+
-- partially works, Main3.hs isn't known while `src/MyLib2.hs` is.
39+
runStatusWithTargets ["Main3.hs", "src/MyLib2.hs"]
40+
41+
-- component fails to compile, still works
42+
cabal "status" ["--output-format=json", "--target", "Lib.hs"]
43+
cabal "status" ["--output-format=json", "--compiler", "--target", "Lib.hs"]
44+
-- unbuildable target, resolves to 'null'
45+
cabal "status" ["--output-format=json", "--target", "Lib2.hs"]
46+
cabal "status" ["--output-format=json", "--compiler", "--target", "Lib.hs"]
47+
where
48+
runStatusWithTargets :: [String] -> TestM ()
49+
runStatusWithTargets targets = do
50+
r <- cabal' "status" $ ["--output-format=json"] ++ concatMap (\t -> ["--target", t]) targets
51+
statusInfo <- withJsonOutput r
52+
assertBool "Must contain targets" (isJust $ siTargetResolving statusInfo)
53+
assertBool "Must contain all targets at least once"
54+
(Just (nub $ sort targets) == fmap (nub . sort . map rtOriginalTarget) (siTargetResolving statusInfo))
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
module Fails where
2+
3+
-- fails to compile intentionally
4+
foo =
Lines changed: 4 additions & 0 deletions
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"
Lines changed: 4 additions & 0 deletions
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"
Lines changed: 3 additions & 0 deletions
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)