1 {-# LANGUAGE OverloadedStrings #-}
2 {-# LANGUAGE TypeApplications #-}
3 module Golden.Splice.Utils where
5 -- Build_symantic_parser is auto-generated by Setup.hs
6 import Build_symantic_parser (ghcPath, ghcFlags, rootDir)
7 import Control.Applicative (Applicative(..))
8 import Control.Monad (Monad(..), unless, void)
9 import Data.Foldable (asum)
10 import Data.Function (($), (.), const, on)
11 import Data.Functor ((<$>), (<$))
12 import Data.Eq (Eq(..))
13 import Data.Maybe (Maybe(..))
14 import Data.Semigroup (Semigroup(..))
15 import Data.String (String, IsString(..))
16 import Data.Text (Text)
17 import Data.Tuple (fst)
18 -- import System.Environment (getEnvironment)
19 import System.FilePath (FilePath, dropExtensions, takeBaseName, (</>), (<.>), (-<.>))
20 import System.IO (IO, IOMode(..), openFile, print)
21 import Test.Tasty (TestTree)
22 import Test.Tasty.Golden (goldenVsFileDiff, goldenVsStringDiff)
23 import Text.Show (Show(..))
24 import qualified Control.Exception as IO
25 import qualified Data.List as List
26 import qualified Language.Haskell.TH as TH
27 import qualified Language.Haskell.TH.Syntax as TH
28 import qualified Language.Haskell.TH.PprLib as TH
29 import qualified System.Directory as IO
30 import qualified System.IO.Error as IO
31 import qualified System.Process as Process
32 --import qualified Text.PrettyPrint as PP
33 import qualified Turtle
40 ghcOpts = traceShowId ghcFlags <>
44 , "-dsuppress-uniques"
47 --, "-O", "-prof", "-fprof-auto-exported"
48 --, "-osuf", "p_o", "-hisuf", "p_hi"
49 -- , "-prof" --, "-fprof-auto"
50 -- , "-eventlog", "-debug"
51 -- , "-fexternal-interpreter", "-opti+RTS", "-opti-p", "-opti-L100", "-opti-ls", "-opti-xc"
52 --, "-fhpc", "-hpcdir", "-opti/home/julm/work/sourcephile/haskell/symantic-parser/dist-newstyle/build/x86_64-linux/ghc-9.0.1/symantic-parser-0.1.0.20210201/hpc/vanilla/mix/symantic-parser-test"
53 -- , "-opti-fhpc", "-opti-hpcdir", "-opti/home/julm/work/sourcephile/haskell/symantic-parser/dist-newstyle/build/x86_64-linux/ghc-9.0.1/symantic-parser-0.1.0.20210201/hpc/vanilla/mix/symantic-parser-test"
55 , "-fprint-explicit-kinds"
57 --, "-XConstraintKinds"
59 --, "-XDefaultSignatures"
61 , "-XFlexibleContexts"
62 , "-XFlexibleInstances"
65 --, "-XKindSignatures"
67 , "-XMultiParamTypeClasses"
71 , "-XScopedTypeVariables"
72 --, "-XStandaloneDeriving"
73 --, "-XStandaloneKindSignatures"
75 , "-XTypeApplications"
79 --, "-XUndecidableInstances"
82 testSplice :: FilePath -> TestTree
83 testSplice spliceFile =
84 goldenVsFileDiff (takeBaseName (dropExtensions spliceFile)) goldenDiff
85 (rootDir</>spliceFile-<.>"expected"<.>"txt")
87 h <- openFile actualFile WriteMode
88 --env <- getEnvironment
89 (_, _, _, pid) <- Process.createProcess
90 (Process.proc ghcPath (spliceFile : ghcOpts))
91 { Process.std_out = Process.UseHandle h
92 , Process.std_err = Process.UseHandle h
93 , Process.cwd = Just rootDir
95 , Process.env = Just $ traceShowId $
96 List.deleteBy ((==) `on` fst) ("HPCTIXFILE", "") env
99 void $ Process.waitForProcess pid
100 normalizeSplice actualFile
102 actualFile = rootDir</>spliceFile-<.>"actual"<.>"txt"
104 coverSplice :: IO (TH.TExp a) -> FilePath -> TestTree
105 coverSplice splice spliceFile =
106 goldenVsStringDiff (takeBaseName (dropExtensions spliceFile)) goldenDiff
107 (rootDir</>spliceFile) $ do
110 fromString <$> Process.readProcess "ormolu"
111 [ "-o", "-XMagicHash"
112 , "-o", "-XUnboxedTuples"
113 , "-o", "-XBangPatterns"
114 , "-o", "-XTypeApplications" ]
115 (show (TH.ppr (TH.unType tExp)))
117 return $ fromString $ PP.renderStyle PP.Style
118 { PP.lineLength = 100
119 , PP.ribbonsPerLine = 0.1
120 , PP.mode = PP.PageMode
121 } $ TH.to_HPJ_Doc $ TH.ppr $ TH.unType tExp
124 normalizeSplice :: FilePath -> IO ()
125 normalizeSplice = Turtle.inplace pat . fromString
127 pat :: Turtle.Pattern Text
129 [ "(0,0)-(0,0)" <$ numPair <* "-" <* numPair
130 , ":0:0:" <$ ":" <* d <* ":" <* d <* "-" <* d
131 , ":0:0" <$ ":" <* d <* ":" <* d
132 , fromString @Text . numPeriod <$> Turtle.lowerBounded 10 Turtle.digit
133 , fromString @Text . ('%' <$) <$> Turtle.lowerBounded 10 punctSym
134 -- Remove pretty-printed references to the symantic-parser package
135 -- (e.g., turn `symantic-parser-1.2.3:Catcher` into `Catcher`)
136 -- to make the output more stable.
137 , "" <$ "symantic-parser-" <* verNum <* ":"
139 verNum = d `Turtle.sepBy` Turtle.char '.'
140 numPair = () <$ "(" <* d <* "," <* d <* ")"
141 punctSym = Turtle.oneOf "!#$%&*+./>"
142 numPeriod = List.zipWith const (List.cycle "0123456789876543210")
143 d = Turtle.some Turtle.digit
145 rmFile :: FilePath -> IO ()
147 IO.catchIOError (IO.removeFile path) $ \exn ->
148 unless (IO.isDoesNotExistError exn) $