{-# LANGUAGE OverloadedStrings #-} module HpackSpec (spec) where import Helper import Prelude hiding (readFile) import qualified Prelude as Prelude import System.Exit (die) import Control.DeepSeq import Hpack.Config import Hpack.CabalFile import Hpack.Error (formatHpackError) import Hpack readFile :: FilePath -> IO String readFile name = Prelude.readFile name >>= (return $!!) spec :: Spec spec = do describe "header" $ do it "generates header" $ do header "foo.yaml" Nothing Nothing `shouldBe` [ "-- This file has been generated from foo.yaml by hpack." , "--" , "-- see: https://github.com/sol/hpack" , "" ] context "with hpack version" $ do it "includes hpack version" $ do header "foo.yaml" (Just $ makeVersion [0,34,0]) Nothing `shouldBe` [ "-- This file has been generated from foo.yaml by hpack version 0.34.0." , "--" , "-- see: https://github.com/sol/hpack" , "" ] context "with hash" $ do it "includes hash" $ do header "foo.yaml" Nothing (Just "some-hash") `shouldBe` [ "-- This file has been generated from foo.yaml by hpack." , "--" , "-- see: https://github.com/sol/hpack" , "--" , "-- hash: some-hash" , "" ] describe "renderCabalFile" $ do it "is inverse to readCabalFile" $ do expected <- lines <$> readFile "resources/test/hpack.cabal" Just c <- readCabalFile "resources/test/hpack.cabal" renderCabalFile "package.yaml" c {cabalFileGitConflictMarkers = ()} `shouldBe` expected describe "hpackResult" $ around_ inTempDirectory $ before_ (writeFile packageConfig "name: foo") $ do let file = "foo.cabal" hpackWithVersion v = hpackResultWithVersion (makeVersion v) defaultOptions >>= either (die . formatHpackError "hpack") return hpackWithStrategy strategy = hpackResult defaultOptions { optionsGenerateHashStrategy = strategy } hpackForce = hpackResult defaultOptions {optionsForce = Force} generated = Result [] file Generated modifiedManually = Result [] file ExistingCabalFileWasModifiedManually outputUnchanged = Result [] file OutputUnchanged alreadyGeneratedByNewerHpack = Result [] file AlreadyGeneratedByNewerHpack modifyPackageConfig = writeFile packageConfig $ unlines [ "name: foo" , "version: 0.1.0" ] modifyCabalFile = do xs <- readFile file writeFile file $ xs ++ "foo\n" manuallyCreateCabalFile = do writeFile file "some existing cabal file" doesNotGenerateHash :: HasCallStack => GenerateHashStrategy -> Spec doesNotGenerateHash strategy = do it "does not generate hash" $ do hpackWithStrategy strategy `shouldReturn` generated readFile file >>= (`shouldNotContain` "hash") generatesHash :: HasCallStack => GenerateHashStrategy -> Spec generatesHash strategy = do it "generates hash" $ do hpackWithStrategy strategy `shouldReturn` generated readFile file >>= (`shouldContain` "hash") doesNotOverwrite :: HasCallStack => GenerateHashStrategy -> Spec doesNotOverwrite strategy = do it "does not overwrite cabal file" $ do existing <- readFile file hpackWithStrategy strategy `shouldReturn` modifiedManually readFile file `shouldReturn` existing with strategy item = context ("with " ++ show strategy) $ item strategy context "without an existing cabal file" $ do with ForceHash generatesHash with PreferHash generatesHash with ForceNoHash doesNotGenerateHash with PreferNoHash doesNotGenerateHash context "with an existing cabal file" $ do context "without a hash" $ before_ (hpackWithStrategy ForceNoHash >> modifyPackageConfig) $ do with ForceHash generatesHash with PreferHash doesNotGenerateHash with ForceNoHash doesNotGenerateHash with PreferNoHash doesNotGenerateHash context "with a hash" $ before_ (hpackWithStrategy ForceHash >> modifyPackageConfig) $ do with ForceHash generatesHash with PreferHash generatesHash with ForceNoHash doesNotGenerateHash with PreferNoHash generatesHash context "with manual modifications" $ before_ modifyCabalFile $ do with ForceHash doesNotOverwrite with PreferHash doesNotOverwrite with ForceNoHash doesNotGenerateHash with PreferNoHash doesNotOverwrite context "when created manually" $ before_ manuallyCreateCabalFile $ do with ForceHash doesNotOverwrite with PreferHash doesNotOverwrite with ForceNoHash doesNotOverwrite with PreferNoHash doesNotOverwrite context "with --force" $ do it "overwrites cabal file" $ do hpackForce `shouldReturn` generated context "when generated with a newer version of hpack" $ do it "does not overwrite cabal file" $ do _ <- hpackWithVersion [0,22,0] old <- readFile file modifyPackageConfig hpackWithVersion [0,20,0] `shouldReturn` alreadyGeneratedByNewerHpack readFile file `shouldReturn` old context "when only the hpack version in the cabal file header changed" $ do it "does not overwrite cabal file" $ do _ <- hpackWithVersion [0,22,0] old <- readFile file hpackWithVersion [0,30,0] `shouldReturn` outputUnchanged readFile file `shouldReturn` old it "does not complain if it's newer" $ do _ <- hpackWithVersion [0,22,0] old <- readFile file hpackWithVersion [0,20,0] `shouldReturn` outputUnchanged readFile file `shouldReturn` old context "with git conflict markers" $ do context "when the new and the existing .cabal file are essentially the same" $ do it "still removes the conflict markers" $ do writeFile file $ unlines [ "--" , "name: foo" ] hpack NoVerbose defaultOptions {optionsForce = Force} old <- readFile file let modified :: String modified = unlines $ case break (== "version: 0.0.0") $ lines old of (xs, v : ys) -> xs ++ "<<<<<<< ours" : v : "=======" : "version: 0.1.0" : ">>>>>>> theirs" : ys _ -> undefined writeFile file modified hpack NoVerbose defaultOptions readFile file `shouldReturn` old