# Modules
Basic implementation of a module system including tests.
This commit is contained in:
66
test/Spec.hs
66
test/Spec.hs
@ -7,12 +7,13 @@ import Parser
|
||||
import REPL
|
||||
import Research
|
||||
|
||||
import Control.Exception (evaluate, try, SomeException)
|
||||
import Control.Exception (evaluate, try, SomeException)
|
||||
import Control.Monad.IO.Class (liftIO)
|
||||
import Data.List (isInfixOf)
|
||||
import Test.Tasty
|
||||
import Test.Tasty.HUnit
|
||||
import Test.Tasty.QuickCheck
|
||||
import Text.Megaparsec (runParser)
|
||||
import Text.Megaparsec (runParser)
|
||||
|
||||
import qualified Data.Map as Map
|
||||
import qualified Data.Set as Set
|
||||
@ -31,6 +32,7 @@ tests = testGroup "Tricu Tests"
|
||||
, lambdas
|
||||
, baseLibrary
|
||||
, fileEval
|
||||
, modules
|
||||
, demos
|
||||
]
|
||||
|
||||
@ -70,9 +72,9 @@ lexer = testGroup "Lexer Tests"
|
||||
Right i -> i @?= expect
|
||||
|
||||
, testCase "Error when using invalid characters in identifiers" $ do
|
||||
case (runParser tricuLexer "" "__result = 5") of
|
||||
case (runParser tricuLexer "" "!result = 5") of
|
||||
Left _ -> return ()
|
||||
Right _ -> assertFailure "Expected failure when trying to assign the value of __result"
|
||||
Right _ -> assertFailure "Expected failure when trying to assign the value of !result"
|
||||
]
|
||||
|
||||
parser :: TestTree
|
||||
@ -498,22 +500,54 @@ fileEval = testGroup "File evaluation tests"
|
||||
decodeResult (result res) @?= "\"String test!\""
|
||||
]
|
||||
|
||||
modules :: TestTree
|
||||
modules = testGroup "Test modules"
|
||||
[ testCase "Detect cyclic dependencies" $ do
|
||||
result <- try (liftIO $ evaluateFileResult "./test/cycle-1.tri") :: IO (Either SomeException T)
|
||||
case result of
|
||||
Left e -> do
|
||||
let errorMsg = show e
|
||||
if "Encountered cyclic import" `isInfixOf` errorMsg
|
||||
then return ()
|
||||
else assertFailure $ "Unexpected error: " ++ errorMsg
|
||||
Right _ -> assertFailure "Expected cyclic dependencies"
|
||||
, testCase "Module imports and namespacing" $ do
|
||||
res <- liftIO $ evaluateFileResult "./test/namespace-A.tri"
|
||||
res @?= Leaf
|
||||
, testCase "Multiple imports" $ do
|
||||
res <- liftIO $ evaluateFileResult "./test/vars-A.tri"
|
||||
res @?= Leaf
|
||||
, testCase "Error on unresolved variable" $ do
|
||||
result <- try (liftIO $ evaluateFileResult "./test/unresolved-A.tri") :: IO (Either SomeException T)
|
||||
case result of
|
||||
Left e -> do
|
||||
let errorMsg = show e
|
||||
if "undefinedVar" `isInfixOf` errorMsg
|
||||
then return ()
|
||||
else assertFailure $ "Unexpected error: " ++ errorMsg
|
||||
Right _ -> assertFailure "Expected unresolved variable error"
|
||||
, testCase "Multi-level imports" $ do
|
||||
res <- liftIO $ evaluateFileResult "./test/multi-level-A.tri"
|
||||
res @?= Leaf
|
||||
, testCase "Lambda expression namespaces" $ do
|
||||
res <- liftIO $ evaluateFileResult "./test/lambda-A.tri"
|
||||
res @?= Leaf
|
||||
]
|
||||
|
||||
|
||||
-- All of our demo tests are also module tests
|
||||
demos :: TestTree
|
||||
demos = testGroup "Test provided demo functionality"
|
||||
[ testCase "Structural equality demo" $ do
|
||||
library <- liftIO $ evaluateFile "./lib/base.tri"
|
||||
res <- liftIO $ evaluateFileWithContext library "./demos/equality.tri"
|
||||
decodeResult (result res) @?= "t t"
|
||||
res <- liftIO $ evaluateFileResult "./demos/equality.tri"
|
||||
decodeResult res @?= "t t"
|
||||
, testCase "Convert values back to source code demo" $ do
|
||||
library <- liftIO $ evaluateFile "./lib/base.tri"
|
||||
res <- liftIO $ evaluateFileWithContext library "./demos/toSource.tri"
|
||||
decodeResult (result res) @?= "\"(t (t (t t) (t t t)) (t t (t t t)))\""
|
||||
res <- liftIO $ evaluateFileResult "./demos/toSource.tri"
|
||||
decodeResult res @?= "\"(t (t (t t) (t t t)) (t t (t t t)))\""
|
||||
, testCase "Determining the size of functions" $ do
|
||||
library <- liftIO $ evaluateFile "./lib/base.tri"
|
||||
res <- liftIO $ evaluateFileWithContext library "./demos/size.tri"
|
||||
decodeResult (result res) @?= "454"
|
||||
res <- liftIO $ evaluateFileResult "./demos/size.tri"
|
||||
decodeResult res @?= "454"
|
||||
, testCase "Level Order Traversal demo" $ do
|
||||
library <- liftIO $ evaluateFile "./lib/base.tri"
|
||||
res <- liftIO $ evaluateFileWithContext library "./demos/levelOrderTraversal.tri"
|
||||
decodeResult (result res) @?= "\"\n1 \n2 3 \n4 5 6 7 \n8 11 10 9 12 \""
|
||||
res <- liftIO $ evaluateFileResult "./demos/levelOrderTraversal.tri"
|
||||
decodeResult res @?= "\"\n1 \n2 3 \n4 5 6 7 \n8 11 10 9 12 \""
|
||||
]
|
||||
|
5
test/cycle-1.tri
Normal file
5
test/cycle-1.tri
Normal file
@ -0,0 +1,5 @@
|
||||
!module Cycle
|
||||
|
||||
!import "test/cycle-2.tri" Cycle2
|
||||
|
||||
cycle1 = t Cycle2.cycle2
|
5
test/cycle-2.tri
Normal file
5
test/cycle-2.tri
Normal file
@ -0,0 +1,5 @@
|
||||
!module Cycle2
|
||||
|
||||
!import "test/cycle-1.tri" Cycle1
|
||||
|
||||
cycle2 = t Cycle1.cycle1
|
2
test/lambda-A.tri
Normal file
2
test/lambda-A.tri
Normal file
@ -0,0 +1,2 @@
|
||||
!module A
|
||||
main = (\x : x) t
|
5
test/modules-1.tri
Normal file
5
test/modules-1.tri
Normal file
@ -0,0 +1,5 @@
|
||||
!module Test
|
||||
|
||||
!import "lib/base.tri" Lib
|
||||
|
||||
main = Lib.not? t
|
1
test/modules-2.tri
Normal file
1
test/modules-2.tri
Normal file
@ -0,0 +1 @@
|
||||
n = t t t
|
3
test/multi-level-A.tri
Normal file
3
test/multi-level-A.tri
Normal file
@ -0,0 +1,3 @@
|
||||
!module A
|
||||
!import "./test/multi-level-B.tri" B
|
||||
main = B.main
|
3
test/multi-level-B.tri
Normal file
3
test/multi-level-B.tri
Normal file
@ -0,0 +1,3 @@
|
||||
!module B
|
||||
!import "./test/multi-level-C.tri" C
|
||||
main = C.val
|
2
test/multi-level-C.tri
Normal file
2
test/multi-level-C.tri
Normal file
@ -0,0 +1,2 @@
|
||||
!module C
|
||||
val = t
|
3
test/namespace-A.tri
Normal file
3
test/namespace-A.tri
Normal file
@ -0,0 +1,3 @@
|
||||
!module A
|
||||
!import "./test/namespace-B.tri" B
|
||||
main = B.x
|
2
test/namespace-B.tri
Normal file
2
test/namespace-B.tri
Normal file
@ -0,0 +1,2 @@
|
||||
!module B
|
||||
x = t
|
2
test/unresolved-A.tri
Normal file
2
test/unresolved-A.tri
Normal file
@ -0,0 +1,2 @@
|
||||
!module A
|
||||
main = undefinedVar
|
7
test/vars-A.tri
Normal file
7
test/vars-A.tri
Normal file
@ -0,0 +1,7 @@
|
||||
!module A
|
||||
|
||||
!import "./test/vars-B.tri" B
|
||||
|
||||
!import "./test/vars-C.tri" C
|
||||
|
||||
main = B.y (C.z)
|
2
test/vars-B.tri
Normal file
2
test/vars-B.tri
Normal file
@ -0,0 +1,2 @@
|
||||
!module B
|
||||
y = \x : x
|
2
test/vars-C.tri
Normal file
2
test/vars-C.tri
Normal file
@ -0,0 +1,2 @@
|
||||
!module C
|
||||
z = t
|
Reference in New Issue
Block a user