headroom-0.3.1.0: test/Headroom/Command/RunSpec.hs
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE NoImplicitPrelude #-}
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE RecordWildCards #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE StrictData #-}
{-# LANGUAGE TemplateHaskell #-}
{-# LANGUAGE TypeApplications #-}
{-# LANGUAGE TypeFamilies #-}
module Headroom.Command.RunSpec
( spec
)
where
import Headroom.Command.Run
import Headroom.Configuration.Types ( CtHeaderFnConfigs
, HeaderFnConfig(..)
, HeaderFnConfigs(..)
, HeaderSyntax(..)
, LicenseType(..)
, UpdateCopyrightConfig(..)
)
import Headroom.Data.EnumExtra ( EnumExtra(..) )
import Headroom.Data.Has ( Has(..) )
import Headroom.Data.Lens ( suffixLenses
, suffixLensesFor
)
import Headroom.Data.TextExtra ( fromLines )
import Headroom.FileSystem ( FileSystem(..) )
import Headroom.FileType.Types ( FileType(..) )
import Headroom.Meta ( TemplateType )
import Headroom.Template ( Template(..) )
import Headroom.Types ( CurrentYear(..) )
import Headroom.Variables ( mkVariables )
import RIO hiding ( assert )
import qualified RIO.Map as M
import qualified RIO.NonEmpty as NE
import qualified RIO.Text as T
import Test.Hspec
import Test.Hspec.QuickCheck ( prop )
import Test.QuickCheck hiding ( sample )
import Test.QuickCheck.Monadic
data TestEnv = TestEnv
{ envLogFunc :: LogFunc
, envCurrentYear :: CurrentYear
, envFileSystem :: FileSystem (RIO TestEnv)
, envHeaderFnConfigs :: CtHeaderFnConfigs
}
suffixLenses ''TestEnv
suffixLensesFor ["fsFindFilesByExts", "fsLoadFile"] ''FileSystem
instance HasLogFunc TestEnv where
logFuncL = envLogFuncL
instance Has CtHeaderFnConfigs TestEnv where
hasLens = envHeaderFnConfigsL
instance Has CurrentYear TestEnv where
hasLens = envCurrentYearL
instance Has (FileSystem (RIO TestEnv)) TestEnv where
hasLens = envFileSystemL
spec :: Spec
spec = do
describe "loadBuiltInTemplates" $ do
it "should load correct number of built-in templates" $ do
templates <- runRIO env $ loadBuiltInTemplates BSD3
M.size templates `shouldBe` 11
describe "loadTemplateFiles" $ do
it "should load templates from given paths" $ do
let env' =
env
& (envFileSystemL . fsFindFilesByExtsL .~ fsFindFilesByExts')
& (envFileSystemL . fsLoadFileL .~ fsLoadFile')
fsFindFilesByExts' "test-dir" _ = pure ["haskell.mustache"]
fsFindFilesByExts' _ _ = throwString "INVALID CONDITION"
fsLoadFile' "haskell.mustache" = pure "template content"
fsLoadFile' _ = throwString "INVALID CONDITION"
templates <- runRIO env' $ loadTemplateFiles ["test-dir"]
M.size templates `shouldBe` 1
M.member Haskell templates `shouldBe` True
describe "typeOfTemplate" $ do
let fileTypes = fmap (T.toLower . enumToText) (allValues @FileType)
templateExt = NE.head $ templateExtensions @TemplateType
pathGen = elements $ fmap (<> "." <> templateExt) fileTypes
prop_typeOfTemplate = monadicIO $ do
path <- T.unpack <$> pick pathGen
result <- run (runRIO env $ typeOfTemplate path)
assert $ isJust result
prop "should detect type of template from template path" prop_typeOfTemplate
describe "postProcessHeader'" $ do
it "should perform expected post-processing on license header" $ do
let sample = fromLines
[ "-- Copyright (c) 2018-2019 1st Author"
, "Copyright (c) 2017 2nd Author"
]
expected = fromLines
[ "-- Copyright (c) 2018-2019 1st Author"
, "-- Copyright (c) 2017-2020 2nd Author"
]
vars = mkVariables [("sndAuthor", "2nd Author")]
syntax = LineComment "--"
actual <- runRIO env $ postProcessHeader' syntax vars sample
actual `shouldBe` expected
describe "sanitizeHeader" $ do
it "does nothing when block comment syntax used" $ do
let sample = fromLines ["{-", "foo", "bar", "-}"]
syntax = BlockComment "{-" "-}"
sanitizeHeader syntax sample `shouldBe` sample
it "adds missing single-line comment syntax" $ do
let sample = fromLines ["-- first", "second", "-- third"]
syntax = LineComment "--"
expected = fromLines ["-- first", "-- second", "-- third"]
sanitizeHeader syntax sample `shouldBe` expected
env :: TestEnv
env = TestEnv { .. }
where
envLogFunc = mkLogFunc (\_ _ _ _ -> pure ())
envCurrentYear = CurrentYear 2020
envFileSystem = FileSystem { fsCreateDirectory = undefined
, fsDoesFileExist = undefined
, fsFindFiles = undefined
, fsFindFilesByExts = undefined
, fsFindFilesByTypes = undefined
, fsGetCurrentDirectory = undefined
, fsListFiles = undefined
, fsLoadFile = undefined
}
envHeaderFnConfigs = HeaderFnConfigs
{ hfcsUpdateCopyright = HeaderFnConfig
{ hfcEnabled = True
, hfcConfig = UpdateCopyrightConfig
{ uccSelectedAuthors =
Just $ "{{ sndAuthor }}" :| []
}
}
}