module Ormolu.Integration.CLISpec (spec) where import Control.Monad (forM_) import Ormolu.Integration.Utils (ProcessSpec (..), getFourmoluExe, proc, readFrom, readProcess) import System.Directory (createDirectoryIfMissing) import System.FilePath (takeDirectory, ()) import System.IO.Temp (withSystemTempDirectory) import Test.Hspec spec :: Spec spec = describe "Fourmolu CLI functionality" . beforeAll getFourmoluExe $ do it "formats stdin when no files specified" $ \fourmoluExe -> do stdout <- readFrom $ (proc fourmoluExe ["--no-cabal"]) {procStdin = unformattedCode} stdout `shouldBe` formattedCode it "formats stdin when stdin specified" $ \fourmoluExe -> do stdout <- readFrom $ (proc fourmoluExe ["--no-cabal", "-"]) {procStdin = unformattedCode} stdout `shouldBe` formattedCode it "finds config file in current directory when formatting stdin" $ \fourmoluExe -> withTempDir $ \tmpdir -> do writeFile' (tmpdir "fourmolu.yaml") "single-constraint-parens: never" stdout <- readFrom $ (proc fourmoluExe ["--no-cabal", "-"]) { procStdin = "f :: (Show a) => a -> String", procCwd = Just tmpdir } stdout `shouldBe` "f :: Show a => a -> String\n" it "finds config file in ancestor directory when formatting stdin" $ \fourmoluExe -> withTempDir $ \tmpdir -> do writeFile' (tmpdir "fourmolu.yaml") "single-constraint-parens: never" let cwd = tmpdir "a" "b" "c" createDirectoryIfMissing True cwd stdout <- readFrom $ (proc fourmoluExe ["--no-cabal", "-"]) { procStdin = "f :: (Show a) => a -> String", procCwd = Just cwd } stdout `shouldBe` "f :: Show a => a -> String\n" it "finds config file in directory of input file" $ \fourmoluExe -> withTempDir $ \tmpdir -> do writeFile' (tmpdir "fourmolu.yaml") "single-constraint-parens: never" writeFile' (tmpdir "input.hs") "f :: (Show a) => a -> String" stdout <- readFrom $ (proc fourmoluExe ["--no-cabal", "input.hs"]) { procCwd = Just tmpdir } stdout `shouldBe` "f :: Show a => a -> String\n" it "finds config file in XDG directory" $ \fourmoluExe -> withTempDir $ \tmpdir -> do let configDir = tmpdir "config" writeFile' (configDir "fourmolu.yaml") "single-constraint-parens: never" stdout <- readFrom $ (proc fourmoluExe ["--no-cabal", "-"]) { procStdin = "f :: (Show a) => a -> String", procCwd = Just tmpdir, procExtraEnv = [("XDG_CONFIG_HOME", configDir)] } stdout `shouldBe` "f :: Show a => a -> String\n" it "uses specified config file" $ \fourmoluExe -> withTempDir $ \tmpdir -> do let configFile = tmpdir "foo" "my-config.yaml" let inputFile = tmpdir "bar" "input.hs" writeFile' configFile "single-constraint-parens: never" writeFile' inputFile "f :: (Show a) => a -> String" stdout <- readFrom $ (proc fourmoluExe ["--no-cabal", "--config", configFile, inputFile]) { procCwd = Just tmpdir } stdout `shouldBe` "f :: Show a => a -> String\n" it "recursively finds files in directories" $ \fourmoluExe -> do withTempDir $ \tmpdir -> do let hsFile = tmpdir "test.hs" writeFile' hsFile unformattedCode output <- readProcess fourmoluExe [tmpdir] output `shouldBe` formattedCode it "ignores files in specific directories" $ \fourmoluExe -> do withTempDir $ \tmpdir -> do let testFiles = [ tmpdir "test1.hs", tmpdir "foo/test2.hs" ] let ignoredFiles = [ tmpdir ".stack-work/test.hs", tmpdir "dist-newstyle/test.hs" ] forM_ (testFiles ++ ignoredFiles) $ \fp -> do writeFile' fp unformattedCode _ <- readProcess fourmoluExe ["-i", tmpdir] forM_ testFiles $ \fp -> do output <- readFile fp output `shouldBe` formattedCode forM_ ignoredFiles $ \fp -> do output <- readFile fp output `shouldBe` unformattedCode where withTempDir = withSystemTempDirectory "fourmolu-cli-test" writeFile' fp s = do createDirectoryIfMissing True (takeDirectory fp) writeFile fp s unformattedCode = "main=print(1+1)\n" formattedCode = "main = print (1 + 1)\n"