module Tester.Suite(Result, runTests, Suite(..), TestResult(..)) where import Data.Bifoldable(bifoldMap) import Data.List.NonEmpty(NonEmpty) import Data.Map((!)) import Data.Validation(Validation) import qualified Data.Set as Set import Tester.Dialect(FlagCells) import Tester.RunSettings(cellsToSettings, testNums) type Result f s = Validation (NonEmpty f) s data TestResult = TestSuccess | TestFailure { msg :: Text } deriving (Eq, Show) data Suite a b c = Suite { testMap :: Map Int a, runTest :: a -> Result b c, failsToStr :: NonEmpty b -> Text, succToStr :: c -> Text } instance Semigroup TestResult where ( TestFailure m1) <> (TestFailure m2) = TestFailure $ m1 <> m2 x@(TestFailure _) <> _ = x _ <> x@(TestFailure _) = x _ <> _ = TestSuccess instance Monoid TestResult where mempty = TestSuccess mappend = (<>) runTests :: FlagCells -> (Suite a b c) -> [TestResult] runTests c s@(Suite _ _ failsToStr _) = fmap (resultToTR failsToStr) $ generateResults c s generateResults :: FlagCells -> (Suite a b c) -> [Result b c] generateResults cells (Suite testMap runTest _ _) = cells |> (cellsToSettings >>> testNums >>> Set.toList >>> (fmap $ (testMap !) >>> runTest)) resultToTR :: (NonEmpty a -> Text)-> Result a b -> TestResult resultToTR fToStr = bifoldMap (fToStr >>> TestFailure) $ const TestSuccess