diff options
| author | Jesse Rosenthal <jrosenthal@jhu.edu> | 2018-01-22 09:02:20 -0500 | 
|---|---|---|
| committer | Jesse Rosenthal <jrosenthal@jhu.edu> | 2018-01-22 09:14:00 -0500 | 
| commit | 0e48c216bcf89340b878421be389ae1d7035e168 (patch) | |
| tree | 7f6f0c8f8281070b39c6b2fe46068d6ed0cd6faf /test | |
| parent | e9ed4832edb1a9f9c3cd7b6c670c39f513444192 (diff) | |
| download | pandoc-0e48c216bcf89340b878421be389ae1d7035e168.tar.gz | |
Powerpoint tests: Convert to golden tests
This will allow us to rebuild the pptx files in the test dir more
easily if we make a change in the writer.
Diffstat (limited to 'test')
| -rw-r--r-- | test/Tests/Writers/Powerpoint.hs | 283 | 
1 files changed, 147 insertions, 136 deletions
| diff --git a/test/Tests/Writers/Powerpoint.hs b/test/Tests/Writers/Powerpoint.hs index 139081013..a493746b7 100644 --- a/test/Tests/Writers/Powerpoint.hs +++ b/test/Tests/Writers/Powerpoint.hs @@ -4,55 +4,18 @@  module Tests.Writers.Powerpoint (tests) where --- import Control.Exception (throwIO)  import Text.Pandoc  import Test.Tasty -import Test.Tasty.HUnit +import Test.Tasty.Golden.Advanced  import Codec.Archive.Zip  import Text.XML.Light +import qualified Data.ByteString as BS  import qualified Data.ByteString.Lazy as BL  import qualified Data.Text.IO as T -import Data.List (isPrefixOf, isSuffixOf, sort, (\\), intercalate) -import Data.Maybe (fromJust, isNothing) +import Data.List (isPrefixOf, isSuffixOf, sort, (\\), intercalate, union) +import Data.Maybe (catMaybes, mapMaybe)  import Tests.Helpers  import Data.Algorithm.Diff -import Control.Monad (when) - - -getPptxBytes :: WriterOptions -             -> FilePath -             -> FilePath -             -> IO (BL.ByteString, BL.ByteString) -getPptxBytes opts nativeFp pptxFp = do -  ntvTxt <- T.readFile nativeFp -  ntv <- runIOorExplode $ readNative def ntvTxt -  myPptxBs <- runIOorExplode $ writePowerpoint opts ntv -  goodPptxBs <- BL.readFile pptxFp -  return (myPptxBs, goodPptxBs) - - -assertSameFileList :: Archive -> Archive -> FilePath -> Assertion -assertSameFileList myArch goodArch pptxFp = do -  let filesMy = filesInArchive myArch -      filesGood = filesInArchive goodArch -      diffMyGood = filesMy \\ filesGood -      diffGoodMy = filesGood \\ filesMy -  if | null diffMyGood && null diffGoodMy -> return () -     | null diffMyGood -> -         assertFailure $ -         "Files in " ++ pptxFp ++ " but not in generated archive:\n" ++ -         intercalate ", " diffGoodMy -     | null diffGoodMy -> -         assertFailure $ -         "Files in generated archive but not in " ++ pptxFp ++ ":\n" ++ -         intercalate ", " diffMyGood -     | otherwise -> -         assertFailure $ -         "Files in " ++ pptxFp ++ " but not in generated archive:\n" ++ -         intercalate ", " diffGoodMy ++ -         "\n" ++ -         "Files in generated archive but not in " ++ pptxFp ++ ":\n" ++ -         intercalate ", " diffMyGood  compareXMLBool :: Content -> Content -> Bool  -- We make a special exception for times at the moment, and just pass @@ -86,111 +49,159 @@ displayDiff :: Content -> Content -> String  displayDiff elemA elemB =    showDiff (1,1) $ getDiff (lines $ ppContent elemA) (lines $ ppContent elemB) -compareXMLFile :: FilePath -> Archive -> Archive -> Assertion -compareXMLFile fp myArch goodArch = do -  let mbMyEntry = findEntryByPath fp myArch -  when (isNothing mbMyEntry) -    (assertFailure $ -    "Can't extract " ++ fp ++ " from generated archive") -  let mbMyXMLDoc = parseXMLDoc $ fromEntry $ fromJust mbMyEntry -  when (isNothing mbMyXMLDoc) -    (assertFailure $ -    "Can't parse xml in  " ++ fp ++ " from generated archive") -  let myContent = Elem $ fromJust mbMyXMLDoc - -  let mbGoodEntry = findEntryByPath fp goodArch -  when (isNothing mbGoodEntry) -    (assertFailure $ -    "Can't extract " ++ fp ++ " from archive in stored pptx file") -  let mbGoodXMLDoc = parseXMLDoc $ fromEntry $ fromJust mbGoodEntry -  when (isNothing mbGoodXMLDoc) -    (assertFailure $ -    "Can't parse xml in  " ++ fp ++ " from archive in stored pptx file") -  let goodContent = Elem $ fromJust mbGoodXMLDoc - -  assertBool -    ("Non-matching xml in " ++ fp ++ ":\n" ++ displayDiff myContent goodContent) -    (compareXMLBool myContent goodContent) - -compareBinaryFile :: FilePath -> Archive -> Archive -> Assertion -compareBinaryFile fp myArch goodArch = do -  let mbMyEntry = findEntryByPath fp myArch -  when (isNothing mbMyEntry) -    (assertFailure $ -    "Can't extract " ++ fp ++ " from generated archive") -  let myBytes = fromEntry $ fromJust mbMyEntry - -  let mbGoodEntry = findEntryByPath fp goodArch -  when (isNothing mbGoodEntry) -    (assertFailure $ -    "Can't extract " ++ fp ++ " from archive in stored pptx file") -  let goodBytes = fromEntry $ fromJust mbGoodEntry - -  assertBool (fp ++ " doesn't match") (myBytes == goodBytes) - -testSameFileList :: WriterOptions -> FilePath -> FilePath -> TestTree -testSameFileList opts myFp goodFp = -  testCase ("Identical file list in archives") $ do -  (myBS, goodBS) <- getPptxBytes opts myFp goodFp -  let myArch = toArchive myBS -      goodArch = toArchive goodBS -  (assertSameFileList myArch goodArch goodFp) - -testSameXML :: WriterOptions -> FilePath -> FilePath -> TestTree -testSameXML opts myFp goodFp = testCaseSteps "Comparing extracted xml files" $ -  \step -> do -    (myBS, goodBS) <- getPptxBytes opts myFp goodFp -    let myArch = toArchive myBS -        goodArch = toArchive goodBS - -    let xmlFileList = sort $ -          filter (\fp -> ".xml" `isSuffixOf` fp || ".rels" `isSuffixOf` fp) -          (filesInArchive myArch) -    mapM_ -      (\fp -> step ("- " ++ fp) >> compareXMLFile fp myArch goodArch) -      xmlFileList - -testSameMedia :: WriterOptions -> FilePath -> FilePath -> TestTree -testSameMedia opts myFp goodFp = testCaseSteps "Comparing media files" $ -  \step -> do -    (myBS, goodBS) <- getPptxBytes opts myFp goodFp -    let myArch = toArchive myBS -        goodArch = toArchive goodBS - -    let mediaFileList = sort $ -          filter (\fp -> "ppt/media/" `isPrefixOf` fp) -          (filesInArchive myArch) - -    mapM_ -      (\fp -> step ("- " ++ fp) >> compareBinaryFile fp myArch goodArch) -      mediaFileList - -testCompareWithOpts :: String -> WriterOptions ->FilePath -> FilePath -> TestTree -testCompareWithOpts testName opts nativeFp pptxFp = -  testGroup testName [ testSameFileList opts nativeFp pptxFp -                     , testSameXML opts nativeFp pptxFp -                     , testSameMedia opts nativeFp pptxFp -                     ] - - -testCompare :: String -> FilePath -> FilePath -> TestTree -testCompare testName nativeFp pptxFp = -  testCompareWithOpts testName def nativeFp pptxFp +goldenArchive :: FilePath -> IO Archive +goldenArchive fp = (toArchive . BL.fromStrict) <$> BS.readFile fp + +testArchive :: WriterOptions -> FilePath -> IO Archive +testArchive opts fp = do +  txt <- T.readFile fp +  bs <- runIOorExplode $ readNative def txt >>= writePowerpoint opts +  return $ toArchive bs + +updateGoldenFile :: WriterOptions -> FilePath -> FilePath -> IO () +updateGoldenFile opts nativeFP goldenFP = do +  txt <- T.readFile nativeFP +  bs <- runIOorExplode $ readNative def txt >>= writePowerpoint opts +  BL.writeFile goldenFP bs + +compareFileList :: FilePath -> Archive -> Archive -> Maybe String +compareFileList goldenFP goldenArch testArch = +  let testFiles = filesInArchive testArch +      goldenFiles = filesInArchive goldenArch +      diffTestGolden = testFiles \\ goldenFiles +      diffGoldenTest = goldenFiles \\ testFiles + +      results = +        [ if null diffGoldenTest +          then Nothing +          else Just $ +               "Files in " ++ goldenFP ++ " but not in generated archive:\n" ++ +               intercalate ", " diffGoldenTest +        , if null diffTestGolden +          then Nothing +          else Just $ +               "Files in generated archive but not in " ++ goldenFP ++ ":\n" ++ +               intercalate ", " diffTestGolden +        ] +  in +    if null $ catMaybes results +    then Nothing +    else Just $ intercalate "\n" $ catMaybes results + +compareXMLFile' :: FilePath -> Archive -> Archive -> Either String () +compareXMLFile' fp goldenArch testArch = do +  testEntry <- case findEntryByPath fp testArch of +                 Just entry -> Right entry +                 Nothing -> Left $ +                   "Can't extract " ++ fp ++ " from generated archive" +  testXMLDoc <- case parseXMLDoc $ fromEntry testEntry of +                  Just doc -> Right doc +                  Nothing -> Left $ +                    "Can't parse xml in  " ++ fp ++ " from generated archive" + +  goldenEntry <- case findEntryByPath fp goldenArch of +                 Just entry -> Right entry +                 Nothing -> Left $ +                   "Can't extract " ++ fp ++ " from archive in stored pptx file" +  goldenXMLDoc <- case parseXMLDoc $ fromEntry goldenEntry of +                  Just doc -> Right doc +                  Nothing -> Left $ +                    "Can't parse xml in  " ++ fp ++ " from archive in stored pptx file" + +  let testContent = Elem $ testXMLDoc +      goldenContent = Elem $ goldenXMLDoc + +  if (compareXMLBool goldenContent testContent) +    then Right () +    else Left $ +    "Non-matching xml in " ++ fp ++ ":\n" ++ displayDiff testContent goldenContent + +compareXMLFile :: FilePath -> Archive -> Archive -> Maybe String +compareXMLFile fp goldenArch testArch = +  case compareXMLFile' fp goldenArch testArch of +    Right _ -> Nothing +    Left s -> Just s + +compareAllXMLFiles :: Archive -> Archive -> Maybe String +compareAllXMLFiles goldenArch testArch = +  let allFiles = filesInArchive goldenArch `union` filesInArchive testArch +      allXMLFiles = sort $ +        filter +        (\fp -> ".xml" `isSuffixOf` fp || ".rels" `isSuffixOf` fp) +        allFiles +      results = +        mapMaybe (\fp -> compareXMLFile fp goldenArch testArch) allXMLFiles +  in +    if null results +    then Nothing +    else Just $ unlines results + +compareMediaFile' :: FilePath -> Archive -> Archive -> Either String () +compareMediaFile' fp goldenArch testArch = do +  testEntry <- case findEntryByPath fp testArch of +                 Just entry -> Right entry +                 Nothing -> Left $ +                   "Can't extract " ++ fp ++ " from generated archive" +  goldenEntry <- case findEntryByPath fp goldenArch of +                 Just entry -> Right entry +                 Nothing -> Left $ +                   "Can't extract " ++ fp ++ " from archive in stored pptx file" + +  if (fromEntry testEntry == fromEntry goldenEntry) +    then Right () +    else Left $ +    "Non-matching binary file: " ++ fp + +compareMediaFile :: FilePath -> Archive -> Archive -> Maybe String +compareMediaFile fp goldenArch testArch = +  case compareMediaFile' fp goldenArch testArch of +    Right _ -> Nothing +    Left s -> Just s + +compareAllMediaFiles :: Archive -> Archive -> Maybe String +compareAllMediaFiles goldenArch testArch = +  let allFiles = filesInArchive goldenArch `union` filesInArchive testArch +      allMediaFiles = sort $ +        filter +        (\fp -> "/ppt/media/" `isPrefixOf` fp) +        allFiles +      results = +        mapMaybe (\fp -> compareMediaFile fp goldenArch testArch) allMediaFiles +  in +    if null results +    then Nothing +    else Just $ unlines results + +pptxTest :: String -> WriterOptions -> FilePath -> FilePath -> TestTree +pptxTest testName opts nativeFP goldenFP = +  goldenTest +  testName +  (goldenArchive goldenFP) +  (testArchive opts nativeFP) +  (\goldenArch testArch -> +     let res = catMaybes [ compareFileList goldenFP goldenArch testArch +                         , compareAllXMLFiles goldenArch testArch +                         , compareAllMediaFiles goldenArch testArch +                         ] +     in return $ if null res then Nothing else Just $ unlines res) +  (\_ -> updateGoldenFile opts nativeFP goldenFP)  --------------------------------------------------------------  tests :: [TestTree] -tests = [ testCompare +tests = [ pptxTest            "Inline formatting" +          def            "pptx/inline_formatting.native"            "pptx/inline_formatting.pptx" -        , testCompare -          "slide breaks (default slide-level)" +        , pptxTest +          "Slide breaks (default slide-level)" +          def            "pptx/slide_breaks.native"            "pptx/slide_breaks.pptx" -        , testCompareWithOpts +        , pptxTest            "slide breaks (slide-level set to 1)" -          def{writerSlideLevel=Just 1} +          def{ writerSlideLevel = Just 1 }            "pptx/slide_breaks.native"            "pptx/slide_breaks_slide_level_1.pptx"          ] | 
