checkmate 0.3.2 → 0.4.0
raw patch · 22 files changed
+285/−229 lines, 22 filesdep −rangedep ~githubdep ~hspec-megaparsecdep ~megaparsec
Dependencies removed: range
Dependency ranges changed: github, hspec-megaparsec, megaparsec, process
Files
- CHANGELOG.md +28/−0
- README.md +14/−5
- app/Main.hs +0/−3
- checkmate.cabal +83/−76
- hlint.hs +12/−0
- src/Checkmate/Check.hs +3/−2
- src/Checkmate/Diff.hs +0/−11
- src/Checkmate/Discover.hs +9/−5
- src/Checkmate/Parser/CheckFile.hs +13/−9
- src/Checkmate/Parser/IndentBlock.hs +29/−25
- src/Checkmate/Range.hs +11/−0
- src/Checkmate/Renderer.hs +1/−1
- test/Checkmate/CheckSpec.hs +4/−5
- test/Checkmate/DiffSpec.hs +0/−24
- test/Checkmate/DiscoverSpec.hs +46/−27
- test/Checkmate/Parser/CheckFileSpec.hs +3/−7
- test/Checkmate/Parser/IndentBlockSpec.hs +12/−13
- test/Checkmate/RangeSpec.hs +13/−0
- test/Checkmate/RendererSpec.hs +3/−3
- test/HLint.hs +0/−12
- test/Main.hs +1/−0
- test/Spec.hs +0/−1
CHANGELOG.md view
@@ -1,6 +1,34 @@ Checkmate changelog =================== +Version 0.4.0+-------------++Released on September 1, 2018.++ - Became internally independent from the [range] library.+ - Became to use GHC 8.4 internally.+ - The officially distributed executable binaries for Linux became+ independent from [glibc] again, and statically linked to [musl] instead.++[range]: https://hackage.haskell.org/package/range+[musl]: https://www.musl-libc.org/+++Version 0.3.3+-------------++Released on May 16, 2018.++ - The officially distributed executable binaries for Linux became+ dependent on [glibc].++ - Fixed a bug that it had failed to scan if any file in a change set is+ deleted.++[glibc]: https://www.gnu.org/software/libc/++ Version 0.3.2 -------------
README.md view
@@ -3,6 +3,7 @@ [![Build Status][ci-badge]][ci] [![Hackage][hackage-badge]][hackage]+[![GitHub release][release-badge]][latest release] Checkmate is a small program to generate human-readable checklists from a given patch (or pull request). Leave `CHECK` comments (that are the same@@ -12,10 +13,11 @@ It helps contributors and reviewers to remind matters that require attention when a part of the code is changed. -[ci-badge]: https://travis-ci.org/spoqa/checkmate.svg?branch=master-[ci]: https://travis-ci.org/spoqa/checkmate+[ci-badge]: https://travis-ci.com/dahlia/checkmate.svg?branch=master+[ci]: https://travis-ci.com/dahlia/checkmate [hackage-badge]: https://img.shields.io/hackage/v/checkmate.svg [hackage]: https://hackage.haskell.org/package/checkmate+[release-badge]: https://img.shields.io/github/release/dahlia/checkmate.svg?label=download&colorB=4c1 Situation@@ -135,10 +137,17 @@ stack install checkmate ~~~~~~~~ -[every release]: https://github.com/spoqa/checkmate/releases-[latest release]: https://github.com/spoqa/checkmate/releases/latest+Note: if you experience an error like `ConnectionFailure+Network.BSD.getProtocolByName: does not exist (no such protocol name: tcp)`+on Debian/Ubuntu Linux, try to install [*netbase*][netbase] package.+(Read [this explanation][1] for details.)++[every release]: https://github.com/dahlia/checkmate/releases+[latest release]: https://github.com/dahlia/checkmate/releases/latest [Cabal]: https://www.haskell.org/cabal/ [Stack]: https://www.haskellstack.org/+[netbase]: https://packages.debian.org/search?keywords=netbase+[1]: https://github.com/commercialhaskell/stack/issues/2372#issuecomment-234113085 Integration with CI@@ -156,7 +165,7 @@ of the latest release, i.e.: ~~~~~~~ bash- CHECKMATE_DOWNLOAD_URL=https://github.com/spoqa/checkmate/releases/download/0.3.2/checkmate-linux-x86_64+ CHECKMATE_DOWNLOAD_URL=https://github.com/dahlia/checkmate/releases/download/0.4.0/checkmate-linux-x86_64 ~~~~~~~ [personal API tokens]: https://github.com/blog/1509-personal-api-tokens
app/Main.hs view
@@ -1,10 +1,7 @@ {-# LANGUAGE OverloadedStrings #-}-import Control.Monad import Data.List (elemIndices) import Data.List.NonEmpty (nonEmpty, last)-import Data.Maybe import Data.Semigroup ((<>))-import Prelude hiding (error) import System.Environment import System.Exit import System.IO
checkmate.cabal view
@@ -1,29 +1,30 @@--- This file has been generated from package.yaml by hpack version 0.17.1.+-- This file has been generated from package.yaml by hpack version 0.28.2. -- -- see: https://github.com/sol/hpack+--+-- hash: 283f7df21c88e26a8b798e9c1a8fc53f126eebb02ca0906b89696f2f25f90eca name: checkmate-version: 0.3.2+version: 0.4.0 synopsis: Generate checklists relevant to a given patch category: Development stability: alpha-homepage: https://github.com/spoqa/checkmate#readme-bug-reports: https://github.com/spoqa/checkmate/issues+homepage: https://github.com/dahlia/checkmate#readme+bug-reports: https://github.com/dahlia/checkmate/issues author: Hong Minhee maintainer: hong.minhee@gmail.com-copyright: (c) 2017 Hong Minhee+copyright: © 2017–2018 Hong Minhee license: AGPL-3 license-file: LICENSE build-type: Simple cabal-version: >= 1.10- extra-source-files: CHANGELOG.md README.md source-repository head type: git- location: https://github.com/spoqa/checkmate+ location: https://github.com/dahlia/checkmate flag static description: Static link@@ -31,106 +32,112 @@ default: False library- hs-source-dirs:- src- ghc-options: -Wall -fwarn-incomplete-uni-patterns- build-depends:- base >= 4.7 && < 5- , diff-parse >= 0.2.1 && < 0.3.0- , directory == 1.3.*- , filepath >= 1.4.1.1 && < 2.0.0- , megaparsec >= 5.3.1 && < 5.4.0- , range >= 0.1.2 && < 0.2.0- , text == 1.*- , containers >= 0.5.7.1 && < 0.6.0.0- , github == 0.17.*- , monad-parallel >= 0.7.2.2 && < 0.8.0.0 exposed-modules: Checkmate.Check- Checkmate.Diff Checkmate.Discover Checkmate.Parser.CheckFile Checkmate.Parser.IndentBlock Checkmate.Publisher.GitHub+ Checkmate.Range Checkmate.Renderer+ other-modules:+ Paths_checkmate+ hs-source-dirs:+ src+ ghc-options: -Wall -fwarn-incomplete-uni-patterns+ build-depends:+ base >=4.7 && <5+ , containers >=0.5.7.1 && <0.6.0.0+ , diff-parse >=0.2.1 && <0.3.0+ , directory ==1.3.*+ , filepath >=1.4.1.1 && <2.0.0+ , github ==0.19.*+ , megaparsec ==6.5.*+ , monad-parallel >=0.7.2.2 && <0.8.0.0+ , text ==1.*+ if os(darwin)+ ghc-options: -Wwarn -optP-Wno-nonportable-include-path+ else+ ghc-options: -Wwarn default-language: Haskell2010 executable checkmate main-is: Main.hs+ other-modules:+ Paths_checkmate hs-source-dirs: app- ghc-options: -Wall build-depends:- base >= 4.7 && < 5- , diff-parse >= 0.2.1 && < 0.3.0- , directory == 1.3.*- , filepath >= 1.4.1.1 && < 2.0.0- , megaparsec >= 5.3.1 && < 5.4.0- , range >= 0.1.2 && < 0.2.0- , text == 1.*+ base >=4.7 && <5 , checkmate- , optparse-applicative >= 0.13.2.0 && < 0.15.0.0- , process >= 1.4.3.0 && < 1.5.0.0+ , diff-parse >=0.2.1 && <0.3.0+ , directory ==1.3.*+ , filepath >=1.4.1.1 && <2.0.0+ , megaparsec ==6.5.*+ , optparse-applicative >=0.13.2.0 && <0.15.0.0+ , process >=1.6.1.0 && <1.7.0.0+ , text ==1.*+ if os(darwin)+ ghc-options: -Wwarn -optP-Wno-nonportable-include-path+ else+ ghc-options: -Wwarn if flag(static)- ghc-options: -fwarn-incomplete-uni-patterns -threaded -rtsopts -with-rtsopts=-N -static -optl-static -optl-pthread -optc-Os -fPIC+ ghc-options: -Wall -fwarn-incomplete-uni-patterns -threaded -rtsopts -with-rtsopts=-N -static -optl-static -optl-pthread -optc-Os -fPIC else- ghc-options: -fwarn-incomplete-uni-patterns -threaded -rtsopts -with-rtsopts=-N+ ghc-options: -Wall -fwarn-incomplete-uni-patterns -threaded -rtsopts -with-rtsopts=-N default-language: Haskell2010 test-suite hlint type: exitcode-stdio-1.0- main-is: HLint.hs- hs-source-dirs:- test- ghc-options: -Wall+ main-is: hlint.hs+ other-modules:+ Paths_checkmate build-depends:- base >= 4.7 && < 5- , diff-parse >= 0.2.1 && < 0.3.0- , directory == 1.3.*- , filepath >= 1.4.1.1 && < 2.0.0- , megaparsec >= 5.3.1 && < 5.4.0- , range >= 0.1.2 && < 0.2.0- , text == 1.*- , hlint >= 2.0.9 && < 3+ base >=4.7 && <5+ , diff-parse >=0.2.1 && <0.3.0+ , directory ==1.3.*+ , filepath >=1.4.1.1 && <2.0.0+ , hlint >=2.0.9 && <3+ , megaparsec ==6.5.*+ , text ==1.*+ if os(darwin)+ ghc-options: -Wwarn -optP-Wno-nonportable-include-path+ else+ ghc-options: -Wwarn+ default-language: Haskell2010++test-suite spec+ type: exitcode-stdio-1.0+ main-is: Main.hs other-modules: Checkmate.CheckSpec- Checkmate.DiffSpec Checkmate.DiscoverSpec Checkmate.Parser.CheckFileSpec Checkmate.Parser.IndentBlockSpec+ Checkmate.RangeSpec Checkmate.RendererSpec- Spec- default-language: Haskell2010--test-suite spec- type: exitcode-stdio-1.0- main-is: Spec.hs+ Paths_checkmate hs-source-dirs: test ghc-options: -Wall -fno-warn-incomplete-uni-patterns -fno-warn-missing-signatures -rtsopts -threaded -with-rtsopts=-N -Wno-orphans build-depends:- base >= 4.7 && < 5- , diff-parse >= 0.2.1 && < 0.3.0- , directory == 1.3.*- , filepath >= 1.4.1.1 && < 2.0.0- , megaparsec >= 5.3.1 && < 5.4.0- , range >= 0.1.2 && < 0.2.0- , text == 1.*- , bytestring >= 0.10.8.1 && < 0.11+ QuickCheck >=2.9.2 && <3.0.0+ , base >=4.7 && <5+ , bytestring >=0.10.8.1 && <0.11 , checkmate- , file-embed >= 0.0.10 && < 0.1.0- , hspec >= 2.4.4 && < 3.0.0- , hspec-megaparsec >= 0.3.1 && < 0.4.0- , interpolatedstring-perl6 == 1.*- , QuickCheck >= 2.9.2 && < 3.0.0- , quickcheck-text >= 0.1.2.1 && < 0.2.0.0- , temporary >= 1.2.1 && < 1.3.0.0- other-modules:- Checkmate.CheckSpec- Checkmate.DiffSpec- Checkmate.DiscoverSpec- Checkmate.Parser.CheckFileSpec- Checkmate.Parser.IndentBlockSpec- Checkmate.RendererSpec- HLint+ , diff-parse >=0.2.1 && <0.3.0+ , directory ==1.3.*+ , file-embed >=0.0.10 && <0.1.0+ , filepath >=1.4.1.1 && <2.0.0+ , hspec >=2.4.4 && <3.0.0+ , hspec-megaparsec >=1.0.0 && <1.1.0+ , interpolatedstring-perl6 ==1.*+ , megaparsec ==6.5.*+ , quickcheck-text >=0.1.2.1 && <0.2.0.0+ , temporary >=1.2.1 && <1.3.0.0+ , text ==1.*+ if os(darwin)+ ghc-options: -Wwarn -optP-Wno-nonportable-include-path+ else+ ghc-options: -Wwarn default-language: Haskell2010
+ hlint.hs view
@@ -0,0 +1,12 @@+import Language.Haskell.HLint+import System.Exit++arguments :: [String]+arguments = ["app", "src", "test"]++main :: IO ()+main = do+ hlints <- hlint arguments+ case hlints of+ [] -> exitSuccess+ _ -> exitFailure
src/Checkmate/Check.hs view
@@ -7,11 +7,12 @@ import Data.Set import Data.Text-import Data.Range.Range hiding (union) import System.FilePath +import Checkmate.Range+ data Scope- = FileBlock { scopePath :: FilePath, scopeRange :: Range Int }+ = FileBlock { scopePath :: FilePath, scopeRange :: Range } | Directory { scopePath :: FilePath } deriving (Show)
− src/Checkmate/Diff.hs
@@ -1,11 +0,0 @@-module Checkmate.Diff- ( rangeFromDiffRange- ) where--import Data.Range.Range as Range-import Text.Diff.Parse.Types as DT--rangeFromDiffRange :: DT.Range -> Range.Range Int-rangeFromDiffRange (DT.Range start lineLen)- | lineLen < 2 = Range.SingletonRange start- | otherwise = Range.SpanRange start $ start + (lineLen - 1)
src/Checkmate/Discover.hs view
@@ -6,8 +6,9 @@ , parseDiff ) where +import System.IO.Error+ import Control.Monad.Parallel as P-import Data.Range.Range as Range import Data.Set as S import Data.Text import System.Directory@@ -16,9 +17,9 @@ import Text.Diff.Parse.Types import Checkmate.Check-import Checkmate.Diff import Checkmate.Parser.CheckFile import Checkmate.Parser.IndentBlock+import Checkmate.Range checkFileNames :: Set FilePath checkFileNames = fromList@@ -69,7 +70,10 @@ discoverFile baseDirPath FileDelta { fileDeltaContent = Hunks hunks , fileDeltaDestFile = filePathT } = do- result <- parseSourceFile filePath+ result <- catchIOError (parseSourceFile filePath) $ \ e ->+ if isDoesNotExistError e+ then return $ Right S.empty+ else ioError e return $ case result of Left _ -> S.empty Right checklist -> fromList@@ -80,5 +84,5 @@ where filePath :: FilePath filePath = baseDirPath </> unpack filePathT- ranges :: [Range.Range Int]- ranges = [rangeFromDiffRange r | Hunk { hunkDestRange = r } <- hunks]+ ranges :: [Range]+ ranges = [r | Hunk { hunkDestRange = r } <- hunks]
src/Checkmate/Parser/CheckFile.hs view
@@ -1,29 +1,33 @@+{-# LANGUAGE OverloadedStrings #-} module Checkmate.Parser.CheckFile- ( parseCheckFile+ ( ParseError+ , parseCheckFile , parseCheckFileText , parser ) where import Control.Monad+import Data.Void import Data.Set import qualified Data.Text as T import Data.Text.IO import System.FilePath-import Text.Megaparsec-import Text.Megaparsec.Text+import Text.Megaparsec hiding (ParseError)+import Text.Megaparsec.Char+import qualified Text.Megaparsec.Error as E import Checkmate.Check -parseCheckFile :: FilePath- -> IO (Either (ParseError (Token T.Text) Dec) Checklist)+type Parser = Parsec Void T.Text+type ParseError = E.ParseError Char Void++parseCheckFile :: FilePath -> IO (Either ParseError Checklist) parseCheckFile filePath = do input <- Data.Text.IO.readFile filePath return $ parseCheckFileText filePath input -parseCheckFileText :: FilePath- -> T.Text- -> Either (ParseError (Token T.Text) Dec) Checklist+parseCheckFileText :: FilePath -> T.Text -> Either ParseError Checklist parseCheckFileText filePath = parse (parser $ takeDirectory filePath) filePath @@ -53,7 +57,7 @@ checkP = do bulletP texts <- (`sepBy1` try (eol >> notFollowedBy bulletP)) $ do- chars <- many $ noneOf "\n"+ chars <- many $ noneOf ['\n'] return $ T.pack chars let texts' = texts :: [T.Text] return $ T.strip $ T.intercalate (T.singleton '\n') texts'
src/Checkmate/Parser/IndentBlock.hs view
@@ -1,30 +1,34 @@+{-# LANGUAGE OverloadedStrings #-} module Checkmate.Parser.IndentBlock- ( parser+ ( ParseError+ , parser , parseSourceCode , parseSourceFile ) where import Control.Monad import Data.List+import Data.Void -import Data.Range.Range import Data.Set import Data.Text import Data.Text.IO-import Text.Megaparsec-import Text.Megaparsec.Text+import Text.Megaparsec hiding (ParseError)+import Text.Megaparsec.Char+import qualified Text.Megaparsec.Error as E import Checkmate.Check+import Checkmate.Range -parseSourceFile :: FilePath- -> IO (Either (ParseError (Token Text) Dec) Checklist)+type Parser = Parsec Void Text+type ParseError = E.ParseError Char Void++parseSourceFile :: FilePath -> IO (Either ParseError Checklist) parseSourceFile filePath = do input <- Data.Text.IO.readFile filePath return $ parseSourceCode filePath input -parseSourceCode :: FilePath- -> Text- -> Either (ParseError (Token Text) Dec) Checklist+parseSourceCode :: FilePath -> Text -> Either ParseError Checklist parseSourceCode = parse parser data Line = CheckComment Text | Line | EmptyLine deriving (Eq, Ord, Show)@@ -40,43 +44,43 @@ ] return $ Data.Set.fromList checks where- mkRange :: (Int, Int) -> Range Int+ mkRange :: (Int, Int) -> Range mkRange (from, to)- | from >= to = SingletonRange from- | otherwise = SpanRange from to+ | from >= to = Range from 1+ | otherwise = Range from (to - from + 1) indent :: Parser Int indent = choice [ tab >> return 8 , char ' ' >> return 1 ] someSpaces :: Parser ()- someSpaces = skipMany $ oneOf " \t"+ someSpaces = skipMany $ oneOf [' ', '\t'] checkKeyword :: Parser () checkKeyword = void $ string "CHECK" checkThenSpaces :: Parser () checkThenSpaces = do checkKeyword- (char ':' >> someSpaces) <|> skipSome (oneOf " \t")- lineCommentStart :: Parser String+ (char ':' >> someSpaces) <|> skipSome (oneOf [' ', '\t'])+ lineCommentStart :: Parser Text lineCommentStart = choice- [ do { c <- oneOf "#%'"; return [c] }- , string "//"- , string "--"- ]+ [ Data.Text.singleton <$> oneOf ['#', '%']+ , string "//"+ , string "--"+ ] lineCommentCheck :: Parser Text lineCommentCheck = do startSeq <- lineCommentStart someSpaces checkThenSpaces- chars <- many $ noneOf "\n"+ chars <- many $ noneOf ['\n'] nextLines <- many $ try $ do void eol someSpaces void $ string startSeq someSpaces- many $ noneOf "\n"+ many $ noneOf ['\n'] return $ stripEnd $ pack $ Data.List.unlines $ chars : nextLines- blockCommentPairs :: [(String, String)]+ blockCommentPairs :: [(Text, Text)] blockCommentPairs = [ ("/*", "*/"), ("{-", "-}"), ("<!--", "-->"), ("<#", "#>") , ("%{", "%}")@@ -84,11 +88,11 @@ blockCommentCheck :: Int -> Parser Text blockCommentCheck depth = choice $ fmap (blockComment depth) blockCommentPairs- blockComment :: Int -> (String, String) -> Parser Text+ blockComment :: Int -> (Text, Text) -> Parser Text blockComment depth (start, end) = do void $ string start linebreaks <- many $ try $ do- skipMany $ oneOf " \t\r"+ skipMany $ oneOf [' ', '\t', '\r'] char '\n' innerDepth <- many indent checkThenSpaces@@ -105,7 +109,7 @@ lineT <- choice [ try $ fmap CheckComment lineCommentCheck , try $ CheckComment <$> blockCommentCheck depth- , try (some (noneOf "\n") >> return Line)+ , try (some (noneOf ['\n']) >> return Line) , return EmptyLine ] return (filePath, read . show . unPos $ lineNo, depth, lineT)
+ src/Checkmate/Range.hs view
@@ -0,0 +1,11 @@+module Checkmate.Range+ ( Range (..)+ , rangesOverlap+ ) where++import Text.Diff.Parse.Types++rangesOverlap :: Range -> Range -> Bool+rangesOverlap (Range aFrom aLen) (Range bFrom bLen) =+ aFrom <= bFrom && bFrom < aFrom + aLen ||+ bFrom <= aFrom && aFrom < bFrom + bLen
src/Checkmate/Renderer.hs view
@@ -7,7 +7,7 @@ import Data.List import Data.Set-import Data.Text hiding (groupBy, isSuffixOf, zip)+import Data.Text hiding (groupBy, zip) import System.FilePath import Checkmate.Check
test/Checkmate/CheckSpec.hs view
@@ -1,24 +1,23 @@ {-# LANGUAGE FlexibleInstances #-} module Checkmate.CheckSpec (spec) where -import Data.Range.Range import System.FilePath import Test.Hspec import Checkmate.Check+import Checkmate.Range spec :: Spec spec = describe "Scope" $ do let p = "foo" </> "bar"- r = SingletonRange 1+ r = Range 1 1 it "doesn't equal if two values' data constructors are different" $ do FileBlock p r `shouldNotBe` Directory p FileBlock p r `shouldNotBe` Directory (p </> "baz") it "doesn't equal if two FileBlocks have different scopeRange" $ do- FileBlock p r `shouldNotBe` FileBlock p (SingletonRange 2)- FileBlock p r `shouldNotBe`- FileBlock (p </> "baz") (SingletonRange 2)+ FileBlock p r `shouldNotBe` FileBlock p (Range 2 1)+ FileBlock p r `shouldNotBe` FileBlock (p </> "baz") (Range 2 1) it "equals if two values' scopePaths refer to the same path" $ do Directory p `shouldBe` Directory p FileBlock p r `shouldBe` FileBlock p r
− test/Checkmate/DiffSpec.hs
@@ -1,24 +0,0 @@-module Checkmate.DiffSpec (spec) where--import Data.Range.Range as Range-import Test.Hspec-import Test.QuickCheck-import Text.Diff.Parse.Types as DT--import Checkmate.Diff (rangeFromDiffRange)--instance Arbitrary DT.Range where- arbitrary = do- NonZero start <- arbitrary- NonZero lineLen <- arbitrary- return $ DT.Range (abs start) (abs lineLen)--spec :: Spec-spec =- specify "rangeFromDiffRange" $ property $ \ dr@(DT.Range start lineLen) ->- let r = rangeFromDiffRange dr- in- Range.inRange r start &&- not (Range.inRange r $ start - 1) &&- Range.inRange r (start + lineLen - 1) &&- not (Range.inRange r $ start + lineLen)
test/Checkmate/DiscoverSpec.hs view
@@ -7,7 +7,6 @@ import Data.ByteString import Data.FileEmbed-import Data.Range.Range (Range (..)) import Data.Text import System.Directory import System.FilePath@@ -65,19 +64,19 @@ pyChecklistFixture :: FilePath -> Checklist pyChecklistFixture d = [ Check { checkScope = FileBlock { scopePath = pyPath- , scopeRange = SpanRange 2 25+ , scopeRange = Range 2 24 } , checkOrderIndex = 1 , checkText = "module-level check" } , Check { checkScope = FileBlock { scopePath = pyPath- , scopeRange = SpanRange 11 15+ , scopeRange = Range 11 5 } , checkOrderIndex = 3 , checkText = "function-level check 2" } , Check { checkScope = FileBlock { scopePath = pyPath- , scopeRange = SpanRange 14 15+ , scopeRange = Range 14 2 } , checkOrderIndex = 4 , checkText = "nested function-level check"@@ -90,19 +89,19 @@ jsChecklistFixture :: FilePath -> Checklist jsChecklistFixture d = [ Check { checkScope = FileBlock { scopePath = jsPath- , scopeRange = SpanRange 2 21+ , scopeRange = Range 2 20 } , checkOrderIndex = 1 , checkText = "global check" } , Check { checkScope = FileBlock { scopePath = jsPath- , scopeRange = SpanRange 10 20+ , scopeRange = Range 10 11 } , checkOrderIndex = 3 , checkText = "function-level check 2" } , Check { checkScope = FileBlock { scopePath = jsPath- , scopeRange = SpanRange 13 17+ , scopeRange = Range 13 5 } , checkOrderIndex = 4 , checkText = "closure check.\nIt can be multiline."@@ -112,9 +111,12 @@ jsPath :: FilePath jsPath = d </> "subdir" </> "inner_sample.js" +withTempDir :: (FilePath -> IO a) -> IO a+withTempDir = withSystemTempDirectory "checkmate-test"+ withFixtureDir :: (FilePath -> IO a) -> IO a withFixtureDir action =- withSystemTempDirectory "checkmate-test" $ \ dirPath -> do+ withTempDir $ \ dirPath -> do forM_ fixtures $ \ (filePath, contents) -> do let path = dirPath </> filePath parent = takeDirectory path@@ -125,22 +127,39 @@ spec :: Spec spec = do- specify "discover" $- withFixtureDir $ \ dirPath -> do- checklist <- discover dirPath diffFixture- let expected = subdirChecklistFixture dirPath- `union` pyChecklistFixture dirPath- `union` jsChecklistFixture dirPath- checklist `shouldBe` expected- specify "discoverDirectory" $- withFixtureDir $ \ dirPath -> do- subdirChecks <- discoverDirectory dirPath "subdir"- subdirChecks `shouldBe` subdirChecklistFixture dirPath- rootChecks <- discoverDirectory dirPath "."- rootChecks `shouldBe` rootChecklistFixture dirPath- specify "discoverFile" $- withFixtureDir $ \ dirPath -> do- pyChecks <- discoverFile dirPath $ Prelude.head diffFixture- pyChecks `shouldBe` pyChecklistFixture dirPath- jsChecks <- discoverFile dirPath $ Prelude.last diffFixture- jsChecks `shouldBe` jsChecklistFixture dirPath+ describe "discover" $ do+ it "scans all relative checks" $+ withFixtureDir $ \ dirPath -> do+ checklist <- discover dirPath diffFixture+ let expected = subdirChecklistFixture dirPath+ `union` pyChecklistFixture dirPath+ `union` jsChecklistFixture dirPath+ checklist `shouldBe` expected+ it "ignores files/directories that do not exist" $+ withTempDir $ \ dirPath -> do+ checklist <- discover dirPath diffFixture+ checklist `shouldBe` []+ describe "discoverDirectory" $ do+ it "lists files in the given path" $+ withFixtureDir $ \ dirPath -> do+ subdirChecks <- discoverDirectory dirPath "subdir"+ subdirChecks `shouldBe` subdirChecklistFixture dirPath+ rootChecks <- discoverDirectory dirPath "."+ rootChecks `shouldBe` rootChecklistFixture dirPath+ it "ignores files/directories that do not exist" $+ withTempDir $ \ dirPath -> do+ checks <- discoverDirectory+ (dirPath </> "dir-do-not-exist")+ "dir-do-not-exist"+ checks `shouldBe` []+ describe "discoverFile" $ do+ it "scans all relative checks" $+ withFixtureDir $ \ dirPath -> do+ pyChecks <- discoverFile dirPath $ Prelude.head diffFixture+ pyChecks `shouldBe` pyChecklistFixture dirPath+ jsChecks <- discoverFile dirPath $ Prelude.last diffFixture+ jsChecks `shouldBe` jsChecklistFixture dirPath+ it "ignores files/directories that do not exist" $+ withTempDir $ \ dirPath -> do+ checklist <- discoverFile dirPath $ Prelude.head diffFixture+ checklist `shouldBe` []
test/Checkmate/Parser/CheckFileSpec.hs view
@@ -11,7 +11,7 @@ import Test.Hspec import Test.Hspec.Megaparsec import Text.InterpolatedString.Perl6-import Text.Megaparsec+import Text.Megaparsec hiding (ParseError) import System.FilePath import System.IO.Temp @@ -32,9 +32,7 @@ return (takeDirectory filePath, result) parserSpec :: String- -> ( Text -> IO ( FilePath- , Either (ParseError (Token Text) Dec) Checklist- )+ -> ( Text -> IO (FilePath, Either ParseError Checklist) ) -> Spec parserSpec specName parseFn =@@ -98,9 +96,7 @@ , Check dir 7 "d" ] where- parse' :: Text -> IO ( Scope- , Either (ParseError (Token Text) Dec) Checklist- )+ parse' :: Text -> IO (Scope, Either ParseError Checklist) parse' text = do (dir, result) <- parseFn text return (Directory dir, result)
test/Checkmate/Parser/IndentBlockSpec.hs view
@@ -7,17 +7,17 @@ import System.IO (hClose) import Data.FileEmbed-import Data.Range.Range import Data.Text import Data.Text.IO import Text.InterpolatedString.Perl6 import Test.Hspec import Test.Hspec.Megaparsec-import Text.Megaparsec+import Text.Megaparsec hiding (ParseError) import System.IO.Temp import Checkmate.Check import Checkmate.Parser.IndentBlock+import Checkmate.Range pythonFixture :: Text pythonFixture = $(embedStringFile "test/fixtures/sample.py")@@ -47,14 +47,13 @@ return true; |] parsed `shouldParse`- [ Check (FileBlock "a.js" $ SpanRange 3 8) 1+ [ Check (FileBlock "a.js" $ Range 3 6) 1 "multiline\ntest\ntest2" ] -parserSpec- :: String- -> (Text -> IO (FilePath, Either (ParseError (Token Text) Dec) Checklist))- -> Spec+parserSpec :: String+ -> (Text -> IO (FilePath, Either ParseError Checklist))+ -> Spec parserSpec specName parse' = describe specName $ do it "returns an empty set if a given text is empty" $ do (_, parsed) <- parse' ""@@ -63,11 +62,11 @@ (path, parsed) <- parse' pythonFixture let s = FileBlock path parsed `shouldParse`- [ Check (s $ SpanRange 2 25) 1 "module-level check"- , Check (s $ SpanRange 6 7) 2 "function-level check"- , Check (s $ SpanRange 11 15) 3 "function-level check 2"- , Check (s $ SpanRange 14 15) 4 "nested function-level check"- , Check (s $ SpanRange 19 25) 5 "class-level check"- , Check (s $ SpanRange 23 25) 6+ [ Check (s $ Range 2 24) 1 "module-level check"+ , Check (s $ Range 6 2) 2 "function-level check"+ , Check (s $ Range 11 5) 3 "function-level check 2"+ , Check (s $ Range 14 2) 4 "nested function-level check"+ , Check (s $ Range 19 7) 5 "class-level check"+ , Check (s $ Range 23 3) 6 "method-level check.\nIt can be multiline." ]
+ test/Checkmate/RangeSpec.hs view
@@ -0,0 +1,13 @@+module Checkmate.RangeSpec where++import Test.Hspec++import Checkmate.Range++spec :: Spec+spec =+ specify "rangesOverlap" $ do+ Range 7 10 `shouldSatisfy` rangesOverlap (Range 5 5)+ Range 5 5 `shouldSatisfy` rangesOverlap (Range 7 10)+ Range 3 3 `shouldNotSatisfy` rangesOverlap (Range 7 10)+ Range 7 10 `shouldNotSatisfy` rangesOverlap (Range 3 3)
test/Checkmate/RendererSpec.hs view
@@ -3,13 +3,13 @@ {-# LANGUAGE QuasiQuotes #-} module Checkmate.RendererSpec where -import Data.Range.Range import Data.Text import System.FilePath import Test.Hspec import Text.InterpolatedString.Perl6 import Checkmate.Check+import Checkmate.Range import Checkmate.Renderer fixture :: Checklist@@ -20,9 +20,9 @@ "consectetur adipiscing elit," , Check (Directory $ "b" </> "foo" </> "bar" </> ".") 3 "sed do eiusmod tempor incididunt ut labore et dolore magna aliqua."- , Check (FileBlock ("b" </> "foo" </> "bar" </> "baz.c") $ SpanRange 8 21) 1+ , Check (FileBlock ("b" </> "foo" </> "bar" </> "baz.c") $ Range 8 21) 1 "Ut enim ad minim veniam,"- , Check (FileBlock ("b" </> "foo" </> "bar" </> "baz.c") $ SpanRange 9 21)+ , Check (FileBlock ("b" </> "foo" </> "bar" </> "baz.c") $ Range 9 21) 2 $ "quis nostrud exercitation ullamco laboris nisi ut\n" `append` "aliquip ex ea commodo consequat."
− test/HLint.hs
@@ -1,12 +0,0 @@-import Language.Haskell.HLint-import System.Exit--arguments :: [String]-arguments = ["app", "src", "test"]--main :: IO ()-main = do- hlints <- hlint arguments- case hlints of- [] -> exitSuccess- _ -> exitFailure
+ test/Main.hs view
@@ -0,0 +1,1 @@+{-# OPTIONS_GHC -F -pgmF hspec-discover #-}
− test/Spec.hs
@@ -1,1 +0,0 @@-{-# OPTIONS_GHC -F -pgmF hspec-discover #-}