From f039ea673ef24cfae3abe008308c5c61aa04f119 Mon Sep 17 00:00:00 2001 From: Ryan Hendrickson Date: Mon, 21 Aug 2023 03:41:29 -0400 Subject: [PATCH] Allow --pattern|-p option to repeat The effect of multiple -p options is the same as &&-ing the expressions together, but allowing them to be specified in separate options makes scripting test commands simpler. --- .github/workflows/ci.yaml | 1 + core-tests/core-tests.cabal | 6 ++++++ core-tests/multiple-pattern-test.hs | 14 ++++++++++++++ core-tests/multiple-pattern-test.sh | 28 ++++++++++++++++++++++++++++ core/CHANGELOG.md | 1 + core/Test/Tasty/Patterns.hs | 11 +++++++++-- 6 files changed, 59 insertions(+), 2 deletions(-) create mode 100644 core-tests/multiple-pattern-test.hs create mode 100755 core-tests/multiple-pattern-test.sh diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index 4be4ef93..00be1b32 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -69,6 +69,7 @@ jobs: core-tests/exit-status-tests.sh # Prevent Git for Windows from replacing slashes with backslashes in patterns MSYS_NO_PATHCONV=1 core-tests/failing-pattern-test.sh + core-tests/multiple-pattern-test.sh - name: Test resource-release-test.sh if: runner.os != 'Windows' diff --git a/core-tests/core-tests.cabal b/core-tests/core-tests.cabal index b3545a19..3a1adff0 100644 --- a/core-tests/core-tests.cabal +++ b/core-tests/core-tests.cabal @@ -50,3 +50,9 @@ executable failing-pattern-test build-depends: base <= 5, tasty, tasty-hunit, random >= 1.2, mtl default-extensions: ScopedTypeVariables ghc-options: -Wall -fno-warn-type-defaults + +executable multiple-pattern-test + import: commons + main-is: multiple-pattern-test.hs + build-depends: base < 5, tasty, tasty-hunit + ghc-options: -Wall -fno-warn-type-defaults diff --git a/core-tests/multiple-pattern-test.hs b/core-tests/multiple-pattern-test.hs new file mode 100644 index 00000000..ed232a08 --- /dev/null +++ b/core-tests/multiple-pattern-test.hs @@ -0,0 +1,14 @@ +import Test.Tasty +import Test.Tasty.HUnit + +main :: IO () +main = defaultMain $ testGroup "all" + [ testGroup "red" + [ testCase "square" $ pure () + , testCase "circle" $ pure () + ] + , testGroup "green" + [ testCase "square" $ pure () + , testCase "circle" $ pure () + ] + ] diff --git a/core-tests/multiple-pattern-test.sh b/core-tests/multiple-pattern-test.sh new file mode 100755 index 00000000..de069207 --- /dev/null +++ b/core-tests/multiple-pattern-test.sh @@ -0,0 +1,28 @@ +#!/bin/sh + +set -eux + +if ! command -v multiple-pattern-test +then + echo "multiple-pattern-test executable is not in PATH, aborting" + exit 1 +fi + +[ "$(multiple-pattern-test -l | wc -l)" -eq 4 ] +[ "$(multiple-pattern-test -l -p red | wc -l)" -eq 2 ] +[ "$(multiple-pattern-test -l -p circle | wc -l)" -eq 2 ] +[ "$(multiple-pattern-test -l -p red -p circle | wc -l)" -eq 1 ] +[ "$(multiple-pattern-test -l -p red -p circle -p green | wc -l)" -eq 0 ] + +# Edge case: the empty pattern matches everything +[ "$(multiple-pattern-test -l -p '' | wc -l)" -eq 4 ] +[ "$(multiple-pattern-test -l -p '' -p '' | wc -l)" -eq 4 ] +[ "$(multiple-pattern-test -l -p '' -p red | wc -l)" -eq 2 ] +[ "$(multiple-pattern-test -l -p red -p '' | wc -l)" -eq 2 ] +[ "$(multiple-pattern-test -l -p '' -p red -p '' | wc -l)" -eq 2 ] +[ "$(multiple-pattern-test -l -p red -p '' -p circle | wc -l)" -eq 1 ] + +# Environment variable is entirely overridden by any command line options +[ "$(TASTY_PATTERN=red.circle multiple-pattern-test -l | wc -l)" -eq 1 ] +[ "$(TASTY_PATTERN=red.circle multiple-pattern-test -l -p square | wc -l)" -eq 2 ] +[ "$(TASTY_PATTERN=red.circle multiple-pattern-test -l -p square -p green | wc -l)" -eq 1 ] diff --git a/core/CHANGELOG.md b/core/CHANGELOG.md index b681e9ef..94944551 100644 --- a/core/CHANGELOG.md +++ b/core/CHANGELOG.md @@ -14,6 +14,7 @@ _YYYY-MM-DD_ * `PrintTest` constructor now has an extra field used to report progress. Supply `const (pure ())` as this extra field value if you want to skip progress reporting. * Progress reporting is no longer ignored. +* The `-p`/`--pattern` option can be specified multiple times; only tests that match all patterns are run. Version 1.4.3 --------------- diff --git a/core/Test/Tasty/Patterns.hs b/core/Test/Tasty/Patterns.hs index 14dc7ec0..6689a967 100644 --- a/core/Test/Tasty/Patterns.hs +++ b/core/Test/Tasty/Patterns.hs @@ -1,6 +1,6 @@ -- | Test patterns -{-# LANGUAGE CPP, DeriveDataTypeable #-} +{-# LANGUAGE CPP, DeriveDataTypeable, TypeApplications #-} module Test.Tasty.Patterns ( TestPattern(..) @@ -18,6 +18,9 @@ import Test.Tasty.Patterns.Parser import Test.Tasty.Patterns.Eval import Data.Char +import Data.Coerce (coerce) +import Data.List.NonEmpty (nonEmpty) +import Data.Maybe (catMaybes) import Data.Typeable import Options.Applicative hiding (Success) #if !MIN_VERSION_base(4,11,0) @@ -39,12 +42,16 @@ newtype TestPattern = noPattern :: TestPattern noPattern = TestPattern Nothing +-- | Since tasty-1.5, this option can be specified multiple times on the +-- command line. Only the tests matching all given patterns will be selected. instance IsOption TestPattern where defaultValue = noPattern parseValue = parseTestPattern optionName = return "pattern" optionHelp = return "Select only tests which satisfy a pattern or awk expression" - optionCLParser = mkOptionCLParser (short 'p' <> metavar "PATTERN") + optionCLParser = + fmap (TestPattern . fmap (foldr1 And) . nonEmpty . catMaybes . coerce @[TestPattern]) . some $ + mkOptionCLParser (short 'p' <> metavar "PATTERN") -- | @since 1.2 parseExpr :: String -> Maybe Expr