hledger/hledger-lib/test/doctests.hs

66 lines
1.9 KiB
Haskell

{-
Run doctests in Hledger source files under the current directory
(./Hledger.hs, ./Hledger/**, ./Text/**) using the doctest runner.
Arguments are case-insensitive file path substrings, to limit the files searched.
--verbose shows files being searched for doctests and progress while running.
--slow reloads ghci between each test (https://github.com/sol/doctest#a-note-on-performance).
Eg, in hledger source dir:
$ make ghci-doctest, :main [--verbose] [--slow] [CIFILEPATHSUBSTRINGS]
or:
$ stack test hledger-lib:test:doctests [--test-arguments '[--verbose] [--slow] [CIFILEPATHSUBSTRINGS]']
-}
-- This file can't be called doctest.hs ("File name does not match module name")
{-# LANGUAGE PackageImports #-}
import Control.Monad
import Data.Char
import Data.List
import System.Environment
import "Glob" System.FilePath.Glob
import Test.DocTest
main = do
args <- getArgs
let
verbose = "--verbose" `elem` args
slow = "--slow" `elem` args
pats = filter (not . ("-" `isPrefixOf`)) args
-- find source files
sourcefiles <- (filter (not . isInfixOf "/.") . concat) <$> sequence [
glob "Hledger.hs"
,glob "Hledger/**/*.hs"
,glob "Text/**/*.hs"
]
-- filter by patterns (case insensitive infix substring match)
let
fs | null pats = sourcefiles
| otherwise = [f | f <- sourcefiles, let f' = map toLower f, any (`isInfixOf` f') pats']
where pats' = map (map toLower) pats
fslen = length fs
if (null fs)
then do
putStrLn $ "No file paths found matching: " ++ unwords pats
else do
putStrLn $
"Loading and searching for doctests in "
++ show fslen
++ if fslen > 1 then " files, plus any files they import:" else " file, plus any files it imports:"
when verbose $ putStrLn $ unwords fs
doctest $
(if verbose then ("--verbose" :) else id) $ -- doctest >= 0.15.0
(if slow then id else ("--fast" :)) $ -- doctest >= 0.11.4
fs