git.iko.soy/rowtype-yoga/purescript-native
on golang help sign in
Merge pull request #1323 from hdgarrood/should-fail-with
464af8ePhil Freeman
examples/failing/365.purs+1
@@ -1,3 +1,4 @@
1+-- @shouldFailWith CycleInDeclaration
1module Main where
2module Main where
2
3
3import Prelude
4import Prelude
examples/failing/438.purs+6−2
@@ -1,3 +1,8 @@
1+-- @shouldFailWith NoInstanceFound
2+
3+-- See issue 438 for details: this test is mainly here to test that code like
4+-- this doesn't cause the compiler to loop.
5+
1module Main where
6module Main where
2
7
3import Prelude
8import Prelude
@@ -5,7 +10,6 @@ import Prelude
5data Fix f = In (f (Fix f))
10data Fix f = In (f (Fix f))
6
11
7instance eqFix :: (Eq (f (Fix f))) => Eq (Fix f) where
12instance eqFix :: (Eq (f (Fix f))) => Eq (Fix f) where
8− (==) (In f) (In g) = f == g
13+ eq (In f) (In g) = f == g
9− (/=) a b = not (a == b)
10
14
11example = In [] == In []
15example = In [] == In []
examples/failing/ArrayType.purs+2
@@ -1,3 +1,5 @@
1+-- @shouldFailWith TypesDoNotUnify
2+
1module Main where
3module Main where
2
4
3import Prelude
5import Prelude
examples/failing/Arrays.purs+3
@@ -1,5 +1,8 @@
1+-- @shouldFailWith ExprDoesNotHaveType
1module Main where
2module Main where
2
3
3import Prelude
4import Prelude
4
5
6+foreign import (!!) :: forall a. Array a -> Int -> a
7+
5test = \arr -> arr !! (0 !! 0)
8test = \arr -> arr !! (0 !! 0)
examples/failing/CaseDoesNotMatchAllConstructorArgs.purs+1
@@ -1,3 +1,4 @@
1+-- @shouldFailWith IncorrectConstructorArity
1module Main where
2module Main where
2
3
3import Prelude
4import Prelude
examples/failing/Do.purs+2
@@ -1,3 +1,5 @@
1+-- @shouldFailWith InvalidDoBind
2+-- @shouldFailWith InvalidDoLet
1module Main where
3module Main where
2
4
3import Prelude
5import Prelude
examples/failing/DoNotSuggestComposition.purs+3
@@ -1,3 +1,6 @@
1+-- @shouldFailWith TypesDoNotUnify
2+-- TODO: Check that this does not produce a "function composition is (<<<)"
3+-- suggestion.
1module DoNotSuggestComposition where
4module DoNotSuggestComposition where
2
5
3import Prelude
6import Prelude
examples/failing/DoNotSuggestComposition2.purs+4
@@ -1,3 +1,7 @@
1+-- @shouldFailWith CannotApplyFunction
2+-- TODO: Check that this does not produce a "function composition is (<<<)"
3+-- suggestion.
4+
1module DoNotSuggestComposition2 where
5module DoNotSuggestComposition2 where
2
6
3foo = let x = { y: 3 } in x 2
7foo = let x = { y: 3 } in x 2
examples/failing/DuplicateDeclarationsInLet.purs+1
@@ -1,3 +1,4 @@
1+-- @shouldFailWith OverlappingNamesInLet
1module Main where
2module Main where
2
3
3import Prelude
4import Prelude
examples/failing/DuplicateProperties1.purs+1
@@ -1,3 +1,4 @@
1+-- @shouldFailWith TypesDoNotUnify
1module DuplicateProperties where
2module DuplicateProperties where
2
3
3import Prelude
4import Prelude
examples/failing/DuplicateProperties2.purs+1
@@ -1,3 +1,4 @@
1+-- @shouldFailWith DuplicateLabel
1module DuplicateProperties where
2module DuplicateProperties where
2
3
3import Prelude
4import Prelude
examples/failing/DuplicateTypeVars.purs+1
@@ -1,3 +1,4 @@
1+-- @shouldFailWith DuplicateTypeArgument
1module Main where
2module Main where
2
3
3import Prelude
4import Prelude
examples/failing/Eff.purs+1
@@ -1,3 +1,4 @@
1+-- @shouldFailWith TypesDoNotUnify
1module Main where
2module Main where
2
3
3import Prelude
4import Prelude
examples/failing/ExtraRecordField.purs+2−1
@@ -1,4 +1,5 @@
1−
1+-- @shouldFailWith PropertyIsMissing
2+-- TODO: Make this fail with a new error ExtraProperty instead.
2module ExtraRecordField where
3module ExtraRecordField where
3
4
4import Prelude ((<>))
5import Prelude ((<>))
examples/failing/Foldable.purs+1
@@ -1,3 +1,4 @@
1+-- @shouldFailWith CycleInDeclaration
1module Main where
2module Main where
2
3
3import Prelude
4import Prelude
examples/failing/InstanceExport.purs+2
@@ -1,3 +1,4 @@
1+-- @shouldFailWith TransitiveExportError
1module InstanceExport (S(..), f) where
2module InstanceExport (S(..), f) where
2
3
3import Prelude
4import Prelude
@@ -13,5 +14,6 @@ instance fs :: F S where
13module Test where
14module Test where
14
15
15import InstanceExport
16import InstanceExport
17+import Prelude
16
18
17test = f $ S "Test"
19test = f $ S "Test"
examples/failing/KindError.purs+1
@@ -1,3 +1,4 @@
1+-- @shouldFailWith KindsDoNotUnify
1module Main where
2module Main where
2
3
3import Prelude
4import Prelude
examples/failing/LeadingZeros1.purs+1
@@ -1,3 +1,4 @@
1+-- @shouldFailWith ErrorParsingModule
1module Main where
2module Main where
2
3
3import Prelude
4import Prelude
examples/failing/LeadingZeros2.purs+1
@@ -1,3 +1,4 @@
1+-- @shouldFailWith ErrorParsingModule
1module Main where
2module Main where
2
3
3import Prelude
4import Prelude
examples/failing/Let.purs+1
@@ -1,3 +1,4 @@
1+-- @shouldFailWith CycleInDeclaration
1module Main where
2module Main where
2
3
3import Prelude
4import Prelude
examples/failing/MPTCs.purs+1
@@ -1,3 +1,4 @@
1+-- @shouldFailWith KindsDoNotUnify
1module Main where
2module Main where
2
3
3import Prelude
4import Prelude
examples/failing/MissingClassExport.purs+1
@@ -1,3 +1,4 @@
1+-- @shouldFailWith TransitiveExportError
1module Test (bar) where
2module Test (bar) where
2
3
3import Prelude
4import Prelude
examples/failing/MissingClassMemberExport.purs+1
@@ -1,3 +1,4 @@
1+-- @shouldFailWith TransitiveExportError
1module Test (Foo) where
2module Test (Foo) where
2
3
3import Prelude
4import Prelude
examples/failing/MissingRecordField.purs+2−1
@@ -1,4 +1,5 @@
1−
1+-- @shouldFailWith TypesDoNotUnify
2+-- TODO: Update type checker to make this fail with PropertyIsMissing instead.
2module MissingRecordField where
3module MissingRecordField where
3
4
4import Prelude ((>))
5import Prelude ((>))
examples/failing/MultipleErrors.purs+4−2
@@ -1,11 +1,13 @@
1+-- @shouldFailWith ExprDoesNotHaveType
2+-- @shouldFailWith ExprDoesNotHaveType
1module MultipleErrors where
3module MultipleErrors where
2
4
3import Prelude
5import Prelude
4
6
5−foo :: Number -> Number
7+foo :: Int -> Int
6foo 0 = "Test"
8foo 0 = "Test"
7foo n = bar (n - 1)
9foo n = bar (n - 1)
8
10
9−bar :: Number -> Number
11+bar :: Int -> Int
10bar 0 = "Test"
12bar 0 = "Test"
11bar n = foo (n - 1)
13bar n = foo (n - 1)
examples/failing/MultipleErrors2.purs+2
@@ -1,3 +1,5 @@
1+-- @shouldFailWith UnknownValue
2+-- @shouldFailWith UnknownValue
1module MultipleErrors2 where
3module MultipleErrors2 where
2
4
3import Prelude
5import Prelude
examples/failing/MutRec.purs+1
@@ -1,3 +1,4 @@
1+-- @shouldFailWith CycleInDeclaration
1module MutRec where
2module MutRec where
2
3
3import Prelude
4import Prelude
examples/failing/MutRec2.purs+1
@@ -1,3 +1,4 @@
1+-- @shouldFailWith CycleInDeclaration
1module Main where
2module Main where
2
3
3import Prelude
4import Prelude
examples/failing/NewtypeMultiArgs.purs+1
@@ -1,3 +1,4 @@
1+-- @shouldFailWith InvalidNewtype
1module Main where
2module Main where
2
3
3import Prelude
4import Prelude
examples/failing/NewtypeMultiCtor.purs+1
@@ -1,3 +1,4 @@
1+-- @shouldFailWith InvalidNewtype
1module Main where
2module Main where
2
3
3import Prelude
4import Prelude
examples/failing/NoOverlap.pursdeleted−13
@@ -1,13 +0,0 @@
1−module Main where
2−
3−import Prelude
4−
5−data Foo = Foo
6−
7−instance showFoo1 :: Show Foo where
8− show _ = "Foo"
9−
10−instance showFoo2 :: Show Foo where
11− show _ = "Bar"
12−
13−test = show Foo
examples/failing/NullaryAbs.purs+1
@@ -1,3 +1,4 @@
1+-- @shouldFailWith ErrorParsingModule
1module Main where
2module Main where
2
3
3import Prelude
4import Prelude
examples/failing/Object.purs+1
@@ -1,3 +1,4 @@
1+-- @shouldFailWith PropertyIsMissing
1module Main where
2module Main where
2
3
3import Prelude
4import Prelude
examples/failing/OverlappingArguments.purs+1
@@ -1,3 +1,4 @@
1+-- @shouldFailWith OverlappingArgNames
1module OverlappingArguments where
2module OverlappingArguments where
2
3
3import Prelude
4import Prelude
examples/failing/OverlappingBinders.purs+1
@@ -1,3 +1,4 @@
1+-- @shouldFailWith OverlappingArgNames
1module OverlappingBinders where
2module OverlappingBinders where
2
3
3import Prelude
4import Prelude
examples/failing/OverlappingInstances.purs+1
@@ -1,3 +1,4 @@
1+-- @shouldFailWith OverlappingInstances
1module OverlappingInstances where
2module OverlappingInstances where
2
3
3import Prelude
4import Prelude
examples/failing/OverlappingInstances2.purs+5−6
@@ -1,3 +1,4 @@
1+-- @shouldFailWith OverlappingInstances
1module OverlappingInstances where
2module OverlappingInstances where
2
3
3import Prelude
4import Prelude
@@ -5,14 +6,12 @@ import Prelude
5data A = A | B
6data A = A | B
6
7
7instance eqA1 :: Eq A where
8instance eqA1 :: Eq A where
8− (==) A A = true
9+ eq A A = true
9− (==) B B = true
10+ eq B B = true
10− (==) _ _ = false
11+ eq _ _ = false
11− (/=) x y = not (x == y)
12
12
13instance eqA2 :: Eq A where
13instance eqA2 :: Eq A where
14− (==) _ _ = true
14+ eq _ _ = true
15− (/=) _ _ = false
16
15
17instance ordA :: Ord A where
16instance ordA :: Ord A where
18 compare A B = LT
17 compare A B = LT
examples/failing/OverlappingVars.purs+1
@@ -1,3 +1,4 @@
1+-- @shouldFailWith NoInstanceFound
1module Main where
2module Main where
2
3
3import Prelude
4import Prelude
examples/failing/Rank2Types.purs+1
@@ -1,3 +1,4 @@
1+-- @shouldFailWith ExprDoesNotHaveType
1module Main where
2module Main where
2
3
3import Prelude
4import Prelude
examples/failing/Reserved.purs+1
@@ -1,3 +1,4 @@
1+-- @shouldFailWith ErrorParsingModule
1module Main where
2module Main where
2
3
3import Prelude
4import Prelude
examples/failing/RowConstructors1.purs+1
@@ -1,3 +1,4 @@
1+-- @shouldFailWith KindsDoNotUnify
1module Main where
2module Main where
2
3
3import Prelude
4import Prelude
examples/failing/RowConstructors2.purs+1
@@ -1,3 +1,4 @@
1+-- @shouldFailWith KindsDoNotUnify
1module Main where
2module Main where
2
3
3import Prelude
4import Prelude
examples/failing/RowConstructors3.purs+1
@@ -1,3 +1,4 @@
1+-- @shouldFailWith KindsDoNotUnify
1module Main where
2module Main where
2
3
3import Prelude
4import Prelude
examples/failing/SkolemEscape.purs+1
@@ -1,3 +1,4 @@
1+-- @shouldFailWith EscapedSkolem
1module Main where
2module Main where
2
3
3import Prelude
4import Prelude
examples/failing/SkolemEscape2.purs+1
@@ -1,3 +1,4 @@
1+-- @shouldFailWith EscapedSkolem
1module Main where
2module Main where
2
3
3import Prelude
4import Prelude
examples/failing/SuggestComposition.purs+2
@@ -1,3 +1,5 @@
1+-- @shouldFailWith TypesDoNotUnify
2+-- TODO: Ensure the correct suggestion is produced.
1module SuggestComposition where
3module SuggestComposition where
2
4
3import Prelude
5import Prelude
examples/failing/Superclasses1.purs+1
@@ -1,3 +1,4 @@
1+-- @shouldFailWith NoInstanceFound
1module Main where
2module Main where
2
3
3import Prelude
4import Prelude
examples/failing/Superclasses2.purs+2
@@ -1,3 +1,5 @@
1+-- @shouldFailWith CycleInTypeSynonym
2+-- TODO: Should this have its own error, perhaps CycleInTypeClassDeclaration?
1module CycleInSuperclasses where
3module CycleInSuperclasses where
2
4
3import Prelude
5import Prelude
examples/failing/Superclasses3.purs+1
@@ -1,3 +1,4 @@
1+-- @shouldFailWith UndefinedTypeVariable
1module UnknownSuperclassTypeVar where
2module UnknownSuperclassTypeVar where
2
3
3import Prelude
4import Prelude
examples/failing/Superclasses4.purs+2−1
@@ -1,3 +1,4 @@
1+-- @shouldFailWith OverlappingInstances
1module OverlappingInstances where
2module OverlappingInstances where
2
3
3import Prelude
4import Prelude
@@ -11,4 +12,4 @@ instance foo2 :: Foo Number
11test :: forall a. (Foo a) => a -> a
12test :: forall a. (Foo a) => a -> a
12test a = a
13test a = a
13
14
14−test1 = test 0
15+test1 = test 0.0
examples/failing/TopLevelCaseNoArgs.purs+1
@@ -1,3 +1,4 @@
1+-- @shouldFailWith DuplicateValueDeclaration
1module Main where
2module Main where
2
3
3import Prelude
4import Prelude
examples/failing/TypeClassInstances.purs+1
@@ -1,3 +1,4 @@
1+-- @shouldFailWith MissingClassMember
1module Main where
2module Main where
2
3
3import Prelude
4import Prelude
examples/failing/TypeClasses2.purs+1
@@ -1,3 +1,4 @@
1+-- @shouldFailWith NoInstanceFound
1module Main where
2module Main where
2
3
3import Prelude ()
4import Prelude ()
examples/failing/TypeError.purs+1
@@ -1,3 +1,4 @@
1+-- @shouldFailWith ExprDoesNotHaveType
1module Main where
2module Main where
2
3
3import Prelude
4import Prelude
examples/failing/TypeSynonyms.purs+1
@@ -1,3 +1,4 @@
1+-- @shouldFailWith CycleInTypeSynonym
1module Main where
2module Main where
2
3
3import Prelude
4import Prelude
examples/failing/TypeSynonyms2.purs+1
@@ -1,3 +1,4 @@
1+-- @shouldFailWith TypeSynonymInstance
1module Main where
2module Main where
2
3
3import Prelude
4import Prelude
examples/failing/TypeSynonyms3.purs+1
@@ -1,3 +1,4 @@
1+-- @shouldFailWith TypeSynonymInstance
1module Main where
2module Main where
2
3
3import Prelude
4import Prelude
examples/failing/TypeSynonyms4.purs+1
@@ -1,3 +1,4 @@
1+-- @shouldFailWith PartiallyAppliedSynonym
1module TypeSynonyms4 where
2module TypeSynonyms4 where
2
3
3import Prelude
4import Prelude
examples/failing/TypeSynonyms5.purs+1
@@ -1,3 +1,4 @@
1+-- @shouldFailWith CycleInTypeSynonym
1module Main where
2module Main where
2
3
3import Prelude
4import Prelude
examples/failing/TypeWildcards1.purs+1
@@ -1,3 +1,4 @@
1+-- @shouldFailWith ErrorParsingModule
1module TypeWildcards where
2module TypeWildcards where
2
3
3import Prelude
4import Prelude
examples/failing/TypeWildcards2.purs+1
@@ -1,3 +1,4 @@
1+-- @shouldFailWith ErrorParsingModule
1module TypeWildcards where
2module TypeWildcards where
2
3
3import Prelude
4import Prelude
examples/failing/TypeWildcards3.purs+1
@@ -1,3 +1,4 @@
1+-- @shouldFailWith ErrorParsingModule
1module TypeWildcards where
2module TypeWildcards where
2
3
3import Prelude
4import Prelude
examples/failing/UnderscoreModuleName.purs+1
@@ -1,3 +1,4 @@
1+-- @shouldFailWith ErrorParsingModule
1module Bad_Module where
2module Bad_Module where
2
3
3import Prelude
4import Prelude
examples/failing/UnifyInTypeInstanceLookup.purs+3
@@ -1,3 +1,6 @@
1+-- @shouldFailWith NoInstanceFound
2+-- See issue #390.
3+-- TODO: Improve this error.
1module Main where
4module Main where
2
5
3import Prelude
6import Prelude
examples/failing/UnknownType.purs+1
@@ -1,3 +1,4 @@
1+-- @shouldFailWith UnknownType
1module Main where
2module Main where
2
3
3import Prelude
4import Prelude
tests/Main.hs+75−18
@@ -18,13 +18,30 @@
18{-# LANGUAGE GeneralizedNewtypeDeriving #-}
18{-# LANGUAGE GeneralizedNewtypeDeriving #-}
19{-# LANGUAGE FlexibleInstances #-}
19{-# LANGUAGE FlexibleInstances #-}
20
20
21+-- Failing tests can specify the kind of error that should be thrown with a
22+-- @shouldFailWith declaration. For example:
23+--
24+-- "-- @shouldFailWith TypesDoNotUnify"
25+--
26+-- will cause the test to fail unless that module fails to compile with exactly
27+-- one TypesDoNotUnify error.
28+--
29+-- If a module is expected to produce multiple type errors, then use multiple
30+-- @shouldFailWith lines; for example:
31+--
32+-- -- @shouldFailWith TypesDoNotUnify
33+-- -- @shouldFailWith TypesDoNotUnify
34+-- -- @shouldFailWith TransitiveExportError
35+
21module Main (main) where
36module Main (main) where
22
37
23import qualified Language.PureScript as P
38import qualified Language.PureScript as P
24import qualified Language.PureScript.CodeGen.JS as J
39import qualified Language.PureScript.CodeGen.JS as J
25import qualified Language.PureScript.CoreFn as CF
40import qualified Language.PureScript.CoreFn as CF
26
41
27−import Data.List (isSuffixOf)
42+import Data.Char (isSpace)
43+import Data.Maybe (mapMaybe, fromMaybe)
44+import Data.List (isSuffixOf, sort, stripPrefix)
28import Data.Traversable (traverse)
45import Data.Traversable (traverse)
29import Data.Time.Clock (UTCTime())
46import Data.Time.Clock (UTCTime())
30
47
@@ -33,6 +50,7 @@ import qualified Data.Map as M
33import Control.Monad
50import Control.Monad
34import Control.Monad.IO.Class (liftIO)
51import Control.Monad.IO.Class (liftIO)
35import Control.Applicative
52import Control.Applicative
53+import Control.Arrow ((>>>))
36
54
37import Control.Monad.Reader
55import Control.Monad.Reader
38import Control.Monad.Writer
56import Control.Monad.Writer
@@ -111,6 +129,8 @@ readInput inputFiles = forM inputFiles $ \inputFile -> do
111 text <- readFile inputFile
129 text <- readFile inputFile
112 return (inputFile, text)
130 return (inputFile, text)
113
131
132+type TestM = WriterT [(FilePath, String)] IO
133+
114compile :: [FilePath] -> M.Map P.ModuleName (FilePath, P.ForeignJS) -> IO (Either P.MultipleErrors P.Environment)
134compile :: [FilePath] -> M.Map P.ModuleName (FilePath, P.ForeignJS) -> IO (Either P.MultipleErrors P.Environment)
115compile inputFiles foreigns = runTest $ do
135compile inputFiles foreigns = runTest $ do
116 fs <- liftIO $ readInput inputFiles
136 fs <- liftIO $ readInput inputFiles
@@ -120,17 +140,17 @@ compile inputFiles foreigns = runTest $ do
120assert :: [FilePath] ->
140assert :: [FilePath] ->
121 M.Map P.ModuleName (FilePath, P.ForeignJS) ->
141 M.Map P.ModuleName (FilePath, P.ForeignJS) ->
122 (Either P.MultipleErrors P.Environment -> IO (Maybe String)) ->
142 (Either P.MultipleErrors P.Environment -> IO (Maybe String)) ->
123− IO ()
143+ TestM ()
124assert inputFiles foreigns f = do
144assert inputFiles foreigns f = do
125− e <- compile inputFiles foreigns
145+ e <- liftIO $ compile inputFiles foreigns
126− maybeErr <- f e
146+ maybeErr <- liftIO $ f e
127 case maybeErr of
147 case maybeErr of
128− Just err -> putStrLn err >> exitFailure
148+ Just err -> tell [(last inputFiles, err)]
129 Nothing -> return ()
149 Nothing -> return ()
130
150
131−assertCompiles :: [FilePath] -> M.Map P.ModuleName (FilePath, P.ForeignJS) -> IO ()
151+assertCompiles :: [FilePath] -> M.Map P.ModuleName (FilePath, P.ForeignJS) -> TestM ()
132assertCompiles inputFiles foreigns = do
152assertCompiles inputFiles foreigns = do
133− putStrLn $ "Assert " ++ last inputFiles ++ " compiles successfully"
153+ liftIO . putStrLn $ "Assert " ++ last inputFiles ++ " compiles successfully"
134 assert inputFiles foreigns $ \e ->
154 assert inputFiles foreigns $ \e ->
135 case e of
155 case e of
136 Left errs -> return . Just . P.prettyPrintMultipleErrors False $ errs
156 Left errs -> return . Just . P.prettyPrintMultipleErrors False $ errs
@@ -144,13 +164,40 @@ assertCompiles inputFiles foreigns = do
144 Just (ExitFailure _, _, err) -> return $ Just err
164 Just (ExitFailure _, _, err) -> return $ Just err
145 Nothing -> return $ Just "Couldn't find node.js executable"
165 Nothing -> return $ Just "Couldn't find node.js executable"
146
166
147−assertDoesNotCompile :: [FilePath] -> M.Map P.ModuleName (FilePath, P.ForeignJS) -> IO ()
167+assertDoesNotCompile :: [FilePath] -> M.Map P.ModuleName (FilePath, P.ForeignJS) -> TestM ()
148assertDoesNotCompile inputFiles foreigns = do
168assertDoesNotCompile inputFiles foreigns = do
169+ let testFile = last inputFiles
149− putStrLn $ "Assert " ++ last inputFiles ++ " does not compile"
170+ liftIO . putStrLn $ "Assert " ++ testFile ++ " does not compile"
171+ shouldFailWith <- getShouldFailWith testFile
150 assert inputFiles foreigns $ \e ->
172 assert inputFiles foreigns $ \e ->
151 case e of
173 case e of
174+ Left errs -> do
152− Left errs -> putStrLn (P.prettyPrintMultipleErrors False errs) >> return Nothing
175+ putStrLn (P.prettyPrintMultipleErrors False errs)
176+ return $ if null shouldFailWith
177+ then Just $ "shouldFailWith declaration is missing (errors were: "
178+ ++ show (map P.errorCode (P.runMultipleErrors errs))
179+ ++ ")"
180+ else checkShouldFailWith shouldFailWith errs
181+ Right _ ->
153− Right _ -> return $ Just "Should not have compiled"
182+ return $ Just "Should not have compiled"
183+
184+ where
185+ getShouldFailWith =
186+ readFile
187+ >>> liftIO
188+ >>> fmap ( lines
189+ >>> mapMaybe (stripPrefix "-- @shouldFailWith ")
190+ >>> map trim
191+ )
192+
193+ checkShouldFailWith expected errs =
194+ let actual = map P.errorCode $ P.runMultipleErrors errs
195+ in if sort expected == sort actual
196+ then Nothing
197+ else Just $ "Expected these errors: " ++ show expected ++ ", but got these: " ++ show actual
198+
199+ trim =
200+ dropWhile isSpace >>> reverse >>> dropWhile isSpace >>> reverse
154
201
155findNodeProcess :: IO (Maybe String)
202findNodeProcess :: IO (Maybe String)
156findNodeProcess = runMaybeT . msum $ map (MaybeT . findExecutable) names
203findNodeProcess = runMaybeT . msum $ map (MaybeT . findExecutable) names
@@ -172,14 +219,24 @@ main = do
172 Right (foreigns, _) <- runExceptT $ runWriterT $ P.parseForeignModulesFromFiles foreignFiles
219 Right (foreigns, _) <- runExceptT $ runWriterT $ P.parseForeignModulesFromFiles foreignFiles
173
220
174 let passing = cwd </> "examples" </> "passing"
221 let passing = cwd </> "examples" </> "passing"
175− passingTestCases <- getDirectoryContents passing
222+ passingTestCases <- sort . filter (".purs" `isSuffixOf`) <$> getDirectoryContents passing
176− forM_ passingTestCases $ \inputFile -> when (".purs" `isSuffixOf` inputFile) $
177− assertCompiles (supportPurs ++ [passing </> inputFile]) foreigns
178 let failing = cwd </> "examples" </> "failing"
223 let failing = cwd </> "examples" </> "failing"
179− failingTestCases <- getDirectoryContents failing
224+ failingTestCases <- sort . filter (".purs" `isSuffixOf`) <$> getDirectoryContents failing
180− forM_ failingTestCases $ \inputFile -> when (".purs" `isSuffixOf` inputFile) $
225+
226+ failures <- execWriterT $ do
227+ forM_ passingTestCases $ \inputFile ->
228+ assertCompiles (supportPurs ++ [passing </> inputFile]) foreigns
229+ forM_ failingTestCases $ \inputFile ->
181− assertDoesNotCompile (supportPurs ++ [failing </> inputFile]) foreigns
230+ assertDoesNotCompile (supportPurs ++ [failing </> inputFile]) foreigns
231+
232+ if null failures
182− exitSuccess
233+ then exitSuccess
234+ else do
235+ putStrLn "Failures:"
236+ forM_ failures $ \(fp, err) ->
237+ let fp' = fromMaybe fp $ stripPrefix (failing ++ [pathSeparator]) fp
238+ in putStrLn $ fp' ++ ": " ++ err
239+ exitFailure
183
240
184fetchSupportCode :: IO ()
241fetchSupportCode :: IO ()
185fetchSupportCode = do
242fetchSupportCode = do