module Test.Common (
checkDefinesFail,
checkDefinesSuccess,
checkEquals,
checkTypeFail,
checkTypeSuccess,
containsAtLeast,
containsAtMost,
containsExactly,
containsNoDuplicates,
forceParse,
loadFile,
parseFilterMap,
parseTheTest,
readMulti,
readSingle,
readSingleWith,
runAllTests,
showParams,
) where
import Control.Monad (when)
import Data.Either
import Data.List
import System.Exit
import System.FilePath
import System.IO
import qualified Data.Map as Map
import qualified Data.Set as Set
import Base.CompilerError
import Base.CompilerMessage
import Base.TrackedErrors
import Parser.Common
import Parser.TextParser
import Parser.TypeInstance ()
import Types.TypeInstance
runAllTests :: [IO (TrackedErrors ())] -> IO ()
runAllTests :: [IO (TrackedErrors ())] -> IO ()
runAllTests [IO (TrackedErrors ())]
ts = do
[TrackedErrors ()]
results <- [IO (TrackedErrors ())] -> IO [TrackedErrors ()]
forall (t :: * -> *) (m :: * -> *) a.
(Traversable t, Monad m) =>
t (m a) -> m (t a)
sequence [IO (TrackedErrors ())]
ts
let ([(Int, CompilerMessage)]
es,[()]
ps) = [Either (Int, CompilerMessage) ()]
-> ([(Int, CompilerMessage)], [()])
forall a b. [Either a b] -> ([a], [b])
partitionEithers ([Either (Int, CompilerMessage) ()]
-> ([(Int, CompilerMessage)], [()]))
-> [Either (Int, CompilerMessage) ()]
-> ([(Int, CompilerMessage)], [()])
forall a b. (a -> b) -> a -> b
$ (Int -> TrackedErrors () -> Either (Int, CompilerMessage) ())
-> [Int]
-> [TrackedErrors ()]
-> [Either (Int, CompilerMessage) ()]
forall a b c. (a -> b -> c) -> [a] -> [b] -> [c]
zipWith Int -> TrackedErrors () -> Either (Int, CompilerMessage) ()
forall a b. a -> TrackedErrors b -> Either (a, CompilerMessage) b
numberError ([Int
1..] :: [Int]) [TrackedErrors ()]
results
((Int, CompilerMessage) -> IO ())
-> [(Int, CompilerMessage)] -> IO ()
forall (t :: * -> *) (m :: * -> *) a b.
(Foldable t, Monad m) =>
(a -> m b) -> t a -> m ()
mapM_ (\(Int
n,CompilerMessage
e) -> Handle -> String -> IO ()
hPutStr Handle
stderr (String
"Test " String -> String -> String
forall a. [a] -> [a] -> [a]
++ Int -> String
forall a. Show a => a -> String
show Int
n String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
": " String -> String -> String
forall a. [a] -> [a] -> [a]
++ CompilerMessage -> String
forall a. Show a => a -> String
show CompilerMessage
e String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
"\n")) [(Int, CompilerMessage)]
es
Handle -> String -> IO ()
hPutStr Handle
stderr (String -> IO ()) -> String -> IO ()
forall a b. (a -> b) -> a -> b
$ Int -> String
forall a. Show a => a -> String
show ([()] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length [()]
ps) String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
" tests passed + " String -> String -> String
forall a. [a] -> [a] -> [a]
++
Int -> String
forall a. Show a => a -> String
show ([(Int, CompilerMessage)] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length [(Int, CompilerMessage)]
es) String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
" tests failed\n"
Bool -> IO () -> IO ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
when (Bool -> Bool
not (Bool -> Bool) -> Bool -> Bool
forall a b. (a -> b) -> a -> b
$ [(Int, CompilerMessage)] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null [(Int, CompilerMessage)]
es) IO ()
forall a. IO a
exitFailure
numberError :: a -> TrackedErrors b -> Either (a,CompilerMessage) b
numberError :: a -> TrackedErrors b -> Either (a, CompilerMessage) b
numberError a
n TrackedErrors b
c
| TrackedErrors b -> Bool
forall (t :: (* -> *) -> * -> *) a.
(ErrorContextT t, ErrorContextM (t Identity)) =>
t Identity a -> Bool
isCompilerError TrackedErrors b
c = (a, CompilerMessage) -> Either (a, CompilerMessage) b
forall a b. a -> Either a b
Left (a
n,TrackedErrors b -> CompilerMessage
forall a. TrackedErrors a -> CompilerMessage
getCompilerError TrackedErrors b
c)
| Bool
otherwise = b -> Either (a, CompilerMessage) b
forall a b. b -> Either a b
Right (TrackedErrors b -> b
forall a. TrackedErrors a -> a
getCompilerSuccess TrackedErrors b
c)
forceParse :: ParseFromSource a => String -> a
forceParse :: String -> a
forceParse String
s = TrackedErrors a -> a
forall a. TrackedErrors a -> a
getCompilerSuccess (TrackedErrors a -> a) -> TrackedErrors a -> a
forall a b. (a -> b) -> a -> b
$ TextParser a -> String -> String -> TrackedErrors a
forall (m :: * -> *) a.
ErrorContextM m =>
TextParser a -> String -> String -> m a
runTextParser TextParser a
forall a. ParseFromSource a => TextParser a
sourceParser String
"(string)" String
s
readSingle :: ParseFromSource a => String -> String -> TrackedErrors a
readSingle :: String -> String -> TrackedErrors a
readSingle = TextParser a -> String -> String -> TrackedErrors a
forall a. TextParser a -> String -> String -> TrackedErrors a
readSingleWith TextParser a
forall a. ParseFromSource a => TextParser a
sourceParser
readSingleWith :: TextParser a -> String -> String -> TrackedErrors a
readSingleWith :: TextParser a -> String -> String -> TrackedErrors a
readSingleWith TextParser a
p = TextParser a -> String -> String -> TrackedErrors a
forall (m :: * -> *) a.
ErrorContextM m =>
TextParser a -> String -> String -> m a
runTextParser (ParsecT CompilerMessage String Identity ()
-> ParsecT CompilerMessage String Identity ()
-> TextParser a
-> TextParser a
forall (m :: * -> *) open close a.
Applicative m =>
m open -> m close -> m a -> m a
between ParsecT CompilerMessage String Identity ()
nullParse ParsecT CompilerMessage String Identity ()
endOfDoc TextParser a
p)
readMulti :: ParseFromSource a => String -> String -> TrackedErrors [a]
readMulti :: String -> String -> TrackedErrors [a]
readMulti String
f String
s = TextParser [a] -> String -> String -> TrackedErrors [a]
forall (m :: * -> *) a.
ErrorContextM m =>
TextParser a -> String -> String -> m a
runTextParser (ParsecT CompilerMessage String Identity ()
-> ParsecT CompilerMessage String Identity ()
-> TextParser [a]
-> TextParser [a]
forall (m :: * -> *) open close a.
Applicative m =>
m open -> m close -> m a -> m a
between ParsecT CompilerMessage String Identity ()
optionalSpace ParsecT CompilerMessage String Identity ()
endOfDoc (ParsecT CompilerMessage String Identity a
-> ParsecT CompilerMessage String Identity () -> TextParser [a]
forall (m :: * -> *) a sep. MonadPlus m => m a -> m sep -> m [a]
sepBy ParsecT CompilerMessage String Identity a
forall a. ParseFromSource a => TextParser a
sourceParser ParsecT CompilerMessage String Identity ()
optionalSpace)) String
f String
s
parseFilterMap :: [(String,[String])] -> TrackedErrors ParamFilters
parseFilterMap :: [(String, [String])] -> TrackedErrors ParamFilters
parseFilterMap [(String, [String])]
pa = do
[(ParamName, [TypeFilter])]
pa2 <- ((String, [String])
-> TrackedErrorsT Identity (ParamName, [TypeFilter]))
-> [(String, [String])]
-> TrackedErrorsT Identity [(ParamName, [TypeFilter])]
forall (m :: * -> *) a b.
CollectErrorsM m =>
(a -> m b) -> [a] -> m [b]
mapErrorsM (String, [String])
-> TrackedErrorsT Identity (ParamName, [TypeFilter])
forall b.
ParseFromSource b =>
(String, [String]) -> TrackedErrorsT Identity (ParamName, [b])
parseFilters [(String, [String])]
pa
ParamFilters -> TrackedErrors ParamFilters
forall (m :: * -> *) a. Monad m => a -> m a
return (ParamFilters -> TrackedErrors ParamFilters)
-> ParamFilters -> TrackedErrors ParamFilters
forall a b. (a -> b) -> a -> b
$ [(ParamName, [TypeFilter])] -> ParamFilters
forall k a. Ord k => [(k, a)] -> Map k a
Map.fromList [(ParamName, [TypeFilter])]
pa2
where
parseFilters :: (String, [String]) -> TrackedErrorsT Identity (ParamName, [b])
parseFilters (String
n,[String]
fs) = do
[b]
fs2 <- (String -> TrackedErrorsT Identity b)
-> [String] -> TrackedErrorsT Identity [b]
forall (m :: * -> *) a b.
CollectErrorsM m =>
(a -> m b) -> [a] -> m [b]
mapErrorsM (String -> String -> TrackedErrorsT Identity b
forall a. ParseFromSource a => String -> String -> TrackedErrors a
readSingle String
"(string)") [String]
fs
(ParamName, [b]) -> TrackedErrorsT Identity (ParamName, [b])
forall (m :: * -> *) a. Monad m => a -> m a
return (String -> ParamName
ParamName String
n,[b]
fs2)
parseTheTest :: ParseFromSource a => [(String,[String])] -> [String] -> TrackedErrors ([a],ParamFilters)
parseTheTest :: [(String, [String])]
-> [String] -> TrackedErrors ([a], ParamFilters)
parseTheTest [(String, [String])]
pa [String]
xs = do
[a]
ts <- (String -> TrackedErrorsT Identity a)
-> [String] -> TrackedErrorsT Identity [a]
forall (m :: * -> *) a b.
CollectErrorsM m =>
(a -> m b) -> [a] -> m [b]
mapErrorsM (String -> String -> TrackedErrorsT Identity a
forall a. ParseFromSource a => String -> String -> TrackedErrors a
readSingle String
"(string)") [String]
xs
ParamFilters
pa2 <- [(String, [String])] -> TrackedErrors ParamFilters
parseFilterMap [(String, [String])]
pa
([a], ParamFilters) -> TrackedErrors ([a], ParamFilters)
forall (m :: * -> *) a. Monad m => a -> m a
return ([a]
ts,ParamFilters
pa2)
showParams :: [(String,[String])] -> String
showParams :: [(String, [String])] -> String
showParams [(String, [String])]
pa = String
"[" String -> String -> String
forall a. [a] -> [a] -> [a]
++ String -> [String] -> String
forall a. [a] -> [[a]] -> [a]
intercalate String
"," ([[String]] -> [String]
forall (t :: * -> *) a. Foldable t => t [a] -> [a]
concat ([[String]] -> [String]) -> [[String]] -> [String]
forall a b. (a -> b) -> a -> b
$ ((String, [String]) -> [String])
-> [(String, [String])] -> [[String]]
forall a b. (a -> b) -> [a] -> [b]
map (String, [String]) -> [String]
expand [(String, [String])]
pa) String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
"]" where
expand :: (String, [String]) -> [String]
expand (String
n,[String]
ps) = (String -> String) -> [String] -> [String]
forall a b. (a -> b) -> [a] -> [b]
map (\String
p -> String
n String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
" " String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
p) [String]
ps
checkTypeSuccess :: TypeResolver r => r -> [(String,[String])] -> String -> TrackedErrors ()
checkTypeSuccess :: r -> [(String, [String])] -> String -> TrackedErrors ()
checkTypeSuccess r
r [(String, [String])]
pa String
x = do
([GeneralInstance
t],ParamFilters
pa2) <- [(String, [String])]
-> [String] -> TrackedErrors ([GeneralInstance], ParamFilters)
forall a.
ParseFromSource a =>
[(String, [String])]
-> [String] -> TrackedErrors ([a], ParamFilters)
parseTheTest [(String, [String])]
pa [String
x]
TrackedErrors () -> TrackedErrors ()
forall (m :: * -> *) a. ErrorContextM m => m a -> m a
check (TrackedErrors () -> TrackedErrors ())
-> TrackedErrors () -> TrackedErrors ()
forall a b. (a -> b) -> a -> b
$ r -> ParamFilters -> GeneralInstance -> TrackedErrors ()
forall (m :: * -> *) r.
(CollectErrorsM m, TypeResolver r) =>
r -> ParamFilters -> GeneralInstance -> m ()
validateGeneralInstance r
r ParamFilters
pa2 GeneralInstance
t
where
prefix :: String
prefix = String
x String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
" " String -> String -> String
forall a. [a] -> [a] -> [a]
++ [(String, [String])] -> String
showParams [(String, [String])]
pa
check :: m a -> m a
check m a
x2 = m a
x2 m a -> String -> m a
forall (m :: * -> *) a. ErrorContextM m => m a -> String -> m a
<!! String
prefix String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
":"
checkTypeFail :: TypeResolver r => r -> [(String,[String])] -> String -> TrackedErrors ()
checkTypeFail :: r -> [(String, [String])] -> String -> TrackedErrors ()
checkTypeFail r
r [(String, [String])]
pa String
x = do
([GeneralInstance
t],ParamFilters
pa2) <- [(String, [String])]
-> [String] -> TrackedErrors ([GeneralInstance], ParamFilters)
forall a.
ParseFromSource a =>
[(String, [String])]
-> [String] -> TrackedErrors ([a], ParamFilters)
parseTheTest [(String, [String])]
pa [String
x]
TrackedErrors () -> TrackedErrors ()
forall a. TrackedErrors a -> TrackedErrors ()
check (TrackedErrors () -> TrackedErrors ())
-> TrackedErrors () -> TrackedErrors ()
forall a b. (a -> b) -> a -> b
$ r -> ParamFilters -> GeneralInstance -> TrackedErrors ()
forall (m :: * -> *) r.
(CollectErrorsM m, TypeResolver r) =>
r -> ParamFilters -> GeneralInstance -> m ()
validateGeneralInstance r
r ParamFilters
pa2 GeneralInstance
t
where
prefix :: String
prefix = String
x String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
" " String -> String -> String
forall a. [a] -> [a] -> [a]
++ [(String, [String])] -> String
showParams [(String, [String])]
pa
check :: TrackedErrors a -> TrackedErrors ()
check :: TrackedErrors a -> TrackedErrors ()
check TrackedErrors a
c
| TrackedErrors a -> Bool
forall (t :: (* -> *) -> * -> *) a.
(ErrorContextT t, ErrorContextM (t Identity)) =>
t Identity a -> Bool
isCompilerError TrackedErrors a
c = () -> TrackedErrors ()
forall (m :: * -> *) a. Monad m => a -> m a
return ()
| Bool
otherwise = String -> TrackedErrors ()
forall (m :: * -> *) a. ErrorContextM m => String -> m a
compilerErrorM (String -> TrackedErrors ()) -> String -> TrackedErrors ()
forall a b. (a -> b) -> a -> b
$ String
prefix String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
": Expected failure\n"
checkDefinesSuccess :: TypeResolver r => r -> [(String,[String])] -> String -> TrackedErrors ()
checkDefinesSuccess :: r -> [(String, [String])] -> String -> TrackedErrors ()
checkDefinesSuccess r
r [(String, [String])]
pa String
x = do
([DefinesInstance
t],ParamFilters
pa2) <- [(String, [String])]
-> [String] -> TrackedErrors ([DefinesInstance], ParamFilters)
forall a.
ParseFromSource a =>
[(String, [String])]
-> [String] -> TrackedErrors ([a], ParamFilters)
parseTheTest [(String, [String])]
pa [String
x]
TrackedErrors () -> TrackedErrors ()
forall (m :: * -> *) a. ErrorContextM m => m a -> m a
check (TrackedErrors () -> TrackedErrors ())
-> TrackedErrors () -> TrackedErrors ()
forall a b. (a -> b) -> a -> b
$ r -> ParamFilters -> DefinesInstance -> TrackedErrors ()
forall (m :: * -> *) r.
(CollectErrorsM m, TypeResolver r) =>
r -> ParamFilters -> DefinesInstance -> m ()
validateDefinesInstance r
r ParamFilters
pa2 DefinesInstance
t
where
prefix :: String
prefix = String
x String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
" " String -> String -> String
forall a. [a] -> [a] -> [a]
++ [(String, [String])] -> String
showParams [(String, [String])]
pa
check :: m a -> m a
check m a
x2 = m a
x2 m a -> String -> m a
forall (m :: * -> *) a. ErrorContextM m => m a -> String -> m a
<!! String
prefix String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
":"
checkDefinesFail :: TypeResolver r => r -> [(String,[String])] -> String -> TrackedErrors ()
checkDefinesFail :: r -> [(String, [String])] -> String -> TrackedErrors ()
checkDefinesFail r
r [(String, [String])]
pa String
x = do
([DefinesInstance
t],ParamFilters
pa2) <- [(String, [String])]
-> [String] -> TrackedErrors ([DefinesInstance], ParamFilters)
forall a.
ParseFromSource a =>
[(String, [String])]
-> [String] -> TrackedErrors ([a], ParamFilters)
parseTheTest [(String, [String])]
pa [String
x]
TrackedErrors () -> TrackedErrors ()
forall a. TrackedErrors a -> TrackedErrors ()
check (TrackedErrors () -> TrackedErrors ())
-> TrackedErrors () -> TrackedErrors ()
forall a b. (a -> b) -> a -> b
$ r -> ParamFilters -> DefinesInstance -> TrackedErrors ()
forall (m :: * -> *) r.
(CollectErrorsM m, TypeResolver r) =>
r -> ParamFilters -> DefinesInstance -> m ()
validateDefinesInstance r
r ParamFilters
pa2 DefinesInstance
t
where
prefix :: String
prefix = String
x String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
" " String -> String -> String
forall a. [a] -> [a] -> [a]
++ [(String, [String])] -> String
showParams [(String, [String])]
pa
check :: TrackedErrors a -> TrackedErrors ()
check :: TrackedErrors a -> TrackedErrors ()
check TrackedErrors a
c
| TrackedErrors a -> Bool
forall (t :: (* -> *) -> * -> *) a.
(ErrorContextT t, ErrorContextM (t Identity)) =>
t Identity a -> Bool
isCompilerError TrackedErrors a
c = () -> TrackedErrors ()
forall (m :: * -> *) a. Monad m => a -> m a
return ()
| Bool
otherwise = String -> TrackedErrors ()
forall (m :: * -> *) a. ErrorContextM m => String -> m a
compilerErrorM (String -> TrackedErrors ()) -> String -> TrackedErrors ()
forall a b. (a -> b) -> a -> b
$ String
prefix String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
": Expected failure\n"
containsExactly :: (Ord a, Show a) => [a] -> [a] -> TrackedErrors ()
containsExactly :: [a] -> [a] -> TrackedErrors ()
containsExactly [a]
actual [a]
expected = do
[a] -> TrackedErrors ()
forall a. (Ord a, Show a) => [a] -> TrackedErrors ()
containsNoDuplicates [a]
actual
[a] -> [a] -> TrackedErrors ()
forall a. (Ord a, Show a) => [a] -> [a] -> TrackedErrors ()
containsAtLeast [a]
actual [a]
expected
[a] -> [a] -> TrackedErrors ()
forall a. (Ord a, Show a) => [a] -> [a] -> TrackedErrors ()
containsAtMost [a]
actual [a]
expected
containsNoDuplicates :: (Ord a, Show a) => [a] -> TrackedErrors ()
containsNoDuplicates :: [a] -> TrackedErrors ()
containsNoDuplicates [a]
expected =
(([a] -> TrackedErrors ()) -> [[a]] -> TrackedErrors ()
forall (m :: * -> *) a b.
CollectErrorsM m =>
(a -> m b) -> [a] -> m ()
mapErrorsM_ [a] -> TrackedErrors ()
forall (m :: * -> *) a. (ErrorContextM m, Show a) => [a] -> m ()
checkSingle ([[a]] -> TrackedErrors ()) -> [[a]] -> TrackedErrors ()
forall a b. (a -> b) -> a -> b
$ [a] -> [[a]]
forall a. Eq a => [a] -> [[a]]
group ([a] -> [[a]]) -> [a] -> [[a]]
forall a b. (a -> b) -> a -> b
$ [a] -> [a]
forall a. Ord a => [a] -> [a]
sort [a]
expected) TrackedErrors () -> String -> TrackedErrors ()
forall (m :: * -> *) a. ErrorContextM m => m a -> String -> m a
<!! [a] -> String
forall a. Show a => a -> String
show [a]
expected
where
checkSingle :: [a] -> m ()
checkSingle xa :: [a]
xa@(a
x:a
_:[a]
_) =
String -> m ()
forall (m :: * -> *) a. ErrorContextM m => String -> m a
compilerErrorM (String -> m ()) -> String -> m ()
forall a b. (a -> b) -> a -> b
$ String
"Item " String -> String -> String
forall a. [a] -> [a] -> [a]
++ a -> String
forall a. Show a => a -> String
show a
x String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
" occurs " String -> String -> String
forall a. [a] -> [a] -> [a]
++ Int -> String
forall a. Show a => a -> String
show ([a] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length [a]
xa) String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
" times"
checkSingle [a]
_ = () -> m ()
forall (m :: * -> *) a. Monad m => a -> m a
return ()
containsAtLeast :: (Ord a, Show a) => [a] -> [a] -> TrackedErrors ()
containsAtLeast :: [a] -> [a] -> TrackedErrors ()
containsAtLeast [a]
actual [a]
expected =
((a -> TrackedErrors ()) -> [a] -> TrackedErrors ()
forall (m :: * -> *) a b.
CollectErrorsM m =>
(a -> m b) -> [a] -> m ()
mapErrorsM_ (Set a -> a -> TrackedErrors ()
forall a (m :: * -> *).
(Ord a, ErrorContextM m, Show a) =>
Set a -> a -> m ()
checkInActual (Set a -> a -> TrackedErrors ()) -> Set a -> a -> TrackedErrors ()
forall a b. (a -> b) -> a -> b
$ [a] -> Set a
forall a. Ord a => [a] -> Set a
Set.fromList [a]
actual) [a]
expected) TrackedErrors () -> String -> TrackedErrors ()
forall (m :: * -> *) a. ErrorContextM m => m a -> String -> m a
<!!
[a] -> String
forall a. Show a => a -> String
show [a]
actual String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
" (actual) vs. " String -> String -> String
forall a. [a] -> [a] -> [a]
++ [a] -> String
forall a. Show a => a -> String
show [a]
expected String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
" (expected)"
where
checkInActual :: Set a -> a -> m ()
checkInActual Set a
va a
v =
if a
v a -> Set a -> Bool
forall a. Ord a => a -> Set a -> Bool
`Set.member` Set a
va
then () -> m ()
forall (m :: * -> *) a. Monad m => a -> m a
return ()
else String -> m ()
forall (m :: * -> *) a. ErrorContextM m => String -> m a
compilerErrorM (String -> m ()) -> String -> m ()
forall a b. (a -> b) -> a -> b
$ String
"Item " String -> String -> String
forall a. [a] -> [a] -> [a]
++ a -> String
forall a. Show a => a -> String
show a
v String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
" was expected but not present"
containsAtMost :: (Ord a, Show a) => [a] -> [a] -> TrackedErrors ()
containsAtMost :: [a] -> [a] -> TrackedErrors ()
containsAtMost [a]
actual [a]
expected =
((a -> TrackedErrors ()) -> [a] -> TrackedErrors ()
forall (m :: * -> *) a b.
CollectErrorsM m =>
(a -> m b) -> [a] -> m ()
mapErrorsM_ (Set a -> a -> TrackedErrors ()
forall a (m :: * -> *).
(Ord a, ErrorContextM m, Show a) =>
Set a -> a -> m ()
checkInExpected (Set a -> a -> TrackedErrors ()) -> Set a -> a -> TrackedErrors ()
forall a b. (a -> b) -> a -> b
$ [a] -> Set a
forall a. Ord a => [a] -> Set a
Set.fromList [a]
expected) [a]
actual) TrackedErrors () -> String -> TrackedErrors ()
forall (m :: * -> *) a. ErrorContextM m => m a -> String -> m a
<!!
[a] -> String
forall a. Show a => a -> String
show [a]
actual String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
" (actual) vs. " String -> String -> String
forall a. [a] -> [a] -> [a]
++ [a] -> String
forall a. Show a => a -> String
show [a]
expected String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
" (expected)"
where
checkInExpected :: Set a -> a -> m ()
checkInExpected Set a
va a
v =
if a
v a -> Set a -> Bool
forall a. Ord a => a -> Set a -> Bool
`Set.member` Set a
va
then () -> m ()
forall (m :: * -> *) a. Monad m => a -> m a
return ()
else String -> m ()
forall (m :: * -> *) a. ErrorContextM m => String -> m a
compilerErrorM (String -> m ()) -> String -> m ()
forall a b. (a -> b) -> a -> b
$ String
"Item " String -> String -> String
forall a. [a] -> [a] -> [a]
++ a -> String
forall a. Show a => a -> String
show a
v String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
" is unexpected"
checkEquals :: (Eq a, Show a) => a -> a -> TrackedErrors ()
checkEquals :: a -> a -> TrackedErrors ()
checkEquals a
actual a
expected
| a
actual a -> a -> Bool
forall a. Eq a => a -> a -> Bool
== a
expected = () -> TrackedErrors ()
forall (m :: * -> *) a. Monad m => a -> m a
return ()
| Bool
otherwise = String -> TrackedErrors ()
forall (m :: * -> *) a. ErrorContextM m => String -> m a
compilerErrorM (String -> TrackedErrors ()) -> String -> TrackedErrors ()
forall a b. (a -> b) -> a -> b
$ String
"Expected " String -> String -> String
forall a. [a] -> [a] -> [a]
++ a -> String
forall a. Show a => a -> String
show a
expected String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
" but got " String -> String -> String
forall a. [a] -> [a] -> [a]
++ a -> String
forall a. Show a => a -> String
show a
actual
loadFile :: String -> IO String
loadFile :: String -> IO String
loadFile String
f = String -> IO String
readFile (String
"src" String -> String -> String
</> String
"Test" String -> String -> String
</> String
f)