Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Windows portability (fix #16) #31

Merged
merged 22 commits into from
Sep 20, 2021
Merged
Changes from all commits
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
2ddb9bd
Testcase for #16
andreasabel Sep 6, 2021
f861d2c
WIP testcase for #16: use interactive test runner
andreasabel Sep 6, 2021
d557642
WIP #16: print output of showDiff test
andreasabel Sep 6, 2021
ec378de
WIP #16: E.catch, show test details direct on macOS/windows
andreasabel Sep 6, 2021
6b2c53e
Re #16: on `git diff`, interpret non-empty stderr as failure
andreasabel Sep 6, 2021
bf66105
Re #16: try shellEscape hack for Windows sh -c
andreasabel Sep 7, 2021
dde3cfa
Interactive: simplify tryAccept (fewer arguments)
andreasabel Sep 7, 2021
aa5b3a9
Cosmetics
andreasabel Sep 8, 2021
86de0e8
Tests: use withCurrentDirectory to not affect subsequent tests
andreasabel Sep 8, 2021
5047bdb
WIP #16: an interactive test where the golden value never matches
andreasabel Sep 8, 2021
9c3c7b8
Re #16: replace shellEscape hack by backslashes-to-slashes
andreasabel Sep 8, 2021
1fd573e
Cosmetics; tryAccept: rename isTerm to isANSI
andreasabel Sep 8, 2021
0bf8aab
Re #16: unify printDiff and showDiff; check for sh, git etc before ca…
andreasabel Sep 8, 2021
5c2cbe7
CI #16: add --test-options=-i (work around #32
andreasabel Sep 8, 2021
7e23839
Re #16: replace "sh -c" by callCommand, shell, system, rawSystem
andreasabel Sep 9, 2021
d223299
Re #16: retain `sh -c` indirection for `colordiff`
andreasabel Sep 13, 2021
e771a23
CHANGELOG: added release dates (source: git tags)
andreasabel Sep 13, 2021
ad44d4c
README and CHANGELOG for #16
andreasabel Sep 13, 2021
b5e1ba5
Re #16: revert to: don't accept automatically if -i < /dev/null
andreasabel Sep 18, 2021
e578bfe
Bump to 3.3, CI for 9.2.1-rc1
andreasabel Sep 20, 2021
bc87401
Haddockumentation fixes (mostly cosmetic).
andreasabel Sep 20, 2021
d2b273f
Release 3.3: Finish CHANGELOG; cosmetics .cabal file
andreasabel Sep 20, 2021
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
66 changes: 51 additions & 15 deletions .github/workflows/haskell-ci.yml
Original file line number Diff line number Diff line change
@@ -8,9 +8,9 @@
#
# For more information, see https://github.com/haskell-CI/haskell-ci
#
# version: 0.13.20210606
# version: 0.13.20210901
#
# REGENDATA ("0.13.20210606",["github","tasty-silver.cabal"])
# REGENDATA ("0.13.20210901",["github","tasty-silver.cabal"])
#
name: Haskell-CI
on:
@@ -26,15 +26,20 @@ jobs:
strategy:
matrix:
include:
- compiler: ghc-9.2.0.20210821
compilerKind: ghc
compilerVersion: 9.2.0.20210821
setup-method: ghcup
allow-failure: true
- compiler: ghc-9.0.1
compilerKind: ghc
compilerVersion: 9.0.1
setup-method: hvr-ppa
allow-failure: false
- compiler: ghc-8.10.4
- compiler: ghc-8.10.7
compilerKind: ghc
compilerVersion: 8.10.4
setup-method: hvr-ppa
compilerVersion: 8.10.7
setup-method: ghcup
allow-failure: false
- compiler: ghc-8.8.4
compilerKind: ghc
@@ -87,9 +92,17 @@ jobs:
run: |
apt-get update
apt-get install -y --no-install-recommends gnupg ca-certificates dirmngr curl git software-properties-common libtinfo5
apt-add-repository -y 'ppa:hvr/ghc'
apt-get update
apt-get install -y "$HCNAME" cabal-install-3.4
if [ "${{ matrix.setup-method }}" = ghcup ]; then
mkdir -p "$HOME/.ghcup/bin"
curl -sL https://downloads.haskell.org/ghcup/0.1.16.2/x86_64-linux-ghcup-0.1.16.2 > "$HOME/.ghcup/bin/ghcup"
chmod a+x "$HOME/.ghcup/bin/ghcup"
"$HOME/.ghcup/bin/ghcup" install ghc "$HCVER"
"$HOME/.ghcup/bin/ghcup" install cabal 3.4.0.0
else
apt-add-repository -y 'ppa:hvr/ghc'
apt-get update
apt-get install -y "$HCNAME" cabal-install-3.4
fi
env:
HCKIND: ${{ matrix.compilerKind }}
HCNAME: ${{ matrix.compiler }}
@@ -101,16 +114,25 @@ jobs:
echo "CABAL_DIR=$HOME/.cabal" >> "$GITHUB_ENV"
echo "CABAL_CONFIG=$HOME/.cabal/config" >> "$GITHUB_ENV"
HCDIR=/opt/$HCKIND/$HCVER
HC=$HCDIR/bin/$HCKIND
echo "HC=$HC" >> "$GITHUB_ENV"
echo "HCPKG=$HCDIR/bin/$HCKIND-pkg" >> "$GITHUB_ENV"
echo "HADDOCK=$HCDIR/bin/haddock" >> "$GITHUB_ENV"
echo "CABAL=/opt/cabal/3.4/bin/cabal -vnormal+nowrap" >> "$GITHUB_ENV"
if [ "${{ matrix.setup-method }}" = ghcup ]; then
HC=$HOME/.ghcup/bin/$HCKIND-$HCVER
echo "HC=$HC" >> "$GITHUB_ENV"
echo "HCPKG=$HOME/.ghcup/bin/$HCKIND-pkg-$HCVER" >> "$GITHUB_ENV"
echo "HADDOCK=$HOME/.ghcup/bin/haddock-$HCVER" >> "$GITHUB_ENV"
echo "CABAL=$HOME/.ghcup/bin/cabal-3.4.0.0 -vnormal+nowrap" >> "$GITHUB_ENV"
else
HC=$HCDIR/bin/$HCKIND
echo "HC=$HC" >> "$GITHUB_ENV"
echo "HCPKG=$HCDIR/bin/$HCKIND-pkg" >> "$GITHUB_ENV"
echo "HADDOCK=$HCDIR/bin/haddock" >> "$GITHUB_ENV"
echo "CABAL=/opt/cabal/3.4/bin/cabal -vnormal+nowrap" >> "$GITHUB_ENV"
fi

HCNUMVER=$(${HC} --numeric-version|perl -ne '/^(\d+)\.(\d+)\.(\d+)(\.(\d+))?$/; print(10000 * $1 + 100 * $2 + ($3 == 0 ? $5 != 1 : $3))')
echo "HCNUMVER=$HCNUMVER" >> "$GITHUB_ENV"
echo "ARG_TESTS=--enable-tests" >> "$GITHUB_ENV"
echo "ARG_BENCH=--enable-benchmarks" >> "$GITHUB_ENV"
echo "HEADHACKAGE=false" >> "$GITHUB_ENV"
if [ $((HCNUMVER >= 90200)) -ne 0 ] ; then echo "HEADHACKAGE=true" >> "$GITHUB_ENV" ; else echo "HEADHACKAGE=false" >> "$GITHUB_ENV" ; fi
echo "ARG_COMPILER=--$HCKIND --with-compiler=$HC" >> "$GITHUB_ENV"
echo "GHCJSARITH=0" >> "$GITHUB_ENV"
env:
@@ -139,6 +161,17 @@ jobs:
repository hackage.haskell.org
url: http://hackage.haskell.org/
EOF
if $HEADHACKAGE; then
cat >> $CABAL_CONFIG <<EOF
repository head.hackage.ghc.haskell.org
url: https://ghc.gitlab.haskell.org/head.hackage/
secure: True
root-keys: 7541f32a4ccca4f97aea3b22f5e593ba2c0267546016b992dfadcd2fe944e55d
26021a13b401500c8eb2761ca95c61f2d625bfef951b939a8124ed12ecf07329
f76d08be13e9a61a377a85e2fb63f4c5435d40f8feb3e12eb05905edb8cdea89
key-threshold: 3
EOF
fi
cat $CABAL_CONFIG
- name: versions
run: |
@@ -186,7 +219,10 @@ jobs:
if [ $((HCNUMVER >= 80200)) -ne 0 ] ; then echo " ghc-options: -Werror=missing-methods" >> cabal.project ; fi
cat >> cabal.project <<EOF
EOF
$HCPKG list --simple-output --names-only | perl -ne 'for (split /\s+/) { print "constraints: $_ installed\n" unless /^(bytestring|process|tasty-silver)$/; }' >> cabal.project.local
if $HEADHACKAGE; then
echo "allow-newer: $($HCPKG list --simple-output | sed -E 's/([a-zA-Z-]+)-[0-9.]+/*:\1,/g')" >> cabal.project
fi
$HCPKG list --simple-output --names-only | perl -ne 'for (split /\s+/) { print "constraints: $_ installed\n" unless /^(bytestring|directory|process|tasty-silver)$/; }' >> cabal.project.local
cat cabal.project
cat cabal.project.local
- name: dump install plan
2 changes: 1 addition & 1 deletion .github/workflows/macOS.yml
Original file line number Diff line number Diff line change
@@ -64,4 +64,4 @@ jobs:

- name: Test
run: |
cabal test
cabal test --test-show-details=direct --test-options=-i
2 changes: 1 addition & 1 deletion .github/workflows/windows.yml
Original file line number Diff line number Diff line change
@@ -64,4 +64,4 @@ jobs:

- name: Test
run: |
cabal test
cabal test --test-show-details=direct --test-options=-i
50 changes: 29 additions & 21 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,118 +1,126 @@
Changes
=======

Version 3.3 (20 Sep 2021)
-----------

* Windows portability (#16):
- Calls to `git diff` are no longer indirected via `sh -c`.
- When indirection via `sh -c` is used, backslashes in filenames are converted to slashes.
* Tested with GHC 7.4 - 9.2.1-RC1

Version 3.2.3 (13 Sep 2021)
-------------

* Tested with GHC 7.4 - 9.0 (fixed compilation with GHC 7.4 - 7.8)
* CI via GitHub Actions on platforms `ubuntu`, `macOS`, `windows`.

Version 3.2.2
Version 3.2.2 (22 Jun 2021)
-------------

* Fix cabal warning (#27, thanks to felixonmars)

Version 3.2.1
Version 3.2.1 (22 Dec 2020)
-------------

* Fix option parser (#25)

Version 3.2
Version 3.2 (21 Dec 2020)
-----------

* Compatibility with tasty 1.4 (breaks compatibility with older versions of tasty)

Version 3.1.15
Version 3.1.15 (8 Jun 2020)
--------------

* Fix missing space in git diff calls introduced in v3.1.14 (#22, thanks to croyzor)

Version 3.1.14
Version 3.1.14 (8 Jun 2020)
--------------

* Fix wrong interpretation of git diff exit codes (#21, thanks to croyzor)

Version 3.1.13
Version 3.1.13 (12 Jul 2019)
--------------

* Add option to disable ansi tricks (#18, thanks to L-TChen)

Version 3.1.12
Version 3.1.12 (24 Sep 2018)
--------------

* Fix compilation with GHC 8.4 (thanks to asr)

Version 3.1.11
Version 3.1.11 (29 Dec 2017)
--------------

* Fix compilation with GHC 8.4

Version 3.1.10
Version 3.1.10 (1 Apr 2017)
--------------

* Better error handling for calls to external tools (`git diff`)

Version 3.1.9
Version 3.1.9 (29 Aug 2016)
-------------

* Fix compilation with optparse-applicative 0.13.*.
* Provide character-level diff if wdiff and colordiff are available.

Version 3.1.8.1
Version 3.1.8.1 (19 Jan 2016)
---------------

* Fix compilation with GHC 8.

Version 3.1.8
Version 3.1.8 (10 Nov 2015)
-------------

* Make update function optional for test cases.

Version 3.1.7
Version 3.1.7 (14 May 2015)
-------------

* Add feature to disable certain tests, still showing them in the UI
but not running them.
* Fix a concurrency issue in the interactive test runner.

Version 3.1.6
Version 3.1.6 (14 May 2015)
-------------

* Expose regex filter modules.
* Fix issue with regex filters when used together with withResource nodes.

Version 3.1.5
Version 3.1.5 (12 Apr 2015)
-------------

* Add experimental --regex-include option to select tests using a regex.
This option is highly experimental and may change in later versions!
* The --regex-include/--regex-exclude option may be given multiple times now.
The exclusion regexes are applied first, after that all inclusion regexes.

Version 3.1.4
Version 3.1.4 (12 Apr 2015)
-------------

* Add experimental --regex-exclude option to filter out tests using a regex.
This option is highly experimental and may change in later versions!

Version 3.1.3
Version 3.1.3 (6 Apr 2015)
-------------

* Use package temporary instead of temporary-rc.
* Re-add command line options for test runner which were accidentally removed.

Version 3.1.2
Version 3.1.2 (6 Apr 2015)
-------------

* Add non-interactive mode to test runner, printing diffs/actual values directly to stdout.
Useful for (travis) CI.

Version 3.1.1
Version 3.1.1 (4 Apr 2015)
-------------

* Report success instead of failure if new result is accepted in interactive mode.

Version 3.1
Version 3.1 (4 Apr 2015)
-----------

* Fixed & tested support for GHC 7.4.2 - 7.10.1
@@ -121,7 +129,7 @@ Version 3.1
* Enable travis CI builds

Version 3.0 - 3.0.2.2
-----------
---------------------

* Refactored API
* Add interactive mode
19 changes: 19 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -23,6 +23,25 @@ to the user. Based upon this diff, the user can choose to update the golden stan
fix the test case as necessary. Interactive mode requires that at least `git diff` and `less` is
available, or preferrably `wdiff` and `colordiff` for character-based diffs.

Portability
-----------

`tasty-silver` aims to work under Linux, macOS, and Windows. In
particular, it should work in the [GitHub CI virtual
environments](https://github.com/actions/virtual-environments).

Known limitations:

- On `macOS`, GHC ≥ 7.10 is required, as GHC ≤ 7.8 produces code that
is not compatible with the System Integrity Protection mechanism of
Mac OS X. In particular, you could see errors like:
```
/usr/bin/less: getPermissions:fileAccess: permission denied (Operation not permitted)
```

- On Windows, the colored diff may not be available as it depends on
the availability of `colordiff`, `less`, `sh`, and `wdiff`.

Examples
--------

48 changes: 23 additions & 25 deletions Test/Tasty/Silver.hs
Original file line number Diff line number Diff line change
@@ -3,42 +3,45 @@
{- |
This module provides a simplified interface. If you want more, see "Test.Tasty.Silver.Advanced".
Note about filenames. They are looked up in the usual way, thus relative
=== Note about filenames
They are looked up in the usual way, thus relative
names are relative to the processes current working directory.
It is common to run tests from the package's root directory (via @cabal
test@ or @cabal install --enable-tests@), so if your test files are under
test@ or @stack test@), so if your test files are under
the @tests\/@ subdirectory, your relative file names should start with
@tests\/@ (even if your @test.hs@ is itself under @tests\/@, too).
Note about line endings. The best way to avoid headaches with line endings
=== Note about line endings
The best way to avoid headaches with line endings
(when running tests both on UNIX and Windows) is to treat your golden files
as binary, even when they are actually textual.
This means:
* When writing output files from Haskell code, open them in binary mode
(see 'openBinaryFile', 'withBinaryFile' and 'hSetBinaryMode'). This will
disable automatic @\\n -> \\r\\n@ conversion on Windows. For convenience, this
module exports 'writeBinaryFile' which is just like `writeFile` but opens
the file in binary mode. When using 'ByteString's note that
(see 'System.IO.openBinaryFile', 'System.IO.withBinaryFile' and 'System.IO.hSetBinaryMode'). This will
disable automatic @\\n -> \\r\\n@ conversion on Windows.
When using 'Data.ByteString.ByteString', note that
"Data.ByteString" and "Data.ByteString.Lazy" use binary mode for
@writeFile@, while "Data.ByteString.Char8" and "Data.ByteString.Lazy.Char8"
@'writeFile'@, while "Data.ByteString.Char8" and "Data.ByteString.Lazy.Char8"
use text mode.
* Tell your VCS not to do any newline conversion for golden files. For
git check in a @.gitattributes@ file with the following contents (assuming
* Tell your version control not to do any newline conversion for golden files. For
git, check in a @.gitattributes@ file with the following contents (assuming
your golden files have @.golden@ extension):
>*.golden -text
On its side, tasty-golden reads and writes files in binary mode, too.
On its side, `tasty-silver` reads and writes files in binary mode, too.
Why not let Haskell/git do automatic conversion on Windows? Well, for
instance, @tar@ will not do the conversion for you when unpacking a release
tarball, so when you run @cabal install your-package --enable-tests@, the
tarball, so when you run e.g. @stack install your-package --tests@, the
tests will be broken.
As a last resort, you can strip all @\\r@s from both arguments in your
As a last resort, you can strip all @\\r@ characters from both arguments in your
comparison function when necessary. But most of the time treating the files
as binary does the job.
-}
@@ -68,7 +71,7 @@ import System.Exit
import System.FilePath
import System.Process.Text as PT

import Test.Tasty.Providers
import Test.Tasty.Providers (TestTree, TestName)
import Test.Tasty.Silver.Advanced

-- | Compare a given file contents against the golden file contents. Assumes that both text files are utf8 encoded.
@@ -146,12 +149,11 @@ printProcResult (ex, a, b) = T.unlines (["ret > " `T.append` T.pack (show ex)]

-- | Find all files in the given directory and its subdirectories that have
-- the given extensions.
--
-- It is typically used to find all test files and produce a golden test
-- per test file.
--
-- The returned paths use forward slashes to separate path components,
-- even on Windows. Thus if the file name ends up in a golden file, it
-- The returned paths use forward slashes (@'/'@) to separate path components,
-- /even on Windows/. Thus if the file name ends up in a golden file, it
-- will not differ when run on another platform.
--
-- The semantics of extensions is the same as in 'takeExtension'. In
@@ -162,25 +164,21 @@ printProcResult (ex, a, b) = T.unlines (["ret > " `T.append` T.pack (show ex)]
--
-- It doesn't do anything special to handle symlinks (in particular, it
-- probably won't work on symlink loops).
--
-- Nor is it optimized to work with huge directory trees (you'd probably
-- want to use some form of coroutines for that).
findByExtension
:: [FilePath] -- ^ extensions
-> FilePath -- ^ directory
-> IO [FilePath] -- ^ paths
findByExtension extsList = go where
findByExtension extsList = go
where
exts = Set.fromList extsList
go dir = do
allEntries <- getDirectoryContents dir
let entries = filter (not . (`elem` [".", ".."])) allEntries
liftM concat $ forM entries $ \e -> do
let path = dir ++ "/" ++ e
let path = dir ++ "/" ++ e -- NOT </>! Slash accepted even on Windows.
isDir <- doesDirectoryExist path
if isDir
then go path
else
return $
if takeExtension path `Set.member` exts
then [path]
else []
else return [ path | takeExtension path `Set.member` exts ]
4 changes: 2 additions & 2 deletions Test/Tasty/Silver/Advanced.hs
Original file line number Diff line number Diff line change
@@ -2,7 +2,7 @@
{-# LANGUAGE CPP #-}

module Test.Tasty.Silver.Advanced
( -- * The main function
( -- * Constructing golden tests
goldenTest1,

goldenTestIO,
@@ -12,7 +12,7 @@ module Test.Tasty.Silver.Advanced
GShow (..),
GDiff (..),

-- * reading files
-- * Reading files
readFileMaybe
)
where
6 changes: 4 additions & 2 deletions Test/Tasty/Silver/Filter.hs
Original file line number Diff line number Diff line change
@@ -38,6 +38,7 @@ import Test.Tasty hiding (defaultMain)
import Test.Tasty.Options
import Test.Tasty.Runners

-- | Path into the 'TestTree'. Separator is the slash character(@'/'@).
type TestPath = String

-- we have to store the regex as String, as there is no Typeable instance
@@ -97,9 +98,10 @@ filterWithRegex opts = filterWithPred (checkRF True $ excRgxs ++ incRgxs)
-- are met:
-- 1. At least one RFInclude matches.
-- 2. No RFExclude filter matches.
checkRF :: Bool -- ^ If true, ignore 1. condition if no RFInclude is given.
checkRF :: Bool -- ^ If 'True', ignore first condition if no 'RFInclude' is given.
-> [RegexFilter]
-> TestPath -> Bool
-> TestPath
-> Bool
checkRF ignNoInc rf tp =
((null incRgxs && ignNoInc) || any regexMatches incRgxs)
&& (not $ any regexMatches excRgxs)
328 changes: 232 additions & 96 deletions Test/Tasty/Silver/Interactive.hs

Large diffs are not rendered by default.

13 changes: 7 additions & 6 deletions Test/Tasty/Silver/Interactive/Run.hs
Original file line number Diff line number Diff line change
@@ -7,12 +7,14 @@ module Test.Tasty.Silver.Interactive.Run
)
where

import Data.Tagged
import Data.Typeable

import Test.Tasty hiding (defaultMain)
import Test.Tasty.Runners
import Test.Tasty.Options
import Data.Typeable
import Data.Tagged
import Test.Tasty.Providers
import Test.Tasty.Runners
import Test.Tasty.Silver.Filter ( TestPath )

data CustomTestExec t = IsTest t => CustomTestExec t (OptionSet -> t -> (Progress -> IO ()) -> IO Result)
deriving (Typeable)
@@ -21,10 +23,9 @@ instance IsTest t => IsTest (CustomTestExec t) where
run opts (CustomTestExec t r) cb = r opts t cb
testOptions = retag $ (testOptions :: Tagged t [OptionDescription])

type TestPath = String

-- | Provide new test run function wrapping the existing tests.
wrapRunTest :: (forall t . IsTest t => TestPath -> TestName -> OptionSet -> t -> (Progress -> IO ()) -> IO Result)
wrapRunTest
:: (forall t . IsTest t => TestPath -> TestName -> OptionSet -> t -> (Progress -> IO ()) -> IO Result)
-> TestTree
-> TestTree
wrapRunTest = wrapRunTest' "/"
39 changes: 37 additions & 2 deletions Test/Tasty/Silver/Internal.hs
Original file line number Diff line number Diff line change
@@ -24,7 +24,7 @@ import System.IO.Error
import Test.Tasty.Providers
import Test.Tasty.Options

-- | See 'goldenTest1' for explanation of the fields.
-- | See 'Test.Tasty.Silver.Advanced.goldenTest1' for explanation of the fields.

data Golden =
forall a .
@@ -49,7 +49,7 @@ instance IsOption AcceptTests where
optionHelp = return "Accept current results of golden tests"
optionCLParser = flagCLParser Nothing (AcceptTests True)

-- | Read the file if it exists, else return Nothing.
-- | Read the file if it exists, else return 'Nothing'.
-- Useful for reading golden files.

readFileMaybe :: FilePath -> IO (Maybe SB.ByteString)
@@ -130,3 +130,38 @@ instance Show (GoldenResult' m) where
show GREqual = "GREqual"
show (GRDifferent {}) = "GRDifferent"
show (GRNoGolden {}) = "GRNoGolden"


-- * Generic utilites

-- | Monadic @if@.

ifM :: Monad m => m Bool -> m a -> m a -> m a
ifM mc mt me = do
c <- mc
if c then mt else me

-- | Monadic @if (not ...) ...@.

ifNotM :: Monad m => m Bool -> m a -> m a -> m a
ifNotM mc = flip $ ifM mc

-- | Short-cutting version of @'liftM2' (&&)@.

and2M :: Monad m => m Bool -> m Bool -> m Bool
and2M ma mb = ifM ma mb $ return False

-- | Short-cutting version of @'and' . 'sequence'@.

andM :: Monad m => [m Bool] -> m Bool
andM = Prelude.foldl and2M (return True)

-- | Short-cutting version of @'liftM2' (||)@.

or2M :: Monad m => m Bool -> m Bool -> m Bool
or2M ma mb = ifM ma (return True) mb

-- | Short-cutting version of @'or' . 'sequence'@.

orM :: Monad m => [m Bool] -> m Bool
orM = Prelude.foldl or2M (return False)
6 changes: 5 additions & 1 deletion cabal.haskell-ci
Original file line number Diff line number Diff line change
@@ -1 +1,5 @@
installed: +all -bytestring -process
installed: +all -bytestring -directory -process

-- on Linux we can use ghcup to setup (some) of jobs
-- hvr-ppa latest are 9.0.1 and 8.10.4
ghcup-jobs: >= 9.2 || > 8.10.4 && < 9.0
55 changes: 31 additions & 24 deletions tasty-silver.cabal
Original file line number Diff line number Diff line change
@@ -1,16 +1,16 @@
name: tasty-silver
version: 3.2.3
version: 3.3
synopsis: A fancy test runner, including support for golden tests.
description:
This package provides a fancy test runner and support for «golden testing».

.
A golden test is an IO action that writes its result to a file.
To pass the test, this output file should be identical to the corresponding
«golden» file, which contains the correct result for the test.

.
The test runner allows filtering tests using regexes, and to interactively
inspect the result of golden tests.

.
This package is a heavily extended fork of tasty-golden.

license: MIT
@@ -29,8 +29,9 @@ extra-source-files:
README.md

tested-with:
GHC == 9.2.0.20210821
GHC == 9.0.1
GHC == 8.10.4
GHC == 8.10.7
GHC == 8.8.4
GHC == 8.6.5
GHC == 8.4.4
@@ -63,25 +64,29 @@ library
-Wcompat

build-depends:
ansi-terminal >= 0.6.2.1,
async,
base >= 4.5,
-- regex-tdfa has this lower bound on base, so we make it explicit here
bytestring >= 0.9.2.1,
containers,
directory,
deepseq,
filepath,
mtl,
optparse-applicative,
process >= 1.2,
process-extras >= 0.2,
regex-tdfa >= 1.2.0,
stm >= 2.4.2,
tagged,
tasty >= 1.4,
temporary,
text >= 0.11.0.0
base >= 4.5
-- regex-tdfa has this lower bound on base, so we make it explicit here
, ansi-terminal >= 0.6.2.1
, async
, bytestring >= 0.9.2.1
, containers
, directory >= 1.2.3.0
-- withCurrentDirectory needs >= 1.2.3.0
, deepseq
, filepath
, mtl
, optparse-applicative
, process >= 1.2
, process-extras >= 0.3
-- readCreateProcessWithExitCode needs >= 0.3
, regex-tdfa >= 1.2.0
, silently >= 1.2.5.1
-- Andreas Abel, 2021-09-05, latest silently is today 1.2.5.1
, stm >= 2.4.2
, tagged
, tasty >= 1.4
, temporary
, text >= 0.11.0.0
if impl(ghc < 8.0)
build-depends: semigroups >= 0.18.3

@@ -106,6 +111,8 @@ Test-suite test
-- Andreas Abel, 2021-09-05, latest silently is today 1.2.5.1
, temporary
, transformers >= 0.3
if impl(ghc < 8.0)
build-depends: semigroups

if impl(ghc >= 8.0)
ghc-options:
59 changes: 52 additions & 7 deletions tests/test.hs
Original file line number Diff line number Diff line change
@@ -1,16 +1,22 @@
{-# LANGUAGE CPP #-}
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE ScopedTypeVariables #-}

import Control.Concurrent.MVar
import Control.Monad (unless)
import Control.Monad.IO.Class (liftIO)
import Control.Exception as E ( catch, SomeException )
-- Prelude of GHC 7.4 also has @catch@, so we disambiguate with E.catch
import Control.Monad ( unless )
import Control.Monad.IO.Class ( liftIO )

import Data.List (sort)
#if !(MIN_VERSION_base(4,8,0))
import Data.Monoid (mempty)
import Data.Functor ( (<$) )
import Data.Monoid ( mempty )
#endif

import System.Directory
import System.Directory ( createDirectory, withCurrentDirectory )
import System.FilePath
import System.IO.Silently (capture)
import System.IO.Silently ( capture )
import System.IO.Temp

import Test.Tasty hiding (defaultMain)
@@ -28,17 +34,21 @@ touch f = writeFile f ""

main :: IO ()
main = defaultMain $ testGroup "tests" $
testShowDiff :
testFindByExt :
testWithResource :
testCheckRF :
-- Andreas, 2021-09-18
-- @testGolden@ always fails, would need @--accept@ mode.
-- testGolden :
[]

testFindByExt :: TestTree
testFindByExt =
testCase "findByExtension" $
withSystemTempDirectory "golden-test" $ \basedir -> do

setCurrentDirectory basedir
withCurrentDirectory basedir $ do
-- Andreas 2021-09-07: setCurrentDirectory would affect other tests!

createDirectory ("d1")
createDirectory ("d1" </> "d2")
@@ -58,10 +68,45 @@ testFindByExt =
, "./f2.h"
]

testShowDiff :: TestTree
testShowDiff =
testCase "showDiff" $
withSystemTempDirectory "golden-test" $ \ dir -> do
let
goldenFile = dir </> "golden.txt"
goldenValue = "golden value"
actualFile = dir </> "actual.txt"
actualValue = "actual value"
tree = goldenVsFile "showDiff-internal" goldenFile actualFile $
writeFile actualFile actualValue
writeFile goldenFile goldenValue
writeFile actualFile actualValue
do
-- let io = defaultMain tree
let io = runTestsInteractive (const False) mempty tree
(out, success) <- capture $ E.catch (True <$ io) $ \ (e :: SomeException) -> do
print e
return False
-- unless success $ putStr out
putStr out
assertBool "Test should succeed." success

-- UNUSED, but KEEP!
-- testGolden :: TestTree
-- testGolden =
-- goldenTest1
-- "wrongOutput"
-- (return $ Just "golden value")
-- (return "actual value")
-- (DiffText Nothing) -- always fail
-- ShowText
-- (const $ return ()) -- keep the golden file no matter what

-- | Check if resources are properly initialized.
testWithResource :: TestTree
testWithResource =
testCase "withResource" $
-- The @AcceptTests True@ option automatically replaces the golden value.
case tryIngredients [consoleTestReporter] (singleOption $ AcceptTests True) tree of
Just r' -> do
(out, success) <- capture r'