summaryrefslogtreecommitdiff
path: root/source/Test/Golden.hs
blob: e230c2688daf137b9945c593ce298b2e3cc31867 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
{-# LANGUAGE NoImplicitPrelude #-}
{-# LANGUAGE RecordWildCards #-}

module Test.Golden where


import Api qualified
import Base

import Data.Text.Lazy.IO qualified as LazyTextIO
import System.Directory
import System.FilePath
import Test.Tasty
import Test.Tasty.Golden (goldenVsFile, findByExtension)
import Text.Pretty.Simple (pShowNoColor)
import UnliftIO
goldenTests :: IO TestTree
goldenTests = goldenTestGroup

goldenTestGroup :: MonadUnliftIO io => io TestTree
goldenTestGroup = testGroup "golden tests" <$> sequence
    [ tokenizing
    , scanning
    , parsing
    ]


-- | A testing triple consists of a an 'input' file, which is proccesed, resulting
-- in 'output' file, which is then compared to a 'golden' file.
data Triple = Triple
    { input  :: FilePath
    , output :: FilePath
    , golden :: FilePath
    }
    deriving (Show, Eq)


-- | Gathers all the files for the test. We test all examples and everything in @test/pass/@.
-- The golden files for all tests are stored in @test/pass/@, so we need to adjust the filepath
-- of the files from @examples/@.
gatherTriples :: MonadIO io => String -> io [Triple]
gatherTriples stage = do
    inputs <- liftIO (findByExtension [".tex"] "test/examples")
    pure $
        [ Triple{..}
        | input <- inputs
        , let input' = "test" </> "golden" </> takeBaseName input </> stage
        , let golden = input' <.> "golden"
        , let output = input' <.> "out"
        ]

createTripleDirectoriesIfMissing :: MonadIO io => Triple -> io ()
createTripleDirectoriesIfMissing Triple{..} = liftIO $
    createDirectoryIfMissing True (takeDirectory output)

makeGoldenTest :: MonadUnliftIO io => String -> (Triple -> io ()) -> io TestTree
makeGoldenTest stage action = do
    triples <- gatherTriples stage
    for triples createTripleDirectoriesIfMissing
    runInIO <- askRunInIO
    pure $ testGroup stage
        [ goldenVsFile
            (takeBaseName input) -- test name
            golden
            output
            (runInIO (action triple))
        | triple@Triple{..} <- triples
        ]

tokenizing :: MonadUnliftIO io => io TestTree
tokenizing = makeGoldenTest "tokenizing" $ \Triple{..} -> do
    tokenStream <- Api.tokenize input
    liftIO (LazyTextIO.writeFile output (pShowNoColor (Api.simpleStream tokenStream)))


scanning :: MonadUnliftIO io => io TestTree
scanning = makeGoldenTest "scanning" $ \Triple{..} -> do
    lexicalItems <- Api.scan input
    liftIO (LazyTextIO.writeFile output (pShowNoColor lexicalItems))

parsing :: MonadUnliftIO io => io TestTree
parsing = makeGoldenTest "parsing" $ \Triple{..} -> do
    parseResult <- Api.parse input
    liftIO (LazyTextIO.writeFile output (pShowNoColor parseResult))