packages feed

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 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 #-}