module JUnit ( writeJUnitReport, ) where import Control.Monad import Data.ByteString qualified as B import Data.ByteString.Char8 qualified as BC import Data.Function import Data.List.NonEmpty qualified as NE import Data.Scientific import Data.Text qualified as T import Data.Text.Encoding import System.Directory import System.FilePath import System.IO import Run import Script.Var showTime :: Scientific -> B.ByteString showTime = BC.pack . formatScientific Fixed Nothing writeJUnitReport :: FilePath -> Report -> IO () writeJUnitReport path Report {..} = do createDirectoryIfMissing True $ takeDirectory path withFile path WriteMode $ \h -> do B.hPutStr h $ "\n" B.hPutStr h $ " showTime reportTotalTime <> "\">\n" forM_ (NE.groupBy ((==) `on` (testNameModule . reportTestName)) reportTests) $ \grp -> do B.hPutStr h $ " encodeUtf8 (textModuleName $ testNameModule $ reportTestName $ NE.head grp) <> "\" time=\"" <> showTime (sum $ map reportTime $ NE.toList grp) <> "\">" forM_ grp $ \SingleTestReport {..} -> do B.hPutStr h $ B.concat [ "" , "" , encodeUtf8 $ escape reportOutput , "" , case reportTestFailed of Nothing -> do "" Just Failed -> do "" <> encodeUtf8 (escape reportOutputError) <> "" Just (ProcessCrashed _) -> do "" <> encodeUtf8 (escape reportOutputError) <> "" , "" ] B.hPutStr h $ "" B.hPutStr h $ "\n" where escape = T.concatMap $ \case '&' -> "&" '<' -> "<" '>' -> ">" c -> T.singleton c