|
From: <cod...@go...> - 2008-10-29 22:55:02
|
Author: wol...@gm...
Date: Wed Oct 29 15:54:06 2008
New Revision: 346
Added:
trunk/hoc/Tests/Test.hs
trunk/hoc/Tests/TestFFI.hs
trunk/hoc/Tests/TestPreprocessor.hs
Modified:
trunk/hoc/HOC.cabal
trunk/hoc/InterfaceGenerator2/Preprocessor.hs
trunk/hoc/Setup.hs
trunk/hoc/Tests/TestFoundation.hs
Log:
Build some unit tests for both the core library and the interface generator
from the
main HOC.cabal file.
Enable them using
runhaskell Setup.hs configure -f Tests
Modified: trunk/hoc/HOC.cabal
==============================================================================
--- trunk/hoc/HOC.cabal (original)
+++ trunk/hoc/HOC.cabal Wed Oct 29 15:54:06 2008
@@ -10,6 +10,10 @@
description: write HOC interface generator files in binary format
(requires binary package)
+Flag Tests
+ description: build test cases
+ default: False
+
Library
build-depends: base, template-haskell, unix
@@ -73,3 +77,30 @@
if flag(BinaryInterfaces)
build-depends: binary >= 0.2
cpp-options: -DBINARY_INTERFACES
+
+Executable hoc-test
+ main-is: Test.hs
+ hs-source-dirs: HOC, InterfaceGenerator2, Tests
+
+ cpp-options: -DTEST
+
+ build-depends: HUnit
+
+ if !flag(Tests)
+ buildable: False
+
+ extensions: MagicHash, TemplateHaskell,
+ ForeignFunctionInterface, GeneralizedNewtypeDeriving,
+ EmptyDataDecls, MultiParamTypeClasses,
FunctionalDependencies,
+ ScopedTypeVariables, RecursiveDo, FlexibleContexts,
+ FlexibleInstances, TypeSynonymInstances, DeriveDataTypeable
+
+
+ extra-libraries: objc, ffi
+ if os(darwin)
+ frameworks: Foundation
+ cpp-options: -DMACOSX
+ else
+ extra-lib-dirs: /usr/lib/gcc/i486-linux-gnu/4.1.3/,
/usr/lib/GNUstep/System/Library/Libraries
+ extra-libraries: gnustep-base
+ cpp-options: -DGNUSTEP
Modified: trunk/hoc/InterfaceGenerator2/Preprocessor.hs
==============================================================================
--- trunk/hoc/InterfaceGenerator2/Preprocessor.hs (original)
+++ trunk/hoc/InterfaceGenerator2/Preprocessor.hs Wed Oct 29 15:54:06 2008
@@ -44,7 +44,7 @@
<|> (reserved cpp "ifndef" >> definedMacroCondition >>= \e -> return $
If (negateExpr e))
<|> (reserved cpp "endif" >> return Endif)
<|> (reserved cpp "else" >> return Else)
- <|> (plainLine >>= \p -> return $ Text ("//# " ++ p))
+ <|> (plainLine >>= \p -> return $ Text ("//#" ++ p))
definedMacroCondition = do
macro <- identifier cpp
@@ -69,7 +69,11 @@
<|> do x <- identifier cpp
return (get >>= return . maybe 0 id . Map.lookup x)
- optable = [ [Infix (bop "<" (<)) AssocLeft,
+ optable = [ [Infix (op "*" (*)) AssocLeft,
+ Infix (op "/" div) AssocLeft],
+ [Infix (op "+" (+)) AssocLeft,
+ Infix (op "-" (-)) AssocLeft],
+ [Infix (bop "<" (<)) AssocLeft,
Infix (bop "<=" (<=)) AssocLeft,
Infix (bop "==" (==)) AssocLeft,
Infix (bop "!=" (/=)) AssocLeft,
@@ -157,29 +161,7 @@
(l2 : ls') -> (l ++ '\n' : l2) : ls'
ls' -> ls'
| otherwise = l : handleBackslashes ls
-
-preprocess fn f = execute fn $ parseDirectives f
-{-
-test = putStrLn $ execute "test" $ parseDirectives
- "#include <foo>\n\
- \blah\n\
- \foo bar\n\
- \#if 1\n\
- \baz\n\
- \#else\n\
- \quux\n\
- \#endif\n"
-
-test2 fn = do
--- f <- readFile
$ "/System/Library/Frameworks/Foundation.framework/Versions/C/Headers/" ++
fn
- f <- readFile $ "/usr/lib/GNUstep/System/Library/Headers/" ++ fn
- putStrLn $ execute fn $ parseDirectives f
-
+preprocess :: String -> String -> String
+preprocess fn f = execute fn $ parseDirectives f
-test3 fn = do
- f <- readFile
$ "/System/Library/Frameworks/Foundation.framework/Versions/C/Headers/" ++
fn
- -- putStrLn $
- putStrLn fn
- print $ length $ execute fn $ parseDirectives f
--}
Modified: trunk/hoc/Setup.hs
==============================================================================
--- trunk/hoc/Setup.hs (original)
+++ trunk/hoc/Setup.hs Wed Oct 29 15:54:06 2008
@@ -62,6 +62,7 @@
_ -> fail "Failed in C compilation."
-- system "cp dist/build/HOC_cbits.o dist/build/HOC_cbits.dyn_o"
+ system "cp dist/build/HOC_cbits.o dist/build/hoc-test/hoc-test-tmp/"
let buildInfo = emptyBuildInfo {
options = [ (GHC, ["dist/build/HOC_cbits.o" ]
@@ -71,6 +72,14 @@
++ extralibs) ],
cSources = ["HOC_cbits.o"]
}
+ buildInfo2 = emptyBuildInfo {
+ options = [ (GHC,
["dist/build/hoc-test/hoc-test-tmp/HOC_cbits.o" ]
+ ++ paths ++
+ ["-lobjc",
+ "-lffi"]
+ ++ extralibs) ]{-,
+ cSources = ["HOC_cbits.o"]-}
+ }
- return (Just buildInfo, [])
+ return (Just buildInfo, [("hoc-test", buildInfo2)])
Added: trunk/hoc/Tests/Test.hs
==============================================================================
--- (empty file)
+++ trunk/hoc/Tests/Test.hs Wed Oct 29 15:54:06 2008
@@ -0,0 +1,11 @@
+module Main where
+
+import qualified TestFFI
+import qualified TestPreprocessor
+
+import Test.HUnit
+
+main = runTestTT $ test [
+ TestFFI.tests,
+ TestPreprocessor.tests
+ ]
Added: trunk/hoc/Tests/TestFFI.hs
==============================================================================
--- (empty file)
+++ trunk/hoc/Tests/TestFFI.hs Wed Oct 29 15:54:06 2008
@@ -0,0 +1,88 @@
+{-# LANGUAGE RankNTypes #-}
+module TestFFI where
+
+import HOC.FFICallInterface
+import HOC.Invocation
+
+
+import Foreign
+import Foreign.C
+import Data.Int
+import Test.HUnit
+
+import HOC.Arguments
+import HOC.StdArgumentTypes
+
+foreign import ccall "ffi.h ffi_call"
+ ffi_call :: FFICif -> FunPtr a -> Ptr b -> Ptr (Ptr ()) -> IO Int
+
+
+fficallDirectly cif fp args
+ = allocaRetval $ \ret -> do
+ ffi_call cif fp ret args
+ peekRetval ret
+
+type Invoker = forall a b c d.
+ (ObjCArgument a a, ObjCArgument b b) =>
+ FFICif -> FunPtr (a -> b) -> Ptr (Ptr ()) -> IO b
+
+testArgAndResult :: (Num a, Num b, ObjCArgument a a, ObjCArgument b b)
+ => Invoker -> FunPtr (a -> b) -> IO ()
+
+
+testArgAndResult invoker fp
+ = do
+ fixTypes fp theArg theResult
+
+ argType <- makeFFIType theArg
+ retType <- makeFFIType theResult
+ cif <- ffiPrepCif retType [argType]
+ x <- with theArg $ \arg -> withArray [arg] $ \args -> invoker cif
fp (castPtr args)
+ x @?= theResult
+ return ()
+ where
+ theArg = 23
+ theResult = 19
+
+ fixTypes :: FunPtr (a -> b) -> a -> b -> IO ()
+ fixTypes f a b = return ()
+
+
+
+subtractFrom42 x = 42 - x
+
+foreign export ccall "funIntToInt" subtractFrom42 :: CInt -> CInt
+foreign import ccall "&funIntToInt" funIntToInt :: FunPtr (CInt -> CInt)
+
+foreign export ccall "funCharToChar" subtractFrom42 :: CChar -> CChar
+foreign import ccall "&funCharToChar" funCharToChar :: FunPtr (CChar ->
CChar)
+
+foreign export ccall "funFloatToFloat" subtractFrom42 :: CFloat -> CFloat
+foreign import ccall "&funFloatToFloat" funFloatToFloat :: FunPtr (CFloat
-> CFloat)
+
+foreign export ccall "funDoubleToDouble" subtractFrom42 :: CDouble ->
CDouble
+foreign import ccall "&funDoubleToDouble" funDoubleToDouble :: FunPtr
(CDouble -> CDouble)
+
+foreign export ccall "funLLongToLLong" subtractFrom42 :: CLLong -> CLLong
+foreign import ccall "&funLLongToLLong" funLLongToLLong :: FunPtr (CLLong
-> CLLong)
+
+testArgsAndResults :: Invoker -> Test
+
+
+testArgsAndResults invoker
+ = test [
+ testArgAndResult invoker funIntToInt,
+ testArgAndResult invoker funCharToChar,
+ testArgAndResult invoker funLLongToLLong,
+ testArgAndResult invoker funFloatToFloat,
+ testArgAndResult invoker funDoubleToDouble
+ ]
+
+tests = "TestFFI" ~: test [
+ "peekRetval" ~: test $ with (42 :: Int) $ \p -> do
+ ret <- peekRetval (castPtr p :: Ptr CChar)
+ ret @?= (42 :: CChar)
+ ,
+ "Plain FFI" ~: testArgsAndResults fficallDirectly,
+ "callWithRetval" ~: testArgsAndResults callWithRetval
+ ]
Modified: trunk/hoc/Tests/TestFoundation.hs
==============================================================================
--- trunk/hoc/Tests/TestFoundation.hs (original)
+++ trunk/hoc/Tests/TestFoundation.hs Wed Oct 29 15:54:06 2008
@@ -12,6 +12,10 @@
import Control.Exception ( try, finally )
import qualified System.Info( os )
+deriving instance Show NSRect
+deriving instance Show NSPoint
+deriving instance Show NSSize
+
-- garbage collect and make really sure that finalizers have time to
run
performGCAndWait targetCount time maxRepeat = do
performGC
Added: trunk/hoc/Tests/TestPreprocessor.hs
==============================================================================
--- (empty file)
+++ trunk/hoc/Tests/TestPreprocessor.hs Wed Oct 29 15:54:06 2008
@@ -0,0 +1,141 @@
+module TestPreprocessor where
+
+import Preprocessor
+
+import Test.HUnit
+import Data.Char
+
+rstrip = reverse . dropWhile isSpace . reverse
+
+a ==> b = rstrip (preprocess "test" a) ~?= rstrip b
+
+success a = (filter interesting $ lines $ preprocess "test" a) ~?=
["success"]
+ where
+ interesting ('/' : '/' : _ ) = False
+ interesting other | all isSpace other = False
+ | otherwise = True
+
+tests = "TestPreprocessor" ~: test [
+ "empty" ~: "" ==> "",
+
+ "plainLines" ~:
+ let txt = "asfljkaslf\nasjfhaslkhf\naskfhaskjf\n"
+ in txt ==> txt,
+
+ "comment1" ~:
+ "/* abc */\ndef\n/*ghi*/\n" ==> "/* abc */\ndef\n/*ghi*/\n",
+ "comment2" ~:
+ "/* abc\ndef */\nghi\n" ==> "/* abc*/\n/*def */\nghi\n",
+
+ "ifthenelse1" ~:
+ "#include <foo>\n\
+ \blah\n\
+ \foo bar\n\
+ \#if 42\n\
+ \baz\n\
+ \#else\n\
+ \quux\n\
+ \#endif\n"
+ ==>
+ "//#include <foo>\n\
+ \blah\n\
+ \foo bar\n\
+ \//#if 1\n\
+ \baz\n\
+ \//#else\n\
+ \//T quux\n\
+ \//#endif",
+
+ "elif1" ~: success
+ "#if 1\n\
+ \success\n\
+ \#elif 1\n\
+ \failure2\n\
+ \#else\n\
+ \failure3\n\
+ \#endif",
+
+ "elif2" ~: success
+ "#if 0\n\
+ \failure1\n\
+ \#elif 1\n\
+ \success\n\
+ \#else\n\
+ \failure2\n\
+ \#endif",
+
+ "elif3" ~: success
+ "#if 0\n\
+ \failure1\n\
+ \#elif 0\n\
+ \failure2\n\
+ \#else\n\
+ \success\n\
+ \#endif",
+
+ "elif4" ~: success
+ "#if 6 * 9 == 42\n\
+ \No, that is not the question.\n\
+ \#elif 2 + 2 == 5\n\
+ \We love Big Brother!\n\
+ \#else\n\
+ \success\n\
+ \#endif",
+
+ "elif5" ~: success
+ "#if 6 * 7 == 42\n\
+ \success\n\
+ \#elif 2 + 2 == 5\n\
+ \We love Big Brother!\n\
+ \#else\n\
+ \wrong, too.\n\
+ \#endif",
+
+ "elif6" ~: success
+ "#if 6 * 9 == 42\n\
+ \no.\n\
+ \#elif MAC_OS_X_VERSION_10_5 == 1050\n\
+ \success\n\
+ \#else\n\
+ \wrong, too.\n\
+ \#endif",
+
+ "nest1" ~: success
+ "#if 1\n\
+ \#if 1\n\
+ \success\n\
+ \#else\n\
+ \failure1\n\
+ \#endif\n\
+ \#else\n\
+ \failure2\n\
+ \#if 1\n\
+ \failure3\n\
+ \#else\n\
+ \failure4\n\
+ \#endif\n\
+ \failure5\n\
+ \#endif",
+
+ "nest2" ~: success
+ "#if 0\n\
+ \failure0\n\
+ \#if 1\n\
+ \failure1\n\
+ \#else\n\
+ \failure2\n\
+ \#endif\n\
+ \failure3\n\
+ \#else\n\
+ \#if 0\n\
+ \failure4\n\
+ \#else\n\
+ \success\n\
+ \#endif\n\
+ \#endif",
+
+ "defineBackslash" ~: success
+ "#define FOO bar\n\\\
+ \ baz\n\
+ \success"
+ ]
|