hpack 0.8.0 → 0.9.0
raw patch · 10 files changed
+436/−352 lines, 10 filesdep +temporarydep ~aesonPVP ok
version bump matches the API change (PVP)
Dependencies added: temporary
Dependency ranges changed: aeson
API changes (from Hackage documentation)
+ Hpack: hpack :: FilePath -> Bool -> IO ()
+ Hpack: main :: IO ()
+ Hpack: version :: Version
+ Hpack.Config: [sectionOtherExtensions] :: Section a -> [String]
+ Hpack.Config: instance GHC.Generics.Selector Hpack.Config.S1_0_6CommonOptions
- Hpack.Config: Section :: a -> [FilePath] -> [Dependency] -> [String] -> [GhcOption] -> [GhcProfOption] -> [CppOption] -> Section a
+ Hpack.Config: Section :: a -> [FilePath] -> [Dependency] -> [String] -> [String] -> [GhcOption] -> [GhcProfOption] -> [CppOption] -> Section a
- Hpack.Run: run :: IO ([String], FilePath, String)
+ Hpack.Run: run :: FilePath -> IO ([String], FilePath, String)
Files
- driver/Main.hs +2/−55
- hpack.cabal +13/−8
- src/Hpack.hs +78/−0
- src/Hpack/Config.hs +44/−35
- src/Hpack/Run.hs +9/−4
- src/Hpack/Util.hs +4/−4
- test/Helper.hs +13/−0
- test/Hpack/ConfigSpec.hs +218/−206
- test/Hpack/UtilSpec.hs +40/−40
- test/HpackSpec.hs +15/−0
driver/Main.hs view
@@ -1,59 +1,6 @@ module Main (main) where -import Prelude ()-import Prelude.Compat--import Control.DeepSeq-import Control.Exception-import Control.Monad.Compat-import Data.List.Compat-import Data.Version (showVersion)-import System.Environment-import System.Exit-import System.IO-import System.IO.Error--import Paths_hpack (version)-import Hpack.Config-import Hpack.Run--programVersion :: String-programVersion = "hpack version " ++ showVersion version--header :: String-header = unlines [- "-- This file has been generated from " ++ packageConfig ++ " by " ++ programVersion ++ "."- , "--"- , "-- see: https://github.com/sol/hpack"- , ""- ]+import qualified Hpack main :: IO ()-main = do- args <- getArgs- case args of- ["--version"] -> putStrLn programVersion- ["--silent"] -> hpack False- [] -> hpack True- _ -> do- hPutStrLn stderr "Usage: hpack [ --version | --silent ]"- exitFailure--hpack :: Bool -> IO ()-hpack verbose = do- (warnings, name, new) <- run- forM_ warnings $ \warning -> hPutStrLn stderr ("WARNING: " ++ warning)- old <- force . either (const Nothing) (Just . stripHeader) <$> tryJust (guard . isDoesNotExistError) (readFile name)- if (old == Just (lines new)) then do- output (name ++ " is up-to-date")- else do- (writeFile name $ header ++ new)- output ("generated " ++ name)- where- stripHeader :: String -> [String]- stripHeader = dropWhile null . dropWhile ("--" `isPrefixOf`) . lines-- output :: String -> IO ()- output message- | verbose = putStrLn message- | otherwise = return ()+main = Hpack.main
hpack.cabal view
@@ -1,9 +1,9 @@--- This file has been generated from package.yaml by hpack version 0.5.4.+-- This file has been generated from package.yaml by hpack version 0.8.0. -- -- see: https://github.com/sol/hpack name: hpack-version: 0.8.0+version: 0.9.0 synopsis: An alternative format for Haskell packages category: Development homepage: https://github.com/sol/hpack#readme@@ -23,8 +23,7 @@ src ghc-options: -Wall build-depends:- aeson >= 0.8- , base >= 4.7 && < 5+ base >= 4.7 && < 5 , base-compat >= 0.8 , deepseq , directory@@ -33,7 +32,9 @@ , text , unordered-containers , yaml+ , aeson >= 0.8 exposed-modules:+ Hpack Hpack.Config Hpack.Run Hpack.Yaml@@ -42,6 +43,7 @@ Hpack.Haskell Hpack.Render Hpack.Util+ Paths_hpack default-language: Haskell2010 executable hpack@@ -50,8 +52,7 @@ driver ghc-options: -Wall build-depends:- aeson >= 0.8- , base >= 4.7 && < 5+ base >= 4.7 && < 5 , base-compat >= 0.8 , deepseq , directory@@ -61,6 +62,7 @@ , unordered-containers , yaml , hpack+ , aeson >= 0.8 default-language: Haskell2010 test-suite spec@@ -72,8 +74,7 @@ ghc-options: -Wall cpp-options: -DTEST build-depends:- aeson >= 0.8- , base >= 4.7 && < 5+ base >= 4.7 && < 5 , base-compat >= 0.8 , deepseq , directory@@ -83,9 +84,11 @@ , unordered-containers , yaml , hspec == 2.*+ , temporary , mockery >= 0.3 , interpolate , aeson-qq+ , aeson >= 0.10 other-modules: Helper Hpack.ConfigSpec@@ -94,6 +97,8 @@ Hpack.RenderSpec Hpack.RunSpec Hpack.UtilSpec+ HpackSpec+ Hpack Hpack.Config Hpack.GenericsUtil Hpack.Haskell
+ src/Hpack.hs view
@@ -0,0 +1,78 @@+{-# LANGUAGE CPP #-}+module Hpack (+ hpack+, version+, main+#ifdef TEST+, parseVerbosity+#endif+) where++import Prelude ()+import Prelude.Compat++import Control.DeepSeq+import Control.Exception+import Control.Monad.Compat+import Data.List.Compat+import Data.Version (showVersion)+import System.Environment+import System.Exit+import System.IO+import System.IO.Error++import Paths_hpack (version)+import Hpack.Config+import Hpack.Run++programVersion :: String+programVersion = "hpack version " ++ showVersion version++header :: String+header = unlines [+ "-- This file has been generated from " ++ packageConfig ++ " by " ++ programVersion ++ "."+ , "--"+ , "-- see: https://github.com/sol/hpack"+ , ""+ ]++main :: IO ()+main = do+ args <- getArgs+ case args of+ ["--version"] -> putStrLn programVersion+ _ -> case parseVerbosity args of+ (verbose, [dir]) -> hpack dir verbose+ (verbose, []) -> hpack "." verbose+ _ -> do+ hPutStrLn stderr $ unlines [+ "Usage: hpack [ --silent ] [ dir ]"+ , " hpack --version"+ ]+ exitFailure++parseVerbosity :: [String] -> (Bool, [String])+parseVerbosity xs = (verbose, ys)+ where+ silentFlag = "--silent"+ verbose = not (silentFlag `elem` xs)+ ys = filter (/= silentFlag) xs++hpack :: FilePath -> Bool -> IO ()+hpack dir verbose = do+ (warnings, name, new) <- run dir+ forM_ warnings $ \warning -> hPutStrLn stderr ("WARNING: " ++ warning)+ old <- force . either (const Nothing) (Just . stripHeader) <$> tryJust (guard . isDoesNotExistError) (readFile name)+ if (old == Just (lines new)) then do+ output (name ++ " is up-to-date")+ else do+ (writeFile name $ header ++ new)+ output ("generated " ++ name)+ where+ stripHeader :: String -> [String]+ stripHeader = dropWhile null . dropWhile ("--" `isPrefixOf`) . lines++ output :: String -> IO ()+ output message+ | verbose = putStrLn message+ | otherwise = return ()
src/Hpack/Config.hs view
@@ -26,6 +26,7 @@ , SourceRepository(..) #ifdef TEST , getModules+, determineModules #endif ) where @@ -55,7 +56,7 @@ package name version = Package name version Nothing Nothing Nothing Nothing Nothing Nothing [] [] [] Nothing Nothing Nothing [] [] Nothing Nothing [] [] [] section :: a -> Section a-section a = Section a [] [] [] [] [] []+section a = Section a [] [] [] [] [] [] [] packageConfig :: FilePath packageConfig = "package.yaml"@@ -124,6 +125,7 @@ commonOptionsSourceDirs :: Maybe (List FilePath) , commonOptionsDependencies :: Maybe (List Dependency) , commonOptionsDefaultExtensions :: Maybe (List String)+, commonOptionsOtherExtensions :: Maybe (List String) , commonOptionsGhcOptions :: Maybe (List GhcOption) , commonOptionsGhcProfOptions :: Maybe (List GhcProfOption) , commonOptionsCppOptions :: Maybe (List CppOption)@@ -188,8 +190,12 @@ readPackageConfig :: FilePath -> IO (Either String ([String], Package)) readPackageConfig file = do- config <- decodeYaml file- either (return . Left) (fmap Right . mkPackage) config+ r <- decodeYaml file+ case r of+ Left err -> return (Left err)+ Right config -> do+ dir <- takeDirectory <$> canonicalizePath file+ Right <$> mkPackage dir config data Dependency = Dependency { dependencyName :: String@@ -271,6 +277,7 @@ , sectionSourceDirs :: [FilePath] , sectionDependencies :: [Dependency] , sectionDefaultExtensions :: [String]+, sectionOtherExtensions :: [String] , sectionGhcOptions :: [GhcOption] , sectionGhcProfOptions :: [GhcProfOption] , sectionCppOptions :: [CppOption]@@ -287,18 +294,18 @@ , sourceRepositorySubdir :: Maybe String } deriving (Eq, Show) -mkPackage :: (CaptureUnknownFields (Section PackageConfig)) -> IO ([String], Package)-mkPackage (CaptureUnknownFields unknownFields globalOptions@Section{sectionData = PackageConfig{..}}) = do- mLibrary <- mapM (toLibrary globalOptions) mLibrarySection- executables <- toExecutables globalOptions (map (fmap captureUnknownFieldsValue) executableSections)- tests <- toExecutables globalOptions (map (fmap captureUnknownFieldsValue) testsSections)- benchmarks <- toExecutables globalOptions (map (fmap captureUnknownFieldsValue) benchmarkSections)+mkPackage :: FilePath -> (CaptureUnknownFields (Section PackageConfig)) -> IO ([String], Package)+mkPackage dir (CaptureUnknownFields unknownFields globalOptions@Section{sectionData = PackageConfig{..}}) = do+ let name = fromMaybe (takeBaseName dir) packageConfigName - name <- maybe (takeBaseName <$> getCurrentDirectory) return packageConfigName+ mLibrary <- mapM (toLibrary dir name globalOptions) mLibrarySection+ executables <- toExecutables dir globalOptions (map (fmap captureUnknownFieldsValue) executableSections)+ tests <- toExecutables dir globalOptions (map (fmap captureUnknownFieldsValue) testsSections)+ benchmarks <- toExecutables dir globalOptions (map (fmap captureUnknownFieldsValue) benchmarkSections) - licenseFileExists <- doesFileExist "LICENSE"+ licenseFileExists <- doesFileExist (dir </> "LICENSE") - missingSourceDirs <- nub . sort <$> filterM (fmap not <$> doesDirectoryExist) (+ missingSourceDirs <- nub . sort <$> filterM (fmap not <$> doesDirectoryExist . (dir </>)) ( maybe [] sectionSourceDirs mLibrary ++ concatMap sectionSourceDirs executables ++ concatMap sectionSourceDirs tests@@ -306,10 +313,10 @@ ) (extraSourceFilesWarnings, extraSourceFiles) <-- expandGlobs (fromMaybeList packageConfigExtraSourceFiles)+ expandGlobs dir (fromMaybeList packageConfigExtraSourceFiles) (dataFilesWarnings, dataFiles) <-- expandGlobs (fromMaybeList packageConfigDataFiles)+ expandGlobs dir (fromMaybeList packageConfigDataFiles) let pkg = Package { packageName = name@@ -399,8 +406,8 @@ where fromGithub = (++ "/issues") . sourceRepositoryUrl <$> sourceRepository -toLibrary :: Section global -> Section LibrarySection -> IO (Section Library)-toLibrary globalOptions library = traverse fromLibrarySection sect+toLibrary :: FilePath -> String -> Section global -> Section LibrarySection -> IO (Section Library)+toLibrary dir name globalOptions library = traverse fromLibrarySection sect where sect :: Section LibrarySection sect = mergeSections globalOptions library@@ -410,12 +417,12 @@ fromLibrarySection :: LibrarySection -> IO Library fromLibrarySection LibrarySection{..} = do- modules <- concat <$> mapM getModules sourceDirs- let (exposedModules, otherModules) = determineModules modules librarySectionExposedModules librarySectionOtherModules+ modules <- concat <$> mapM (getModules dir) sourceDirs+ let (exposedModules, otherModules) = determineModules name modules librarySectionExposedModules librarySectionOtherModules return (Library exposedModules otherModules) -toExecutables :: Section global -> [(String, Section ExecutableSection)] -> IO [Section Executable]-toExecutables globalOptions executables = mapM toExecutable sections+toExecutables :: FilePath -> Section global -> [(String, Section ExecutableSection)] -> IO [Section Executable]+toExecutables dir globalOptions executables = mapM toExecutable sections where sections :: [(String, Section ExecutableSection)] sections = map (fmap $ mergeSections globalOptions) executables@@ -427,7 +434,7 @@ where fromExecutableSection :: ExecutableSection -> IO (Executable, [GhcOption]) fromExecutableSection ExecutableSection{..} = do- modules <- maybe (filterMain . concat <$> mapM getModules sectionSourceDirs) (return . fromList) executableSectionOtherModules+ modules <- maybe (filterMain . concat <$> mapM (getModules dir) sectionSourceDirs) (return . fromList) executableSectionOtherModules return (Executable name mainSrcFile modules, ghcOptions) where filterMain :: [String] -> [String]@@ -437,11 +444,12 @@ mergeSections :: Section global -> Section a -> Section a mergeSections globalOptions options- = Section a sourceDirs dependencies defaultExtensions ghcOptions ghcProfOptions cppOptions+ = Section a sourceDirs dependencies defaultExtensions otherExtensions ghcOptions ghcProfOptions cppOptions where a = sectionData options sourceDirs = sectionSourceDirs globalOptions ++ sectionSourceDirs options defaultExtensions = sectionDefaultExtensions globalOptions ++ sectionDefaultExtensions options+ otherExtensions = sectionOtherExtensions globalOptions ++ sectionOtherExtensions options ghcOptions = sectionGhcOptions globalOptions ++ sectionGhcOptions options ghcProfOptions = sectionGhcProfOptions globalOptions ++ sectionGhcProfOptions options cppOptions = sectionCppOptions globalOptions ++ sectionCppOptions options@@ -449,39 +457,40 @@ toSection :: a -> CommonOptions -> Section a toSection a CommonOptions{..}- = Section a sourceDirs dependencies defaultExtensions ghcOptions ghcProfOptions cppOptions+ = Section a sourceDirs dependencies defaultExtensions otherExtensions ghcOptions ghcProfOptions cppOptions where sourceDirs = fromMaybeList commonOptionsSourceDirs defaultExtensions = fromMaybeList commonOptionsDefaultExtensions+ otherExtensions = fromMaybeList commonOptionsOtherExtensions ghcOptions = fromMaybeList commonOptionsGhcOptions ghcProfOptions = fromMaybeList commonOptionsGhcProfOptions cppOptions = fromMaybeList commonOptionsCppOptions dependencies = fromMaybeList commonOptionsDependencies -determineModules :: [String] -> Maybe (List String) -> Maybe (List String) -> ([String], [String])-determineModules modules mExposedModules mOtherModules = case (mExposedModules, mOtherModules) of+determineModules :: String -> [String] -> Maybe (List String) -> Maybe (List String) -> ([String], [String])+determineModules name modules mExposedModules mOtherModules = case (mExposedModules, mOtherModules) of (Nothing, Nothing) -> (modules, []) _ -> (exposedModules, otherModules) where- otherModules = maybe (modules \\ exposedModules) fromList mOtherModules+ otherModules = maybe ((modules \\ exposedModules) ++ pathsModule) fromList mOtherModules exposedModules = maybe (modules \\ otherModules) fromList mExposedModules+ pathsModule = ["Paths_" ++ name] \\ exposedModules -getModules :: FilePath -> IO [String]-getModules src_ = sort <$> do- exists <- doesDirectoryExist src_+getModules :: FilePath -> FilePath -> IO [String]+getModules dir src_ = sort <$> do+ exists <- doesDirectoryExist (dir </> src_) if exists then do- src <- canonicalizePath src_- cwd <- getCurrentDirectory- removeSetup cwd src . toModules <$> getFilesRecursive src+ src <- canonicalizePath (dir </> src_)+ removeSetup src . toModules <$> getFilesRecursive src else return [] where toModules :: [[FilePath]] -> [String] toModules = catMaybes . map toModule - removeSetup :: FilePath -> FilePath -> [String] -> [String]- removeSetup cwd src- | src == cwd = filter (/= "Setup")+ removeSetup :: FilePath -> [String] -> [String]+ removeSetup src+ | src == dir = filter (/= "Setup") | otherwise = id fromMaybeList :: Maybe (List a) -> [a]
src/Hpack/Run.hs view
@@ -23,17 +23,18 @@ import Data.Maybe import Data.List.Compat import System.Exit.Compat+import System.FilePath import Hpack.Util import Hpack.Config import Hpack.Render -run :: IO ([String], FilePath, String)-run = do- mPackage <- readPackageConfig packageConfig+run :: FilePath -> IO ([String], FilePath, String)+run dir = do+ mPackage <- readPackageConfig (dir </> packageConfig) case mPackage of Right (warnings, pkg) -> do- let cabalFile = packageName pkg ++ ".cabal"+ let cabalFile = dir </> (packageName pkg ++ ".cabal") old <- tryReadFile cabalFile @@ -185,6 +186,7 @@ renderSection Section{..} = [ renderSourceDirs sectionSourceDirs , renderDefaultExtensions sectionDefaultExtensions+ , renderOtherExtensions sectionOtherExtensions , renderGhcOptions sectionGhcOptions , renderGhcProfOptions sectionGhcProfOptions , renderCppOptions sectionCppOptions@@ -217,3 +219,6 @@ renderDefaultExtensions :: [String] -> Element renderDefaultExtensions = Field "default-extensions" . WordList++renderOtherExtensions :: [String] -> Element+renderOtherExtensions = Field "other-extensions" . WordList
src/Hpack/Util.hs view
@@ -119,13 +119,13 @@ isNameChar = (`elem` nameChars) nameChars = ['a'..'z'] ++ ['A'..'Z'] ++ "-" -expandGlobs :: [String] -> IO ([String], [FilePath])-expandGlobs patterns = do- files <- (fst <$> globDir compiledPatterns ".") >>= mapM removeDirectories+expandGlobs :: FilePath -> [String] -> IO ([String], [FilePath])+expandGlobs dir patterns = do+ files <- (fst <$> globDir compiledPatterns dir) >>= mapM removeDirectories let warnings = [warn pattern | ([], pattern) <- zip files patterns] return (warnings, combineResults files) where- combineResults = nub . map (makeRelative ".") . sort . concat+ combineResults = nub . map (makeRelative dir) . sort . concat warn pattern = "Specified pattern " ++ show pattern ++ " for extra-source-files does not match any files" compiledPatterns = map (compileWith options) patterns removeDirectories = filterM doesFileExist
test/Helper.hs view
@@ -2,8 +2,21 @@ module Test.Hspec , module Test.Mockery.Directory , module Control.Applicative+, module System.IO.Temp+, module System.FilePath+, withCurrentDirectory ) where import Test.Hspec import Test.Mockery.Directory import Control.Applicative+import System.Directory+import Control.Exception+import System.IO.Temp+import System.FilePath++withCurrentDirectory :: FilePath -> IO a -> IO a+withCurrentDirectory dir action = do+ bracket (getCurrentDirectory) (setCurrentDirectory) $ \ _ -> do+ setCurrentDirectory dir+ action
test/Hpack/ConfigSpec.hs view
@@ -14,7 +14,10 @@ import Data.Aeson.QQ import Data.Aeson.Types import Data.String.Interpolate+import Control.Arrow+import System.Directory (createDirectory) +import Hpack.Util import Hpack.Config hiding (package) import qualified Hpack.Config as Config @@ -27,6 +30,27 @@ library :: Library library = Library [] [] +withPackage :: String -> IO () -> (([String], Package) -> Expectation) -> Expectation+withPackage content beforeAction expectation = withSystemTempDirectory "hspec" $ \dir_ -> do+ let dir = dir_ </> "foo"+ createDirectory dir+ writeFile (dir </> "package.yaml") content+ withCurrentDirectory dir beforeAction+ r <- readPackageConfig (dir </> "package.yaml")+ either expectationFailure expectation r++withPackageConfig :: String -> IO () -> (Package -> Expectation) -> Expectation+withPackageConfig content beforeAction expectation = withPackage content beforeAction (expectation . snd)++withPackageConfig_ :: String -> (Package -> Expectation) -> Expectation+withPackageConfig_ content = withPackageConfig content (return ())++withPackageWarnings :: String -> IO () -> ([String] -> Expectation) -> Expectation+withPackageWarnings content beforeAction expectation = withPackage content beforeAction (expectation . fst)++withPackageWarnings_ :: String -> ([String] -> Expectation) -> Expectation+withPackageWarnings_ content = withPackageWarnings content (return ())+ spec :: Spec spec = do describe "parseJSON" $ do@@ -83,199 +107,191 @@ }|] parseEither parseJSON value `shouldBe` (Left "Error in $: neither key \"git\" nor key \"github\" present" :: Either String Dependency) - describe "getModules" $ around_ inTempDirectory $ do- it "returns Haskell modules in specified source directory" $ do- touch "src/Foo.hs"- touch "src/Bar/Baz.hs"- touch "src/Setup.hs"- getModules "src" >>= (`shouldMatchList` ["Foo", "Bar.Baz", "Setup"])+ describe "getModules" $ around (withSystemTempDirectory "hspec") $ do+ it "returns Haskell modules in specified source directory" $ \dir -> do+ touch (dir </> "src/Foo.hs")+ touch (dir </> "src/Bar/Baz.hs")+ touch (dir </> "src/Setup.hs")+ getModules dir "src" >>= (`shouldMatchList` ["Foo", "Bar.Baz", "Setup"]) context "when source directory is '.'" $ do- it "ignores Setup" $ do- touch "Foo.hs"- touch "Setup.hs"- getModules "." `shouldReturn` ["Foo"]+ it "ignores Setup" $ \dir -> do+ touch (dir </> "Foo.hs")+ touch (dir </> "Setup.hs")+ getModules dir "." `shouldReturn` ["Foo"] context "when source directory is './.'" $ do- it "ignores Setup" $ do- touch "Foo.hs"- touch "Setup.hs"- getModules "./." `shouldReturn` ["Foo"]+ it "ignores Setup" $ \dir -> do+ touch (dir </> "Foo.hs")+ touch (dir </> "Setup.hs")+ getModules dir "./." `shouldReturn` ["Foo"] - describe "readPackageConfig" $ around_ (inTempDirectoryNamed "foo") $ do+ describe "determineModules" $ do+ it "adds the Paths_* module to the other-modules" $ do+ determineModules "foo" [] (Just $ List ["Foo"]) Nothing `shouldBe` (["Foo"], ["Paths_foo"])++ context "when the Paths_* module is part of the exposed-modules" $ do+ it "it does not add the Paths_* module to the other-modules" $ do+ determineModules "foo" [] (Just $ List ["Foo", "Paths_foo"]) Nothing `shouldBe` (["Foo", "Paths_foo"], [])++ describe "readPackageConfig" $ do it "warns on unknown fields" $ do- writeFile "package.yaml" [i|+ withPackageWarnings_ [i| bar: 23 baz: 42 |]- fmap fst <$> readPackageConfig "package.yaml" `shouldReturn` Right [+ (`shouldBe` [ "Ignoring unknown field \"bar\" in package description" , "Ignoring unknown field \"baz\" in package description" ]+ ) it "accepts name" $ do- writeFile "package.yaml" [i|+ withPackageConfig_ [i| name: bar |]- Right (_, c) <- readPackageConfig "package.yaml"- c `shouldBe` package {packageName = "bar"}+ (packageName >>> (`shouldBe` "bar")) it "accepts version" $ do- writeFile "package.yaml" [i|+ withPackageConfig_ [i| version: 0.1.0 |]- Right (_, c) <- readPackageConfig "package.yaml"- c `shouldBe` package {packageVersion = "0.1.0"}+ (packageVersion >>> (`shouldBe` "0.1.0")) it "accepts synopsis" $ do- writeFile "package.yaml" [i|+ withPackageConfig_ [i| synopsis: some synopsis |]- Right (_, c) <- readPackageConfig "package.yaml"- c `shouldBe` package {packageSynopsis = Just "some synopsis"}+ (packageSynopsis >>> (`shouldBe` Just "some synopsis")) it "accepts description" $ do- writeFile "package.yaml" [i|+ withPackageConfig_ [i| description: some description |]- Right (_, c) <- readPackageConfig "package.yaml"- c `shouldBe` package {packageDescription = Just "some description"}+ (packageDescription >>> (`shouldBe` Just "some description")) it "accepts category" $ do- writeFile "package.yaml" [i|+ withPackageConfig_ [i| category: Data |]- Right (_, c) <- readPackageConfig "package.yaml"- c `shouldBe` package {packageCategory = Just "Data"}+ (`shouldBe` package {packageCategory = Just "Data"}) it "accepts author" $ do- writeFile "package.yaml" [i|+ withPackageConfig_ [i| author: John Doe |]- Right (_, c) <- readPackageConfig "package.yaml"- c `shouldBe` package {packageAuthor = ["John Doe"]}+ (`shouldBe` package {packageAuthor = ["John Doe"]}) it "accepts maintainer" $ do- writeFile "package.yaml" [i|+ withPackageConfig_ [i| maintainer: John Doe <john.doe@example.com> |]- Right (_, c) <- readPackageConfig "package.yaml"- c `shouldBe` package {packageMaintainer = ["John Doe <john.doe@example.com>"]}+ (`shouldBe` package {packageMaintainer = ["John Doe <john.doe@example.com>"]}) it "accepts copyright" $ do- writeFile "package.yaml" [i|+ withPackageConfig_ [i| copyright: (c) 2015 John Doe |]- Right (_, c) <- readPackageConfig "package.yaml"- c `shouldBe` package {packageCopyright = ["(c) 2015 John Doe"]}+ (`shouldBe` package {packageCopyright = ["(c) 2015 John Doe"]}) it "accepts stability" $ do- writeFile "package.yaml" [i|+ withPackageConfig_ [i| stability: experimental |]- Right (_, c) <- readPackageConfig "package.yaml"- packageStability c `shouldBe` Just "experimental"+ (packageStability >>> (`shouldBe` Just "experimental")) it "accepts homepage URL" $ do- writeFile "package.yaml" [i|+ withPackageConfig_ [i| github: hspec/hspec homepage: https://example.com/ |]- Right (_, c) <- readPackageConfig "package.yaml"- packageHomepage c `shouldBe` Just "https://example.com/"+ (packageHomepage >>> (`shouldBe` Just "https://example.com/")) it "infers homepage URL from github" $ do- writeFile "package.yaml" [i|+ withPackageConfig_ [i| github: hspec/hspec |]- Right (_, c) <- readPackageConfig "package.yaml"- packageHomepage c `shouldBe` Just "https://github.com/hspec/hspec#readme"+ (packageHomepage >>> (`shouldBe` Just "https://github.com/hspec/hspec#readme")) it "omits homepage URL if it is null" $ do- writeFile "package.yaml" [i|+ withPackageConfig_ [i| github: hspec/hspec homepage: null |]- Right (_, c) <- readPackageConfig "package.yaml"- packageHomepage c `shouldBe` Nothing+ (packageHomepage >>> (`shouldBe` Nothing)) it "accepts bug-reports URL" $ do- writeFile "package.yaml" [i|+ withPackageConfig_ [i| github: hspec/hspec bug-reports: https://example.com/issues |]- Right (_, c) <- readPackageConfig "package.yaml"- packageBugReports c `shouldBe` Just "https://example.com/issues"+ (packageBugReports >>> (`shouldBe` Just "https://example.com/issues")) it "infers bug-reports URL from github" $ do- writeFile "package.yaml" [i|+ withPackageConfig_ [i| github: hspec/hspec |]- Right (_, c) <- readPackageConfig "package.yaml"- packageBugReports c `shouldBe` Just "https://github.com/hspec/hspec/issues"+ (packageBugReports >>> (`shouldBe` Just "https://github.com/hspec/hspec/issues")) it "omits bug-reports URL if it is null" $ do- writeFile "package.yaml" [i|+ withPackageConfig_ [i| github: hspec/hspec bug-reports: null |]- Right (_, c) <- readPackageConfig "package.yaml"- packageBugReports c `shouldBe` Nothing+ (packageBugReports >>> (`shouldBe` Nothing)) it "accepts license" $ do- writeFile "package.yaml" [i|+ withPackageConfig_ [i| license: MIT |]- Right (_, c) <- readPackageConfig "package.yaml"- c `shouldBe` package {packageLicense = Just "MIT"}+ (`shouldBe` package {packageLicense = Just "MIT"}) it "infers license file" $ do- writeFile "package.yaml" [i|+ withPackageConfig [i| name: foo |]- touch "LICENSE"- Right (_, c) <- readPackageConfig "package.yaml"- c `shouldBe` package {packageLicenseFile = Just "LICENSE"}+ (do+ touch "LICENSE"+ )+ (`shouldBe` package {packageLicenseFile = Just "LICENSE"}) it "accepts extra-source-files" $ do- writeFile "package.yaml" [i|+ withPackageConfig [i| extra-source-files: - CHANGES.markdown - README.markdown |]- touch "CHANGES.markdown"- touch "README.markdown"- Right (_, c) <- readPackageConfig "package.yaml"- packageExtraSourceFiles c `shouldBe` ["CHANGES.markdown", "README.markdown"]+ (do+ touch "CHANGES.markdown"+ touch "README.markdown"+ )+ (packageExtraSourceFiles >>> (`shouldBe` ["CHANGES.markdown", "README.markdown"])) it "accepts data-files" $ do- writeFile "package.yaml" [i|+ withPackageConfig [i| data-files: - data/**/*.html |]- touch "data/foo/index.html"- touch "data/bar/index.html"- Right (_, c) <- readPackageConfig "package.yaml"- packageDataFiles c `shouldMatchList` ["data/foo/index.html", "data/bar/index.html"]+ (do+ touch "data/foo/index.html"+ touch "data/bar/index.html"+ )+ (packageDataFiles >>> (`shouldMatchList` ["data/foo/index.html", "data/bar/index.html"])) it "accepts github" $ do- writeFile "package.yaml" [i|+ withPackageConfig_ [i| github: hspec/hspec |]- Right (_, c) <- readPackageConfig "package.yaml"- packageSourceRepository c `shouldBe`- Just (SourceRepository "https://github.com/hspec/hspec" Nothing)+ (packageSourceRepository >>> (`shouldBe` Just (SourceRepository "https://github.com/hspec/hspec" Nothing))) it "accepts third part of github URL as subdir" $ do- writeFile "package.yaml" [i|+ withPackageConfig_ [i| github: hspec/hspec/hspec-core |]- Right (_, c) <- readPackageConfig "package.yaml"- packageSourceRepository c `shouldBe`- Just (SourceRepository "https://github.com/hspec/hspec" (Just "hspec-core"))+ (packageSourceRepository >>> (`shouldBe` Just (SourceRepository "https://github.com/hspec/hspec" (Just "hspec-core")))) it "accepts CPP options" $ do- writeFile "package.yaml" [i|+ withPackageConfig_ [i| cpp-options: -DFOO library: cpp-options: -DLIB@@ -291,147 +307,146 @@ main: Spec.hs cpp-options: -DTEST |]- Right (_, c) <- readPackageConfig "package.yaml"- c `shouldBe` package {+ (`shouldBe` package { packageLibrary = Just (section library) {sectionCppOptions = ["-DFOO", "-DLIB"]} , packageExecutables = [(section $ executable "foo" "Main.hs") {sectionCppOptions = ["-DFOO", "-DFOO"]}] , packageTests = [(section $ executable "spec" "Spec.hs") {sectionCppOptions = ["-DFOO", "-DTEST"]}] }+ ) context "when reading library section" $ do it "warns on unknown fields" $ do- writeFile "package.yaml" [i|+ withPackageWarnings_ [i| library: bar: 23 baz: 42 |]-- fmap fst <$> readPackageConfig "package.yaml" `shouldReturn` Right [+ (`shouldBe` [ "Ignoring unknown field \"bar\" in library section" , "Ignoring unknown field \"baz\" in library section" ]+ ) it "accepts source-dirs" $ do- writeFile "package.yaml" [i|+ withPackageConfig_ [i| library: source-dirs: - foo - bar |]- Right (_, c) <- readPackageConfig "package.yaml"- packageLibrary c `shouldBe` Just (section library) {sectionSourceDirs = ["foo", "bar"]}+ (packageLibrary >>> (`shouldBe` Just (section library) {sectionSourceDirs = ["foo", "bar"]})) it "accepts default-extensions" $ do- writeFile "package.yaml" [i|+ withPackageConfig_ [i| library: default-extensions: - Foo - Bar |]- Right (_, c) <- readPackageConfig "package.yaml"- packageLibrary c `shouldBe` Just (section library) {sectionDefaultExtensions = ["Foo", "Bar"]}+ (packageLibrary >>> (`shouldBe` Just (section library) {sectionDefaultExtensions = ["Foo", "Bar"]})) it "accepts global default-extensions" $ do- writeFile "package.yaml" [i|+ withPackageConfig_ [i| default-extensions: - Foo - Bar library: {} |]- Right (_, c) <- readPackageConfig "package.yaml"- packageLibrary c `shouldBe` Just (section library) {sectionDefaultExtensions = ["Foo", "Bar"]}+ (packageLibrary >>> (`shouldBe` Just (section library) {sectionDefaultExtensions = ["Foo", "Bar"]})) it "accepts global source-dirs" $ do- writeFile "package.yaml" [i|+ withPackageConfig_ [i| source-dirs: - foo - bar library: {} |]- Right (_, c) <- readPackageConfig "package.yaml"- packageLibrary c `shouldBe` Just (section library) {sectionSourceDirs = ["foo", "bar"]}+ (packageLibrary >>> (`shouldBe` Just (section library) {sectionSourceDirs = ["foo", "bar"]})) it "allows to specify exposed-modules" $ do- writeFile "package.yaml" [i|+ withPackageConfig [i| library: source-dirs: src exposed-modules: Foo |]- touch "src/Foo.hs"- touch "src/Bar.hs"- Right (_, c) <- readPackageConfig "package.yaml"- packageLibrary c `shouldBe` Just (section library{libraryExposedModules = ["Foo"], libraryOtherModules = ["Bar"]}) {sectionSourceDirs = ["src"]}+ (do+ touch "src/Foo.hs"+ touch "src/Bar.hs"+ )+ (packageLibrary >>> (`shouldBe` Just (section library{libraryExposedModules = ["Foo"], libraryOtherModules = ["Bar", "Paths_foo"]}) {sectionSourceDirs = ["src"]})) it "allows to specify other-modules" $ do- writeFile "package.yaml" [i|+ withPackageConfig [i| library: source-dirs: src other-modules: Bar |]- touch "src/Foo.hs"- touch "src/Bar.hs"- Right (_, c) <- readPackageConfig "package.yaml"- packageLibrary c `shouldBe` Just (section library{libraryExposedModules = ["Foo"], libraryOtherModules = ["Bar"]}) {sectionSourceDirs = ["src"]}+ (do+ touch "src/Foo.hs"+ touch "src/Bar.hs"+ )+ (packageLibrary >>> (`shouldBe` Just (section library{libraryExposedModules = ["Foo"], libraryOtherModules = ["Bar"]}) {sectionSourceDirs = ["src"]})) it "allows to specify both exposed-modules and other-modules" $ do- writeFile "package.yaml" [i|+ withPackageConfig [i| library: source-dirs: src exposed-modules: Foo other-modules: Bar |]- touch "src/Baz.hs"- Right (_, c) <- readPackageConfig "package.yaml"- packageLibrary c `shouldBe` Just (section library{libraryExposedModules = ["Foo"], libraryOtherModules = ["Bar"]}) {sectionSourceDirs = ["src"]}+ (do+ touch "src/Baz.hs"+ )+ (packageLibrary >>> (`shouldBe` Just (section library{libraryExposedModules = ["Foo"], libraryOtherModules = ["Bar"]}) {sectionSourceDirs = ["src"]})) - context "when neither exposed-module nor other-module are specified" $ do+ context "when neither exposed-modules nor other-modules are specified" $ do it "exposes all modules" $ do- writeFile "package.yaml" [i|+ withPackageConfig [i| library: source-dirs: src |]- touch "src/Foo.hs"- touch "src/Bar.hs"- Right (_, c) <- readPackageConfig "package.yaml"- packageLibrary c `shouldBe` Just (section library{libraryExposedModules = ["Bar", "Foo"]}) {sectionSourceDirs = ["src"]}+ (do+ touch "src/Foo.hs"+ touch "src/Bar.hs"+ )+ (packageLibrary >>> (`shouldBe` Just (section library{libraryExposedModules = ["Bar", "Foo"]}) {sectionSourceDirs = ["src"]})) context "when reading executable section" $ do it "warns on unknown fields" $ do- writeFile "package.yaml" [i|+ withPackageWarnings_ [i| executables: foo: main: Main.hs bar: 42 baz: 23 |]-- fmap fst <$> readPackageConfig "package.yaml" `shouldReturn` Right [+ (`shouldBe` [ "Ignoring unknown field \"bar\" in executable section \"foo\"" , "Ignoring unknown field \"baz\" in executable section \"foo\"" ]+ ) it "reads executable section" $ do- writeFile "package.yaml" [i|+ withPackageConfig_ [i| executables: foo: main: driver/Main.hs |]- Right (_, c) <- readPackageConfig "package.yaml"- packageExecutables c `shouldBe` [section $ executable "foo" "driver/Main.hs"]+ (packageExecutables >>> (`shouldBe` [section $ executable "foo" "driver/Main.hs"])) it "accepts arbitrary entry points as main" $ do- writeFile "package.yaml" [i|+ withPackageConfig_ [i| executables: foo: main: Foo |]- Right (_, c) <- readPackageConfig "package.yaml"- packageExecutables c `shouldBe` [+ (packageExecutables >>> (`shouldBe` [ (section $ executable "foo" "Foo.hs") {sectionGhcOptions = ["-main-is Foo"]} ]+ )) it "accepts source-dirs" $ do- writeFile "package.yaml" [i|+ withPackageConfig_ [i| executables: foo: main: Main.hs@@ -439,11 +454,10 @@ - foo - bar |]- Right (_, c) <- readPackageConfig "package.yaml"- packageExecutables c `shouldBe` [(section $ executable "foo" "Main.hs") {sectionSourceDirs = ["foo", "bar"]}]+ (packageExecutables >>> (`shouldBe` [(section $ executable "foo" "Main.hs") {sectionSourceDirs = ["foo", "bar"]}])) it "accepts global source-dirs" $ do- writeFile "package.yaml" [i|+ withPackageConfig_ [i| source-dirs: - foo - bar@@ -451,38 +465,39 @@ foo: main: Main.hs |]- Right (_, c) <- readPackageConfig "package.yaml"- packageExecutables c `shouldBe` [(section $ executable "foo" "Main.hs") {sectionSourceDirs = ["foo", "bar"]}]+ (packageExecutables >>> (`shouldBe` [(section $ executable "foo" "Main.hs") {sectionSourceDirs = ["foo", "bar"]}])) it "infers other-modules" $ do- touch "src/Main.hs"- touch "src/Foo.hs"- touch "src/Bar.hs"- touch "src/Baz.lhs"- writeFile "package.yaml" [i|+ withPackageConfig [i| executables: foo: main: Main.hs source-dirs: src |]- Right (_, [r]) <- (fmap . fmap) packageExecutables <$> readPackageConfig "package.yaml"- executableOtherModules (sectionData r) `shouldBe` ["Bar", "Baz", "Foo"]+ (do+ touch "src/Main.hs"+ touch "src/Foo.hs"+ touch "src/Bar.hs"+ touch "src/Baz.lhs"+ )+ (map (executableOtherModules . sectionData) . packageExecutables >>> (`shouldBe` [["Bar", "Baz", "Foo"]])) it "allows to specify other-modules" $ do- touch "src/Foo.hs"- touch "src/Bar.hs"- writeFile "package.yaml" [i|+ withPackageConfig [i| executables: foo: main: Main.hs source-dirs: src other-modules: Baz |]- Right (_, [r]) <- (fmap . fmap) packageExecutables <$> readPackageConfig "package.yaml"- executableOtherModules (sectionData r) `shouldBe` ["Baz"]+ (do+ touch "src/Foo.hs"+ touch "src/Bar.hs"+ )+ (map (executableOtherModules . sectionData) . packageExecutables >>> (`shouldBe` [["Baz"]])) it "accepts default-extensions" $ do- writeFile "package.yaml" [i|+ withPackageConfig_ [i| executables: foo: main: driver/Main.hs@@ -490,11 +505,10 @@ - Foo - Bar |]- Right (_, c) <- readPackageConfig "package.yaml"- packageExecutables c `shouldBe` [(section $ executable "foo" "driver/Main.hs") {sectionDefaultExtensions = ["Foo", "Bar"]}]+ (packageExecutables >>> (`shouldBe` [(section $ executable "foo" "driver/Main.hs") {sectionDefaultExtensions = ["Foo", "Bar"]}])) it "accepts global default-extensions" $ do- writeFile "package.yaml" [i|+ withPackageConfig_ [i| default-extensions: - Foo - Bar@@ -502,86 +516,79 @@ foo: main: driver/Main.hs |]- Right (_, c) <- readPackageConfig "package.yaml"- packageExecutables c `shouldBe` [(section $ executable "foo" "driver/Main.hs") {sectionDefaultExtensions = ["Foo", "Bar"]}]+ (packageExecutables >>> (`shouldBe` [(section $ executable "foo" "driver/Main.hs") {sectionDefaultExtensions = ["Foo", "Bar"]}])) it "accepts GHC options" $ do- writeFile "package.yaml" [i|+ withPackageConfig_ [i| executables: foo: main: driver/Main.hs ghc-options: -Wall |]- Right (_, c) <- readPackageConfig "package.yaml"- c `shouldBe` package {packageExecutables = [(section $ executable "foo" "driver/Main.hs") {sectionGhcOptions = ["-Wall"]}]}+ (`shouldBe` package {packageExecutables = [(section $ executable "foo" "driver/Main.hs") {sectionGhcOptions = ["-Wall"]}]}) it "accepts global GHC options" $ do- writeFile "package.yaml" [i|+ withPackageConfig_ [i| ghc-options: -Wall executables: foo: main: driver/Main.hs |]- Right (_, c) <- readPackageConfig "package.yaml"- c `shouldBe` package {packageExecutables = [(section $ executable "foo" "driver/Main.hs") {sectionGhcOptions = ["-Wall"]}]}+ (`shouldBe` package {packageExecutables = [(section $ executable "foo" "driver/Main.hs") {sectionGhcOptions = ["-Wall"]}]}) it "accepts GHC profiling options" $ do- writeFile "package.yaml" [i|+ withPackageConfig_ [i| executables: foo: main: driver/Main.hs ghc-prof-options: -fprof-auto |]- Right (_, c) <- readPackageConfig "package.yaml"- c `shouldBe` package {packageExecutables = [(section $ executable "foo" "driver/Main.hs") {sectionGhcProfOptions = ["-fprof-auto"]}]}+ (`shouldBe` package {packageExecutables = [(section $ executable "foo" "driver/Main.hs") {sectionGhcProfOptions = ["-fprof-auto"]}]}) it "accepts global GHC profiling options" $ do- writeFile "package.yaml" [i|+ withPackageConfig_ [i| ghc-prof-options: -fprof-auto executables: foo: main: driver/Main.hs |]- Right (_, c) <- readPackageConfig "package.yaml"- c `shouldBe` package {packageExecutables = [(section $ executable "foo" "driver/Main.hs") {sectionGhcProfOptions = ["-fprof-auto"]}]}+ (`shouldBe` package {packageExecutables = [(section $ executable "foo" "driver/Main.hs") {sectionGhcProfOptions = ["-fprof-auto"]}]}) context "when reading test section" $ do it "warns on unknown fields" $ do- writeFile "package.yaml" [i|+ withPackageWarnings_ [i| tests: foo: main: Main.hs bar: 42 baz: 23 |]-- fmap fst <$> readPackageConfig "package.yaml" `shouldReturn` Right [+ (`shouldBe` [ "Ignoring unknown field \"bar\" in test section \"foo\"" , "Ignoring unknown field \"baz\" in test section \"foo\"" ]+ ) it "reads test section" $ do- writeFile "package.yaml" [i|+ withPackageConfig_ [i| tests: spec: main: test/Spec.hs |]- Right (_, c) <- readPackageConfig "package.yaml"- c `shouldBe` package {packageTests = [section $ executable "spec" "test/Spec.hs"]}+ (`shouldBe` package {packageTests = [section $ executable "spec" "test/Spec.hs"]}) it "accepts single dependency" $ do- writeFile "package.yaml" [i|+ withPackageConfig_ [i| tests: spec: main: test/Spec.hs dependencies: hspec |]- Right (_, c) <- readPackageConfig "package.yaml"- c `shouldBe` package {packageTests = [(section $ executable "spec" "test/Spec.hs") {sectionDependencies = ["hspec"]}]}+ (`shouldBe` package {packageTests = [(section $ executable "spec" "test/Spec.hs") {sectionDependencies = ["hspec"]}]}) it "accepts list of dependencies" $ do- writeFile "package.yaml" [i|+ withPackageConfig_ [i| tests: spec: main: test/Spec.hs@@ -589,12 +596,11 @@ - hspec - QuickCheck |]- Right (_, c) <- readPackageConfig "package.yaml"- c `shouldBe` package {packageTests = [(section $ executable "spec" "test/Spec.hs") {sectionDependencies = ["hspec", "QuickCheck"]}]}+ (`shouldBe` package {packageTests = [(section $ executable "spec" "test/Spec.hs") {sectionDependencies = ["hspec", "QuickCheck"]}]}) context "when both global and section specific dependencies are specified" $ do it "combines dependencies" $ do- writeFile "package.yaml" [i|+ withPackageConfig_ [i| dependencies: - base @@ -603,12 +609,11 @@ main: test/Spec.hs dependencies: hspec |]- Right (_, c) <- readPackageConfig "package.yaml"- c `shouldBe` package {packageTests = [(section $ executable "spec" "test/Spec.hs") {sectionDependencies = ["base", "hspec"]}]}+ (`shouldBe` package {packageTests = [(section $ executable "spec" "test/Spec.hs") {sectionDependencies = ["base", "hspec"]}]}) context "when a specified source directory does not exist" $ do it "warns" $ do- writeFile "package.yaml" [i|+ withPackageWarnings [i| source-dirs: - some-dir - some-existing-dir@@ -623,31 +628,38 @@ main: Main.hs source-dirs: some-test-dir |]- touch "some-existing-dir/foo"- fmap fst <$> readPackageConfig "package.yaml" `shouldReturn` Right [+ (do+ touch "some-existing-dir/foo"+ )+ (`shouldBe` [ "Specified source-dir \"some-dir\" does not exist" , "Specified source-dir \"some-exec-dir\" does not exist" , "Specified source-dir \"some-lib-dir\" does not exist" , "Specified source-dir \"some-test-dir\" does not exist" ]+ ) - context "when package.yaml can not be parsed" $ do- it "returns an error" $ do- writeFile "package.yaml" [i|- foo: bar- foo baz- |]- readPackageConfig "package.yaml" `shouldReturn` Left "package.yaml:3:10: could not find expected ':' while scanning a simple key"+ around (withSystemTempDirectory "hspec") $ do+ context "when package.yaml can not be parsed" $ do+ it "returns an error" $ \dir -> do+ let file = dir </> "package.yaml"+ writeFile file [i|+ foo: bar+ foo baz+ |]+ readPackageConfig file `shouldReturn` Left (file ++ ":3:12: could not find expected ':' while scanning a simple key") - context "when package.yaml is invalid" $ do- it "returns an error" $ do- writeFile "package.yaml" [i|- executables:- foo:- ain: driver/Main.hs- |]- readPackageConfig "package.yaml" `shouldReturn` Left "package.yaml: Error in $.executables.foo: failed to parse field executables: The key \"main\" was not found"+ context "when package.yaml is invalid" $ do+ it "returns an error" $ \dir -> do+ let file = dir </> "package.yaml"+ writeFile file [i|+ executables:+ foo:+ ain: driver/Main.hs+ |]+ readPackageConfig file `shouldReturn` Left (file ++ ": Error in $.executables.foo: failed to parse field executables: The key \"main\" was not found") - context "when package.yaml does not exist" $ do- it "returns an error" $- readPackageConfig "package.yaml" `shouldReturn` Left "package.yaml: Yaml file not found: package.yaml"+ context "when package.yaml does not exist" $ do+ it "returns an error" $ \dir -> do+ let file = dir </> "package.yaml"+ readPackageConfig file `shouldReturn` Left [i|#{file}: Yaml file not found: #{file}|]
test/Hpack/UtilSpec.hs view
@@ -142,64 +142,64 @@ it "rejects invalid fields" $ do splitField "foo bar" `shouldBe` Nothing - describe "expandGlobs" $ around_ inTempDirectory $ do- it "accepts simple files" $ do- touch "foo.js"- expandGlobs ["foo.js"] `shouldReturn` ([], ["foo.js"])+ describe "expandGlobs" $ around (withSystemTempDirectory "hspec") $ do+ it "accepts simple files" $ \dir -> do+ touch (dir </> "foo.js")+ expandGlobs dir ["foo.js"] `shouldReturn` ([], ["foo.js"]) - it "removes duplicates" $ do- touch "foo.js"- expandGlobs ["foo.js", "*.js"] `shouldReturn` ([], ["foo.js"])+ it "removes duplicates" $ \dir -> do+ touch (dir </> "foo.js")+ expandGlobs dir ["foo.js", "*.js"] `shouldReturn` ([], ["foo.js"]) - it "rejects directories" $ do- touch "foo"- createDirectory "bar"- expandGlobs ["*"] `shouldReturn` ([], ["foo"])+ it "rejects directories" $ \dir -> do+ touch (dir </> "foo")+ createDirectory (dir </> "bar")+ expandGlobs dir ["*"] `shouldReturn` ([], ["foo"]) - it "rejects character ranges" $ do- touch "foo1"- touch "foo2"- touch "foo[1,2]"- expandGlobs ["foo[1,2]"] `shouldReturn` ([], ["foo[1,2]"])+ it "rejects character ranges" $ \dir -> do+ touch (dir </> "foo1")+ touch (dir </> "foo2")+ touch (dir </> "foo[1,2]")+ expandGlobs dir ["foo[1,2]"] `shouldReturn` ([], ["foo[1,2]"]) context "when expanding *" $ do- it "expands by extension" $ do+ it "expands by extension" $ \dir -> do let files = [ "files/foo.js" , "files/bar.js" , "files/baz.js"]- mapM_ touch files- touch "files/foo.hs"- expandGlobs ["files/*.js"] `shouldReturn` ([], sort files)+ mapM_ (touch . (dir </>)) files+ touch (dir </> "files/foo.hs")+ expandGlobs dir ["files/*.js"] `shouldReturn` ([], sort files) - it "rejects dot-files" $ do- touch "foo/bar"- touch "foo/.baz"- expandGlobs ["foo/*"] `shouldReturn` ([], ["foo/bar"])+ it "rejects dot-files" $ \dir -> do+ touch (dir </> "foo/bar")+ touch (dir </> "foo/.baz")+ expandGlobs dir ["foo/*"] `shouldReturn` ([], ["foo/bar"]) - it "accepts dot-files when explicitly asked to" $ do- touch "foo/bar"- touch "foo/.baz"- expandGlobs ["foo/.*"] `shouldReturn` ([], ["foo/.baz"])+ it "accepts dot-files when explicitly asked to" $ \dir -> do+ touch (dir </> "foo/bar")+ touch (dir </> "foo/.baz")+ expandGlobs dir ["foo/.*"] `shouldReturn` ([], ["foo/.baz"]) - it "matches at most one directory component" $ do- touch "foo/bar/baz.js"- touch "foo/bar.js"- expandGlobs ["*/*.js"] `shouldReturn` ([], ["foo/bar.js"])+ it "matches at most one directory component" $ \dir -> do+ touch (dir </> "foo/bar/baz.js")+ touch (dir </> "foo/bar.js")+ expandGlobs dir ["*/*.js"] `shouldReturn` ([], ["foo/bar.js"]) context "when expanding **" $ do- it "matches arbitrary many directory components" $ do+ it "matches arbitrary many directory components" $ \dir -> do let file = "foo/bar/baz.js"- touch file- expandGlobs ["**/*.js"] `shouldReturn` ([], [file])+ touch (dir </> file)+ expandGlobs dir ["**/*.js"] `shouldReturn` ([], [file]) context "when a pattern does not match anything" $ do- it "warns" $ do- expandGlobs ["foo"] `shouldReturn`+ it "warns" $ \dir -> do+ expandGlobs dir ["foo"] `shouldReturn` (["Specified pattern \"foo\" for extra-source-files does not match any files"], []) context "when a pattern only matches a directory" $ do- it "warns" $ do- createDirectory "foo"- expandGlobs ["foo"] `shouldReturn`+ it "warns" $ \dir -> do+ createDirectory (dir </> "foo")+ expandGlobs dir ["foo"] `shouldReturn` (["Specified pattern \"foo\" for extra-source-files does not match any files"], [])
+ test/HpackSpec.hs view
@@ -0,0 +1,15 @@+module HpackSpec (spec) where++import Test.Hspec++import Hpack++spec :: Spec+spec = do+ describe "parseVerbosity" $ do+ it "returns True by default" $ do+ parseVerbosity ["foo"] `shouldBe` (True, ["foo"])++ context "with --silent" $ do+ it "returns False" $ do+ parseVerbosity ["--silent"] `shouldBe` (False, [])