@@ -5,27 +5,35 @@ module Tests.Writers.Powerpoint (tests) where
55import Control.Exception (throwIO)
66import Text.Pandoc
77import Text.Pandoc.Builder
8+import Text.Pandoc.Arbitrary ()
9+import Text.Pandoc.Walk
810import Test.Tasty
911import Test.Tasty.HUnit
12+import Test.Tasty.QuickCheck
1013import Codec.Archive.Zip
11−import Data.List (isPrefixOf, isSuffixOf)
14+import Text.XML.Light
15+import Data.List (isPrefixOf, isSuffixOf, sort)
16+import Data.Maybe (mapMaybe)
17+
18+getPptxArchive :: WriterOptions -> Pandoc -> IO Archive
19+getPptxArchive opts pd = do
20+ mbs <- runIO $
21+ do setUserDataDir $ Just "../data"
22+ writePowerpoint opts pd
23+ case mbs of
24+ Left e -> throwIO e
25+ Right bs -> return $ toArchive bs
1226
1327----- Number of Slides -----------
1428
1529numberOfSlides :: WriterOptions -> Pandoc -> IO Int
1630numberOfSlides opts pd = do
17− mbs <- runIO $
18− do setUserDataDir $ Just "../data"
19− writePowerpoint opts pd
20− case mbs of
21− Left e -> throwIO e
22− Right bs -> do
23− let archive = toArchive bs
24− return $
25− length $
26− filter (isSuffixOf ".xml") $
27− filter (isPrefixOf "ppt/slides/slide") $
28− filesInArchive archive
31+ archive <- getPptxArchive opts pd
32+ return $
33+ length $
34+ filter (isSuffixOf ".xml") $
35+ filter (isPrefixOf "ppt/slides/slide") $
36+ filesInArchive archive
2937
3038testNumberOfSlides :: TestName -> Int -> WriterOptions -> Pandoc -> TestTree
3139testNumberOfSlides name n opts pd =
@@ -101,6 +109,61 @@ numSlideTests = testGroup "Number of slides in output"
101109 para $ text "Foo" <> note (para "note text"))
102110 ]
103111
112+----- Content Types -----------
113+
114+
115+contentTypesFileExists :: WriterOptions -> Pandoc -> TestTree
116+contentTypesFileExists opts pd =
117+ testCase "Existence of [Content_Types].xml file" $
118+ do archive <- getPptxArchive opts pd
119+ assertBool "Missing [Content_Types].xml file" $
120+ "[Content_Types].xml" `elem` (filesInArchive archive)
121+
122+
123+
124+-- We want an "Override" entry for each xml file under ppt/.
125+prop_ContentOverrides :: Pandoc -> IO Bool
126+prop_ContentOverrides pd = do
127+ -- remove Math to avoid warnings
128+ let go :: Inline -> Inline
129+ go (Math _ _) = Str "Math"
130+ go i = i
131+ pd' = walk go pd
132+ archive <- getPptxArchive def pd'
133+ let xmlFiles = filter ("[Content_Types].xml" /=) $
134+ filter (isSuffixOf ".xml") $
135+ filesInArchive archive
136+ contentTypes <- case findEntryByPath "[Content_Types].xml" archive of
137+ Just ent -> return $ fromEntry ent
138+ Nothing -> throwIO $
139+ PandocSomeError "Missing [Content_Types].xml file"
140+ typesElem <- case parseXMLDoc contentTypes of
141+ Just element -> return $ element
142+ Nothing -> throwIO $
143+ PandocSomeError "[Content_Types].xml cannot be parsed"
144+ let ns = findAttr (QName "xmlns" Nothing Nothing) typesElem
145+ overrides = findChildren (QName "Override" ns Nothing) typesElem
146+ partNames = mapMaybe (findAttr (QName "PartName" Nothing Nothing)) overrides
147+ -- files in content_types are absolute
148+ absXmlFiles = map (\fp -> case fp of
149+ ('/':_) -> fp
150+ _ -> '/': fp
151+ )
152+ xmlFiles
153+ return $ sort absXmlFiles == sort partNames
154+
155+contentOverridesTests :: TestTree
156+contentOverridesTests = localOption (QuickCheckTests 20) $
157+ testProperty "Content Overrides for each XML file" $
158+ \x -> ioProperty $ prop_ContentOverrides (x :: Pandoc)
159+
160+contentTypeTests :: TestTree
161+contentTypeTests = testGroup "[Content_Types].xml file"
162+ [ contentTypesFileExists def (doc $ para "foo")
163+ , contentOverridesTests
164+ ]
104165
105166tests :: [TestTree]
106−tests = [numSlideTests]
167+tests = [ numSlideTests
168+ , contentTypeTests
169+ ]