module Test.Syd.Def.Golden
( module Test.Syd.Def.Golden,
GoldenTest (..),
)
where
import Data.ByteString (ByteString)
import qualified Data.ByteString as SB
import qualified Data.ByteString.Builder as SBB
import qualified Data.ByteString.Lazy as LB
import Data.Text (Text)
import qualified Data.Text as T
import qualified Data.Text.Encoding as TE
import Path
import Path.IO
import Test.Syd.Expectation
import Test.Syd.Run
import Text.Show.Pretty
pureGoldenByteStringFile :: FilePath -> ByteString -> GoldenTest ByteString
pureGoldenByteStringFile :: String -> ByteString -> GoldenTest ByteString
pureGoldenByteStringFile String
fp ByteString
bs = String -> IO ByteString -> GoldenTest ByteString
goldenByteStringFile String
fp (ByteString -> IO ByteString
forall a. a -> IO a
forall (f :: * -> *) a. Applicative f => a -> f a
pure ByteString
bs)
goldenByteStringFile :: FilePath -> IO ByteString -> GoldenTest ByteString
goldenByteStringFile :: String -> IO ByteString -> GoldenTest ByteString
goldenByteStringFile String
fp IO ByteString
produceBS =
GoldenTest
{ goldenTestRead :: IO (Maybe ByteString)
goldenTestRead = do
Path Abs File
resolvedFile <- String -> IO (Path Abs File)
forall (m :: * -> *). MonadIO m => String -> m (Path Abs File)
resolveFile' String
fp
IO ByteString -> IO (Maybe ByteString)
forall (m :: * -> *) a.
(MonadIO m, MonadCatch m) =>
m a -> m (Maybe a)
forgivingAbsence (IO ByteString -> IO (Maybe ByteString))
-> IO ByteString -> IO (Maybe ByteString)
forall a b. (a -> b) -> a -> b
$ String -> IO ByteString
SB.readFile (String -> IO ByteString) -> String -> IO ByteString
forall a b. (a -> b) -> a -> b
$ Path Abs File -> String
fromAbsFile Path Abs File
resolvedFile,
goldenTestProduce :: IO ByteString
goldenTestProduce = IO ByteString
produceBS,
goldenTestWrite :: ByteString -> IO ()
goldenTestWrite = \ByteString
actual -> do
Path Abs File
resolvedFile <- String -> IO (Path Abs File)
forall (m :: * -> *). MonadIO m => String -> m (Path Abs File)
resolveFile' String
fp
Path Abs Dir -> IO ()
forall (m :: * -> *) b. MonadIO m => Path b Dir -> m ()
ensureDir (Path Abs Dir -> IO ()) -> Path Abs Dir -> IO ()
forall a b. (a -> b) -> a -> b
$ Path Abs File -> Path Abs Dir
forall b t. Path b t -> Path b Dir
parent Path Abs File
resolvedFile
String -> ByteString -> IO ()
SB.writeFile (Path Abs File -> String
fromAbsFile Path Abs File
resolvedFile) ByteString
actual,
goldenTestCompare :: ByteString -> ByteString -> IO (Maybe Assertion)
goldenTestCompare = \ByteString
actual ByteString
expected ->
Maybe Assertion -> IO (Maybe Assertion)
forall a. a -> IO a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Maybe Assertion -> IO (Maybe Assertion))
-> Maybe Assertion -> IO (Maybe Assertion)
forall a b. (a -> b) -> a -> b
$
if ByteString
actual ByteString -> ByteString -> Bool
forall a. Eq a => a -> a -> Bool
== ByteString
expected
then Maybe Assertion
forall a. Maybe a
Nothing
else Assertion -> Maybe Assertion
forall a. a -> Maybe a
Just (Assertion -> Maybe Assertion) -> Assertion -> Maybe Assertion
forall a b. (a -> b) -> a -> b
$ Assertion -> String -> Assertion
Context (ByteString -> ByteString -> Assertion
bytestringsNotEqualButShouldHaveBeenEqual ByteString
actual ByteString
expected) (String -> String
goldenContext String
fp)
}
pureGoldenLazyByteStringFile :: FilePath -> LB.ByteString -> GoldenTest LB.ByteString
pureGoldenLazyByteStringFile :: String -> ByteString -> GoldenTest ByteString
pureGoldenLazyByteStringFile String
fp ByteString
bs = String -> IO ByteString -> GoldenTest ByteString
goldenLazyByteStringFile String
fp (ByteString -> IO ByteString
forall a. a -> IO a
forall (f :: * -> *) a. Applicative f => a -> f a
pure ByteString
bs)
goldenLazyByteStringFile :: FilePath -> IO LB.ByteString -> GoldenTest LB.ByteString
goldenLazyByteStringFile :: String -> IO ByteString -> GoldenTest ByteString
goldenLazyByteStringFile String
fp IO ByteString
produceBS =
GoldenTest
{ goldenTestRead :: IO (Maybe ByteString)
goldenTestRead = do
Path Abs File
resolvedFile <- String -> IO (Path Abs File)
forall (m :: * -> *). MonadIO m => String -> m (Path Abs File)
resolveFile' String
fp
IO ByteString -> IO (Maybe ByteString)
forall (m :: * -> *) a.
(MonadIO m, MonadCatch m) =>
m a -> m (Maybe a)
forgivingAbsence (IO ByteString -> IO (Maybe ByteString))
-> IO ByteString -> IO (Maybe ByteString)
forall a b. (a -> b) -> a -> b
$ (ByteString -> ByteString) -> IO ByteString -> IO ByteString
forall a b. (a -> b) -> IO a -> IO b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap ByteString -> ByteString
LB.fromStrict (IO ByteString -> IO ByteString) -> IO ByteString -> IO ByteString
forall a b. (a -> b) -> a -> b
$ String -> IO ByteString
SB.readFile (String -> IO ByteString) -> String -> IO ByteString
forall a b. (a -> b) -> a -> b
$ Path Abs File -> String
fromAbsFile Path Abs File
resolvedFile,
goldenTestProduce :: IO ByteString
goldenTestProduce = IO ByteString
produceBS,
goldenTestWrite :: ByteString -> IO ()
goldenTestWrite = \ByteString
actual -> do
Path Abs File
resolvedFile <- String -> IO (Path Abs File)
forall (m :: * -> *). MonadIO m => String -> m (Path Abs File)
resolveFile' String
fp
Path Abs Dir -> IO ()
forall (m :: * -> *) b. MonadIO m => Path b Dir -> m ()
ensureDir (Path Abs Dir -> IO ()) -> Path Abs Dir -> IO ()
forall a b. (a -> b) -> a -> b
$ Path Abs File -> Path Abs Dir
forall b t. Path b t -> Path b Dir
parent Path Abs File
resolvedFile
String -> ByteString -> IO ()
SB.writeFile (Path Abs File -> String
fromAbsFile Path Abs File
resolvedFile) (ByteString -> ByteString
LB.toStrict ByteString
actual),
goldenTestCompare :: ByteString -> ByteString -> IO (Maybe Assertion)
goldenTestCompare = \ByteString
actual ByteString
expected ->
Maybe Assertion -> IO (Maybe Assertion)
forall a. a -> IO a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Maybe Assertion -> IO (Maybe Assertion))
-> Maybe Assertion -> IO (Maybe Assertion)
forall a b. (a -> b) -> a -> b
$
let actualBS :: ByteString
actualBS = ByteString -> ByteString
LB.toStrict ByteString
actual
expectedBS :: ByteString
expectedBS = ByteString -> ByteString
LB.toStrict ByteString
expected
in if ByteString
actualBS ByteString -> ByteString -> Bool
forall a. Eq a => a -> a -> Bool
== ByteString
expectedBS
then Maybe Assertion
forall a. Maybe a
Nothing
else Assertion -> Maybe Assertion
forall a. a -> Maybe a
Just (Assertion -> Maybe Assertion) -> Assertion -> Maybe Assertion
forall a b. (a -> b) -> a -> b
$ Assertion -> String -> Assertion
Context (ByteString -> ByteString -> Assertion
bytestringsNotEqualButShouldHaveBeenEqual ByteString
actualBS ByteString
expectedBS) (String -> String
goldenContext String
fp)
}
pureGoldenByteStringBuilderFile :: FilePath -> SBB.Builder -> GoldenTest SBB.Builder
pureGoldenByteStringBuilderFile :: String -> Builder -> GoldenTest Builder
pureGoldenByteStringBuilderFile String
fp Builder
bs = String -> IO Builder -> GoldenTest Builder
goldenByteStringBuilderFile String
fp (Builder -> IO Builder
forall a. a -> IO a
forall (f :: * -> *) a. Applicative f => a -> f a
pure Builder
bs)
goldenByteStringBuilderFile :: FilePath -> IO SBB.Builder -> GoldenTest SBB.Builder
goldenByteStringBuilderFile :: String -> IO Builder -> GoldenTest Builder
goldenByteStringBuilderFile String
fp IO Builder
produceBS =
GoldenTest
{ goldenTestRead :: IO (Maybe Builder)
goldenTestRead = do
Path Abs File
resolvedFile <- String -> IO (Path Abs File)
forall (m :: * -> *). MonadIO m => String -> m (Path Abs File)
resolveFile' String
fp
IO Builder -> IO (Maybe Builder)
forall (m :: * -> *) a.
(MonadIO m, MonadCatch m) =>
m a -> m (Maybe a)
forgivingAbsence (IO Builder -> IO (Maybe Builder))
-> IO Builder -> IO (Maybe Builder)
forall a b. (a -> b) -> a -> b
$ (ByteString -> Builder) -> IO ByteString -> IO Builder
forall a b. (a -> b) -> IO a -> IO b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap ByteString -> Builder
SBB.byteString (IO ByteString -> IO Builder) -> IO ByteString -> IO Builder
forall a b. (a -> b) -> a -> b
$ String -> IO ByteString
SB.readFile (String -> IO ByteString) -> String -> IO ByteString
forall a b. (a -> b) -> a -> b
$ Path Abs File -> String
fromAbsFile Path Abs File
resolvedFile,
goldenTestProduce :: IO Builder
goldenTestProduce = IO Builder
produceBS,
goldenTestWrite :: Builder -> IO ()
goldenTestWrite = \Builder
actual -> do
Path Abs File
resolvedFile <- String -> IO (Path Abs File)
forall (m :: * -> *). MonadIO m => String -> m (Path Abs File)
resolveFile' String
fp
Path Abs Dir -> IO ()
forall (m :: * -> *) b. MonadIO m => Path b Dir -> m ()
ensureDir (Path Abs Dir -> IO ()) -> Path Abs Dir -> IO ()
forall a b. (a -> b) -> a -> b
$ Path Abs File -> Path Abs Dir
forall b t. Path b t -> Path b Dir
parent Path Abs File
resolvedFile
String -> ByteString -> IO ()
SB.writeFile (Path Abs File -> String
fromAbsFile Path Abs File
resolvedFile) (ByteString -> ByteString
LB.toStrict (Builder -> ByteString
SBB.toLazyByteString Builder
actual)),
goldenTestCompare :: Builder -> Builder -> IO (Maybe Assertion)
goldenTestCompare = \Builder
actual Builder
expected ->
Maybe Assertion -> IO (Maybe Assertion)
forall a. a -> IO a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Maybe Assertion -> IO (Maybe Assertion))
-> Maybe Assertion -> IO (Maybe Assertion)
forall a b. (a -> b) -> a -> b
$
let actualBS :: ByteString
actualBS = ByteString -> ByteString
LB.toStrict (Builder -> ByteString
SBB.toLazyByteString Builder
actual)
expectedBS :: ByteString
expectedBS = ByteString -> ByteString
LB.toStrict (Builder -> ByteString
SBB.toLazyByteString Builder
expected)
in if ByteString
actualBS ByteString -> ByteString -> Bool
forall a. Eq a => a -> a -> Bool
== ByteString
expectedBS
then Maybe Assertion
forall a. Maybe a
Nothing
else Assertion -> Maybe Assertion
forall a. a -> Maybe a
Just (Assertion -> Maybe Assertion) -> Assertion -> Maybe Assertion
forall a b. (a -> b) -> a -> b
$ Assertion -> String -> Assertion
Context (ByteString -> ByteString -> Assertion
bytestringsNotEqualButShouldHaveBeenEqual ByteString
actualBS ByteString
expectedBS) (String -> String
goldenContext String
fp)
}
pureGoldenTextFile :: FilePath -> Text -> GoldenTest Text
pureGoldenTextFile :: String -> Text -> GoldenTest Text
pureGoldenTextFile String
fp Text
bs = String -> IO Text -> GoldenTest Text
goldenTextFile String
fp (Text -> IO Text
forall a. a -> IO a
forall (f :: * -> *) a. Applicative f => a -> f a
pure Text
bs)
goldenTextFile :: FilePath -> IO Text -> GoldenTest Text
goldenTextFile :: String -> IO Text -> GoldenTest Text
goldenTextFile String
fp IO Text
produceBS =
GoldenTest
{ goldenTestRead :: IO (Maybe Text)
goldenTestRead = do
Path Abs File
resolvedFile <- String -> IO (Path Abs File)
forall (m :: * -> *). MonadIO m => String -> m (Path Abs File)
resolveFile' String
fp
IO Text -> IO (Maybe Text)
forall (m :: * -> *) a.
(MonadIO m, MonadCatch m) =>
m a -> m (Maybe a)
forgivingAbsence (IO Text -> IO (Maybe Text)) -> IO Text -> IO (Maybe Text)
forall a b. (a -> b) -> a -> b
$ ByteString -> Text
TE.decodeUtf8 (ByteString -> Text) -> IO ByteString -> IO Text
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> String -> IO ByteString
SB.readFile (Path Abs File -> String
fromAbsFile Path Abs File
resolvedFile),
goldenTestProduce :: IO Text
goldenTestProduce = IO Text
produceBS,
goldenTestWrite :: Text -> IO ()
goldenTestWrite = \Text
actual -> do
Path Abs File
resolvedFile <- String -> IO (Path Abs File)
forall (m :: * -> *). MonadIO m => String -> m (Path Abs File)
resolveFile' String
fp
Path Abs Dir -> IO ()
forall (m :: * -> *) b. MonadIO m => Path b Dir -> m ()
ensureDir (Path Abs Dir -> IO ()) -> Path Abs Dir -> IO ()
forall a b. (a -> b) -> a -> b
$ Path Abs File -> Path Abs Dir
forall b t. Path b t -> Path b Dir
parent Path Abs File
resolvedFile
String -> ByteString -> IO ()
SB.writeFile (Path Abs File -> String
fromAbsFile Path Abs File
resolvedFile) (Text -> ByteString
TE.encodeUtf8 Text
actual),
goldenTestCompare :: Text -> Text -> IO (Maybe Assertion)
goldenTestCompare = \Text
actual Text
expected ->
Maybe Assertion -> IO (Maybe Assertion)
forall a. a -> IO a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Maybe Assertion -> IO (Maybe Assertion))
-> Maybe Assertion -> IO (Maybe Assertion)
forall a b. (a -> b) -> a -> b
$
if Text
actual Text -> Text -> Bool
forall a. Eq a => a -> a -> Bool
== Text
expected
then Maybe Assertion
forall a. Maybe a
Nothing
else Assertion -> Maybe Assertion
forall a. a -> Maybe a
Just (Assertion -> Maybe Assertion) -> Assertion -> Maybe Assertion
forall a b. (a -> b) -> a -> b
$ Assertion -> String -> Assertion
Context (Text -> Text -> Assertion
textsNotEqualButShouldHaveBeenEqual Text
actual Text
expected) (String -> String
goldenContext String
fp)
}
pureGoldenStringFile :: FilePath -> String -> GoldenTest String
pureGoldenStringFile :: String -> String -> GoldenTest String
pureGoldenStringFile String
fp String
bs = String -> IO String -> GoldenTest String
goldenStringFile String
fp (String -> IO String
forall a. a -> IO a
forall (f :: * -> *) a. Applicative f => a -> f a
pure String
bs)
goldenStringFile :: FilePath -> IO String -> GoldenTest String
goldenStringFile :: String -> IO String -> GoldenTest String
goldenStringFile String
fp IO String
produceBS =
GoldenTest
{ goldenTestRead :: IO (Maybe String)
goldenTestRead = do
Path Abs File
resolvedFile <- String -> IO (Path Abs File)
forall (m :: * -> *). MonadIO m => String -> m (Path Abs File)
resolveFile' String
fp
IO String -> IO (Maybe String)
forall (m :: * -> *) a.
(MonadIO m, MonadCatch m) =>
m a -> m (Maybe a)
forgivingAbsence (IO String -> IO (Maybe String)) -> IO String -> IO (Maybe String)
forall a b. (a -> b) -> a -> b
$ (Text -> String) -> IO Text -> IO String
forall a b. (a -> b) -> IO a -> IO b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap Text -> String
T.unpack (IO Text -> IO String) -> IO Text -> IO String
forall a b. (a -> b) -> a -> b
$ ByteString -> Text
TE.decodeUtf8 (ByteString -> Text) -> IO ByteString -> IO Text
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> String -> IO ByteString
SB.readFile (Path Abs File -> String
fromAbsFile Path Abs File
resolvedFile),
goldenTestProduce :: IO String
goldenTestProduce = IO String
produceBS,
goldenTestWrite :: String -> IO ()
goldenTestWrite = \String
actual -> do
Path Abs File
resolvedFile <- String -> IO (Path Abs File)
forall (m :: * -> *). MonadIO m => String -> m (Path Abs File)
resolveFile' String
fp
Path Abs Dir -> IO ()
forall (m :: * -> *) b. MonadIO m => Path b Dir -> m ()
ensureDir (Path Abs Dir -> IO ()) -> Path Abs Dir -> IO ()
forall a b. (a -> b) -> a -> b
$ Path Abs File -> Path Abs Dir
forall b t. Path b t -> Path b Dir
parent Path Abs File
resolvedFile
String -> ByteString -> IO ()
SB.writeFile (Path Abs File -> String
fromAbsFile Path Abs File
resolvedFile) (Text -> ByteString
TE.encodeUtf8 (String -> Text
T.pack String
actual)),
goldenTestCompare :: String -> String -> IO (Maybe Assertion)
goldenTestCompare = \String
actual String
expected ->
Maybe Assertion -> IO (Maybe Assertion)
forall a. a -> IO a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Maybe Assertion -> IO (Maybe Assertion))
-> Maybe Assertion -> IO (Maybe Assertion)
forall a b. (a -> b) -> a -> b
$
if String
actual String -> String -> Bool
forall a. Eq a => a -> a -> Bool
== String
expected
then Maybe Assertion
forall a. Maybe a
Nothing
else Assertion -> Maybe Assertion
forall a. a -> Maybe a
Just (Assertion -> Maybe Assertion) -> Assertion -> Maybe Assertion
forall a b. (a -> b) -> a -> b
$ Assertion -> String -> Assertion
Context (String -> String -> Assertion
stringsNotEqualButShouldHaveBeenEqual String
actual String
expected) (String -> String
goldenContext String
fp)
}
goldenShowInstance :: (Show a) => FilePath -> a -> GoldenTest String
goldenShowInstance :: forall a. Show a => String -> a -> GoldenTest String
goldenShowInstance String
fp a
a = String -> String -> GoldenTest String
pureGoldenStringFile String
fp (a -> String
forall a. Show a => a -> String
show a
a)
goldenPrettyShowInstance :: (Show a) => FilePath -> a -> GoldenTest String
goldenPrettyShowInstance :: forall a. Show a => String -> a -> GoldenTest String
goldenPrettyShowInstance String
fp a
a = String -> String -> GoldenTest String
pureGoldenStringFile String
fp (a -> String
forall a. Show a => a -> String
ppShow a
a)
goldenContext :: FilePath -> String
goldenContext :: String -> String
goldenContext String
fp = String
"The golden results are in: " String -> String -> String
forall a. Semigroup a => a -> a -> a
<> String
fp