@@ -1,247 +0,0 @@
2−{-# LANGUAGE OverloadedStrings #-}
3−{-# LANGUAGE ScopedTypeVariables #-}
4−module Test.Compiler (compilerTests) where
6−import Control.Exception (try, IOException)
8−import qualified Data.Text.Lazy as LText
9−import qualified Data.Text.Lazy.IO as LText
10−import qualified Data.Map as Map
11−import Data.Maybe (isJust)
12−import qualified Data.Text.IO as Text
13−import Data.Text (Text)
15−import System.Directory (createDirectoryIfMissing)
16−import System.Environment (lookupEnv)
17−import System.FilePath ((</>), (<.>), dropFileName, joinPath, splitDirectories)
18−import System.FilePath.Find (find, (==?), extension)
21−import Test.Framework.Providers.HUnit (testCase)
22−import Test.HUnit (Assertion, assertFailure, assertBool, assertEqual)
24−import qualified Elm.Compiler as Compiler
25−import qualified Elm.Package as Package
26−import qualified AST.Module as Module
27−import qualified AST.Module.Name as ModuleName
28−import qualified AST.Variable as Variable
29−import qualified AST.Type as Type
36−writeExpectedJsEnvVarName :: String
37−writeExpectedJsEnvVarName =
38− "ELM_WRITE_NEW_EXPECTED"
44− do goods <- testIf isSuccess =<< getElms "good"
45− bads <- testIf isFailure =<< getElms "bad"
46− expectedJsTests <- testMatchesExpected "good" "good-expected-js"
48− testGroup "Compile Tests"
49− [ testGroup "Good Tests" goods
50− , testGroup "Bad Tests" bads
51− , testGroup "Expected JS Tests" expectedJsTests
59−getElms :: FilePath -> IO [FilePath]
63− (extension ==? ".elm")
64− (testsDir </> filePath)
69− "tests" </> "test-files"
72−convertToExpectedJsFilePath :: String -> FilePath -> FilePath
73−convertToExpectedJsFilePath expectedJsDir filePath =
76− </> joinPath (drop 3 (splitDirectories filePath))
84−compile :: FilePath -> Text -> Either String Compiler.Result
85−compile filePath source =
88− Compiler.Context Package.core False importDict interfaces
90− (dealiaser, _warnings, result) =
91− Compiler.compile context source
93− formatErrors errors =
94− concatMap (Compiler.errorToString dealiaser filePath source) errors
96− either (Left . formatErrors) Right result
99−importDict :: Map.Map ModuleName.Raw ModuleName.Canonical
103− ( ModuleName._module name, name )
105− Map.fromList $ map toPair $ Map.keys interfaces
108−interfaces :: Module.Interfaces
112− (ModuleName.inCore "Debug",
115− ("crash", Type.Lambda (Type.Var "String") (Type.Var "a"))
121−buildCoreInterface :: [(Text, Type.Canonical)] -> Module.Interface
122−buildCoreInterface members =
124− exports = map (Variable.Value . fst) members
126− types = Map.fromList members
131− Module.Interface Compiler.version Package.core exports imports types adts aliases fixities
138−readFileOrErrorStr :: FilePath -> IO String
139−readFileOrErrorStr filePath =
140− do strOrExc <- try $ readFile filePath
145− Left (e :: IOException) ->
154− :: (Either String Compiler.Result -> Assertion)
157−testIf handleResult filePaths =
158− let doTest filePath =
159− do source <- Text.readFile filePath
160− let formattedResult = compile filePath source
161− return $ testCase filePath (handleResult formattedResult)
163− traverse doTest filePaths
166−doMatchesExpectedTest :: String -> FilePath -> IO Test
167−doMatchesExpectedTest expectedJsDir filePath =
168− do source <- Text.readFile filePath
169− expectedJs <- readFileOrErrorStr (convertToExpectedJsFilePath expectedJsDir filePath)
171− let formattedResult = compile filePath source
172− let assertion = matchesExpected expectedJs formattedResult
174− return $ testCase filePath assertion
177−doWriteNewExpectedTest :: String -> FilePath -> IO Test
178−doWriteNewExpectedTest expectedJsDir filePath =
179− do source <- Text.readFile filePath
180− let formattedResult = compile filePath source
181− let expectedFilePath = convertToExpectedJsFilePath expectedJsDir filePath
183− case formattedResult of
184− Right (Compiler.Result _ _ js) ->
185− do createDirectoryIfMissing True (dropFileName expectedFilePath)
186− -- Force the evaluation of `js` before `writeFile`
187− -- so that if an error is raised we do not unintentionally write an empty file.
188− -- NB: `js` can be an empty string in the case of NoExpressions.elm
189− assertBool "" (LText.length js >= 0)
190− LText.writeFile expectedFilePath js
191− assertFailure ("Wrote new expected js: " ++ expectedFilePath)
194− assertFailure "Compile failed. Could not write new expected js."
195− return $ testCase filePath assertion
198−testMatchesExpected :: String -> String -> IO [Test]
199−testMatchesExpected elmDir expectedJsDir =
200− do elmFiles <- getElms elmDir
201− envVar <- lookupEnv writeExpectedJsEnvVarName
204− traverse (doWriteNewExpectedTest expectedJsDir) elmFiles
206− traverse (doMatchesExpectedTest expectedJsDir) elmFiles
213−isSuccess :: Either String a -> Assertion
219− Left errorMessages ->
220− assertFailure errorMessages
223−isFailure :: Either a b -> Assertion
227− assertFailure "Compilation succeeded but should have failed"
233−matchesExpected :: String -> Either String Compiler.Result -> Assertion
234−matchesExpected expectedJs result =
236− Right (Compiler.Result _ _ js) ->
237− assertEqual matchFailureMessage (LText.pack expectedJs) js
239− Left errorMessages ->
240− assertFailure $ "Compile failed:\n" ++ errorMessages
243−matchFailureMessage :: String
244−matchFailureMessage =
245− "Compiled JS did not match expected JS." ++
246− "\n If the change is intentional, rerun " ++
247− "the tests with environment variable: " ++ writeExpectedJsEnvVarName ++ "=1"