fay-0.24.2.0: src/tests/Test/Compile.hs
{-# LANGUAGE CPP #-}
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE RecordWildCards #-}
{-# LANGUAGE TemplateHaskell #-}
module Test.Compile (tests,runScriptFile) where
import Fay
import Fay.Compiler.Prelude
import Language.Haskell.Exts
import Test.Tasty
import Test.Tasty.HUnit
import Test.Tasty.TH
tests :: TestTree
tests = $testGroupGenerator
case_imports :: Assertion
case_imports = do
cfg <- defConf
res <- compileFile cfg fp
assertBool "Could not compile file with imports" (isRight res)
case_importedList :: Assertion
case_importedList = do
cfg <- defConf
res <- compileFileWithState cfg fp
case res of
Left err -> error (show err)
Right (_,_,r) -> assertBool "RecordImport_Export was not added to stateImported" .
isJust . lookup (ModuleName () "RecordImport_Export") $ stateImported r
fp :: FilePath
fp = "tests/RecordImport_Import.hs"
case_stateRecordTypes :: Assertion
case_stateRecordTypes = do
cfg <- defConf
res <- compileFileWithState cfg "tests/Compile/Records.hs"
case res of
Left err -> error (show err)
Right (_,_,r) ->
-- TODO order should not matter
assertEqual "stateRecordTypes mismatch"
[ ("Compile.Records.T", ["Compile.Records.:+"])
, ("Compile.Records.R", ["Compile.Records.R","Compile.Records.S"])
]
(filter (isFromMod "Compile.Records") $ stateRecordTypes r)
case_importStateRecordTypes :: Assertion
case_importStateRecordTypes = do
cfg <- defConf
res <- compileFileWithState cfg "tests/Compile/ImportRecords.hs"
case res of
Left err -> error (show err)
Right (_,_,r) ->
-- TODO order should not matter
assertEqual "stateRecordTypes mismatch"
[ ("Compile.Records.T",["Compile.Records.:+"])
, ("Compile.Records.R",["Compile.Records.R", "Compile.Records.S"])
]
(filter (isFromMod "Compile.Records") $ stateRecordTypes r)
isFromMod :: String -> (QName (),[QName ()]) -> Bool
isFromMod modName = (==) modName . getModuleName . fst
where
getModuleName (Qual _ (ModuleName _ n) _) = n
getModuleName x = error $ "getModuleName: expected qualified name: " ++ show x
case_typecheckCPP :: Assertion
case_typecheckCPP = do
cfg <- defConf
res <- compileFile cfg { configTypecheck = True, configFilePath = Just "tests/Compile/CPPTypecheck.hs" } "tests/Compile/CPPTypecheck.hs"
either (assertFailure . show) (const $ return ()) res
case_cppMultiLineStrings :: Assertion
case_cppMultiLineStrings = do
cfg <- defConf
res <- compileFile cfg { configTypecheck = True, configFilePath = Just "tests/Compile/CPPMultiLineStrings.hs" } "tests/Compile/CPPMultiLineStrings.hs"
either (assertFailure . show) (const $ return ()) res
case_strictWrapper :: Assertion
case_strictWrapper = do
cfg <- defConf
res <- compileFile cfg { configTypecheck = True, configFilePath = Just "tests/Compile/StrictWrapper.hs", configStrict = ["StrictWrapper"] } "tests/Compile/StrictWrapper.hs"
let isTs = configTypeScript cfg
suffix = if isTs then ".ts" else ".js"
(\a b -> either a b res) (assertFailure . show) $ \js -> do
writeFile ("tests/Compile/StrictWrapper" ++ suffix) js
(err, out) <- either id id <$> runScriptFile isTs ("tests/Compile/StrictWrapper" ++ suffix)
when (err /= "") $ assertFailure err
expected <- readFile "tests/Compile/StrictWrapper.res"
assertEqual "strictWrapper node stdout" expected out
assertPretty :: Config -> String -> Assertion
assertPretty cfg flagName = do
let isTs = configTypeScript cfg
suffix = if isTs then ".ts" else ".js"
res <- compileFile cfg $ "tests/Compile/" ++ flagName ++ ".hs"
case res of
Left l -> assertFailure $ "Should compile, but failed with: " ++ show l
Right js -> do
writeFile ("tests/Compile/" ++ flagName ++ suffix) js
(err, out) <- either id id <$> runScriptFile isTs
("tests/Compile/" ++ flagName ++ suffix)
when (err /= "") $ assertFailure err
expected <- readFile $ "tests/Compile/" ++ flagName ++ ".res"
assertEqual (flagName ++ " node stdout") expected out
case_pretty :: Assertion
case_pretty = do
cfg <- defConf
assertPretty cfg { configPrettyPrint = True } "pretty"
case_prettyThunks :: Assertion
case_prettyThunks = do
cfg <- defConf
assertPretty cfg { configPrettyThunks = True } "prettyThunks"
case_prettyOperators :: Assertion
case_prettyOperators = do
cfg <- defConf
assertPretty cfg { configPrettyOperators = True } "prettyOperators"
case_charEnum :: Assertion
case_charEnum = do
cfg <- defConf
res <- compileFile cfg { configTypecheck = True, configFilePath = Just "tests/Compile/EnumChar.hs" } "tests/Compile/EnumChar.hs"
case res of
Left UnsupportedEnum{} -> return ()
Left l -> assertFailure $ "Should have failed with UnsupportedEnum, but failed with: " ++ show l
Right _ -> assertFailure "Should have failed with UnsupportedEnum, but compiled"
defConf :: IO Config
defConf = do
cfg <- defaultConfigWithSandbox
return $ addConfigDirectoryIncludePaths ["tests/"] cfg { configTypecheck = False }
-- | Run a JS or TS file.
runScriptFile :: Bool -- ^ If a file-format is TypeScript, this is True.
-> String -- ^ A name of script file
-> IO (Either (String,String) (String,String))
runScriptFile True file = do
tsc_ret <- readAllFromProcess "tsc" [file] ""
case tsc_ret of
Left _ -> return tsc_ret
Right _ -> readAllFromProcess "node" [(reverse (drop 3 (reverse file))) ++ ".js" ] ""
runScriptFile False file = readAllFromProcess "node" [file] ""