hspec-junit-formatter 1.0.2.0 → 1.0.2.1
raw patch · 6 files changed
+82/−18 lines, 6 filesPVP: minor bump suggested
API additions: PVP suggests at least a minor version bump
API changes (from Hackage documentation)
+ Test.Hspec.JUnit.Config: getJUnitPrefixSourcePath :: JUnitConfig -> FilePath -> FilePath
+ Test.Hspec.JUnit.Config: setJUnitConfigSourcePathPrefix :: FilePath -> JUnitConfig -> JUnitConfig
Files
- CHANGELOG.md +6/−1
- hspec-junit-formatter.cabal +3/−1
- library/Test/Hspec/JUnit.hs +6/−4
- library/Test/Hspec/JUnit/Config.hs +22/−0
- tests/Main.hs +39/−12
- tests/golden.xml +6/−0
CHANGELOG.md view
@@ -1,6 +1,11 @@-## [_Unreleased_](https://github.com/freckle/hspec-junit-formatter/compare/v1.0.2.0...main)+## [_Unreleased_](https://github.com/freckle/hspec-junit-formatter/compare/v1.0.2.1...main) None++## [v1.0.2.1](https://github.com/freckle/hspec-junit-formatter/compare/v1.0.2.0...v1.0.2.1)++- Support for prefixing reported source paths (e.g. if in a monorepo)+- Ensure tests pass within unpacked release tarball ## [v1.0.2.0](https://github.com/freckle/hspec-junit-formatter/compare/v1.0.1.0...v1.0.2.0)
hspec-junit-formatter.cabal view
@@ -1,6 +1,6 @@ cabal-version: 1.12 name: hspec-junit-formatter-version: 1.0.2.0+version: 1.0.2.1 license: MIT license-file: LICENSE copyright: 2021 Renaissance Learning Inc@@ -17,6 +17,7 @@ extra-source-files: README.md CHANGELOG.md+ tests/golden.xml source-repository head type: git@@ -105,4 +106,5 @@ hspec >=2.8.1, hspec-junit-formatter -any, temporary >=1.3,+ text >=1.2.4.1, xml-conduit >=1.9.1.1
library/Test/Hspec/JUnit.hs view
@@ -57,7 +57,7 @@ , suiteTimestamp = time , suiteCases = xs }- suite $ uncurry (itemToTestCase group) <$> items+ suite $ uncurry (itemToTestCase applyPrefix group) <$> items } runConduitRes@@ -68,6 +68,7 @@ where file = getJUnitConfigOutputFile junitConfig suiteName = getJUnitConfigSuiteName junitConfig+ applyPrefix = getJUnitPrefixSourcePath junitConfig groupItems :: [(Path, Item)] -> [(Text, [(Text, Item)])] groupItems = Map.toList . Map.fromListWith (<>) . fmap group@@ -75,8 +76,9 @@ group ((path, name), item) = (T.intercalate "/" $ pack <$> path, [(pack name, item)]) -itemToTestCase :: Text -> Text -> Item -> Schema.TestCase-itemToTestCase group name item = Schema.TestCase+itemToTestCase+ :: (FilePath -> FilePath) -> Text -> Text -> Item -> Schema.TestCase+itemToTestCase applyPrefix group name item = Schema.TestCase { testCaseClassName = group , testCaseName = name , testCaseDuration = unSeconds $ itemDuration item@@ -110,7 +112,7 @@ Nothing -> str Just Location {..} -> mconcat- [ pack locationFile+ [ pack $ applyPrefix locationFile , ":" , pack $ show locationLine , ":"
library/Test/Hspec/JUnit/Config.hs view
@@ -6,10 +6,12 @@ , setJUnitConfigOutputDirectory , setJUnitConfigOutputName , setJUnitConfigOutputFile+ , setJUnitConfigSourcePathPrefix -- * Use , getJUnitConfigOutputFile , getJUnitConfigSuiteName+ , getJUnitPrefixSourcePath ) where import Prelude@@ -23,6 +25,7 @@ , junitConfigOutputName :: FilePath , junitConfigOutputFile :: Maybe FilePath , junitConfigSuiteName :: Text+ , junitConfigSourcePathPrefix :: Maybe FilePath } -- | Construct a 'JUnitConfig' given a suite name@@ -35,6 +38,7 @@ , junitConfigOutputName = "junit.xml" , junitConfigOutputFile = Nothing , junitConfigSuiteName = name+ , junitConfigSourcePathPrefix = Nothing } -- | Set the directory within which to generate the report@@ -59,6 +63,16 @@ setJUnitConfigOutputFile :: FilePath -> JUnitConfig -> JUnitConfig setJUnitConfigOutputFile x config = config { junitConfigOutputFile = Just x } +-- | Set a prefix to apply to source paths in the report+--+-- Default is none. This can be required if you run specs from a sub-directory+-- in a monorepository, and you need reported paths to be from the repository+-- root.+--+setJUnitConfigSourcePathPrefix :: FilePath -> JUnitConfig -> JUnitConfig+setJUnitConfigSourcePathPrefix x config =+ config { junitConfigSourcePathPrefix = Just x }+ -- | Retrieve the full path to the generated report getJUnitConfigOutputFile :: JUnitConfig -> FilePath getJUnitConfigOutputFile JUnitConfig {..} = fromMaybe@@ -68,3 +82,11 @@ -- | Retrieve the suite name given on construction getJUnitConfigSuiteName :: JUnitConfig -> Text getJUnitConfigSuiteName = junitConfigSuiteName++-- | Retrieve the function to apply to reported source paths+--+-- Will be 'id' if no prefix configured.+--+getJUnitPrefixSourcePath :: JUnitConfig -> FilePath -> FilePath+getJUnitPrefixSourcePath JUnitConfig {..} =+ maybe id (</>) junitConfigSourcePathPrefix
tests/Main.hs view
@@ -7,6 +7,8 @@ import Control.Monad (void) import qualified Data.Map.Strict as Map+import Data.Text (Text)+import qualified Data.Text as T import qualified ExampleSpec import System.FilePath ((</>)) import System.IO.Temp (withSystemTempDirectory)@@ -19,22 +21,38 @@ main = hspec $ do describe "XML output" $ do it "matches golden file" $ do- withJUNitReport ExampleSpec.spec $ \doc -> do+ withJUnitReport ExampleSpec.spec $ \doc -> do golden <- XML.readFile XML.def "tests/golden.xml" removeTimeAttributes doc `shouldBe` removeTimeAttributes golden -withJUNitReport :: Spec -> (XML.Document -> IO ()) -> IO ()-withJUNitReport spec f = withSystemTempDirectory "" $ \tmp -> do- let- path = tmp </> "test.xml"- junitConfig =- setJUnitConfigOutputDirectory tmp- $ setJUnitConfigOutputName "test.xml"- $ defaultJUnitConfig "hspec-junit-format"- hspecConfig = configWithJUnit junitConfig defaultConfig- void $ runSpec spec hspecConfig- f =<< XML.readFile XML.def path+ it "can prefix source paths" $ do+ let modify = setJUnitConfigSourcePathPrefix "lol/monorepo" + withJUnitReportConfig modify ExampleSpec.spec $ \doc -> do+ let+ root = XML.documentRoot doc+ hasPrefix = ("lol/monorepo/tests/ExampleSpec.hs" `T.isPrefixOf`)++ elementInnerTexts root `shouldSatisfy` all hasPrefix++withJUnitReport :: Spec -> (XML.Document -> IO ()) -> IO ()+withJUnitReport = withJUnitReportConfig id++withJUnitReportConfig+ :: (JUnitConfig -> JUnitConfig) -> Spec -> (XML.Document -> IO ()) -> IO ()+withJUnitReportConfig modifyConfig spec f =+ withSystemTempDirectory "" $ \tmp -> do+ let+ path = tmp </> "test.xml"+ junitConfig =+ modifyConfig+ $ setJUnitConfigOutputDirectory tmp+ $ setJUnitConfigOutputName "test.xml"+ $ defaultJUnitConfig "hspec-junit-format"+ hspecConfig = configWithJUnit junitConfig defaultConfig+ void $ runSpec spec hspecConfig+ f =<< XML.readFile XML.def path+ -- | Remove volatile attributes so they don't invalidate comparison removeTimeAttributes :: XML.Document -> XML.Document removeTimeAttributes =@@ -53,3 +71,12 @@ onNodeElement f = \case XML.NodeElement el -> XML.NodeElement $ f el n -> n++elementInnerTexts :: XML.Element -> [Text]+elementInnerTexts = concatMap go . XML.elementNodes+ where+ go :: XML.Node -> [Text]+ go = \case+ XML.NodeElement el -> elementInnerTexts el+ XML.NodeContent x -> [x]+ _ -> []
+ tests/golden.xml view
@@ -0,0 +1,6 @@+<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++expected: "False"+ but got: "True"+</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>