6import Data.Char (isLetter)
7import qualified Data.IntMap as IMap
11import Options.Applicative
12import System.Directory
13import System.Environment
15import System.FilePath ((</>))
20import Test.Tasty.Golden
21import Test.Tasty.Ingredients.Rerun
22import Test.Tasty.Options
23import Test.Tasty.Runners
25--------------------------------------------------------------------- [ Config ]
29-- Add arguments to calls of idris executable
33testDirectory :: String
36-------------------------------------------------------------------- [ Options ]
38-- The `--node` option makes idris use the node code generator
39-- As a consequence, incompatible tests are removed
41newtype NodeOpt = NodeOpt Bool deriving (Eq, Ord, Typeable)
44nodeHelp = "Performs the tests with the node code generator"
45instance IsOption NodeOpt where
46 defaultValue = NodeOpt False
47 parseValue = fmap NodeOpt . safeRead
48 optionName = return nodeArg
49 optionHelp = return nodeHelp
50 optionCLParser = NodeOpt <$> switch (long nodeArg <> help nodeHelp)
52ingredients :: [Ingredient]
53ingredients = defaultIngredients ++
54 [rerunningTests [consoleTestReporter],
55 includingOptions [Option (Proxy :: Proxy NodeOpt)] ]
57----------------------------------------------------------------------- [ Core ]
59-- Compare a given file contents against the golden file contents
60-- A ripoff of goldenVsFile from Tasty.Golden
61test :: String -> String -> IO () -> TestTree
62test testName path = goldenVsFileDiff testName diff ref output
64 ref = path </> "expected"
65 output = path </> "output"
66 diff ref new = ["diff", "--strip-trailing-cr", "-u", new, ref]
68-- Should always output a 3-charater string from a postive Int
69indexToString :: Int -> String
70indexToString index = let str = show index in
71 replicate (3 - length str) '0' ++ str
73-- Turns the collection of TestFamily into actual tests usable by Tasty
74mkGoldenTests :: [TestFamily] -> Flags -> TestTree
75mkGoldenTests testFamilies flags =
76 testGroup "Regression and feature tests"
77 (fmap mkTestFamily testFamilies)
79 mkTestFamily (TestFamily id name tests) =
80 testGroup name (fmap (mkTest id) (IMap.keys tests))
82 let testname = id ++ indexToString index
83 path = testDirectory </> testname
85 test testname path (runTest path flags)
88-- "bash" needed because Haskell has cmd as the default shell on windows, and
89-- we also want to run the process with another current directory, so we get
91runTest :: String -> Flags -> IO ()
92runTest path flags = do
93 let run = (proc "bash" ("run" : flags)) {cwd = Just path}
94 (_, output, error_out) <- readCreateProcessWithExitCode run ""
95 writeFile (path </> "output") (normalise output)
96 when (error_out /= "") $ hPutStrLn stderr ("\nError: " ++ path ++ "\n" ++ error_out)
98 -- Normalise paths e.g. '.\foo.idr' to './foo.idr'.
99 -- Also embedded paths e.g. ".\\Prelude\\List.idr" to "./Prelude/List.idr".
100 normalise ('.' : '\\' : c : xs) | isLetter c = '.' : '/' : c : normalise xs
101 normalise ('\\':'\\':xs) = '/' : normalise xs
102 normalise (x : xs) = x : normalise xs
107 defaultMainWithIngredients ingredients $
108 askOption $ \(NodeOpt node) ->
109 let (codegen, flags) = if node then (JS, ["--codegen", "node"])
112 mkGoldenTests (testFamiliesForCodegen codegen)
113 (flags ++ idrisFlags)
keysesc to close
- j k
- move down, up
- enter
- open
- esc
- back, or up a level
- 1 2 3 4
- readme, files, commits, refs
- /
- filter
- y
- copy the clone command
- c
- compare the chosen commit with another (or shift-click both)
- ?
- show or hide this list