hpc-codecov 0.5.0.0 → 0.6.0.0
raw patch · 22 files changed
+352/−56 lines, 22 filesPVP ok
version bump matches the API change (PVP)
API changes (from Hackage documentation)
+ Trace.Hpc.Codecov.Report: [reportExprOnly] :: Report -> Bool
+ Trace.Hpc.Codecov.Report: [reportIgnoreDittos] :: Report -> Bool
- Trace.Hpc.Codecov.Report: Report :: FilePath -> [FilePath] -> [FilePath] -> [String] -> Maybe FilePath -> Bool -> Format -> Report
+ Trace.Hpc.Codecov.Report: Report :: FilePath -> [FilePath] -> [FilePath] -> [String] -> Maybe FilePath -> Bool -> Format -> Bool -> Bool -> Report
Files
- CHANGELOG.md +15/−0
- README.md +27/−1
- hpc-codecov.cabal +22/−4
- src/Trace/Hpc/Codecov/Options.hs +35/−13
- src/Trace/Hpc/Codecov/Report/Entry.hs +71/−22
- test/Test/Main.hs +48/−15
- test/data/eo01/.hpc/Main.mix +1/−0
- test/data/eo01/eo01.hs +43/−0
- test/data/eo01/eo01.info.golden +30/−0
- test/data/eo01/eo01.json.golden +1/−0
- test/data/eo01/eo01.tix +1/−0
- test/data/ifd01/.hpc/Main.mix +1/−0
- test/data/ifd01/ifd01.hs +24/−0
- test/data/ifd01/ifd01.json.golden +1/−0
- test/data/ifd01/ifd01.tix +1/−0
- test/data/ith01/.hpc/Main.mix +1/−0
- test/data/ith01/.hpc/TH01.mix +1/−0
- test/data/ith01/TH01.hs +11/−0
- test/data/ith01/ith01.hs +15/−0
- test/data/ith01/ith01.json.golden +1/−0
- test/data/ith01/ith01.tix +1/−0
- test/data/project1/stack.yaml +1/−1
CHANGELOG.md view
@@ -1,5 +1,20 @@ # Revision history for hpc-codecov +## 0.6.0.0 -- 2024-04-26++- Add "--expr-only" option. This option will ignore other constructor+ than 'ExpBox' in 'Trace.Hpc.Mix.BoxLabel' data type when collecting+ 'Trace.Hpc.Mix.MixEntry' info.++- Add "--ignore-dittos" option. This option will remove the coverage+ info of repeated occurance of entries with identical start and end+ position.++ As of mix data format generated by ghc 9.4/9.6/9.8, this option+ removes mix entries of record field declarations, type class member+ functions in derived instances (when the member function is more+ than two), and codes generated via TemplateHaskell.+ ## 0.5.0.0 -- 2023-11-01 - Add Cobertura XML format for the generated report with
README.md view
@@ -129,6 +129,32 @@ $ hpc-codecov -X my-project -x Main,Paths_my_project cabal:my-project-test ``` +### Project using cabal-install, count expressions only++Search under the directry made by ``cabal-install``, generating a+report for a test suite named ``my-project-test``. Ignore the entries+in ``.mix`` file other than ``ExpBox`` (i.e.; ignore ``TopLevelBox``,+``LocalBox``, and ``BinBox`` constructors of+[``BoxLabel``](https://hackage.haskell.org/package/hpc-0.7.0.1/docs/Trace-Hpc-Mix.html#t:BoxLabel)+data in ``.mix`` file).++```console+$ hpc-codecov --expr-only cabal:my-project-test+```++### Project using cabal-install, ignore compiler generated source codes++Search under the directory made by ``cabal-install``, generating a+report for a test suite named ``my-projejct-test``. Ignore the+consecutive ``.mix`` entries with identical start and end source code+positions, which is a sign of compiler-generated source codes. The+``--ignore-dittos`` option may affects codes containing record field+declarations, derived instances, and TemplateHaskell.++```console+$ hpc-codecov --ignore-dittos cabal:my-project-test+```+ ### Project using stack Search under the directory made by ``stack`` for a test suite named@@ -174,7 +200,7 @@ multiple cabal packages, running via Docker: ```-$ docker run --rm -v $PWD:$PWD ghcr.io/8c6794b6/hpc-codecov /hpc-codecov -r $PWD stack:all+$ docker run --rm -v $PWD:$PWD ghcr.io/8c6794b6/hpc-codecov hpc-codecov -r $PWD stack:all ``` Low-level examples
hpc-codecov.cabal view
@@ -1,6 +1,6 @@ cabal-version: 2.0 name: hpc-codecov-version: 0.5.0.0+version: 0.6.0.0 synopsis: Generate reports from hpc data license: BSD3 license-file: LICENSE@@ -43,13 +43,31 @@ test/data/project1/test/Spec.hs test/data/project1/project1.cabal test/data/project1/stack.yaml+ --+ test/data/eo01/eo01.hs+ test/data/eo01/eo01.tix+ test/data/eo01/eo01.info.golden+ test/data/eo01/eo01.json.golden+ test/data/eo01/.hpc/Main.mix+ --+ test/data/ifd01/ifd01.hs+ test/data/ifd01/ifd01.tix+ test/data/ifd01/ifd01.json.golden+ test/data/ifd01/.hpc/Main.mix+ --+ test/data/ith01/ith01.hs+ test/data/ith01/ith01.tix+ test/data/ith01/ith01.json.golden+ test/data/ith01/TH01.hs+ test/data/ith01/.hpc/Main.mix+ test/data/ith01/.hpc/TH01.mix tested-with: GHC == 8.10.7 , GHC == 9.0.2 , GHC == 9.2.8- , GHC == 9.4.7- , GHC == 9.6.3- , GHC == 9.8.1+ , GHC == 9.4.8+ , GHC == 9.6.5+ , GHC == 9.8.2 library hs-source-dirs: src
src/Trace/Hpc/Codecov/Options.hs view
@@ -46,36 +46,46 @@ -- | Options for generating test coverage report. data Options = Options- { optTix :: FilePath+ { optTix :: FilePath -- ^ Input tix file.- , optMixDirs :: [FilePath]+ , optMixDirs :: [FilePath] -- ^ Directory containing mix files referred by the tix file.- , optSrcDirs :: [FilePath]+ , optSrcDirs :: [FilePath] -- ^ Directory containing source codes referred by the mix files.- , optExcludes :: [String]+ , optExcludes :: [String] -- ^ Module name strings to exclude from coverage report.- , optOutFile :: Maybe FilePath+ , optOutFile :: Maybe FilePath -- ^ Output file to write JSON report, if given. - , optFormat :: String+ , optFormat :: String -- ^ Format of generated report. - , optVerbose :: Bool+ , optVerbose :: Bool -- ^ Flag for showing verbose message during coverage report -- generation. - , optRootDir :: FilePath+ , optRootDir :: FilePath -- ^ Project root directory for the build tool.- , optBuildDir :: Maybe FilePath+ , optBuildDir :: Maybe FilePath -- ^ Name of the build directory used by the build tool- , optSkipDirs :: [String]+ , optSkipDirs :: [String] -- ^ Directories to ignore while discovering. - , optShowVersion :: Bool+ , optExprOnly :: Bool+ -- ^ Flag for conting 'ExpBox' entries only.+ --+ -- @since 0.6.0.0+ , optIgnoreDittos :: Bool+ -- ^ Flag for ignoring repeated entries with the same source code+ -- positions.+ --+ -- @since 0.6.0.0++ , optShowVersion :: Bool -- ^ Flag for showing version.- , optShowNumeric :: Bool+ , optShowNumeric :: Bool -- ^ Flag for showing numeric version.- , optShowHelp :: Bool+ , optShowHelp :: Bool -- ^ Flag for showing help message. } @@ -92,6 +102,8 @@ , optRootDir = "" , optBuildDir = Nothing , optSkipDirs = []+ , optExprOnly = False+ , optIgnoreDittos = False , optShowVersion = False , optShowNumeric = False , optShowHelp = False@@ -153,6 +165,14 @@ \'codecov', 'lcov', or 'cobertura'\n\ \(default: codecov)" + , Option [] ["expr-only"]+ (NoArg (\o -> o {optExprOnly = True}))+ "Count expressions only"+ , Option [] ["ignore-dittos"]+ (NoArg (\o -> o {optIgnoreDittos = True}))+ "Ignore consecutive entries with the\n\+ \same source code positions"+ , Option ['v'] ["verbose"] (NoArg (\o -> o {optVerbose = True})) "Show verbose output"@@ -237,6 +257,8 @@ , reportExcludes = optExcludes opt , reportOutFile = optOutFile opt , reportVerbose = verbose+ , reportExprOnly = optExprOnly opt+ , reportIgnoreDittos = optIgnoreDittos opt } tix = optTix opt verbose = optVerbose opt
src/Trace/Hpc/Codecov/Report/Entry.hs view
@@ -66,22 +66,36 @@ -- | Data type to hold information for generating test coverage -- report. data Report = Report- { reportTix :: FilePath+ { reportTix :: FilePath -- ^ Input tix file.- , reportMixDirs :: [FilePath]+ , reportMixDirs :: [FilePath] -- ^ Directories containing mix files referred by the tix file.- , reportSrcDirs :: [FilePath]+ , reportSrcDirs :: [FilePath] -- ^ Directories containing source codes referred by the mix files.- , reportExcludes :: [String]+ , reportExcludes :: [String] -- ^ Module name strings to exclude from coverage report.- , reportOutFile :: Maybe FilePath+ , reportOutFile :: Maybe FilePath -- ^ Output file to write report data, if given.- , reportVerbose :: Bool+ , reportVerbose :: Bool -- ^ Flag for showing verbose message during report generation.- , reportFormat :: Format+ , reportFormat :: Format -- ^ Format of the report output. -- -- @since 0.4.0.0+ , reportExprOnly :: Bool+ -- ^ Flag for ignoring other data than 'ExpBox' entries in mix+ -- files.+ --+ -- @since 0.6.0.0+ , reportIgnoreDittos :: Bool+ -- ^ Flag for ignoring some of the compiler generated source codes.+ --+ -- As of the @.mix@ file generated by ghc 9.{4,6,8}, record field+ -- declarations, class names with more than two member functions in+ -- @deriving(..)@ clauses, and top-level TemplateHaskell splices+ -- are known to be ignored.+ --+ -- @since 0.6.0.0 } deriving (Eq, Show) instance Semigroup Report where@@ -99,6 +113,8 @@ , reportOutFile = Nothing , reportVerbose = False , reportFormat = Codecov+ , reportExprOnly = False+ , reportIgnoreDittos = False } mappendReport :: Report -> Report -> Report@@ -111,6 +127,8 @@ , reportOutFile = extend (<|>) reportOutFile , reportVerbose = extend (||) reportVerbose , reportFormat = reportFormat r2+ , reportExprOnly = extend (||) reportExprOnly+ , reportIgnoreDittos = extend (||) reportIgnoreDittos } -- | Single file entry in coverage report.@@ -191,7 +209,11 @@ say rpt ("Searching mix: " ++ name) Mix path _ _ _ entries <- readMixFile (reportMixDirs rpt) tm say rpt ("Found mix: " ++ path)- let Info _ min_line max_line hits fns pre_brs = makeInfo count ixs entries+ let (num_removed, ixs', entries')+ | reportIgnoreDittos rpt = removeDittoEntries ixs entries+ | otherwise = (0, ixs, entries)+ Info _ min_line max_line hits fns pre_brs =+ makeInfo (reportExprOnly rpt) (count - num_removed) ixs' entries' lineHits = makeLineHits min_line max_line hits path' <- ensureSrcPath rpt path return (CoverageEntry { ce_filename = path'@@ -241,6 +263,29 @@ then say rpt ("Found source: " ++ path') >> return path' else go (path':acc) dirs +-- | Remove consequent non-'BinBox' entries from given tix and mix+-- entries with identical source code positions. Returns a triple of+-- (number_of_removed_entries, filtered_tix, filtered_mix).+removeDittoEntries+ :: [Integer] -> [MixEntry] -> (Int, [Integer], [MixEntry])+removeDittoEntries = go Nothing (0, [], [])+ where+ go Nothing (n, rixs, rmes) (_:_:ixs) (m1:m2:mes)+ | isDitto m1 m2 = go (Just m1) (n+2, rixs, rmes) ixs mes++ go Nothing (n, rixs, rmes) (i:ixs) (m:mes) =+ go Nothing (n, i:rixs, m:rmes) ixs mes++ go (Just removed) acc@(n, rixs, rmes) (i:ixs) (m:mes)+ | isDitto removed m = go (Just m) (n+1, rixs, rmes) ixs mes+ | otherwise = go Nothing acc (i:ixs) (m:mes)++ go _ (n, rixs, rmes) _ _ =+ (n, reverse rixs, reverse rmes)++ isDitto (_, BinBox {}) _ = False+ isDitto (p1, _) (p2, _) = p1 == p2+ -- | Arrange branch hit information. -- -- LCOV tracefile seems like want to have a true branch before the@@ -334,33 +379,37 @@ ticked = full -- See also: "utils/hpc/HpcMarkup.hs" in "ghc" git repository.-makeInfo :: Int -> [Integer] -> [MixEntry] -> Info-makeInfo size tixs = foldl' f z+makeInfo :: Bool -> Int -> [Integer] -> [MixEntry] -> Info+makeInfo expr_only size tixs = foldl' f z where z = Info 0 maxBound 0 [] [] [] f (Info i0 min_line max_line txs fns brs) (pos, boxLabel) = let binBox = case (isTicked i0, isTicked i1) of (False, False) -> txs- (True, False) -> (sl, partial, numTicked i0) : txs+ (True, False) -> (sl, partial, numTicked_i0) : txs (False, True) -> (sl, partial, numTicked i1) : txs (True, True) -> txs tickBox = let t | isTicked i0 = ticked | otherwise = notTicked- in (sl, t, numTicked i0) : txs- tlBox ns = (sl, el, numTicked i0, intercalate "." ns) : fns- br bool = (sl, bool, numTicked i0)- (txs', fns', brs') =- case boxLabel of- ExpBox {} -> (tickBox, fns, brs)- TopLevelBox ns -> (tickBox, tlBox ns, brs)- LocalBox {} -> (tickBox, fns, brs)- BinBox _ True -> (binBox, fns, br True : brs)- BinBox _ False -> (txs, fns, br False : brs)+ in (sl, t, numTicked_i0) : txs+ tlBox ns = (sl, el, numTicked_i0, intercalate "." ns) : fns+ br bool = (sl, bool, numTicked_i0)+ numTicked_i0 = numTicked i0+ (txs', fns', brs')+ | expr_only = case boxLabel of+ ExpBox {} -> (tickBox, fns, brs)+ _ -> (txs, fns, brs)+ | otherwise = case boxLabel of+ ExpBox {} -> (tickBox, fns, brs)+ TopLevelBox ns -> (tickBox, tlBox ns, brs)+ LocalBox {} -> (tickBox, fns, brs)+ BinBox _ True -> (binBox, fns, br True : brs)+ BinBox _ False -> (txs, fns, br False : brs) (sl, _, el, _) = fromHpcPos pos i1 = i0 + 1- in Info i1 (min sl min_line) (max el max_line) txs' fns' brs'+ in Info i1 (min sl min_line) (max el max_line) txs' fns' brs' -- Hope that the mix file does not contain out of bound index. numTicked = unsafeAt arr_tix
test/Test/Main.hs view
@@ -23,7 +23,7 @@ -- filepath import System.FilePath (joinPath, takeFileName,- (</>))+ (<.>), (</>)) -- directory import System.Directory (canonicalizePath,@@ -82,6 +82,7 @@ defaultMain $ testGroup "main" $ [reportTest, cmdline, recipReport, exceptionTest, parserTest] +++ [exprOnly, ignoreDittos] ++ [selfReportTest | not test_in_test, isJust mb_tool] ++ [discoverStackTest | not test_in_test, mb_tool == Just Stack] ++ [discoverCabalTest | not test_in_test, mb_tool == Just Cabal]@@ -130,6 +131,7 @@ r3 = r1 <> r2 assertEqual "<> for verbose" (reportVerbose r3) True assertEqual "<> for excludes" (reportExcludes r3) ["M1","M2","M3"]+ assertEqual "default format" (reportFormat mempty) Codecov ] cmdline :: TestTree@@ -184,6 +186,41 @@ ,"test/data/reciprocal/reciprocal.tix"])) ] +exprOnly :: TestTree+exprOnly = testGroup "expr-only" $+ let eo01_dir = joinPath ["test", "data", "eo01"]+ common_args = ["--mix=" <> (eo01_dir </> ".hpc")+ ,"--src=" <> eo01_dir+ ,"--expr-only"+ ,eo01_dir </> "eo01.tix"]+ in [ let golden_path = goldenPath (ofile <.> "golden")+ ofile = eo01_dir </> "eo01.json"+ act = main' (common_args <> ["--out=" <> ofile])+ in goldenVsFile "expr-only" golden_path ofile act++ , let golden_path = goldenPath (ofile <.> "golden")+ ofile = eo01_dir </> "eo01.info"+ act = main' (common_args <> ["--out=" <> ofile,"-flcov"])+ in goldenVsFile "expr-only-lcov" golden_path ofile act+ ]++ignoreDittos :: TestTree+ignoreDittos = testGroup "ignore-dittos" $+ let doGolden name =+ let golden_path = goldenPath (ofile <.> "golden")+ ofile = dir </> name <.> "json"+ tix = dir </> name <.> "tix"+ dir = joinPath ["test", "data", name]+ act = main' [ "--mix=" <> (dir </> ".hpc")+ , "--src=" <> dir+ , "--out=" <> ofile+ , "--ignore-dittos"+ , tix ]+ in goldenVsFile name golden_path ofile act+ in [ doGolden "ifd01"+ , doGolden "ith01"+ ]+ -- Note: Running test to generate .mix and .tix of hpc-codecov package -- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ --@@ -341,7 +378,7 @@ discoverStackTest :: TestTree discoverStackTest =- let t = buildAndTestWithStack+ let t = buildAndTestWith Stack withProject name act = case getAcquireAndRelease Stack name [] of (a,r) -> withResource a r (const act) in testGroup "discover_stack"@@ -357,6 +394,7 @@ [ t "project1" [ "--root=" ++ testData "project1" , "--verbose"+ , "--exclude=Paths_project1,Spec" , "--build=dot-stack-work" , "stack:project1-test.tix"] ["--work-dir=dot-stack-work"]@@ -384,11 +422,7 @@ , after AllSucceed "cobertura.project1" $ testGroup "golden" [ let ofile = "project1-refilled.xml"- golden_file =- if os == "mingw32" then- "project1-windows.xml.golden"- else- "project1.xml.golden"+ golden_file = goldenPath "project1.xml.golden" golden_path = joinPath ["test", "data", "golden", golden_file] act = refillTimestampWithZero "project1.xml" ofile in goldenVsFile "cobertura" golden_path ofile act@@ -426,14 +460,14 @@ discoverCabalTest :: TestTree discoverCabalTest =- let t = buildAndTestWithCabal+ let t = buildAndTestWith Cabal withProject name act = case getAcquireAndRelease Cabal name [] of (a,r) -> withResource a r (const act) in testGroup "discover_cabal" [ t "project1" [ "--root=" ++ testData "project1" , "--verbose"- , "-x", "Paths_project1"+ , "-x", "Paths_project1,Spec" , "-X", "project1-exe" , "cabal:project1-test" ] []@@ -452,12 +486,6 @@ , "cabal:" ++ canonical_tix_path]) ] -buildAndTestWithStack :: String -> [String] -> [String] -> TestTree-buildAndTestWithStack = buildAndTestWith Stack--buildAndTestWithCabal :: String -> [String] -> [String] -> TestTree-buildAndTestWithCabal = buildAndTestWith Cabal- buildAndTestWith :: BuildTool -> String -> [String] -> [String] -> TestTree buildAndTestWith tool name args tool_args = withResource acquire release work where@@ -564,3 +592,8 @@ -- | Get directory under test data. testData :: String -> FilePath testData dir = "test" </> "data" </> dir++goldenPath :: FilePath -> FilePath+goldenPath path+ | os == "mingw32" = path <.> "windows"+ | otherwise = path
+ test/data/eo01/.hpc/Main.mix view
@@ -0,0 +1,1 @@+Mix "eo01.hs" 2024-04-22 07:53:45.081675261 UTC 1101637578 8 [(32:5-32:5,ExpBox False),(32:9-32:9,ExpBox False),(32:5-32:9,BinBox GuardBinBox True),(32:5-32:9,BinBox GuardBinBox False),(32:5-32:9,ExpBox False),(32:13-32:13,ExpBox True),(33:5-33:5,ExpBox False),(33:10-33:10,ExpBox False),(33:5-33:10,BinBox GuardBinBox True),(33:5-33:10,BinBox GuardBinBox False),(33:5-33:10,ExpBox False),(33:14-33:14,ExpBox True),(34:5-34:5,ExpBox False),(34:9-34:9,ExpBox False),(34:5-34:9,BinBox GuardBinBox True),(34:5-34:9,BinBox GuardBinBox False),(34:5-34:9,ExpBox False),(34:13-34:13,ExpBox False),(34:17-34:17,ExpBox False),(34:13-34:17,ExpBox True),(35:5-35:13,BinBox GuardBinBox True),(35:5-35:13,BinBox GuardBinBox False),(35:5-35:13,ExpBox False),(35:17-35:21,ExpBox True),(31:1-35:21,TopLevelBox ["br02"]),(17:5-17:5,ExpBox False),(17:9-17:9,ExpBox False),(17:5-17:9,BinBox GuardBinBox True),(17:5-17:9,BinBox GuardBinBox False),(17:5-17:9,ExpBox False),(17:13-17:13,ExpBox True),(18:5-18:5,ExpBox False),(18:10-18:10,ExpBox False),(18:5-18:10,BinBox GuardBinBox True),(18:5-18:10,BinBox GuardBinBox False),(18:5-18:10,ExpBox False),(18:14-18:14,ExpBox True),(19:5-19:5,ExpBox False),(19:9-19:9,ExpBox False),(19:5-19:9,BinBox GuardBinBox True),(19:5-19:9,BinBox GuardBinBox False),(19:5-19:9,ExpBox False),(19:13-19:13,ExpBox False),(19:17-19:17,ExpBox False),(19:13-19:17,ExpBox True),(20:5-20:13,BinBox GuardBinBox True),(20:5-20:13,BinBox GuardBinBox False),(20:5-20:13,ExpBox False),(20:17-20:21,ExpBox True),(16:1-20:21,TopLevelBox ["br01"]),(11:3-11:3,ExpBox False),(11:7-11:7,ExpBox False),(11:3-11:7,ExpBox True),(13:3-13:7,ExpBox True),(10:1-13:7,TopLevelBox ["pm01"]),(39:10-39:13,ExpBox False),(39:15-39:19,ExpBox False),(39:8-39:19,ExpBox False),(40:21-40:21,ExpBox False),(40:26-40:26,ExpBox False),(40:20-40:27,ExpBox False),(40:14-40:27,ExpBox False),(39:3-40:27,ExpBox False),(41:3-41:7,ExpBox False),(41:16-41:22,ExpBox False),(41:11-41:22,ExpBox False),(41:3-41:22,ExpBox False),(42:3-42:7,ExpBox False),(42:16-42:16,ExpBox False),(42:18-42:18,ExpBox False),(42:11-42:18,ExpBox False),(42:3-42:18,ExpBox False),(43:3-43:7,ExpBox False),(43:16-43:16,ExpBox False),(43:20-43:20,ExpBox False),(43:18-43:21,ExpBox False),(43:23-43:23,ExpBox False),(43:11-43:23,ExpBox False),(43:3-43:23,ExpBox False),(38:8-43:23,ExpBox False),(38:1-43:23,TopLevelBox ["main"]),(25:20-25:22,ExpBox False),(25:20-25:22,TopLevelBox ["unB"]),(22:20-22:22,ExpBox False),(22:20-22:22,TopLevelBox ["unA"]),(5:5-5:10,ExpBox False),(5:5-5:10,TopLevelBox ["field1"]),(6:5-6:10,ExpBox False),(6:5-6:10,TopLevelBox ["field2"]),(23:13-23:19,TopLevelBox ["fmap"]),(23:13-23:19,TopLevelBox ["<$"]),(23:22-23:32,TopLevelBox ["pure"]),(23:22-23:32,TopLevelBox ["<*>"]),(23:22-23:32,TopLevelBox ["liftA2"]),(23:22-23:32,TopLevelBox ["*>"]),(23:22-23:32,TopLevelBox ["<*"]),(23:35-23:39,TopLevelBox [">>="]),(23:35-23:39,TopLevelBox [">>"]),(23:35-23:39,TopLevelBox ["return"]),(28:27-28:27,ExpBox False),(28:29-28:30,ExpBox False),(28:21-28:31,ExpBox False),(28:19-28:31,ExpBox False),(28:3-28:31,TopLevelBox ["fmap"]),(27:10-27:35,TopLevelBox ["<$"])]
+ test/data/eo01/eo01.hs view
@@ -0,0 +1,43 @@+{-# LANGUAGE GeneralizedNewtypeDeriving #-}+module Main where++data R = R+ { field1 :: Bool+ , field2 :: Bool+ }++pm01 :: Maybe Int -> Int+pm01 (Just n) =+ n + 1+pm01 Nothing =+ 12345++br01 :: Int -> Int -> Int+br01 a b+ | a < b = b+ | a == 0 = b+ | b < 0 = a + b+ | otherwise = 12345++newtype A f x = A {unA :: f x}+ deriving (Functor, Applicative, Monad)++newtype B f x = B {unB :: f x}++instance Functor f => Functor (B f) where+ fmap f (B fx) = B (fmap f fx)++br02 :: Int -> Int -> Int -> Int+br02 a b c+ | a < b = b+ | a == 0 = b+ | b < c = a + b+ | otherwise = 12345++main :: IO ()+main = do+ case R True False of+ R t f -> print (t && f)+ print $ pm01 Nothing+ print $ br01 2 1+ print $ br02 0 (-1) 0
+ test/data/eo01/eo01.info.golden view
@@ -0,0 +1,30 @@+TN:+SF:test/data/eo01/eo01.hs+FNF:0+FNH:0+BRF:0+BRH:0+DA:5,0+DA:6,0+DA:11,0+DA:13,1+DA:17,1+DA:18,1+DA:19,1+DA:20,1+DA:22,0+DA:25,0+DA:28,0+DA:32,1+DA:33,1+DA:34,0+DA:35,0+DA:38,1+DA:39,1+DA:40,1+DA:41,1+DA:42,1+DA:43,1+LF:21+LH:13+end_of_record
+ test/data/eo01/eo01.json.golden view
@@ -0,0 +1,1 @@+{"coverage":{"test/data/eo01/eo01.hs":{"5":0,"6":0,"11":0,"13":1,"17":"1/2","18":"1/2","19":"1/2","20":1,"22":0,"25":0,"28":0,"32":"1/2","33":1,"34":0,"35":0,"38":1,"39":1,"40":1,"41":1,"42":1,"43":"1/2"}}}
+ test/data/eo01/eo01.tix view
@@ -0,0 +1,1 @@+Tix [ TixModule "Main" 1101637578 105 [1,1,0,1,1,0,1,1,1,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,0,1,1,0,1,1,0,1,1,0,1,1,0,1,1,0,0,0,1,0,1,1,1,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]]
+ test/data/ifd01/.hpc/Main.mix view
@@ -0,0 +1,1 @@+Mix "ifd01.hs" 2024-04-25 08:12:05.340917168 UTC 1766259647 8 [(16:5-16:6,BinBox GuardBinBox True),(16:5-16:6,BinBox GuardBinBox False),(16:5-16:6,ExpBox False),(16:19-16:39,ExpBox False),(16:10-16:39,ExpBox True),(17:5-17:6,BinBox GuardBinBox True),(17:5-17:6,BinBox GuardBinBox False),(17:5-17:6,ExpBox False),(17:19-17:39,ExpBox False),(17:10-17:39,ExpBox True),(18:5-18:13,BinBox GuardBinBox True),(18:5-18:13,BinBox GuardBinBox False),(18:5-18:13,ExpBox False),(18:26-18:42,ExpBox False),(18:17-18:42,ExpBox True),(15:1-18:42,TopLevelBox ["post"]),(5:5-5:6,BinBox GuardBinBox True),(5:5-5:6,BinBox GuardBinBox False),(5:5-5:6,ExpBox False),(5:19-5:40,ExpBox False),(5:10-5:40,ExpBox True),(6:5-6:6,BinBox GuardBinBox True),(6:5-6:6,BinBox GuardBinBox False),(6:5-6:6,ExpBox False),(6:19-6:40,ExpBox False),(6:10-6:40,ExpBox True),(7:5-7:13,BinBox GuardBinBox True),(7:5-7:13,BinBox GuardBinBox False),(7:5-7:13,ExpBox False),(7:26-7:43,ExpBox False),(7:17-7:43,ExpBox True),(4:1-7:43,TopLevelBox ["pre"]),(22:3-22:5,ExpBox False),(22:11-22:14,ExpBox False),(22:16-22:20,ExpBox False),(22:9-22:20,ExpBox False),(22:3-22:20,ExpBox False),(23:3-23:7,ExpBox False),(23:13-23:16,ExpBox False),(23:18-23:22,ExpBox False),(23:11-23:22,ExpBox False),(23:3-23:22,ExpBox False),(24:3-24:6,ExpBox False),(24:12-24:16,ExpBox False),(24:18-24:21,ExpBox False),(24:10-24:21,ExpBox False),(24:3-24:21,ExpBox False),(21:8-24:21,ExpBox False),(21:1-24:21,TopLevelBox ["main"]),(10:5-10:10,ExpBox False),(10:5-10:10,TopLevelBox ["field1"]),(11:5-11:10,ExpBox False),(11:5-11:10,TopLevelBox ["field2"]),(12:15-12:18,TopLevelBox ["showsPrec"]),(12:15-12:18,TopLevelBox ["show"]),(12:15-12:18,TopLevelBox ["showList"])]
+ test/data/ifd01/ifd01.hs view
@@ -0,0 +1,24 @@+module Main where++pre :: R -> IO ()+pre (R f1 f2)+ | f1 = putStrLn "=== ifd01.hs: f1 ==="+ | f2 = putStrLn "=== ifd01.hs: f2 ==="+ | otherwise = putStrLn "=== ifd01.hs ==="++data R = R+ { field1 :: Bool+ , field2 :: Bool+ } deriving (Show)++post :: R -> IO ()+post (R f1 f2)+ | f1 = putStrLn "=== the end: f1 ==="+ | f2 = putStrLn "=== the end: f2 ==="+ | otherwise = putStrLn "=== the end ==="++main :: IO ()+main = do+ pre $ R True False+ print $ R True False+ post $ R False True
+ test/data/ifd01/ifd01.json.golden view
@@ -0,0 +1,1 @@+{"coverage":{"test/data/ifd01/ifd01.hs":{"4":1,"5":"1/2","6":0,"7":0,"15":1,"16":"1/2","17":"1/2","18":0,"21":1,"22":"1/2","23":1,"24":1}}}
+ test/data/ifd01/ifd01.tix view
@@ -0,0 +1,1 @@+Tix [ TixModule "Main" 1766259647 56 [0,1,1,0,0,1,0,1,1,1,0,0,0,0,0,1,1,0,1,1,1,0,0,0,0,0,0,0,0,0,0,1,1,1,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,1,1,0]]
+ test/data/ith01/.hpc/Main.mix view
@@ -0,0 +1,1 @@+Mix "ith01.hs" 2024-04-23 03:53:32.953597733 UTC 3976838569 8 [(9:2-9:8,ExpBox False),(9:2-9:8,TopLevelBox ["bar"]),(13:9-13:11,ExpBox False),(13:3-13:11,ExpBox False),(14:9-14:11,ExpBox False),(14:3-14:11,ExpBox False),(12:8-14:11,ExpBox False),(12:1-14:11,TopLevelBox ["main"]),(7:2-7:8,ExpBox False),(7:2-7:8,TopLevelBox ["foo"])]
+ test/data/ith01/.hpc/TH01.mix view
@@ -0,0 +1,1 @@+Mix "./TH01.hs" 2024-04-23 03:53:45.147022169 UTC 899367073 8 [(11:11-11:37,ExpBox False),(11:1-11:37,TopLevelBox ["barDecl"]),(8:11-8:37,ExpBox False),(8:1-8:37,TopLevelBox ["fooDecl"])]
+ test/data/ith01/TH01.hs view
@@ -0,0 +1,11 @@+{-# LANGUAGE TemplateHaskell #-}++module TH01 where++import Language.Haskell.TH++fooDecl :: Q [Dec]+fooDecl = [d| foo = 42; foo :: Int |]++barDecl :: Q [Dec]+barDecl = [d| bar :: Int; bar = 42 |]
+ test/data/ith01/ith01.hs view
@@ -0,0 +1,15 @@+{-# LANGUAGE TemplateHaskell #-}++module Main where++import TH01++$fooDecl++$barDecl++main :: IO ()+main = do+ print foo+ print bar+
+ test/data/ith01/ith01.json.golden view
@@ -0,0 +1,1 @@+{"coverage":{"test/data/ith01/ith01.hs":{"12":1,"13":1,"14":1},"test/data/ith01/./TH01.hs":{"8":0,"11":0}}}
+ test/data/ith01/ith01.tix view
@@ -0,0 +1,1 @@+Tix [ TixModule "Main" 3976838569 10 [1,1,1,1,1,1,1,1,1,1], TixModule "TH01" 899367073 4 [0,0,0,0]]
test/data/project1/stack.yaml view
@@ -17,7 +17,7 @@ # # resolver: ./custom-snapshot.yaml # resolver: https://example.com/snapshots/2018-01-01.yaml-resolver: lts-21.19+resolver: lts-22.18 # User packages to be built. # Various formats can be used as shown in the example below.