summaryrefslogtreecommitdiff
path: root/source/Test/Unit/OutputPlan.hs
diff options
context:
space:
mode:
authoradelon <22380201+adelon@users.noreply.github.com>2026-08-06 17:54:00 +0200
committeradelon <22380201+adelon@users.noreply.github.com>2026-08-06 17:54:00 +0200
commit82328890108bae64b372b8d58620ebc62699de76 (patch)
tree575404c6b425c19259c0ded296f1c8ffb7ff0e2b /source/Test/Unit/OutputPlan.hs
parent1a25421c2a168d420581358c8733fcd8f36f379b (diff)
Migrate to `Felix` namespaceHEADhotg
Diffstat (limited to 'source/Test/Unit/OutputPlan.hs')
-rw-r--r--source/Test/Unit/OutputPlan.hs236
1 files changed, 0 insertions, 236 deletions
diff --git a/source/Test/Unit/OutputPlan.hs b/source/Test/Unit/OutputPlan.hs
deleted file mode 100644
index 45658bf..0000000
--- a/source/Test/Unit/OutputPlan.hs
+++ /dev/null
@@ -1,236 +0,0 @@
-{-# LANGUAGE NoImplicitPrelude #-}
-
-module Test.Unit.OutputPlan (unitTests) where
-
-import Base
-import Felix.OutputPlan qualified as Output
-import Felix.Source
-import Felix.Store qualified as Store
-
-import Control.Exception qualified as Exception
-import System.Directory qualified as Directory
-import System.Environment qualified as Environment
-import System.FilePath.Posix qualified as Posix
-import System.IO.Temp qualified as Temp
-import Test.Tasty
-import Test.Tasty.HUnit
-
-
-unitTests :: TestTree
-unitTests =
- testGroup "Verification output preflight"
- [ testCase "accepts absent and empty dump destinations"
- acceptsAbsentAndEmptyDumpDestinations
- , testCase "rejects a nonempty dump before store startup"
- rejectsNonemptyDumpBeforeStoreStartup
- , testCase "rejects persistent and fresh store collisions"
- rejectsStoreCollisions
- , testCase "reserves the store rollback journal"
- reservesRollbackJournal
- , testCase "rejects dump and HTML route collisions"
- rejectsDumpHtmlCollisions
- ]
-
-acceptsAbsentAndEmptyDumpDestinations :: Assertion
-acceptsAbsentAndEmptyDumpDestinations =
- Temp.withSystemTempDirectory "felix-output-dump" \root -> do
- let storeParent = root Posix.</> "store"
- storeFile = storeParent Posix.</> "store.sqlite"
- dump = root Posix.</> "dump"
- Directory.createDirectory storeParent
- plan <- expectRightIO
- (Store.planStore
- (Store.ExplicitStore storeFile))
- Store.withStoreLease plan \lease -> do
- absent <- Output.planVerificationOutputs
- (Store.storeLeasePath lease)
- (Just dump)
- Nothing
- plannedAbsent <- expectOutputRight absent
- assertEqual "absent dump path"
- (Just dump)
- (Output.dumpOutputPath
- <$> Output.verificationDumpOutput plannedAbsent)
-
- Directory.createDirectory dump
- emptyResult <- Output.planVerificationOutputs
- (Store.storeLeasePath lease)
- (Just dump)
- Nothing
- void (expectOutputRight emptyResult)
-
-rejectsNonemptyDumpBeforeStoreStartup :: Assertion
-rejectsNonemptyDumpBeforeStoreStartup =
- Temp.withSystemTempDirectory "felix-output-before-store" \root -> do
- let cacheRoot = root Posix.</> "cache"
- dump = root Posix.</> "dump"
- Directory.createDirectory cacheRoot
- Directory.createDirectory dump
- writeFile (dump Posix.</> "old.p") "stale"
- withEnvironment "XDG_CACHE_HOME" cacheRoot do
- plan <- expectRightIO
- (Store.planStore Store.DefaultStore)
- Store.withStoreLease plan \lease -> do
- result <- Output.planVerificationOutputs
- (Store.storeLeasePath lease)
- (Just dump)
- Nothing
- case result of
- Left Output.DumpDestinationNotEmpty{} ->
- pure ()
- Left other ->
- assertFailure
- ("unexpected nonempty result: " <> show other)
- Right _ ->
- assertFailure "nonempty dump was accepted"
- assertBool "preflight did not create the default store"
- . not
- =<< Directory.doesPathExist
- (cacheRoot Posix.</> "felix")
-
-rejectsStoreCollisions :: Assertion
-rejectsStoreCollisions =
- Temp.withSystemTempDirectory "felix-output-store-collision" \root -> do
- let dump = root Posix.</> "dump"
- persistentStore = dump Posix.</> "store.sqlite"
- Directory.createDirectory dump
- persistentPlan <- expectRightIO
- (Store.planStore
- (Store.ExplicitStore persistentStore))
- Store.withStoreLease persistentPlan \lease -> do
- result <- Output.planVerificationOutputs
- (Store.storeLeasePath lease)
- (Just dump)
- Nothing
- expectCollision result
-
- freshPlan <- expectRightIO
- (Store.planStore Store.FreshTemporaryStore)
- Store.withStoreLease freshPlan \lease -> do
- let freshParent =
- Posix.takeDirectory
- (Store.storePathFilePath
- (Store.storeLeasePath lease))
- result <- Output.planVerificationOutputs
- (Store.storeLeasePath lease)
- (Just freshParent)
- Nothing
- expectCollision result
-
- relative <- expectRight (safeRelativePath "page.html")
- let htmlRoot = root Posix.</> "html"
- htmlStore = htmlRoot Posix.</> "page.html"
- Directory.createDirectory htmlRoot
- htmlPlan <- expectRightIO
- (Store.planStore
- (Store.ExplicitStore htmlStore))
- Store.withStoreLease htmlPlan \lease -> do
- result <- Output.planVerificationOutputs
- (Store.storeLeasePath lease)
- Nothing
- (Just (htmlRoot, [relative]))
- expectCollision result
-
-rejectsDumpHtmlCollisions :: Assertion
-rejectsDumpHtmlCollisions =
- Temp.withSystemTempDirectory "felix-output-cross-collision" \root -> do
- let storeParent = root Posix.</> "store"
- storeFile = storeParent Posix.</> "store.sqlite"
- htmlRoot = root Posix.</> "html"
- Directory.createDirectory storeParent
- Directory.createDirectory htmlRoot
- relative <- expectRight (safeRelativePath "nested/page.html")
- plan <- expectRightIO
- (Store.planStore
- (Store.ExplicitStore storeFile))
- Store.withStoreLease plan \lease -> do
- result <- Output.planVerificationOutputs
- (Store.storeLeasePath lease)
- (Just htmlRoot)
- (Just (htmlRoot, [relative]))
- expectCollision result
-
-reservesRollbackJournal :: Assertion
-reservesRollbackJournal =
- Temp.withSystemTempDirectory "felix-output-journal" \root -> do
- let storeParent = root Posix.</> "store"
- storeFile = storeParent Posix.</> "store.sqlite"
- journal = storeFile <> "-journal"
- Directory.createDirectory storeParent
- plan <- expectRightIO
- (Store.planStore
- (Store.ExplicitStore storeFile))
- Store.withStoreLease plan \lease -> do
- result <- Output.planVerificationOutputs
- (Store.storeLeasePath lease)
- (Just journal)
- Nothing
- case result of
- Left
- (Output.CollidingOutputNamespaces
- (Output.OutputNamespaceCollision
- Output.StoreJournalOutputNamespace
- reserved
- Output.DumpOutputNamespace
- requested :| [])) -> do
- assertEqual "reserved journal" journal reserved
- assertEqual "requested dump" journal requested
- Left other ->
- assertFailure
- ("unexpected journal collision: " <> show other)
- Right _ ->
- assertFailure "store rollback journal was not reserved"
-
-expectCollision
- :: Either Output.OutputPlanError Output.VerificationOutputPlan
- -> Assertion
-expectCollision = \case
- Left Output.CollidingOutputNamespaces{} ->
- pure ()
- Left other ->
- assertFailure
- ("unexpected output-plan result: " <> show other)
- Right _ ->
- assertFailure "colliding output namespaces were accepted"
-
-expectOutputRight
- :: Either Output.OutputPlanError Output.VerificationOutputPlan
- -> IO Output.VerificationOutputPlan
-expectOutputRight = \case
- Left failure ->
- assertFailure (show failure) >> fail "unreachable"
- Right plan ->
- pure plan
-
-expectRight :: Show failure => Either failure value -> IO value
-expectRight = \case
- Left failure ->
- assertFailure (show failure) >> fail "unreachable"
- Right value ->
- pure value
-
-expectRightIO
- :: Show failure
- => IO (Either failure value)
- -> IO value
-expectRightIO action =
- expectRight =<< action
-
-withEnvironment
- :: String
- -> String
- -> IO value
- -> IO value
-withEnvironment name value action =
- Exception.bracket
- (Environment.lookupEnv name)
- restore
- \_previous -> do
- Environment.setEnv name value
- action
- where
- restore = \case
- Nothing ->
- Environment.unsetEnv name
- Just previous ->
- Environment.setEnv name previous