packages feed

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 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.