vcs-ignore-0.0.1.0: test/Data/VCS/Ignore/Repo/GitSpec.hs
{-# LANGUAGE OverloadedStrings #-}
module Data.VCS.Ignore.Repo.GitSpec where
import qualified Data.List as L
import qualified Data.Text as T
import Data.VCS.Ignore.Repo ( RepoError(..) )
import Data.VCS.Ignore.Repo.Git
import System.Directory ( makeAbsolute )
import System.FilePath ( (</>) )
import Test.Hspec
spec :: Spec
spec = do
let repo = "test-data" </> "fake-git-repo"
describe "compilePattern" $ do
it "compiles negated pattern" $ do
compilePattern "!/foo/bar"
`shouldBe` Pattern ["/foo/bar", "/foo/bar/**"] "!/foo/bar" True
it "compiles pattern matching files or directories inside path" $ do
compilePattern ".hidden"
`shouldBe` Pattern ["**/.hidden", "**/.hidden/**"] ".hidden" False
compilePattern ".hidden/"
`shouldBe` Pattern ["**/.hidden/**"] ".hidden/" False
describe "matchesPattern" $ do
it "matches all content in subdirectory" $ do
matchesPattern (compilePattern "/foo/*") "/foo" `shouldBe` False
matchesPattern (compilePattern "/foo/*") "/foo/bar" `shouldBe` True
it "matches all content in all subdirectories" $ do
matchesPattern (compilePattern "/foo/**") "/foo/bar" `shouldBe` True
matchesPattern (compilePattern "/foo/**") "/foo/bar/c" `shouldBe` True
it "matches negated pattern" $ do
matchesPattern (compilePattern "!/foo/*") "/foo" `shouldBe` False
matchesPattern (compilePattern "!/foo/*") "/foo/bar" `shouldBe` True
it "matches dir pattern anywhere in the path" $ do
matchesPattern (compilePattern "bar/") "/foo/bar/x" `shouldBe` True
matchesPattern (compilePattern "bar/") "/foo/bar" `shouldBe` False
it "matches dir or file pattern anywhere in the path" $ do
matchesPattern (compilePattern "bar") "/foo/bar/x" `shouldBe` True
matchesPattern (compilePattern "bar") "/foo/bar" `shouldBe` True
describe "parsePatterns" $ do
it "parses glob patterns from input text (pattern per line)" $ do
let input = T.unlines [".cabal-sandbox/", "## comment", ".DS_Store"]
expected = [".cabal-sandbox/", ".DS_Store"]
parsePatterns input `shouldBe` expected
describe "loadPatterns" $ do
it "loads and parses glob patterns from input file" $ do
let source = repo </> "a" </> ".gitignore"
expected = ["**/*.xml"]
loadPatterns source `shouldReturn` expected
it "returns empty list if input cannot be read" $ do
let source = repo </> "non-existing"
loadPatterns source `shouldReturn` []
describe "findGitIgnores" $ do
it "finds all .gitignore files in repo" $ do
let expected =
[ repo </> "a" </> ".gitignore"
, repo </> "a" </> "b" </> ".gitignore"
, repo </> ".gitignore"
]
L.sort <$> findGitIgnores repo `shouldReturn` L.sort expected
describe "gitIgnorePatterns" $ do
it "loads patterns for all .gitignore files in repo" $ do
let expected =
[("/a/", ["**/*.xml"]), ("/a/b/", ["*.txt"]), ("/", ["foo"])]
sortFst <$> gitIgnorePatterns repo `shouldReturn` sortFst expected
describe "scanRepo'" $ do
it "scans repository for ignored patterns" $ do
absRepo <- makeAbsolute repo
let
fn1 = pure []
fn2 = const $ pure []
fn3 = const $ pure True
expected = Git
{ gitPatterns = sortFst
[("/", ["foo"]), ("/a/", ["**/*.xml"]), ("/a/b/", ["*.txt"])]
, gitRepoRoot = absRepo
}
result <- scanRepo' fn1 fn2 gitIgnorePatterns fn3 repo
let result' = result { gitPatterns = sortFst (gitPatterns result) }
result' `shouldBe` expected
it "aborts scanning if given path is not valid GIT repo" $ do
let fn1 = pure []
fn2 = const $ pure []
fn3 = const $ pure False
let err (InvalidRepo _ _) = True
scanRepo' fn1 fn2 gitIgnorePatterns fn3 repo `shouldThrow` err
describe "isIgnored'" $ do
it "checks whether given path is excluded" $ do
absRepo <- makeAbsolute repo
let git = Git
{ gitPatterns = [ ("/" , ["!keep.xml", ".hidden/", ".hid"])
, ("/a/" , ["**/*.xml"])
, ("/a/b/", ["*.txt"])
]
, gitRepoRoot = absRepo
}
isIgnored' git "foo/bar" `shouldReturn` False
isIgnored' git "a/hello.txt" `shouldReturn` False
isIgnored' git "a/hello.xml" `shouldReturn` True
isIgnored' git "a/b/hello.xml" `shouldReturn` True
isIgnored' git "a/b/keep.xml" `shouldReturn` False
isIgnored' git "/foo/bar" `shouldReturn` False
isIgnored' git "/a/hello.txt" `shouldReturn` False
isIgnored' git "/a/hello.xml" `shouldReturn` True
isIgnored' git "/a/b/hello.xml" `shouldReturn` True
isIgnored' git "/a/b/../hello.txt" `shouldReturn` False
isIgnored' git "/a/b/../hello.xml" `shouldReturn` True
isIgnored' git "/a/b/.hidden" `shouldReturn` False
isIgnored' git "/a/b/.hidden/foo" `shouldReturn` True
isIgnored' git "/a/b/.hid" `shouldReturn` True
isIgnored' git "/a/b/.hid/foo" `shouldReturn` True
sortFst :: Ord a => [(a, b)] -> [(a, b)]
sortFst = L.sortOn fst