Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

New RECREATE_GOLDEN_FILES #54

Merged
merged 2 commits into from
Jan 3, 2024
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
103 changes: 69 additions & 34 deletions src/Hedgehog/Extras/Test/Golden.hs
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
{-# LANGUAGE MultiWayIf #-}

module Hedgehog.Extras.Test.Golden
( diffVsGoldenFile,
diffFileVsGoldenFile,
Expand Down Expand Up @@ -43,16 +45,66 @@ mGoldenFileLogFile :: Maybe FilePath
mGoldenFileLogFile = IO.unsafePerformIO $
IO.lookupEnv "GOLDEN_FILE_LOG_FILE"

-- | Whether the test should create the golden files if the file does ont exist.
createFiles :: Bool
createFiles = IO.unsafePerformIO $ do
-- | Whether the test should create the golden files if the files do not exist.
createGoldenFiles :: Bool
createGoldenFiles = IO.unsafePerformIO $ do
smelc marked this conversation as resolved.
Show resolved Hide resolved
value <- IO.lookupEnv "CREATE_GOLDEN_FILES"
return $ value == Just "1"

-- | Whether the test should recreate the golden files if the files already exist.
recreateGoldenFiles :: Bool
recreateGoldenFiles = IO.unsafePerformIO $ do
value <- IO.lookupEnv "RECREATE_GOLDEN_FILES"
return $ value == Just "1"

writeGoldenFile :: ()
=> MonadIO m
=> MonadTest m
=> FilePath
-> String
-> m ()
writeGoldenFile goldenFile actualContent = do
H.note_ $ "Creating golden file " <> goldenFile
H.createDirectoryIfMissing_ (takeDirectory goldenFile)
H.writeFile goldenFile actualContent

reportGoldenFileMissing :: ()
=> MonadIO m
=> MonadTest m
=> FilePath
-> m ()
reportGoldenFileMissing goldenFile = do
H.note_ $ unlines
[ "Golden file " <> goldenFile <> " does not exist."
, "To create it, run with CREATE_GOLDEN_FILES=1."
, "To recreate it, run with RECREATE_GOLDEN_FILES=1."
]
H.failure

checkAgainstGoldenFile :: ()
=> MonadIO m
=> MonadTest m
=> FilePath
-> [String]
-> m ()
checkAgainstGoldenFile goldenFile actualLines = do
referenceLines <- List.lines <$> H.readFile goldenFile
let difference = getGroupedDiff actualLines referenceLines
case difference of
[] -> pure ()
[Both{}] -> pure ()
_ -> do
H.note_ $ unlines
[ "Golden test failed against golden file: " <> goldenFile
, "To recreate golden file, run with RECREATE_GOLDEN_FILES=1."
]
failMessage callStack $ ppDiff difference

-- | Diff contents against the golden file. If CREATE_GOLDEN_FILES environment is
-- set to "1", then should the gold file not exist it would be created. If
-- GOLDEN_FILE_LOG_FILE is set to a filename, then the golden file path will be
-- logged to the specified file.
-- set to "1", then should the golden file not exist it would be created. If
-- RECREATE_GOLDEN_FILES is set to "1", then should the golden file exist it would
-- be recreated. If GOLDEN_FILE_LOG_FILE is set to a filename, then the golden file
-- path will be logged to the specified file.
--
-- Set the environment variable when you intend to generate or re-generate the golden
-- file for example when running the test for the first time or if the golden file
Expand All @@ -69,35 +121,18 @@ diffVsGoldenFile
=> String -- ^ Actual content
-> FilePath -- ^ Reference file
-> m ()
diffVsGoldenFile actualContent referenceFile = GHC.withFrozenCallStack $ do
diffVsGoldenFile actualContent goldenFile = GHC.withFrozenCallStack $ do
forM_ mGoldenFileLogFile $ \logFile ->
liftIO $ semBracket $ IO.appendFile logFile $ referenceFile <> "\n"

fileExists <- liftIO $ IO.doesFileExist referenceFile

if fileExists
then do
referenceLines <- List.lines <$> H.readFile referenceFile
let difference = getGroupedDiff actualLines referenceLines
case difference of
[] -> pure ()
[Both{}] -> pure ()
_ -> do
H.note_ $ "Golden test failed against golden file: " <> referenceFile
failMessage callStack $ ppDiff difference
else if createFiles
then do
-- CREATE_GOLDEN_FILES is set, so we create any golden files that don't
-- already exist.
H.note_ $ "Creating golden file " <> referenceFile
H.createDirectoryIfMissing_ (takeDirectory referenceFile)
H.writeFile referenceFile actualContent
else do
H.note_ $ mconcat
[ "Golden file " <> referenceFile
, " does not exist. To create, run with CREATE_GOLDEN_FILES=1"
]
H.failure
liftIO $ semBracket $ IO.appendFile logFile $ goldenFile <> "\n"

fileExists <- liftIO $ IO.doesFileExist goldenFile

if
| recreateGoldenFiles -> writeGoldenFile goldenFile actualContent
| fileExists -> checkAgainstGoldenFile goldenFile actualLines
| createGoldenFiles -> writeGoldenFile goldenFile actualContent
| otherwise -> reportGoldenFileMissing goldenFile

where
actualLines = List.lines actualContent

Expand Down
Loading