# 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
	 James Eversole
						James Eversole