packages feed

monad-par-0.3: tests/TestHelpers.hs

{-# LANGUAGE BangPatterns #-}

module TestHelpers where

import Data.List
import Prelude hiding (catch)
import Control.Exception 
import System.IO.Unsafe (unsafePerformIO)
import Data.IORef
import Data.Time.Clock

-- import Control.Monad.Par.Unsafe
import Control.Monad.Par.Scheds.Trace
import Control.Monad.Par.Scheds.TraceInternal (Par(..),Trace(Fork),runCont,runParAsync)

------------------------------------------------------------
-- Helpers

_unsafeio :: IO a -> Par a
_unsafeio io = let x = unsafePerformIO io in
	        x `seq` return x

_waste_time :: Int -> Double
_waste_time n = loop n 1.00111
  where 
    loop 0  !x             = x
    loop !n !x | x > 100.0 = loop (n-1) (x / 2)
    loop !n !x             = loop (n-1) (x + x * 0.5011)

-- This version watches the clock so it uses a constant amount of time
-- regadless of compile/interpret mode an opt lvl.
waste_time :: Double -> IO Double
waste_time seconds = 
    do strt <- getCurrentTime
       let loop !x | x > 100.0 = chk (x / 2)
	   loop !x             = chk (x + x * 0.5011)
	   chk  !x = do t <- getCurrentTime
			if diffUTCTime t strt >= realToFrac seconds
			 then return x
			 else loop x
       loop  1.00111

-- Obviously this takes a lot longer if it's interpreted:
--awhile = 300000000
awhile = 3 * 1000 * 1000
-- awhile = 300000

atomicModifyIORef_ rf fn = atomicModifyIORef rf (\x -> (fn x, ()))


-- Haskell doesn't offer a way to create a Handle for in-memory output.
-- So here we use IORefs instead
collectOutput :: (IORef [String] -> IO ()) -> IO String
collectOutput fn = 
  do c <- newIORef []
     fn c
     ls <- readIORef c
     return (unlines (reverse ls))

prnt :: IORef [String] -> String -> IO ()
prnt ref str = atomicModifyIORef_ ref (str:)

_prnt :: IORef [String] -> String -> Par ()
_prnt ref = _unsafeio . prnt ref
     


-- -----------------------------------------------------------------------------

-- assertException :: (Exception e, Eq e) => e -> IO a -> IO ()
-- assertException ex action =
--     handleJust isWanted (const $ return ()) $ do
--         action
--         assertFailure $ "Expected exception: " ++ show ex
--   where isWanted = guard . (== ex)

-- Ensure that evaluating an expression returns an exception
assertException  :: String -> a -> IO ()
assertException msg val = do
 x <- catch (do evaluate val; return Nothing) 
            (\e -> do putStrLn$ "Good.  Caught exception: " ++ show (e :: SomeException)
                      return (Just$ show e))
 case x of 
  Nothing -> error "Failed to get an exception!"
  Just s -> 
   if isInfixOf msg s 
   then return () 
   else error$ "Got the wrong exception, expected to see the text: "++ show msg 
	       ++ "\nInstead got this exception:\n  " ++ show s