git.iko.soy/rowtype-yoga/purescript-native
on golang help sign in
Merge pull request #2085 from purescript/test-hspec-compiler

Use HSpec for the compiler tests

commit87074a43306845c21ae1cad451fb94b5f1571cb4 authorGary Burgess <gary.burgess@gmail.com> dateMon 2 May 2016, 17:18 (10 years ago) parentac2b456b87b0f7
60 files changed+541−431
examples/passing/1335.purs+14−12 examples/passing/AutoPrelude.purs+11−9 examples/passing/Collatz.purs+4−1 examples/passing/Comparisons.purs+15−15 examples/passing/Console.purs+3−1 examples/passing/ConstraintInference.purs+5−2 examples/passing/ContextSimplification.purs+3−1 examples/passing/DeepCase.purs+4−4 examples/passing/Deriving.purs+5−2 examples/passing/Eff.purs+4−3 examples/passing/EqOrd.purs+4−1 examples/passing/ExtendedInfixOperators.purs+5−2 examples/passing/Fib.purs+14−11 examples/passing/FieldConsPuns.purs+13−10 examples/passing/FieldPuns.purs+10−8 examples/passing/FinalTagless.purs+4−1 examples/passing/Generalization1.purs+2−1 examples/passing/ImportHiding.purs+1 examples/passing/InferRecFunWithConstrainedArgument.purs+4−1 examples/passing/Let.purs+9−7 examples/passing/Let2.purs+4−1 examples/passing/ModuleExport.purs+2−1 examples/passing/ModuleExportDupes.purs+1 examples/passing/ModuleExportExcluded.purs+3−1 examples/passing/ModuleExportQualified.purs+3−1 examples/passing/ModuleExportSelf.purs+1 examples/passing/MonadState.purs+3−1 examples/passing/MultiArgFunctions.purs+1−1 examples/passing/NestedTypeSynonyms.purs+2−1 examples/passing/ObjectGetter.purs+5−4 examples/passing/ObjectUpdate.purs+23−20 examples/passing/ObjectUpdater.purs+2 examples/passing/ObjectWildcards.purs+1−1 examples/passing/OperatorAssociativity.purs+25−25 examples/passing/OperatorInlining.purs+3−1 examples/passing/OperatorSections.purs+2−1 examples/passing/OptionalQualified.purs+1−1 examples/passing/OverlappingInstances.purs+17−13 examples/passing/OverlappingInstances2.purs+27−23 examples/passing/OverlappingInstances3.purs+20−16 examples/passing/PartialFunction.purs+13−10 examples/passing/QualifiedQualifiedImports.purs+1−1 examples/passing/Rank2Data.purs+30−29 examples/passing/Rank2TypeSynonym.purs+3−2 examples/passing/RebindableSyntax.purs+41−39 examples/passing/RuntimeScopeIssue.purs+4−1 examples/passing/ShadowedModuleName.purs+1−1 examples/passing/ShadowedTCO.purs+21−18 examples/passing/ShadowedTCOLet.purs+12−9 examples/passing/StringEscapes.purs+17−15 examples/passing/Superclasses1.purs+4−1 examples/passing/TCO.purs+2−2 examples/passing/TailCall.purs+4−1 examples/passing/TypeClassMemberOrderChange.purs+16−13 examples/passing/TypeClasses.purs+4−2 examples/passing/UTF8Sourcefile.purs+8−10 examples/passing/Unit.purs+4−2 examples/passing/Where.purs+9−12 purescript.cabal+1−1 tests/TestCompiler.hs+66−58
examples/passing/1335.purs+14−12
@@ -1,12 +1,14 @@
1−module Main where
2−
3−import Prelude
4−import Control.Monad.Eff.Console (log)
5−
6−x :: forall a. a -> String
7−x a = y "Done"
8− where
9− y :: forall a. (Show a) => a -> String
10− y a = show (a :: a)
11−
12−main = log (x 0)
1+module Main where
2+
3+import Prelude
4+import Control.Monad.Eff.Console (log)
5+
6+x :: forall a. a -> String
7+x a = y "Test"
8+ where
9+ y :: forall a. (Show a) => a -> String
10+ y a = show (a :: a)
11+
12+main = do
13+ log (x 0)
14+ log "Done"
examples/passing/AutoPrelude.purs+11−9
@@ -1,9 +1,11 @@
1−module Main where
2−
3−import Prelude
4−import Control.Monad.Eff.Console
5−
6−f x = x * 10.0
7−g y = y - 10.0
8−
9−main = log $ show $ (f <<< g) 100.0
1+module Main where
2+
3+import Prelude
4+import Control.Monad.Eff.Console (log)
5+
6+f x = x * 10.0
7+g y = y - 10.0
8+
9+main = do
10+ log $ show $ (f <<< g) 100.0
11+ log "Done"
examples/passing/Collatz.purs+4−1
@@ -3,6 +3,7 @@ module Main where
33import Prelude
44import Control.Monad.Eff
55import Control.Monad.ST
6+import Control.Monad.Eff.Console (log, logShow)
67
78collatz :: Int -> Int
89collatz n = runPure (runST (do
@@ -15,4 +16,6 @@ collatz n = runPure (runST (do
1516 pure $ m == 1
1617 readSTRef count))
1718
18−main = Control.Monad.Eff.Console.logShow $ collatz 1000
19+main = do
20+ logShow $ collatz 1000
21+ log "Done"
examples/passing/Comparisons.purs+15−15
@@ -1,15 +1,15 @@
1−module Main where
2−
3−import Prelude
4−import Control.Monad.Eff
5−import Control.Monad.Eff.Console
6−import Test.Assert
7−
8−main = do
9− assert (1.0 < 2.0)
10− assert (2.0 == 2.0)
11− assert (3.0 > 1.0)
12− assert ("a" < "b")
13− assert ("a" == "a")
14− assert ("z" > "a")
15− log "Done!"
1+module Main where
2+
3+import Prelude
4+import Control.Monad.Eff
5+import Control.Monad.Eff.Console
6+import Test.Assert
7+
8+main = do
9+ assert (1.0 < 2.0)
10+ assert (2.0 == 2.0)
11+ assert (3.0 > 1.0)
12+ assert ("a" < "b")
13+ assert ("a" == "a")
14+ assert ("z" > "a")
15+ log "Done"
examples/passing/Console.purs+3−1
@@ -10,4 +10,6 @@ replicateM_ n act = do
1010 act
1111 replicateM_ (n - 1.0) act
1212
13−main = replicateM_ 10.0 (log "Hello World!")
13+main = do
14+ replicateM_ 10.0 (log "Hello World!")
15+ log "Done"
examples/passing/ConstraintInference.purs+5−2
@@ -1,7 +1,10 @@
11module Main where
22
33import Prelude
4+import Control.Monad.Eff.Console (log)
45
5−shout = Control.Monad.Eff.Console.log <<< (_ <> "!") <<< show
6+shout = log <<< (_ <> "!") <<< show
67
7−main = shout "Done"
8+main = do
9+ shout "Test"
10+ log "Done"
examples/passing/ContextSimplification.purs+3−1
@@ -10,4 +10,6 @@ shout = log <<< (_ <> "!") <<< show
1010usesShowTwice true = shout
1111usesShowTwice false = logShow
1212
13−main = usesShowTwice true "Done"
13+main = do
14+ usesShowTwice true "Test"
15+ log "Done"
examples/passing/DeepCase.purs+4−4
@@ -1,9 +1,7 @@
11module Main where
22
33import Prelude
4−import Control.Monad.Eff.Console
5−import Control.Monad.Eff
6−import Control.Monad.ST
4+import Control.Monad.Eff.Console (log, logShow)
75
86f x y =
97 let
@@ -12,4 +10,6 @@ f x y =
1210 x -> 1.0 + x * x
1311 in g + x + y
1412
15−main = logShow $ f 1.0 10.0
13+main = do
14+ logShow $ f 1.0 10.0
15+ log "Done"
examples/passing/Deriving.purs+5−2
@@ -1,6 +1,7 @@
11module Main where
22
33import Prelude
4+import Control.Monad.Eff.Console (log)
45import Test.Assert
56
67data V
@@ -27,5 +28,7 @@ main = do
2728 assert $ X 0 < X 1
2829 assert $ X 0 < Y "Foo"
2930 assert $ Y "Bar" < Y "Baz"
30− assert $ z == z where
31− z = Z { left: X 0, right: Y "Foo" }
31+ assert $ z == z
32+ log "Done"
33+ where
34+ z = Z { left: X 0, right: Y "Foo" }
examples/passing/Eff.purs+4−3
@@ -3,7 +3,7 @@ module Main where
33import Prelude
44import Control.Monad.Eff
55import Control.Monad.ST
6−import Control.Monad.Eff.Console
6+import Control.Monad.Eff.Console (log, logShow)
77
88test1 = do
99 log "Line 1"
@@ -21,5 +21,6 @@ test3 = pureST (do
2121
2222main = do
2323 test1
24− Control.Monad.Eff.Console.logShow test2
25− Control.Monad.Eff.Console.logShow test3
24+ logShow test2
25+ logShow test3
26+ log "Done"
examples/passing/EqOrd.purs+4−1
@@ -1,6 +1,7 @@
11module Main where
22
33import Prelude
4+import Control.Monad.Eff.Console (log, logShow)
45
56data Pair a b = Pair a b
67
@@ -12,4 +13,6 @@ instance ordPair :: (Ord a, Ord b) => Ord (Pair a b) where
1213instance eqPair :: (Eq a, Eq b) => Eq (Pair a b) where
1314 eq (Pair a1 b1) (Pair a2 b2) = a1 == a2 && b1 == b2
1415
15−main = Control.Monad.Eff.Console.logShow $ Pair 1.0 2.0 == Pair 1.0 2.0
16+main = do
17+ logShow $ Pair 1.0 2.0 == Pair 1.0 2.0
18+ log "Done"
examples/passing/ExtendedInfixOperators.purs+5−2
@@ -1,9 +1,11 @@
11module Main where
22
33import Prelude
4+import Control.Monad.Eff.Console (log, logShow)
5+import Data.Function (on)
46
57comparing :: forall a b. (Ord b) => (a -> b) -> a -> a -> Ordering
6−comparing f = compare `Data.Function.on` f
8+comparing f = compare `on` f
79
810null [] = true
911null _ = false
@@ -11,4 +13,5 @@ null _ = false
1113test = [1.0, 2.0, 3.0] `comparing null` [4.0, 5.0, 6.0]
1214
1315main = do
14− Control.Monad.Eff.Console.logShow test
16+ logShow test
17+ log "Done"
examples/passing/Fib.purs+14−11
@@ -1,15 +1,18 @@
11module Main where
22
33import Prelude
4−import Control.Monad.Eff
5−import Control.Monad.ST
4+import Control.Monad.Eff (whileE)
5+import Control.Monad.Eff.Console (log, logShow)
6+import Control.Monad.ST (runST, newSTRef, readSTRef, writeSTRef)
67
7−main = runST (do
8− n1 <- newSTRef 1.0
9− n2 <- newSTRef 1.0
10− whileE ((>) 1000.0 <$> readSTRef n1) $ do
11− n1' <- readSTRef n1
12− n2' <- readSTRef n2
13− writeSTRef n2 $ n1' + n2'
14− writeSTRef n1 n2'
15− Control.Monad.Eff.Console.logShow n2')
8+main = do
9+ runST do
10+ n1 <- newSTRef 1.0
11+ n2 <- newSTRef 1.0
12+ whileE ((>) 1000.0 <$> readSTRef n1) $ do
13+ n1' <- readSTRef n1
14+ n2' <- readSTRef n2
15+ writeSTRef n2 $ n1' + n2'
16+ writeSTRef n1 n2'
17+ logShow n2'
18+ log "Done"
examples/passing/FieldConsPuns.purs+13−10
@@ -1,10 +1,13 @@
1−module Main where
2−
3−import Prelude
4−import Control.Monad.Eff.Console
5−
6−greet { greeting, name } = log $ greeting <> ", " <> name <> "."
7−
8−main = greet { greeting, name} where
9− greeting = "Hello"
10− name = "World"
1+module Main where
2+
3+import Prelude
4+import Control.Monad.Eff.Console (log, logShow)
5+
6+greet { greeting, name } = log $ greeting <> ", " <> name <> "."
7+
8+main = do
9+ greet { greeting, name }
10+ log "Done"
11+ where
12+ greeting = "Hello"
13+ name = "World"
examples/passing/FieldPuns.purs+10−8
@@ -1,8 +1,10 @@
1−module Main where
2−
3−import Prelude
4−import Control.Monad.Eff.Console
5−
6−greet { greeting, name } = log $ greeting <> ", " <> name <> "."
7−
8−main = greet { greeting: "Hello", name: "World" }
1+module Main where
2+
3+import Prelude
4+import Control.Monad.Eff.Console
5+
6+greet { greeting, name } = log $ greeting <> ", " <> name <> "."
7+
8+main = do
9+ greet { greeting: "Hello", name: "World" }
10+ log "Done"
examples/passing/FinalTagless.purs+4−1
@@ -1,6 +1,7 @@
11module Main where
22
33import Prelude hiding (add)
4+import Control.Monad.Eff.Console (log, logShow)
45
56class E e where
67 num :: Number -> e Number
@@ -19,4 +20,6 @@ runId (Id a) = a
1920three :: Expr Number
2021three = add (num 1.0) (num 2.0)
2122
22−main = Control.Monad.Eff.Console.logShow $ runId three
23+main = do
24+ logShow $ runId three
25+ log "Done"
examples/passing/Generalization1.purs+2−1
@@ -1,10 +1,11 @@
11module Main where
22
33import Prelude
4−import Control.Monad.Eff.Console (logShow)
4+import Control.Monad.Eff.Console (logShow, log)
55
66main = do
77 logShow (sum 1.0 2.0)
88 logShow (sum 1 2)
9+ log "Done"
910
1011sum x y = x + y
examples/passing/ImportHiding.purs+1
@@ -16,3 +16,4 @@ data Unit = X | Y
1616
1717main = do
1818 logShow show
19+ log "Done"
examples/passing/InferRecFunWithConstrainedArgument.purs+4−1
@@ -1,8 +1,11 @@
11module Main where
22
33import Prelude
4+import Control.Monad.Eff.Console (log, logShow)
45
56test 100.0 = 100.0
67test n = test(1.0 + n)
78
8−main = Control.Monad.Eff.Console.logShow $ test 0.0
9+main = do
10+ logShow $ test 0.0
11+ log "Done"
examples/passing/Let.purs+9−7
@@ -2,6 +2,7 @@ module Main where
22
33import Prelude
44import Control.Monad.Eff
5+import Control.Monad.Eff.Console (log, logShow)
56import Control.Monad.ST
67
78test1 x = let
@@ -44,10 +45,11 @@ test10 _ =
4445 in f 10.0
4546
4647main = do
47− Control.Monad.Eff.Console.logShow (test1 1.0)
48− Control.Monad.Eff.Console.logShow (test2 1.0 2.0)
49− Control.Monad.Eff.Console.logShow test3
50− Control.Monad.Eff.Console.logShow test4
51− Control.Monad.Eff.Console.logShow test5
52− Control.Monad.Eff.Console.logShow test7
53− Control.Monad.Eff.Console.logShow (test8 100.0)
48+ logShow (test1 1.0)
49+ logShow (test2 1.0 2.0)
50+ logShow test3
51+ logShow test4
52+ logShow test5
53+ logShow test7
54+ logShow (test8 100.0)
55+ log "Done"
examples/passing/Let2.purs+4−1
@@ -1,6 +1,7 @@
11module Main where
22
33import Prelude
4+import Control.Monad.Eff.Console (log, logShow)
45
56test =
67 let f :: Number -> Boolean
@@ -14,4 +15,6 @@ test =
1415 x = f 1.0
1516 in not x
1617
17−main = Control.Monad.Eff.Console.logShow test
18+main = do
19+ logShow test
20+ log "Done"
examples/passing/ModuleExport.purs+2−1
@@ -2,8 +2,9 @@ module A (module Prelude) where
22 import Prelude
33
44module Main where
5− import Control.Monad.Eff.Console
5+ import Control.Monad.Eff.Console (log, logShow)
66 import A
77
88 main = do
99 logShow (show 1.0)
10+ log "Done"
examples/passing/ModuleExportDupes.purs+1
@@ -17,3 +17,4 @@ module Main where
1717
1818 main = do
1919 logShow (show 1.0)
20+ log "Done"
examples/passing/ModuleExportExcluded.purs+3−1
@@ -5,10 +5,12 @@ module A (module Prelude, foo) where
55 foo _ = 0.0
66
77module Main where
8− import Control.Monad.Eff.Console
8+ import Prelude
9+ import Control.Monad.Eff.Console (log, logShow)
910 import A (foo)
1011
1112 otherwise = false
1213
1314 main = do
1415 logShow "1.0"
16+ log "Done"
examples/passing/ModuleExportQualified.purs+3−1
@@ -2,8 +2,10 @@ module A (module Prelude) where
22 import Prelude
33
44module Main where
5− import Control.Monad.Eff.Console
5+ import Prelude
6+ import Control.Monad.Eff.Console (log, logShow)
67 import A as B
78
89 main = do
910 logShow (B.show 1.0)
11+ log "Done"
examples/passing/ModuleExportSelf.purs+1
@@ -12,3 +12,4 @@ module Main where
1212
1313 main = do
1414 logShow (show bar)
15+ log "Done"
examples/passing/MonadState.purs+3−1
@@ -58,4 +58,6 @@ modify f =
5858 same :: forall a. (a -> a) -> (a -> a)
5959 same = id
6060
61−main = logShow $ runState 0 (modify (_ + 1))
61+main = do
62+ logShow $ runState 0 (modify (_ + 1))
63+ log "Done"
examples/passing/MultiArgFunctions.purs+1−1
@@ -24,4 +24,4 @@ main = do
2424 runFn9 (mkFn9 $ \a b c d e f g h i -> log $ show [a, b, c, d, e, f, g, h, i]) 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0
2525 runFn10 (mkFn10 $ \a b c d e f g h i j-> log $ show [a, b, c, d, e, f, g, h, i, j]) 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0
2626 logShow $ runFn2 g 0.0 0.0
27− log "Done!"
27+ log "Done"
examples/passing/NestedTypeSynonyms.purs+2−1
@@ -1,6 +1,7 @@
11module Main where
22
33import Prelude
4+import Control.Monad.Eff.Console (log)
45
56type X = String
67type Y = X -> X
@@ -8,4 +9,4 @@ type Y = X -> X
89fn :: Y
910fn a = a
1011
11−main = Control.Monad.Eff.Console.logShow (fn "Done")
12+main = log (fn "Done")
examples/passing/ObjectGetter.purs+5−4
@@ -1,13 +1,14 @@
11module Main where
22
33import Prelude
4+import Control.Monad.Eff.Console (log, logShow)
45
56getX = _.x
67
78point = { x: 1.0, y: 0.0 }
89
910main = do
10− Control.Monad.Eff.Console.logShow $ getX point
11− Control.Monad.Eff.Console.log $ _." 123 string Prop Name " { " 123 string Prop Name ": "OK" }
12− Control.Monad.Eff.Console.log $ (_.x >>> _.y) { x: { y: "Nested" } }
13− Control.Monad.Eff.Console.log $ _.value { value: "Done!" }
11+ logShow $ getX point
12+ log $ _." 123 string Prop Name " { " 123 string Prop Name ": "OK" }
13+ log $ (_.x >>> _.y) { x: { y: "Nested" } }
14+ log $ _.value { value: "Done" }
examples/passing/ObjectUpdate.purs+23−20
@@ -1,20 +1,23 @@
1−module Main where
2−
3−import Prelude
4−
5−update1 = \o -> o { foo = "Foo" }
6−
7−update2 :: forall r. { foo :: String | r } -> { foo :: String | r }
8−update2 = \o -> o { foo = "Foo" }
9−
10−replace = \o -> case o of
11− { foo = "Foo" } -> o { foo = "Bar" }
12− { foo = "Bar" } -> o { bar = "Baz" }
13− o -> o
14−
15−polyUpdate :: forall a r. { foo :: a | r } -> { foo :: String | r }
16−polyUpdate = \o -> o { foo = "Foo" }
17−
18−inferPolyUpdate = \o -> o { foo = "Foo" }
19−
20−main = Control.Monad.Eff.Console.log ((update1 {foo: ""}).foo)
1+module Main where
2+
3+import Prelude
4+import Control.Monad.Eff.Console (log)
5+
6+update1 = \o -> o { foo = "Foo" }
7+
8+update2 :: forall r. { foo :: String | r } -> { foo :: String | r }
9+update2 = \o -> o { foo = "Foo" }
10+
11+replace = \o -> case o of
12+ { foo = "Foo" } -> o { foo = "Bar" }
13+ { foo = "Bar" } -> o { bar = "Baz" }
14+ o -> o
15+
16+polyUpdate :: forall a r. { foo :: a | r } -> { foo :: String | r }
17+polyUpdate = \o -> o { foo = "Foo" }
18+
19+inferPolyUpdate = \o -> o { foo = "Foo" }
20+
21+main = do
22+ log ((update1 {foo: ""}).foo)
23+ log "Done"
examples/passing/ObjectUpdater.purs+2
@@ -22,3 +22,5 @@ main = do
2222
2323 let record2 = (_ { x = _ }) { x: 0.0 } 10.0
2424 assert $ record2.x == 10.0
25+
26+ log "Done"
examples/passing/ObjectWildcards.purs+1−1
@@ -17,4 +17,4 @@ main = do
1717 point <- { x: _, y: x } <$> pure 2.0
1818 assert $ point.x == 2.0
1919 assert $ point.y == 1.0
20− log (mkRecord 1.0 "Done!").bar
20+ log (mkRecord 1.0 "Done").bar
examples/passing/OperatorAssociativity.purs+25−25
@@ -1,25 +1,25 @@
1−module Main where
2−
3−import Prelude
4−import Control.Monad.Eff
5−import Control.Monad.Eff.Console
6−import Test.Assert
7−
8−bug :: Number -> Number -> Number
9−bug a b = 0.0 - (a - b)
10−
11−main = do
12− assert (bug 0.0 2.0 == 2.0)
13− assert (0.0 - (0.0 - 2.0) == 2.0)
14− assert (0.0 - (0.0 + 2.0) == -2.0)
15− assert (6.0 / (3.0 * 2.0) == 1.0)
16− assert ((6.0 / 3.0) * 2.0 == 4.0)
17− assert (not (1.0 < 0.0) == true)
18− assert (not ((negate 1.0) < 0.0) == false)
19− assert (negate (1.0 + 10.0) == -11.0)
20− assert (2.0 * 3.0 / 4.0 == 1.5)
21− assert (1.0 * 2.0 * 3.0 * 4.0 * 5.0 / 6.0 == 20.0)
22− assert (1.0 + 10.0 - 5.0 == 6.0)
23− assert (1.0 + 10.0 * 5.0 == 51.0)
24− assert (10.0 * 5.0 - 1.0 == 49.0)
25− log "Success!"
1+module Main where
2+
3+import Prelude
4+import Control.Monad.Eff
5+import Control.Monad.Eff.Console
6+import Test.Assert
7+
8+bug :: Number -> Number -> Number
9+bug a b = 0.0 - (a - b)
10+
11+main = do
12+ assert (bug 0.0 2.0 == 2.0)
13+ assert (0.0 - (0.0 - 2.0) == 2.0)
14+ assert (0.0 - (0.0 + 2.0) == -2.0)
15+ assert (6.0 / (3.0 * 2.0) == 1.0)
16+ assert ((6.0 / 3.0) * 2.0 == 4.0)
17+ assert (not (1.0 < 0.0) == true)
18+ assert (not ((negate 1.0) < 0.0) == false)
19+ assert (negate (1.0 + 10.0) == -11.0)
20+ assert (2.0 * 3.0 / 4.0 == 1.5)
21+ assert (1.0 * 2.0 * 3.0 * 4.0 * 5.0 / 6.0 == 20.0)
22+ assert (1.0 + 10.0 - 5.0 == 6.0)
23+ assert (1.0 + 10.0 * 5.0 == 51.0)
24+ assert (10.0 * 5.0 - 1.0 == 49.0)
25+ log "Done"
examples/passing/OperatorInlining.purs+3−1
@@ -1,7 +1,7 @@
11module Main where
22
33import Prelude
4−import Control.Monad.Eff.Console
4+import Control.Monad.Eff.Console (logShow, log)
55
66main = do
77
@@ -44,3 +44,5 @@ main = do
4444
4545 -- complementedLatticeBoolean
4646 logShow (not true)
47+
48+ log "Done"
examples/passing/OperatorSections.purs+2−1
@@ -1,6 +1,7 @@
11module Main where
22
33import Prelude
4+import Control.Monad.Eff.Console (log)
45import Test.Assert
56
67main = do
@@ -14,4 +15,4 @@ main = do
1415 let (//) x y = x.x / y.x
1516 assert $ (_ // foo { x = 4.0 }) { x: 4.0 } == 1.0
1617 assert $ (foo { x = 4.0 } // _) { x: 4.0 } == 1.0
17− Control.Monad.Eff.Console.log "Done!"
18+ log "Done"
examples/passing/OptionalQualified.purs+1−1
@@ -8,5 +8,5 @@ import Control.Monad.Eff.Console as Console
88bind = P.bind
99
1010main = do
11− message <- P.pure "success!"
11+ message <- P.pure "Done"
1212 Console.log message
examples/passing/OverlappingInstances.purs+17−13
@@ -1,13 +1,17 @@
1−module Main where
2−
3−import Prelude
4−
5−data A = A
6−
7−instance showA1 :: Show A where
8− show A = "Instance 1"
9−
10−instance showA2 :: Show A where
11− show A = "Instance 2"
12−
13−main = Test.Assert.assert $ show A == "Instance 1"
1+module Main where
2+
3+import Prelude
4+import Control.Monad.Eff.Console (log)
5+import Test.Assert (assert)
6+
7+data A = A
8+
9+instance showA1 :: Show A where
10+ show A = "Instance 1"
11+
12+instance showA2 :: Show A where
13+ show A = "Instance 2"
14+
15+main = do
16+ assert $ show A == "Instance 1"
17+ log "Done"
examples/passing/OverlappingInstances2.purs+27−23
@@ -1,23 +1,27 @@
1−module Main where
2−
3−import Prelude
4−
5−data A = A | B
6−
7−instance eqA1 :: Eq A where
8− eq A A = true
9− eq B B = true
10− eq _ _ = false
11−
12−instance eqA2 :: Eq A where
13− eq _ _ = true
14−
15−instance ordA :: Ord A where
16− compare A B = LT
17− compare B A = GT
18− compare _ _ = EQ
19−
20−test :: forall a. (Ord a) => a -> a -> String
21−test x y = show $ x == y
22−
23−main = Test.Assert.assert $ test A B == "false"
1+module Main where
2+
3+import Prelude
4+import Control.Monad.Eff.Console (log)
5+import Test.Assert (assert)
6+
7+data A = A | B
8+
9+instance eqA1 :: Eq A where
10+ eq A A = true
11+ eq B B = true
12+ eq _ _ = false
13+
14+instance eqA2 :: Eq A where
15+ eq _ _ = true
16+
17+instance ordA :: Ord A where
18+ compare A B = LT
19+ compare B A = GT
20+ compare _ _ = EQ
21+
22+test :: forall a. (Ord a) => a -> a -> String
23+test x y = show $ x == y
24+
25+main = do
26+ assert $ test A B == "false"
27+ log "Done"
examples/passing/OverlappingInstances3.purs+20−16
@@ -1,16 +1,20 @@
1−module Main where
2−
3−import Prelude
4−
5−class Foo a
6−
7−instance foo1 :: Foo Number
8−
9−instance foo2 :: Foo Number
10−
11−test :: forall a. (Foo a) => a -> a
12−test a = a
13−
14−test1 = test 0.0
15−
16−main = Test.Assert.assert (test1 == 0.0)
1+module Main where
2+
3+import Prelude
4+import Control.Monad.Eff.Console (log)
5+import Test.Assert (assert)
6+
7+class Foo a
8+
9+instance foo1 :: Foo Number
10+
11+instance foo2 :: Foo Number
12+
13+test :: forall a. (Foo a) => a -> a
14+test a = a
15+
16+test1 = test 0.0
17+
18+main = do
19+ assert (test1 == 0.0)
20+ log "Done"
examples/passing/PartialFunction.purs+13−10
@@ -1,10 +1,13 @@
1−module Main where
2−
3−import Prelude
4−import Test.Assert
5−
6−fn :: Number -> Number
7−fn 0.0 = 0.0
8−fn 1.0 = 2.0
9−
10−main = assertThrows $ \_ -> fn 2.0
1+module Main where
2+
3+import Prelude
4+import Control.Monad.Eff.Console (log)
5+import Test.Assert (assertThrows)
6+
7+fn :: Number -> Number
8+fn 0.0 = 0.0
9+fn 1.0 = 2.0
10+
11+main = do
12+ assertThrows $ \_ -> fn 2.0
13+ log "Done"
examples/passing/QualifiedQualifiedImports.purs+1−1
@@ -3,4 +3,4 @@ module Main where
33-- qualified import with qualified imported names
44import Control.Monad.Eff.Console (log) as Console
55
6−main = Console.log "Success!"
6+main = Console.log "Done"
examples/passing/Rank2Data.purs+30−29
@@ -1,29 +1,30 @@
1−module Main where
2−
3−import Prelude hiding (add)
4−
5−data Id = Id forall a. a -> a
6−
7−runId = \id a -> case id of
8− Id f -> f a
9−
10−data Nat = Nat forall r. r -> (r -> r) -> r
11−
12−runNat = \nat -> case nat of
13− Nat f -> f 0.0 (\n -> n + 1.0)
14−
15−zero' = Nat (\zero' _ -> zero')
16−
17−succ = \n -> case n of
18− Nat f -> Nat (\zero' succ -> succ (f zero' succ))
19−
20−add = \n m -> case n of
21− Nat f -> case m of
22− Nat g -> Nat (\zero' succ -> g (f zero' succ) succ)
23−
24−one' = succ zero'
25−two = succ zero'
26−four = add two two
27−fourNumber = runNat four
28−
29−main = Control.Monad.Eff.Console.log "Done'"
1+module Main where
2+
3+import Prelude hiding (add)
4+import Control.Monad.Eff.Console (log)
5+
6+data Id = Id forall a. a -> a
7+
8+runId = \id a -> case id of
9+ Id f -> f a
10+
11+data Nat = Nat forall r. r -> (r -> r) -> r
12+
13+runNat = \nat -> case nat of
14+ Nat f -> f 0.0 (\n -> n + 1.0)
15+
16+zero' = Nat (\zero' _ -> zero')
17+
18+succ = \n -> case n of
19+ Nat f -> Nat (\zero' succ -> succ (f zero' succ))
20+
21+add = \n m -> case n of
22+ Nat f -> case m of
23+ Nat g -> Nat (\zero' succ -> g (f zero' succ) succ)
24+
25+one' = succ zero'
26+two = succ zero'
27+four = add two two
28+fourNumber = runNat four
29+
30+main = log "Done"
examples/passing/Rank2TypeSynonym.purs+3−2
@@ -1,7 +1,7 @@
11module Main where
22
33import Prelude
4−import Control.Monad.Eff
4+import Control.Monad.Eff.Console (log, logShow)
55
66type Foo a = forall f. (Monad f) => f a
77
@@ -13,4 +13,5 @@ bar = foo 3.0
1313
1414main = do
1515 x <- bar
16− Control.Monad.Eff.Console.logShow x
16+ logShow x
17+ log "Done"
examples/passing/RebindableSyntax.purs+41−39
@@ -1,39 +1,41 @@
1−module Main where
2−
3−import Prelude
4−
5−example1 :: String
6−example1 = do
7− "Do"
8− " notation"
9− " for"
10− " Semigroup"
11− where
12− bind x f = x <> f unit
13−
14−(*>) :: forall f a b. (Apply f) => f a -> f b -> f b
15−(*>) fa fb = const id <$> fa <*> fb
16−
17−newtype Const a b = Const a
18−
19−runConst :: forall a b. Const a b -> a
20−runConst (Const a) = a
21−
22−instance functorConst :: Functor (Const a) where
23− map _ (Const a) = Const a
24−
25−instance applyConst :: (Semigroup a) => Apply (Const a) where
26− apply (Const a1) (Const a2) = Const (a1 <> a2)
27−
28−example2 :: Const String Unit
29−example2 = do
30− Const "Do"
31− Const " notation"
32− Const " for"
33− Const " Apply"
34− where
35− bind x f = x *> f unit
36−
37−main = do
38− Control.Monad.Eff.Console.log example1
39− Control.Monad.Eff.Console.log $ runConst example2
1+module Main where
2+
3+import Prelude
4+import Control.Monad.Eff.Console (log)
5+
6+example1 :: String
7+example1 = do
8+ "Do"
9+ " notation"
10+ " for"
11+ " Semigroup"
12+ where
13+ bind x f = x <> f unit
14+
15+(*>) :: forall f a b. (Apply f) => f a -> f b -> f b
16+(*>) fa fb = const id <$> fa <*> fb
17+
18+newtype Const a b = Const a
19+
20+runConst :: forall a b. Const a b -> a
21+runConst (Const a) = a
22+
23+instance functorConst :: Functor (Const a) where
24+ map _ (Const a) = Const a
25+
26+instance applyConst :: (Semigroup a) => Apply (Const a) where
27+ apply (Const a1) (Const a2) = Const (a1 <> a2)
28+
29+example2 :: Const String Unit
30+example2 = do
31+ Const "Do"
32+ Const " notation"
33+ Const " for"
34+ Const " Apply"
35+ where
36+ bind x f = x *> f unit
37+
38+main = do
39+ log example1
40+ log $ runConst example2
41+ log "Done"
examples/passing/RuntimeScopeIssue.purs+4−1
@@ -1,6 +1,7 @@
11module Main where
22
33import Prelude
4+import Control.Monad.Eff.Console (log, logShow)
45
56class A a where
67 a :: a -> Boolean
@@ -16,4 +17,6 @@ instance bNumber :: B Number where
1617 b 0.0 = false
1718 b n = a (n - 1.0)
1819
19−main = Control.Monad.Eff.Console.logShow $ a 10.0
20+main = do
21+ logShow $ a 10.0
22+ log "Done"
examples/passing/ShadowedModuleName.purs+1−1
@@ -12,4 +12,4 @@ module Main where
1212
1313 data Test = Test
1414
15− main = log (runZ (Z "done"))
15+ main = log (runZ (Z "Done"))
examples/passing/ShadowedTCO.purs+21−18
@@ -1,18 +1,21 @@
1−module Main where
2−
3−import Prelude hiding (add)
4−
5−runNat f = f 0.0 (\n -> n + 1.0)
6−
7−zero' z _ = z
8−
9−succ f zero' succ = succ (f zero' succ)
10−
11−add f g zero' succ = g (f zero' succ) succ
12−
13−one' = succ zero'
14−two = succ one'
15−four = add two two
16−fourNumber = runNat four
17−
18−main = Control.Monad.Eff.Console.log $ show fourNumber
1+module Main where
2+
3+import Prelude hiding (add)
4+import Control.Monad.Eff.Console (log)
5+
6+runNat f = f 0.0 (\n -> n + 1.0)
7+
8+zero' z _ = z
9+
10+succ f zero' succ = succ (f zero' succ)
11+
12+add f g zero' succ = g (f zero' succ) succ
13+
14+one' = succ zero'
15+two = succ one'
16+four = add two two
17+fourNumber = runNat four
18+
19+main = do
20+ log $ show fourNumber
21+ log "Done"
examples/passing/ShadowedTCOLet.purs+12−9
@@ -1,9 +1,12 @@
1−module Main where
2−
3−import Prelude
4−
5−f x y z =
6− let f 1.0 2.0 3.0 = 1.0
7− in f x z y
8−
9−main = Control.Monad.Eff.Console.log $ show $ f 1.0 3.0 2.0
1+module Main where
2+
3+import Prelude
4+import Control.Monad.Eff.Console (log)
5+
6+f x y z =
7+ let f 1.0 2.0 3.0 = 1.0
8+ in f x z y
9+
10+main = do
11+ log $ show $ f 1.0 3.0 2.0
12+ log "Done"
examples/passing/StringEscapes.purs+17−15
@@ -1,15 +1,17 @@
1−module Main where
2−
3−import Prelude ((==), bind)
4−import Test.Assert (assert)
5−
6−singleCharacter = "\0\b\t\n\v\f\r\"\\" == "\x0\x8\x9\xA\xB\xC\xD\x22\x5C"
7−hex = "\x1D306\x2603\x3C6\xE0\x0" == "𝌆☃φà\0"
8−decimal = "\119558\9731\966\224\0" == "𝌆☃φà\0"
9−surrogatePair = "\xD834\xDF06" == "\x1D306"
10−
11−main = do
12− assert singleCharacter
13− assert hex
14− assert decimal
15− assert surrogatePair
1+module Main where
2+
3+import Prelude ((==), bind)
4+import Test.Assert (assert)
5+import Control.Monad.Eff.Console (log)
6+
7+singleCharacter = "\0\b\t\n\v\f\r\"\\" == "\x0\x8\x9\xA\xB\xC\xD\x22\x5C"
8+hex = "\x1D306\x2603\x3C6\xE0\x0" == "𝌆☃φà\0"
9+decimal = "\119558\9731\966\224\0" == "𝌆☃φà\0"
10+surrogatePair = "\xD834\xDF06" == "\x1D306"
11+
12+main = do
13+ assert singleCharacter
14+ assert hex
15+ assert decimal
16+ assert surrogatePair
17+ log "Done"
examples/passing/Superclasses1.purs+4−1
@@ -1,6 +1,7 @@
11module Main where
22
33import Prelude
4+import Control.Monad.Eff.Console (log, logShow)
45
56class Su a where
67 su :: a -> a
@@ -17,4 +18,6 @@ instance clNumber :: Cl Number where
1718test :: forall a. (Cl a) => a -> a
1819test a = su (cl a a)
1920
20−main = Control.Monad.Eff.Console.logShow $ test 10.0
21+main = do
22+ logShow $ test 10.0
23+ log "Done"
examples/passing/TCO.purs+2−2
@@ -1,7 +1,7 @@
11module Main where
22
33import Prelude
4−import Control.Monad.Eff.Console (logShow)
4+import Control.Monad.Eff.Console (log, logShow)
55
66main = do
77 let f x = x + 1
@@ -11,10 +11,10 @@ main = do
1111 logShow (applyN 2 f v)
1212 logShow (applyN 3 f v)
1313 logShow (applyN 4 f v)
14+ log "Done"
1415
1516applyN :: forall a. Int -> (a -> a) -> a -> a
1617applyN = go id
1718 where
1819 go f n _ | n <= 0 = f
1920 go f n g = go (f >>> g) (n - 1) g
20−
examples/passing/TailCall.purs+4−1
@@ -1,6 +1,7 @@
11module Main where
22
33import Prelude
4+import Control.Monad.Eff.Console (log, logShow)
45
56data L a = C a (L a) | N
67
@@ -14,4 +15,6 @@ loop x = loop (x + 1.0)
1415notATailCall = \x ->
1516 (\notATailCall -> notATailCall x) (\x -> x)
1617
17−main = Control.Monad.Eff.Console.logShow (test 0.0 (1.0 `C` (2.0 `C` (3.0 `C` N))))
18+main = do
19+ logShow (test 0.0 (1.0 `C` (2.0 `C` (3.0 `C` N))))
20+ log "Done"
examples/passing/TypeClassMemberOrderChange.purs+16−13
@@ -1,13 +1,16 @@
1−module Main where
2−
3−import Prelude
4−
5−class Test a where
6− fn :: a -> a -> a
7− val :: a
8−
9−instance testBoolean :: Test Boolean where
10− val = true
11− fn x y = y
12−
13−main = Control.Monad.Eff.Console.log (show (fn true val))
1+module Main where
2+
3+import Prelude
4+import Control.Monad.Eff.Console (log)
5+
6+class Test a where
7+ fn :: a -> a -> a
8+ val :: a
9+
10+instance testBoolean :: Test Boolean where
11+ val = true
12+ fn x y = y
13+
14+main = do
15+ log (show (fn true val))
16+ log "Done"
examples/passing/TypeClasses.purs+4−2
@@ -1,6 +1,7 @@
11module Main where
22
33import Prelude
4+import Control.Monad.Eff.Console (log)
45
56test1 = \_ -> show "testing"
67
@@ -65,5 +66,6 @@ test9 _ = runReader 0.0 $ do
6566 n <- ask
6667 pure $ n + 1.0
6768
68−main = Control.Monad.Eff.Console.log (test7 "Done")
69−
69+main = do
70+ log (test7 "Hello")
71+ log "Done"
examples/passing/UTF8Sourcefile.purs+8−10
@@ -1,10 +1,8 @@
1−module Main where
2−
3−import Control.Monad.Eff.Console
4−
5−-- '→' is multibyte sequence \u2192.
6−utf8multibyte = "Hello λ→ world!!"
7−
8−main = do
9− log "done"
10−
1+module Main where
2+
3+import Control.Monad.Eff.Console
4+
5+-- '→' is multibyte sequence \u2192.
6+utf8multibyte = "Hello λ→ world!!"
7+
8+main = log "Done"
examples/passing/Unit.purs+4−2
@@ -1,6 +1,8 @@
11module Main where
22
33import Prelude
4−import Control.Monad.Eff.Console
4+import Control.Monad.Eff.Console (logShow, log)
55
6−main = logShow (const unit $ "Hello world")
6+main = do
7+ logShow (const unit $ "Hello world")
8+ log "Done"
examples/passing/Where.purs+9−12
@@ -1,8 +1,7 @@
11module Main where
22
33import Prelude
4−import Control.Monad.Eff
5−import Control.Monad.ST
4+import Control.Monad.Eff.Console (logShow, log)
65
76test1 x = y
87 where
@@ -14,15 +13,12 @@ test2 x y = x' + y'
1413 x' = x + 1.0
1514 y' = y + 1.0
1615
17−
1816test3 = f 1.0 2.0 3.0
1917 where f x y z = x + y + z
2018
21−
2219test4 = f (+) [1.0, 2.0]
2320 where f x [y, z] = x y z
2421
25−
2622test5 = g 10.0
2723 where
2824 f x | x > 0.0 = g (x / 2.0) + 1.0
@@ -40,10 +36,11 @@ test7 x = go x
4036 go y = go $ (y + x / y) / 2.0
4137
4238main = do
43− Control.Monad.Eff.Console.logShow (test1 1.0)
44− Control.Monad.Eff.Console.logShow (test2 1.0 2.0)
45− Control.Monad.Eff.Console.logShow test3
46− Control.Monad.Eff.Console.logShow test4
47− Control.Monad.Eff.Console.logShow test5
48− Control.Monad.Eff.Console.logShow test6
49− Control.Monad.Eff.Console.logShow (test7 100.0)
39+ logShow (test1 1.0)
40+ logShow (test2 1.0 2.0)
41+ logShow test3
42+ logShow test4
43+ logShow test5
44+ logShow test6
45+ logShow (test7 100.0)
46+ log "Done"
purescript.cabal+1−1
@@ -351,7 +351,7 @@ test-suite tests
351351 Glob -any, aeson-better-errors -any, bytestring -any, aeson -any,
352352 base-compat -any, haskeline >= 0.7.0.0, optparse-applicative -any,
353353 boxes -any, HUnit -any, hspec -any, hspec-discover -any, stm -any, text -any,
354− vector -any, utf8-string -any
354+ vector -any, utf8-string -any, silently -any
355355 ghc-options: -Wall
356356 type: exitcode-stdio-1.0
357357 main-is: Main.hs
tests/TestCompiler.hs+66−58
@@ -26,8 +26,8 @@ import Prelude.Compat
2626import qualified Language.PureScript as P
2727
2828import Data.Char (isSpace)
29−import Data.Maybe (mapMaybe, fromMaybe)
30−import Data.List (isSuffixOf, sort, stripPrefix)
29+import Data.Maybe (mapMaybe)
30+import Data.List (isSuffixOf, sort, stripPrefix, intercalate)
3131import Data.Time.Clock (UTCTime())
3232
3333import qualified Data.Map as M
@@ -44,42 +44,57 @@ import System.Process hiding (cwd)
4444import System.FilePath
4545import System.Directory
4646import System.IO.UTF8
47+import System.IO.Silently
4748import qualified System.FilePath.Glob as Glob
4849
4950import TestUtils
51+import Test.Hspec
5052
5153main :: IO ()
52−main = do
53− cwd <- getCurrentDirectory
54+main = hspec spec
5455
55− let supportDir = cwd </> "tests" </> "support" </> "bower_components"
56− let supportFiles ext = Glob.globDir1 (Glob.compile ("purescript-*/**/*." ++ ext)) supportDir
56+spec :: Spec
57+spec = do
58+ (supportPurs, foreigns, passing, passingTestCases, failing, failingTestCases) <- runIO $ do
59+ cwd <- getCurrentDirectory
5760
58− supportPurs <- supportFiles "purs"
59− supportJS <- supportFiles "js"
61+ let supportDir = cwd </> "tests" </> "support" </> "bower_components"
62+ let supportFiles ext = Glob.globDir1 (Glob.compile ("purescript-*/**/*." ++ ext)) supportDir
6063
61− foreignFiles <- forM supportJS (\f -> (f,) <$> readUTF8File f)
62− Right (foreigns, _) <- runExceptT $ runWriterT $ P.parseForeignModulesFromFiles foreignFiles
64+ supportPurs <- supportFiles "purs"
65+ supportJS <- supportFiles "js"
6366
64− let passing = cwd </> "examples" </> "passing"
65− passingTestCases <- sort . filter (".purs" `isSuffixOf`) <$> getDirectoryContents passing
66− let failing = cwd </> "examples" </> "failing"
67− failingTestCases <- sort . filter (".purs" `isSuffixOf`) <$> getDirectoryContents failing
67+ foreignFiles <- forM supportJS (\f -> (f,) <$> readUTF8File f)
68+ Right (foreigns, _) <- runExceptT $ runWriterT $ P.parseForeignModulesFromFiles foreignFiles
6869
69− failures <- execWriterT $ do
70+ let passing = cwd </> "examples" </> "passing"
71+ passingTestCases <- sort . filter (".purs" `isSuffixOf`) <$> getDirectoryContents passing
72+
73+ let failing = cwd </> "examples" </> "failing"
74+ failingTestCases <- sort . filter (".purs" `isSuffixOf`) <$> getDirectoryContents failing
75+
76+ return (supportPurs, foreigns, passing, passingTestCases, failing, failingTestCases)
77+
78+ context ("Passing examples") $ do
7079 forM_ passingTestCases $ \inputFile ->
71− assertCompiles (supportPurs ++ [passing </> inputFile]) foreigns
72− forM_ failingTestCases $ \inputFile ->
73− assertDoesNotCompile (supportPurs ++ [failing </> inputFile]) foreigns
74−
75− if null failures
76− then pure ()
77− else do
78− putStrLn "Failures:"
79− forM_ failures $ \(fp, err) ->
80− let fp' = fromMaybe fp $ stripPrefix (failing ++ [pathSeparator]) fp
81− in putStrLn $ fp' ++ ": " ++ err
82− exitFailure
80+ it ("'" <> inputFile <> "' should compile and run without error") $ do
81+ assertCompiles (supportPurs ++ [passing </> inputFile]) foreigns
82+
83+ context ("Failing examples") $ do
84+ forM_ failingTestCases $ \inputFile -> do
85+ expectedFailures <- runIO $ getShouldFailWith (failing </> inputFile)
86+ it ("'" <> inputFile <> "' should fail with '" <> intercalate "', '" expectedFailures <> "'") $ do
87+ assertDoesNotCompile (supportPurs ++ [failing </> inputFile]) foreigns expectedFailures
88+
89+ where
90+
91+ getShouldFailWith :: FilePath -> IO [String]
92+ getShouldFailWith = fmap extractFailWiths . readUTF8File
93+ where
94+ extractFailWiths = lines >>> mapMaybe (stripPrefix "-- @shouldFailWith ") >>> map trim
95+
96+trim :: String -> String
97+trim = dropWhile isSpace >>> reverse >>> dropWhile isSpace >>> reverse
8398
8499modulesDir :: FilePath
85100modulesDir = ".test_modules" </> "node_modules"
@@ -113,26 +128,27 @@ type TestM = WriterT [(FilePath, String)] IO
113128runTest :: P.Make a -> IO (Either P.MultipleErrors a)
114129runTest = fmap fst . P.runMake P.defaultOptions
115130
116−compile :: [FilePath] -> M.Map P.ModuleName FilePath -> IO (Either P.MultipleErrors P.Environment)
117−compile inputFiles foreigns = runTest $ do
131+compile
132+ :: [FilePath]
133+ -> M.Map P.ModuleName FilePath
134+ -> IO (Either P.MultipleErrors P.Environment)
135+compile inputFiles foreigns = silence $ runTest $ do
118136 fs <- liftIO $ readInput inputFiles
119137 ms <- P.parseModulesFromFiles id fs
120138 P.make (makeActions foreigns) (map snd ms)
121139
122−assert :: [FilePath] ->
123− M.Map P.ModuleName FilePath ->
124− (Either P.MultipleErrors P.Environment -> IO (Maybe String)) ->
125− TestM ()
140+assert
141+ :: [FilePath]
142+ -> M.Map P.ModuleName FilePath
143+ -> (Either P.MultipleErrors P.Environment -> IO (Maybe String))
144+ -> Expectation
126145assert inputFiles foreigns f = do
127− e <- liftIO $ compile inputFiles foreigns
128− maybeErr <- liftIO $ f e
129− case maybeErr of
130− Just err -> tell [(last inputFiles, err)]
131− Nothing -> return ()
146+ e <- compile inputFiles foreigns
147+ maybeErr <- f e
148+ maybe (return ()) expectationFailure maybeErr
132149
133−assertCompiles :: [FilePath] -> M.Map P.ModuleName FilePath -> TestM ()
150+assertCompiles :: [FilePath] -> M.Map P.ModuleName FilePath -> Expectation
134151assertCompiles inputFiles foreigns = do
135− liftIO . putStrLn $ "Assert " ++ last inputFiles ++ " compiles successfully"
136152 assert inputFiles foreigns $ \e ->
137153 case e of
138154 Left errs -> return . Just . P.prettyPrintMultipleErrors False $ errs
@@ -142,19 +158,22 @@ assertCompiles inputFiles foreigns = do
142158 writeFile entryPoint "require('Main').main()"
143159 result <- traverse (\node -> readProcessWithExitCode node [entryPoint] "") process
144160 case result of
145− Just (ExitSuccess, out, _) -> putStrLn out >> return Nothing
161+ Just (ExitSuccess, out, err)
162+ | not (null err) -> return $ Just $ "Test wrote to stderr:\n\n" <> err
163+ | trim (last (lines out)) == "Done" -> return Nothing
164+ | otherwise -> return $ Just $ "Test did not finish with 'Done':\n\n" <> out
146165 Just (ExitFailure _, _, err) -> return $ Just err
147166 Nothing -> return $ Just "Couldn't find node.js executable"
148167
149−assertDoesNotCompile :: [FilePath] -> M.Map P.ModuleName FilePath -> TestM ()
150−assertDoesNotCompile inputFiles foreigns = do
151− let testFile = last inputFiles
152− liftIO . putStrLn $ "Assert " ++ testFile ++ " does not compile"
153− shouldFailWith <- getShouldFailWith testFile
168+assertDoesNotCompile
169+ :: [FilePath]
170+ -> M.Map P.ModuleName FilePath
171+ -> [String]
172+ -> Expectation
173+assertDoesNotCompile inputFiles foreigns shouldFailWith = do
154174 assert inputFiles foreigns $ \e ->
155175 case e of
156176 Left errs -> do
157− putStrLn (P.prettyPrintMultipleErrors False errs)
158177 return $ if null shouldFailWith
159178 then Just $ "shouldFailWith declaration is missing (errors were: "
160179 ++ show (map P.errorCode (P.runMultipleErrors errs))
@@ -164,19 +183,8 @@ assertDoesNotCompile inputFiles foreigns = do
164183 return $ Just "Should not have compiled"
165184
166185 where
167− getShouldFailWith =
168− readUTF8File
169− >>> liftIO
170− >>> fmap ( lines
171− >>> mapMaybe (stripPrefix "-- @shouldFailWith ")
172− >>> map trim
173− )
174−
175186 checkShouldFailWith expected errs =
176187 let actual = map P.errorCode $ P.runMultipleErrors errs
177188 in if sort expected == sort actual
178189 then Nothing
179190 else Just $ "Expected these errors: " ++ show expected ++ ", but got these: " ++ show actual
180−
181− trim =
182− dropWhile isSpace >>> reverse >>> dropWhile isSpace >>> reverse