packages feed

hspec-junit-formatter-1.0.2.0: tests/Main.hs

module Main
  ( main
  )
where

import Prelude

import Control.Monad (void)
import qualified Data.Map.Strict as Map
import qualified ExampleSpec
import System.FilePath ((</>))
import System.IO.Temp (withSystemTempDirectory)
import Test.Hspec
import Test.Hspec.JUnit
import Test.Hspec.Runner
import qualified Text.XML as XML

main :: IO ()
main = hspec $ do
  describe "XML output" $ do
    it "matches golden file" $ 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

-- | Remove volatile attributes so they don't invalidate comparison
removeTimeAttributes :: XML.Document -> XML.Document
removeTimeAttributes =
  removeAttributesByName "time" . removeAttributesByName "timestamp"

removeAttributesByName :: XML.Name -> XML.Document -> XML.Document
removeAttributesByName name doc = doc
  { XML.documentRoot = go $ XML.documentRoot doc
  }
 where
  go el = el
    { XML.elementAttributes = Map.delete name $ XML.elementAttributes el
    , XML.elementNodes = map (onNodeElement go) $ XML.elementNodes el
    }

  onNodeElement f = \case
    XML.NodeElement el -> XML.NodeElement $ f el
    n -> n