{-# LANGUAGE RankNTypes #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE NoImplicitPrelude #-}
module Test.Morpheus
( FileUrl,
mkUrl,
cd,
file,
deepScan,
scan,
-- get app
getAppsBy,
-- tests
testApi,
testSchema,
testQueryRendering,
renderingAssertion,
testQuery,
testQueryValidation,
-- main
mainTest,
)
where
import Data.Aeson
( FromJSON (..),
ToJSON (..),
encode,
)
import Data.ByteString.Lazy.Char8 (ByteString)
import Relude hiding (ByteString)
import Test.Morpheus.File
import Test.Morpheus.Response
import Test.Morpheus.Utils
import Test.Tasty
( TestTree,
defaultMain,
testGroup,
)
import Test.Tasty.HUnit
( assertFailure,
testCase,
)
mainTest :: String -> [IO TestTree] -> IO ()
mainTest name xs = do
tests <- sequence xs
defaultMain
$ testGroup
name
tests
--
testApi ::
(FromJSON req, ToJSON res) =>
(req -> IO res) ->
FileUrl ->
TestTree
testApi api =
assertResponse
(fmap expects . api <=< getQuery)
testQuery ::
(FromJSON req, ToJSON err, Eq err, FromJSON err) =>
(req -> Either err a) ->
FileUrl ->
TestTree
testQuery f =
assertResponse
(fmap (fromEither . f) . getQuery)
testSchema ::
(ToJSON err, Eq err, FromJSON err) =>
(ByteString -> Either err a) ->
FileUrl ->
TestTree
testSchema f =
assertResponse
(fmap (fromEither . f) . readSchemaFile)
renderingAssertion ::
(ToJSON e) =>
(FileUrl -> IO (Either e ByteString)) ->
FileUrl ->
TestTree
renderingAssertion api url = testCase (fileName url) $ do
actual <- api url
expected <- readGQL "rendering" url
either
(assertFailure . (" error: " <>) . show . encode)
(requireEq id expected)
actual
getAppBy ::
(Show err, FromJSON resolvers) =>
( ByteString -> Either err schema,
schema -> resolvers -> app
) ->
FileUrl ->
IO app
getAppBy (parseSchema, mkApp) url =
mkApp
<$> getSchema parseSchema url
<*> getResolver url
testQueryValidation ::
( ToJSON errors,
Show errors,
FromJSON request,
FromJSON errors,
Eq errors
) =>
( schema -> request -> Either errors a,
ByteString -> Either errors schema
) ->
FileUrl ->
FileUrl ->
TestTree
testQueryValidation (parseRequest, parseSchema) schemaUrl =
assertResponse
( \url -> do
schema <- getSchema parseSchema schemaUrl
query <- getQuery url
pure $ fromEither (parseRequest schema query)
)
testQueryRendering ::
( ToJSON errors,
Show errors,
FromJSON request
) =>
( schema -> request -> Either errors ByteString,
ByteString -> Either errors schema
) ->
FileUrl ->
FileUrl ->
TestTree
testQueryRendering (parseRequest, parseSchema) schemaUrl =
renderingAssertion
( \requestUrl -> do
request <- getQuery requestUrl
schema <- getSchema parseSchema schemaUrl
pure $ parseRequest schema request
)
getAppsWIth ::
(Semigroup b, Show err, FromJSON resolvers) =>
( ByteString -> Either err schema,
schema -> resolvers -> b
) ->
FileUrl ->
[FilePath] ->
IO b
getAppsWIth f url [] = getAppBy f url
getAppsWIth f url (x : xs) = sconcat <$> traverse (getAppBy f . file url) (x :| xs)
getAppsBy ::
(Semigroup b, Show err, FromJSON resolvers) =>
( ByteString -> Either err schema,
schema -> resolvers -> b
) ->
FileUrl ->
IO b
getAppsBy f url = do
files <- searchAppFiles url
getAppsWIth f url (sort files)