packages feed

seihou-cli-0.4.0.0: test/Seihou/CLI/ExtensionSpec.hs

module Seihou.CLI.ExtensionSpec (tests) where

import Control.Exception (bracket_)
import Seihou.CLI.Extension
import System.Directory
  ( getPermissions,
    setOwnerExecutable,
    setPermissions,
  )
import System.Environment (getEnv, setEnv)
import System.Exit (ExitCode (..))
import System.FilePath ((</>))
import System.IO.Temp (withSystemTempDirectory)
import Test.Hspec
import Test.Tasty
import Test.Tasty.Hspec (testSpec)

tests :: IO TestTree
tests = testSpec "Seihou.CLI.Extension" spec

spec :: Spec
spec = do
  describe "extensionExecutableName" $ do
    it "uses the seihou extension executable naming convention" $ do
      extensionExecutableName "okf" `shouldBe` "seihou-okf-extension"

  describe "runExtension" $ do
    it "reports a missing executable by its resolved name" $ do
      result <- runExtension (ExtensionRunOpts "missing-extension-spec" ["--help"])
      result `shouldBe` Left (ExtensionNotFound "missing-extension-spec" "seihou-missing-extension-spec-extension")

    it "forwards arguments to the resolved extension executable unchanged" $
      withSystemTempDirectory "seihou-extension-spec" $ \dir -> do
        let exePath = dir </> "seihou-okf-extension"
            argsPath = dir </> "args.txt"
        writeFile exePath $
          unlines
            [ "#!/bin/sh",
              "printf '%s\\n' \"$@\" > " <> show argsPath
            ]
        permissions <- getPermissions exePath
        setPermissions exePath (setOwnerExecutable True permissions)
        withPrependedPath dir $ do
          result <- runExtension (ExtensionRunOpts "okf" ["docs", "--dir", "."])
          result `shouldBe` Right ()
        readFile argsPath `shouldReturn` "docs\n--dir\n.\n"

    it "reports the extension exit code when the executable fails" $
      withSystemTempDirectory "seihou-extension-failure-spec" $ \dir -> do
        let exePath = dir </> "seihou-okf-extension"
        writeFile exePath "#!/bin/sh\nexit 42\n"
        permissions <- getPermissions exePath
        setPermissions exePath (setOwnerExecutable True permissions)
        withPrependedPath dir $ do
          result <- runExtension (ExtensionRunOpts "okf" [])
          result `shouldBe` Left (ExtensionExited "okf" (ExitFailure 42))

withPrependedPath :: FilePath -> IO a -> IO a
withPrependedPath dir action = do
  originalPath <- getEnv "PATH"
  bracket_
    (setEnv "PATH" (dir <> ":" <> originalPath))
    (setEnv "PATH" originalPath)
    action