Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
84 changes: 60 additions & 24 deletions cabal-install/src/Distribution/Client/CmdTest.hs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
{-# LANGUAGE LambdaCase #-}
{-# LANGUAGE PatternSynonyms #-}
{-# LANGUAGE RecordWildCards #-}

Expand All @@ -11,6 +12,7 @@ module Distribution.Client.CmdTest
, isSubComponentProblem
, notTestProblem
, noTestsProblem
, reportTargetProblems
, selectPackageTargets
, selectComponentTarget
) where
Expand Down Expand Up @@ -57,6 +59,7 @@ import Distribution.Simple.Setup
import Distribution.Simple.Utils
( dieWithException
, notice
, ordNub
, warn
, wrapText
)
Expand Down Expand Up @@ -142,14 +145,17 @@ testAction flags@NixStyleFlags{..} targetStrings globalFlags = do

-- Interpret the targets on the command line as test targets
-- (as opposed to say build or haddock targets).
let resolveTargets =
resolveTargetsFromSolver
selectPackageTargets
selectComponentTarget
elaboratedPlan
Nothing
targets <-
either (reportTargetProblems verbosity failWhenNoTestSuites) return $
resolveTargetsFromSolver
selectPackageTargets
selectComponentTarget
elaboratedPlan
Nothing
targetSelectors
either
(reportTargetProblems verbosity failWhenNoTestSuites targetSelectors resolveTargets)
return
$ resolveTargets targetSelectors

let elaboratedPlan' =
pruneInstallPlanToTargets
Expand Down Expand Up @@ -178,16 +184,22 @@ selectPackageTargets
-> [AvailableTarget k]
-> Either TestTargetProblem [k]
selectPackageTargets targetSelector targets
-- If there are any buildable test-suite targets then we select those
-- If there are any buildable test-suite targets then we select those.
| not (null targetsTestsBuildable) =
Right targetsTestsBuildable
-- If there are test-suites but none are buildable then we report those
-- If there are test-suites but none are buildable then we report those.
| not (null targetsTests) =
Left (TargetProblemNoneEnabled targetSelector targetsTests)
-- If there are no test-suite but some other targets then we report that
-- If there are no test-suite but some other targets then we report that.
| not (null targets) =
Left (noTestsProblem targetSelector)
-- If there are no targets at all then we report that
-- If pkg:tests comes up empty we report no tests.
| TargetPackage _ _ (Just TestKind) <- targetSelector =
Left (noTestsProblem targetSelector)
-- If all:tests comes up empty we report no tests.
| TargetAllPackages (Just TestKind) <- targetSelector =
Left (noTestsProblem targetSelector)
-- If there are no targets at all then we report that.
| otherwise =
Left (TargetProblemNoTargets targetSelector)
where
Expand Down Expand Up @@ -255,22 +267,46 @@ isSubComponentProblem pkgid name subcomponent =
CustomTargetProblem $
TargetProblemIsSubComponent pkgid name subcomponent

reportTargetProblems :: Verbosity -> Flag Bool -> [TestTargetProblem] -> IO a
reportTargetProblems verbosity failWhenNoTestSuites problems =
case (failWhenNoTestSuites, problems) of
(Flag True, [CustomTargetProblem (TargetProblemNoTests _)]) ->
dieWithException verbosity $ ReportTargetProblems problemsMessage
(_, [CustomTargetProblem (TargetProblemNoTests selector)]) -> do
notice verbosity (renderAllowedNoTestsProblem selector)
System.Exit.exitSuccess
(_, _) -> dieWithException verbosity $ ReportTargetProblems problemsMessage
-- | Targets that do not contain any test suites do not abort the command
-- (unless @--test-fail-when-no-test-suites@ is given): they are skipped with
-- a notice, and the remaining requested targets are resolved and tested.
reportTargetProblems
:: Verbosity
-> Flag Bool
-- ^ @--test-fail-when-no-test-suites@
-> [TargetSelector]
-- ^ the target selectors requested on the command line
-> ([TargetSelector] -> Either [TestTargetProblem] TargetsMap)
-- ^ how to resolve (a subset of) the requested targets
-> [TestTargetProblem]
-> IO TargetsMap
reportTargetProblems verbosity failWhenNoTestSuites targetSelectors resolveTargets problems =
if failWhenNoTestSuites /= Flag True && null otherProblems && not (null noTestsSelectors)
then do
for_ noTestsSelectors $ notice verbosity . renderAllowedNoTestsProblem

let remainingSelectors = filter (`notElem` noTestsSelectors) targetSelectors
if null remainingSelectors
then System.Exit.exitSuccess
else
either
(reportTargetProblems verbosity failWhenNoTestSuites remainingSelectors resolveTargets)
return
$ resolveTargets remainingSelectors
else dieWithException verbosity $ ReportTargetProblems problemsMessage
where
problemsMessage = unlines . map renderTestTargetProblem $ problems

-- | Unless @--test-fail-when-no-test-suites@ flag is passed, we don't
-- @die@ when the target problem is 'TargetProblemNoTests'.
-- Instead, we display a notice saying that no tests have run and
-- indicate how this behaviour was enabled.
(noTestsProblems, otherProblems) =
flip partition problems $ \case
(CustomTargetProblem (TargetProblemNoTests _)) -> True
_ -> False

noTestsSelectors =
ordNub [selector | CustomTargetProblem (TargetProblemNoTests selector) <- noTestsProblems]

-- | The message displayed for each skipped target that does not contain
-- any test suites.
renderAllowedNoTestsProblem :: TargetSelector -> String
renderAllowedNoTestsProblem selector =
"No tests to run for " ++ renderTargetSelector selector
Expand Down
26 changes: 26 additions & 0 deletions cabal-install/tests/IntegrationTests2.hs
Original file line number Diff line number Diff line change
Expand Up @@ -1426,6 +1426,32 @@ testTargetProblemsTest config reportSubCase = do
, (CmdTest.noTestsProblem, mkTargetPackage "q-0.1")
]

reportSubCase "pkg with tests and pkg without tests"
do
(_, elaboratedPlan, _) <- planProject "targets/tests-and-no-tests" config
let resolveTargets =
resolveTargetsFromSolver
CmdTest.selectPackageTargets
CmdTest.selectComponentTarget
elaboratedPlan
Nothing
requestedSelectors =
[ mkTargetPackage "p-0.1"
, mkTargetPackage "q-0.1"
]
targets <- case resolveTargets requestedSelectors of
Right ts ->
assertFailure $ "expected target problems, but got: " ++ show ts
Left problems ->
CmdTest.reportTargetProblems
testVerbosity
(Flag False)
requestedSelectors
resolveTargets
problems
distinctTargetComponents targets
@?= Set.fromList [("p-0.1-inplace-p-tests", CTestName "p-tests")]

reportSubCase "not a test"
assertProjectTargetProblems
"targets/variety"
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
module P where
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
module Main where

main :: IO ()
main = return ()
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
packages: ./ q/
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
cabal-version: 3.8
name: p
version: 0.1
build-type: Simple

library
exposed-modules: P
build-depends: base

test-suite p-tests
type: exitcode-stdio-1.0
main-is: Test.hs
build-depends: base
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
module Q where
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
cabal-version: 3.8
name: q
version: 0.1
build-type: Simple

library
exposed-modules: Q
build-depends: base
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
# cabal v2-test
Resolving dependencies...
Build profile: -w ghc-<GHCVER> -O1
In order, the following will be built:
- p-0.1 (test:p-tests) (first run)
Configuring test suite 'p-tests' for p-0.1...
Preprocessing test suite 'p-tests' for p-0.1...
Building test suite 'p-tests' for p-0.1...
Running 1 test suites...
Test suite p-tests: RUNNING...
Test suite p-tests: PASS
Test suite logged to: <ROOT>/cabal.all-tests.dist/work/./dist/build/<ARCH>/ghc-<GHCVER>/p-0.1/t/p-tests/test/p-0.1-p-tests.log
1 of 1 test suites (1 of 1 test cases) passed.
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
# cabal v2-test
Resolving dependencies...
Build profile: -w ghc-<GHCVER> -O1
In order, the following will be built:
- p-0.1 (test:p-tests) (first run)
Configuring test suite 'p-tests' for p-0.1...
Preprocessing test suite 'p-tests' for p-0.1...
Building test suite 'p-tests' for p-0.1...
Running 1 test suites...
Test suite p-tests: RUNNING...
Test suite p-tests: PASS
Test suite logged to: <ROOT>/cabal.all-tests_+failflag.dist/work/./dist/build/<ARCH>/ghc-<GHCVER>/p-0.1/t/p-tests/test/p-0.1-p-tests.log
1 of 1 test suites (1 of 1 test cases) passed.
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
# cabal v2-test
Resolving dependencies...
Build profile: -w ghc-<GHCVER> -O1
In order, the following will be built:
- p-0.1 (test:p-tests) (first run)
Configuring test suite 'p-tests' for p-0.1...
Preprocessing test suite 'p-tests' for p-0.1...
Building test suite 'p-tests' for p-0.1...
Running 1 test suites...
Test suite p-tests: RUNNING...
Test suite p-tests: PASS
Test suite logged to: <ROOT>/cabal.all.dist/work/./dist/build/<ARCH>/ghc-<GHCVER>/p-0.1/t/p-tests/test/p-0.1-p-tests.log
1 of 1 test suites (1 of 1 test cases) passed.
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
# cabal v2-test
Resolving dependencies...
Build profile: -w ghc-<GHCVER> -O1
In order, the following will be built:
- p-0.1 (test:p-tests) (first run)
Configuring test suite 'p-tests' for p-0.1...
Preprocessing test suite 'p-tests' for p-0.1...
Building test suite 'p-tests' for p-0.1...
Running 1 test suites...
Test suite p-tests: RUNNING...
Test suite p-tests: PASS
Test suite logged to: <ROOT>/cabal.all_+failflag.dist/work/./dist/build/<ARCH>/ghc-<GHCVER>/p-0.1/t/p-tests/test/p-0.1-p-tests.log
1 of 1 test suites (1 of 1 test cases) passed.
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
# cabal v2-test
Resolving dependencies...
No tests to run for the test suites in the package q-0.1
Build profile: -w ghc-<GHCVER> -O1
In order, the following will be built:
- p-0.1 (test:p-tests) (first run)
Configuring test suite 'p-tests' for p-0.1...
Preprocessing test suite 'p-tests' for p-0.1...
Building test suite 'p-tests' for p-0.1...
Running 1 test suites...
Test suite p-tests: RUNNING...
Test suite p-tests: PASS
Test suite logged to: <ROOT>/cabal.mixed-tests.dist/work/./dist/build/<ARCH>/ghc-<GHCVER>/p-0.1/t/p-tests/test/p-0.1-p-tests.log
1 of 1 test suites (1 of 1 test cases) passed.
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
# cabal v2-test
Resolving dependencies...
Error: [Cabal-7043]
Cannot run tests for the target 'q:tests' which refers to the test suites in the package q-0.1 because it does not contain any test suites.
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
# cabal v2-test
Resolving dependencies...
No tests to run for the package q-0.1
Build profile: -w ghc-<GHCVER> -O1
In order, the following will be built:
- p-0.1 (test:p-tests) (first run)
Configuring test suite 'p-tests' for p-0.1...
Preprocessing test suite 'p-tests' for p-0.1...
Building test suite 'p-tests' for p-0.1...
Running 1 test suites...
Test suite p-tests: RUNNING...
Test suite p-tests: PASS
Test suite logged to: <ROOT>/cabal.mixed.dist/work/./dist/build/<ARCH>/ghc-<GHCVER>/p-0.1/t/p-tests/test/p-0.1-p-tests.log
1 of 1 test suites (1 of 1 test cases) passed.
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
# cabal v2-test
Resolving dependencies...
Error: [Cabal-7043]
Cannot run tests for the target 'q' which refers to the package q-0.1 because it does not contain any test suites.
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# cabal v2-test
Resolving dependencies...
No tests to run for the test suites in the package q-0.1
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
# cabal v2-test
Resolving dependencies...
Error: [Cabal-7043]
Cannot run tests for the target 'q:tests' which refers to the test suites in the package q-0.1 because it does not contain any test suites.
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# cabal v2-test
Resolving dependencies...
No tests to run for the package q-0.1
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
# cabal v2-test
Resolving dependencies...
Error: [Cabal-7043]
Cannot run tests for the target 'q' which refers to the package q-0.1 because it does not contain any test suites.
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
packages: p q
Loading
Loading