packages feed

hspec-junit-formatter 1.0.2.1 → 1.0.2.2

raw patch · 7 files changed

+122/−17 lines, 7 filesPVP: major bump suggested

API removals or changes: PVP suggests a major version bump

API changes (from Hackage documentation)

+ Test.HSpec.JUnit.Schema: [testCaseLocation] :: TestCase -> Maybe Location
+ Test.Hspec.JUnit.Schema: Location :: FilePath -> Natural -> Location
+ Test.Hspec.JUnit.Schema: [locationFile] :: Location -> FilePath
+ Test.Hspec.JUnit.Schema: [locationLine] :: Location -> Natural
+ Test.Hspec.JUnit.Schema: [testCaseLocation] :: TestCase -> Maybe Location
+ Test.Hspec.JUnit.Schema: data Location
+ Test.Hspec.JUnit.Schema: instance GHC.Show.Show Test.Hspec.JUnit.Schema.Location
- Test.HSpec.JUnit.Schema: TestCase :: Text -> Text -> Double -> Maybe Result -> TestCase
+ Test.HSpec.JUnit.Schema: TestCase :: Maybe Location -> Text -> Text -> Double -> Maybe Result -> TestCase
- Test.Hspec.JUnit.Schema: TestCase :: Text -> Text -> Double -> Maybe Result -> TestCase
+ Test.Hspec.JUnit.Schema: TestCase :: Maybe Location -> Text -> Text -> Double -> Maybe Result -> TestCase

Files

CHANGELOG.md view
@@ -1,6 +1,10 @@-## [_Unreleased_](https://github.com/freckle/hspec-junit-formatter/compare/v1.0.2.1...main)+## [_Unreleased_](https://github.com/freckle/hspec-junit-formatter/compare/v1.0.2.2...main)  None++## [v1.0.2.2](https://github.com/freckle/hspec-junit-formatter/compare/v1.0.2.1...v1.0.2.2)++- Add `file` and `line` attributes in `testcase` nodes  ## [v1.0.2.1](https://github.com/freckle/hspec-junit-formatter/compare/v1.0.2.0...v1.0.2.1) 
hspec-junit-formatter.cabal view
@@ -1,6 +1,6 @@ cabal-version:      1.12 name:               hspec-junit-formatter-version:            1.0.2.1+version:            1.0.2.2 license:            MIT license-file:       LICENSE copyright:          2021 Renaissance Learning Inc
library/Test/Hspec/JUnit.hs view
@@ -8,6 +8,7 @@  import Prelude +import Control.Applicative ((<|>)) import Data.Conduit (runConduitRes, (.|)) import Data.Conduit.Combinators (sinkFile) import Data.Conduit.List (sourceList)@@ -79,7 +80,9 @@ itemToTestCase   :: (FilePath -> FilePath) -> Text -> Text -> Item -> Schema.TestCase itemToTestCase applyPrefix group name item = Schema.TestCase-  { testCaseClassName = group+  { testCaseLocation =+    toSchemaLocation <$> (itemResultLocation item <|> itemLocation item)+  , testCaseClassName = group   , testCaseName = name   , testCaseDuration = unSeconds $ itemDuration item   , testCaseResult = case itemResult item of@@ -123,6 +126,18 @@   prefixInfo str     | T.null $ T.strip $ pack $ itemInfo item = str     | otherwise = pack (itemInfo item) <> "\n\n" <> str++itemResultLocation :: Item -> Maybe Location+itemResultLocation item = case itemResult item of+  Success -> Nothing+  Pending mLocation _ -> mLocation+  Failure mLocation _ -> mLocation++toSchemaLocation :: Location -> Schema.Location+toSchemaLocation Location {..} = Schema.Location+  { Schema.locationFile = locationFile+  , Schema.locationLine = fromIntegral $ max 0 locationLine+  }  unSeconds :: Seconds -> Double unSeconds (Seconds x) = x
library/Test/Hspec/JUnit/Render.hs view
@@ -11,7 +11,8 @@ import Data.Text (Text, pack) import Data.Time.Format.ISO8601 (iso8601Show) import Data.XML.Types (Event)-import Test.Hspec.JUnit.Schema (Result(..), Suite(..), Suites(..), TestCase(..))+import Test.Hspec.JUnit.Schema+  (Location(..), Result(..), Suite(..), Suites(..), TestCase(..)) import Text.Printf import Text.XML.Stream.Render (attr, content, tag) @@ -55,15 +56,18 @@ tshow = pack . show  testCase :: MonadThrow m => ConduitT TestCase Event m ()-testCase = awaitForever $ \(TestCase className name duration mResult) ->-  tag "testcase" (attributes className name duration)-    $ traverse_ yield mResult-    .| result+testCase =+  awaitForever $ \(TestCase mLocation className name duration mResult) ->+    tag "testcase" (attributes mLocation className name duration)+      $ traverse_ yield mResult+      .| result  where-  attributes className name duration =-    attr "name" name <> attr "classname" className <> attr-      "time"-      (roundToStr duration)+  attributes mLocation className name duration =+    maybe mempty (attr "file" . pack . locationFile) mLocation+      <> maybe mempty (attr "line" . pack . show . locationLine) mLocation+      <> attr "name" name+      <> attr "classname" className+      <> attr "time" (roundToStr duration)  result :: MonadThrow m => ConduitT Result Event m () result = awaitForever go
library/Test/Hspec/JUnit/Schema.hs view
@@ -2,6 +2,7 @@   ( Suites(..)   , Suite(..)   , TestCase(..)+  , Location(..)   , Result(..)   ) where @@ -9,6 +10,7 @@  import Data.Text (Text) import Data.Time (UTCTime)+import Numeric.Natural  data Suites = Suites   { suitesName :: Text@@ -24,10 +26,17 @@   deriving stock Show  data TestCase = TestCase-  { testCaseClassName :: Text+  { testCaseLocation :: Maybe Location+  , testCaseClassName :: Text   , testCaseName :: Text   , testCaseDuration :: Double   , testCaseResult :: Maybe Result+  }+  deriving stock Show++data Location = Location+  { locationFile :: FilePath+  , locationLine :: Natural   }   deriving stock Show 
tests/Main.hs view
@@ -6,6 +6,7 @@ import Prelude  import Control.Monad (void)+import Data.Char (isSpace) import qualified Data.Map.Strict as Map import Data.Text (Text) import qualified Data.Text as T@@ -23,7 +24,7 @@     it "matches golden file" $ do       withJUnitReport ExampleSpec.spec $ \doc -> do         golden <- XML.readFile XML.def "tests/golden.xml"-        removeTimeAttributes doc `shouldBe` removeTimeAttributes golden+        normalizeDoc doc `shouldBe` normalizeDoc golden      it "can prefix source paths" $ do       let modify = setJUnitConfigSourcePathPrefix "lol/monorepo"@@ -52,6 +53,23 @@       hspecConfig = configWithJUnit junitConfig defaultConfig     void $ runSpec spec hspecConfig     f =<< XML.readFile XML.def path++normalizeDoc :: XML.Document -> XML.Document+normalizeDoc = removeWhitespaceNodes . removeTimeAttributes++removeWhitespaceNodes :: XML.Document -> XML.Document+removeWhitespaceNodes doc = doc+  { XML.documentRoot = go $ XML.documentRoot doc+  }+ where+  go el =+    el { XML.elementNodes = concatMap filterWhitespace $ XML.elementNodes el }++  filterWhitespace :: XML.Node -> [XML.Node]+  filterWhitespace = \case+    XML.NodeElement el -> [XML.NodeElement $ go el]+    XML.NodeContent c | T.all isSpace c -> []+    n -> [n]  -- | Remove volatile attributes so they don't invalidate comparison removeTimeAttributes :: XML.Document -> XML.Document
tests/golden.xml view
@@ -1,6 +1,61 @@-<testsuites name="hspec-junit-format"><testsuite name="Some section" package="Some section" id="0" time="0.000032355" timestamp="2021-05-17T15:36:10.205608409Z" hostname="localhost" tests="2" failures="1" errors="0" skipped="0"><properties/><testcase name="has a failure" classname="Some section" time="0.000015537"><failure type="error">tests/ExampleSpec.hs:18:7+<testsuites name="hspec-junit-format">+  <testsuite+    name="Some section"+    package="Some section"+    id="0"+    hostname="localhost"+    time="0.000032355"+    timestamp="2021-05-17T15:36:10.205608409Z"+    tests="2" failures="1" errors="0" skipped="0">+    <properties/>+    <testcase+      file="tests/ExampleSpec.hs"+      line="18"+      name="has a failure"+      classname="Some section"+      time="0.000015537">+      <failure type="error">tests/ExampleSpec.hs:18:7  expected: &#34;False&#34;  but got: &#34;True&#34;-</failure></testcase><testcase name="has an expectation" classname="Some section" time="0.000016818"/></testsuite><testsuite name="Some section/A grouped context" package="Some section/A grouped context" id="1" time="0.000021009" timestamp="2021-05-17T15:36:10.205608409Z" hostname="localhost" tests="3" failures="0" errors="0" skipped="1"><properties/><testcase name="gets skipped" classname="Some section/A grouped context" time="0.000006765"><skipped>tests/ExampleSpec.hs:26:9-some reason</skipped></testcase><testcase name="also happens in a group" classname="Some section/A grouped context" time="0.000007421"/><testcase name="happens in a group" classname="Some section/A grouped context" time="0.000006823"/></testsuite></testsuites>+</failure>+    </testcase>+    <testcase+      file="tests/ExampleSpec.hs"+      line="15"+      name="has an expectation"+      classname="Some section"+      time="0.000016818"/>+  </testsuite>+  <testsuite+    name="Some section/A grouped context"+    package="Some section/A grouped context"+    id="1"+    time="0.000021009"+    timestamp="2021-05-17T15:36:10.205608409Z"+    hostname="localhost"+    tests="3" failures="0" errors="0" skipped="1">+    <properties/>+    <testcase+      file="tests/ExampleSpec.hs"+      line="26"+      name="gets skipped"+      classname="Some section/A grouped context"+      time="0.000006765">+      <skipped>tests/ExampleSpec.hs:26:9+some reason</skipped>+    </testcase>+    <testcase+      file="tests/ExampleSpec.hs"+      line="23"+      name="also happens in a group"+      classname="Some section/A grouped context"+      time="0.000007421"/>+    <testcase+      file="tests/ExampleSpec.hs"+      line="21"+      name="happens in a group"+      classname="Some section/A grouped context"+      time="0.000006823"/>+  </testsuite>+</testsuites>