sqlc-hs-0.2.0.0: test/Test/Sqlc/Hs/Golden.hs
module Test.Sqlc.Hs.Golden where
import Data.ByteString qualified
import Data.ProtoLens qualified
import Data.ProtoLens.Labels ()
import Proto.Protos.Codegen qualified
import System.Directory qualified
import System.Exit (ExitCode (..))
import System.FilePath (takeExtension, dropExtension, (</>), replaceExtension)
import System.IO qualified
import System.IO.Error qualified
import System.IO.Temp qualified
import System.Process qualified
import System.Process.ByteString qualified
import Test.Tasty (TestTree, withResource)
import Test.Tasty.Golden (createDirectoriesAndWriteFile, findByExtension)
import Test.Tasty.Golden.Advanced (goldenTest)
test_golden :: IO [TestTree]
test_golden = do
inputs <- findByExtension [".input", ".proto"] "test/golden"
pure $
inputs <&> \input ->
withResource
( do
tmpdir <- System.IO.Temp.getCanonicalTemporaryDirectory
System.IO.Temp.createTempDirectory tmpdir "sqlc-hs-test"
)
( \tmpdir ->
System.IO.Error.catchIOError
(System.Directory.removeDirectoryRecursive tmpdir)
(\_ -> pure ())
)
$ \createTestDirectory ->
let goldenDirectory :: FilePath
goldenDirectory =
dropExtension input
in goldenTest
input
( do
-- Listing a non-existing directory throws an exception such
-- that tasty-golden registers the test as new and just accepts
-- the output.
_ <- System.Directory.listDirectory goldenDirectory
pure goldenDirectory
)
( do
message <-
Data.ByteString.readFile input
message <-
case takeExtension input of
".input" ->
case Data.ProtoLens.readMessage @Proto.Protos.Codegen.GenerateRequest (toLazy (decodeUtf8 message)) of
Left errorMessage ->
error (toText errorMessage)
Right message ->
pure message
".proto" -> do
message <-
case Data.ProtoLens.decodeMessage @Proto.Protos.Codegen.GenerateRequest message of
Left errorMessage ->
error (toText errorMessage)
Right message ->
pure message
writeFile (replaceExtension input ".input") (Data.ProtoLens.showMessage message)
pure message
_ ->
error "Impossible: invalid extension"
(exitCode, stdout, stderr) <-
System.Process.ByteString.readProcessWithExitCode
"sqlc-hs"
[]
(Data.ProtoLens.encodeMessage message)
Data.ByteString.hPut System.IO.stderr stderr
unless (exitCode == ExitSuccess) $
error "sqlc-hs failed with an non-zero exit-code"
message <-
case Data.ProtoLens.decodeMessage @Proto.Protos.Codegen.GenerateResponse stdout of
Left errorMessage ->
error (toText errorMessage)
Right message ->
pure message
testDirectory <- createTestDirectory
-- To ease debugging we write out the files as proper files too.
for_ (message ^. #files) $ \file -> do
let outputFile = testDirectory </> toString (file ^. #name)
createDirectoriesAndWriteFile outputFile (toLazy (file ^. #contents))
pure testDirectory
)
( \a b -> do
(_exitCode, stdout, _stderr) <-
System.Process.readProcessWithExitCode "diff" ["--recursive", a, b] ""
case stdout of
"" ->
pure Nothing
stdout ->
pure (Just stdout)
)
( \testDirectory -> do
-- Delete the goldenDirectory first to avoid any leftover dangling files.
System.IO.Error.catchIOError
(System.Directory.removeDirectoryRecursive goldenDirectory)
(\_ -> pure ())
System.Directory.renameDirectory testDirectory goldenDirectory
)