fir-0.1.0.0: test/Folders.hs
{-# LANGUAGE BlockArguments #-}
{-# LANGUAGE DeriveFoldable #-}
{-# LANGUAGE DeriveFunctor #-}
{-# LANGUAGE DeriveTraversable #-}
{-# LANGUAGE DerivingStrategies #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE StandaloneDeriving #-}
{-# LANGUAGE TupleSections #-}
module Folders where
-- base
import Control.Monad
( forM )
-- filepath
import System.FilePath
( (</>) )
-- fir-tests
import Test
( Test, TestOutput(..)
, runTest
)
data Folder a = Folder String [a]
deriving stock (Functor, Foldable, Traversable)
------------------------------------------------------------------------------------------
-- running tests on folders
runTestsP :: (String -> String -> Test -> Bool)
-> [ Folder (String, Test) ]
-> IO [ Folder (String, Test, TestOutput) ]
runTestsP f
= runTests
. map ( \ (Folder g tests) -> Folder g (filter ( \(p,t) -> f g p t ) tests) )
runTests :: [ Folder (String, Test) ]
-> IO [ Folder (String, Test, TestOutput) ]
runTests
= traverse
( \ (Folder folderName folderTests) ->
Folder folderName <$>
forM folderTests \ (testName, testType) ->
(testName, testType, )
<$> runTest testType ( folderName </> testName )
)
runTestsFromFolder
:: String
-> [ Folder (String, Test) ]
-> IO [ Folder (String, Test, TestOutput) ]
runTestsFromFolder folderName = runTestsP ( \ x _ _ -> x == folderName )
------------------------------------------------------------------------------------------
-- displaying test result folders
deriving stock instance Show (Folder (String, Test))
instance Show (Folder (String, Test, TestOutput)) where
show ( Folder folderName testResults )
= padRToLength 15 folderName
<> "( " <> showPaddedL 2 passes <> " / " <> showPaddedL 2 total <> " )"
<> foldMap showTestResult testResults
<> "\n"
where
total, passes :: Int
total = length testResults
passes = length . filter ( \(_,_,res) -> res == Success ) $ testResults
showTestResult :: (String, Test, TestOutput) -> String
showTestResult (testName, testType, testResult)
= "\n " <> padRToLength 30 testName
<> padRToLength 9 (show testType) <> ": " <> show testResult
instance {-# OVERLAPPING #-} Show [Folder (String, Test, TestOutput)] where
show = unlines . map show
-- utility padding functions
padRToLength :: Int -> String -> String
padRToLength n s
| lg >= n = s
| otherwise = s <> replicate (n - lg) ' '
where lg = length s
padLToLength :: Int -> String -> String
padLToLength n s
| lg >= n = s
| otherwise = replicate (n - lg) ' ' <> s
where lg = length s
showPaddedR :: Show a => Int -> a -> String
showPaddedR n = padRToLength n . show
showPaddedL :: Show a => Int -> a -> String
showPaddedL n = padLToLength n . show