ideas-0.7: src/Documentation/SelfCheck.hs
-----------------------------------------------------------------------------
-- Copyright 2010, Open Universiteit Nederland. This file is distributed
-- under the terms of the GNU General Public License. For more information,
-- see the file "LICENSE.txt", which is included in the distribution.
-----------------------------------------------------------------------------
-- |
-- Maintainer : bastiaan.heeren@ou.nl
-- Stability : provisional
-- Portability : portable (depends on ghc)
--
-----------------------------------------------------------------------------
module Documentation.SelfCheck (selfCheck, blackBoxTests) where
import System.Directory
import Common.TestSuite
import Common.Utils (useFixedStdGen, Some(..), snd3)
import Common.Exercise
import Service.ExercisePackage
import Control.Monad
import Service.Request
import Service.DomainReasoner
import Service.ModeJSON
import Service.ModeXML
import qualified Text.OpenMath.Tests as OpenMath
import qualified Text.UTF8 as UTF8
import qualified Text.JSON as JSON
import Data.List
selfCheck :: String -> DomainReasoner TestSuite
selfCheck dir = do
pkgs <- getPackages
domainSuite <- getTestSuite
run <- runWithCurrent
return $ do
suite "Framework checks" $ do
suite "Text encodings" $ do
addProperty "UTF8 encoding" UTF8.propEncoding
addProperty "JSON encoding" JSON.propEncoding
addProperty "OpenMath encoding" OpenMath.propEncoding
suite "Domain checks" domainSuite
suite "Exercise checks" $
forM_ pkgs $ \(Some pkg) ->
exerciseTestSuite (exercise pkg)
suite "Black box tests" $ do
liftIO (blackBoxTests run dir) >>= id
-- Returns the number of tests performed
blackBoxTests :: (DomainReasoner Bool -> IO Bool) -> String -> IO TestSuite
blackBoxTests run path = do
putStrLn ("Scanning " ++ path)
-- analyse content
xs0 <- getDirectoryContents path
let (xml, xs1) = partition (".xml" `isSuffixOf`) xs0
(json, xs2) = partition (".json" `isSuffixOf`) xs1
-- perform tests
ts1 <- forM json $ \x ->
doBlackBoxTest run JSON (path ++ "/" ++ x)
ts2 <- forM xml $ \x ->
doBlackBoxTest run XML (path ++ "/" ++ x)
-- recursively visit subdirectories
ts3 <- forM (filter ((/= ".") . take 1) xs2) $ \x -> do
let p = path ++ "/" ++ x
valid <- doesDirectoryExist p
if not valid
then return (return ())
else liftM (suite $ "Directory " ++ simplerDirectory p)
(blackBoxTests run p)
return $
sequence_ (ts1 ++ ts2 ++ ts3)
doBlackBoxTest :: (DomainReasoner Bool -> IO Bool) -> DataFormat -> FilePath -> IO TestSuite
doBlackBoxTest run format path = do
b <- doesFileExist expPath
return $ if not b
then warn $ expPath ++ " does not exist"
else assertIO (stripDirectoryPart path) $ run $ do
-- Comparing output with expected output
liftIO useFixedStdGen -- fix the random number generator
txt <- liftIO $ readFile path
expt <- liftIO $ readFile expPath
out <- case format of
JSON -> liftM snd3 (processJSON txt)
XML -> liftM snd3 (processXML txt)
-- Conditional forces evaluation of the result, to make sure that
-- all file handles are closed afterwards.
if out ~= expt then return True else return False
`catchError`
\_ -> return False
where
expPath = baseOf path ++ ".exp"
baseOf = reverse . drop 1 . dropWhile (/= '.') . reverse
x ~= y = filterVersion x == filterVersion y
filterVersion =
let p s = not (null s || "version" `isInfixOf` s)
in unlines . filter p . lines
simplerDirectory :: String -> String
simplerDirectory s
| "../" `isPrefixOf` s = simplerDirectory (drop 3 s)
| "test/" `isPrefixOf` s = simplerDirectory (drop 5 s)
| otherwise = s
stripDirectoryPart :: String -> String
stripDirectoryPart = reverse . takeWhile (/= '/') . reverse
{-
logicConfluence :: IO ()
logicConfluence = reportTest "logic rules" (isConfluent f rs)
where
f = normalizeWith ops . normalFormWith ops rs
ops = map makeCommutative Logic.logicOperators
rwrs = Logic.logicRules \\ [Logic.ruleOrOverAnd, Logic.ruleCommOr, Logic.ruleCommAnd]
rs = [ r | RewriteRule r <- concatMap transformations rwrs ]
-- eqs = bothWays [ r | RewriteRule r <- concatMap transformations Logic.logicRules ]
-}