7import Data.Char (isLetter)
8import qualified Data.IntMap as IMap
10import Data.Monoid ((<>))
13import Options.Applicative
14import System.Directory
15import System.Environment
17import System.FilePath ((</>))
22import Test.Tasty.Golden
23import Test.Tasty.Ingredients.Rerun
24import Test.Tasty.Options
25import Test.Tasty.Runners
27--------------------------------------------------------------------- [ Config ]
31-- Add arguments to calls of idris executable
35testDirectory :: String
38-------------------------------------------------------------------- [ Options ]
40-- The `--node` option makes idris use the node code generator
41-- As a consequence, incompatible tests are removed
43newtype NodeOpt = NodeOpt Bool deriving (Eq, Ord, Typeable)
46nodeHelp = "Performs the tests with the node code generator"
47instance IsOption NodeOpt where
48 defaultValue = NodeOpt False
49 parseValue = fmap NodeOpt . safeRead
50 optionName = return nodeArg
51 optionHelp = return nodeHelp
52 optionCLParser = NodeOpt <$> switch (long nodeArg <> help nodeHelp)
54ingredients :: [Ingredient]
55ingredients = defaultIngredients ++
56 [rerunningTests [consoleTestReporter],
57 includingOptions [Option (Proxy :: Proxy NodeOpt)] ]
59----------------------------------------------------------------------- [ Core ]
61-- Compare a given file contents against the golden file contents
62-- A ripoff of goldenVsFile from Tasty.Golden
63test :: String -> String -> IO () -> TestTree
64test testName path = goldenVsFileDiff testName diff ref output
66 ref = path </> "expected"
67 output = path </> "output"
68 diff ref new | os == "openbsd" = ["diff", "-u", new, ref]
69 | otherwise = ["diff", "--strip-trailing-cr", "-u", new, ref]
71-- Should always output a 3-charater string from a postive Int
72indexToString :: Int -> String
73indexToString index = let str = show index in
74 replicate (3 - length str) '0' ++ str
76-- Turns the collection of TestFamily into actual tests usable by Tasty
77mkGoldenTests :: [TestFamily] -> Flags -> TestTree
78mkGoldenTests testFamilies flags =
79 testGroup "Regression and feature tests"
80 (fmap mkTestFamily testFamilies)
82 mkTestFamily (TestFamily id name tests) =
83 testGroup name (fmap (mkTest id) (IMap.keys tests))
85 let testname = id ++ indexToString index
86 path = testDirectory </> testname
88 test testname path (runTest path flags)
91-- "bash" needed because Haskell has cmd as the default shell on windows, and
92-- we also want to run the process with another current directory, so we get
94runTest :: String -> Flags -> IO ()
95runTest path flags = do
96 let run = (proc "bash" ("run" : flags)) {cwd = Just path}
97 (_, output, error_out) <- readCreateProcessWithExitCode run ""
98 writeFile (path </> "output") (normalise output)
99 when (error_out /= "") $ hPutStrLn stderr ("\nError: " ++ path ++ "\n" ++ error_out)
101 -- Normalise paths e.g. '.\foo.idr' to './foo.idr'.
102 -- Also embedded paths e.g. ".\\Prelude\\List.idr" to "./Prelude/List.idr".
103 normalise ('.' : '\\' : c : xs) | isLetter c = '.' : '/' : c : normalise xs
104 normalise ('\\':'\\':xs) = '/' : normalise xs
105 normalise (x : xs) = x : normalise xs
110 nodePath <- findExecutable "node"
111 nodejsPath <- findExecutable "nodejs"
112 let node = nodePath <|> nodejsPath
115 putStrLn "For running the test suite against Node, node must be installed."
118 defaultMainWithIngredients ingredients $
119 askOption $ \(NodeOpt node) ->
120 let (codegen, flags) = if node then (JS, ["--codegen", "node"])
123 mkGoldenTests (testFamiliesForCodegen codegen)
124 (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