{-# LANGUAGE ScopedTypeVariables #-}
module Main where
import Test.Tasty
import Test.Tasty.QuickCheck
import Test.Tasty.HUnit
import System.Directory
import System.FilePath
import Control.Applicative
import Control.Monad
import Data.List (isSuffixOf)
import Language.Java.Parser
import Language.Java.Syntax
import Language.Java.Pretty
import qualified Control.Exception as E
instance Arbitrary CompilationUnit where
arbitrary = CompilationUnit <$> arbitrary <*> arbitrary <*> ((:[]) <$> arbitrary)
instance Arbitrary PackageDecl where
arbitrary = PackageDecl <$> arbitrary
instance Arbitrary ImportDecl where
arbitrary = ImportDecl <$> arbitrary <*> arbitrary <*> arbitrary
instance Arbitrary TypeDecl where
arbitrary = ClassTypeDecl <$> arbitrary
instance Arbitrary ClassDecl where
arbitrary = ClassDecl <$> pure [] <*> arbitrary <*> pure [] <*> pure Nothing <*> pure [] <*> arbitrary
instance Arbitrary ClassBody where
arbitrary = ClassBody <$> pure []
instance Arbitrary Name where
arbitrary = Name <$> (choose (1,3) >>= \len -> replicateM len arbitrary)
instance Arbitrary Ident where
arbitrary = Ident . unkeyword <$> (choose (1,15) >>= \len -> replicateM len (elements (['a'..'z'] ++ ['A'..'Z'])))
where unkeyword k
| k `elem` ["if","do","then","else"] = "x" ++ k
| otherwise = k
----------------------------------------------------------
testJavaDirectory :: FilePath
testJavaDirectory = "tests" </> "java"
isJavaFile :: FilePath -> Bool
isJavaFile f = ".java" `isSuffixOf` f
toTestCase expected jFile = testCase (takeBaseName jFile) doTest
where doTest = do r <- E.try parseOne
case r of
Left (e :: E.SomeException) -> assertBool ("failure exception: " ++ show e) (not expected)
Right (Left perr) -> assertBool ("failure parse error: " ++ show perr) (not expected)
Right (Right p) -> assertBool ("success: " ++ show p) expected
parseOne = parser compilationUnit <$> readFile jFile
getAllJavaPaths path = map (path </>) . filter isJavaFile <$> getDirectoryContents path
main = do
exists <- doesDirectoryExist testJavaDirectory
when (not exists) $ error "cannot find tests files java directory"
allGoodJavas <- getAllJavaPaths (testJavaDirectory </> "good")
allBadJavas <- getAllJavaPaths (testJavaDirectory </> "bad")
defaultMain $ testGroup "java"
[ testGroup "parsing unit good" (map (toTestCase True) allGoodJavas)
, testGroup "parsing unit bad" (map (toTestCase False) allBadJavas)
, testProperty "parsing.generating==id" (\g -> case parser compilationUnit (show $ pretty g) of
Right g' -> g == g'
Left perr -> error (show (pretty g) ++ show perr))
]