@@ -1,14 +1,35 @@
1+-- | Miscellaneous testing utilities
2+--
3+{-# LANGUAGE ScopedTypeVariables #-}
14module Data.Text.Tests.TestUtils
25 (
3− withRedirect
6+ (=^=)
7+ , withRedirect
48 , withTempFile
59 ) where
610
7−import Control.Exception (bracket, bracket_)
11+import Control.Exception (SomeException, bracket, bracket_, evaluate, try)
812import Control.Monad (when)
13+import Debug.Trace (trace)
914import GHC.IO.Handle.Internals (withHandle)
1015import System.Directory (removeFile)
11−import System.IO
16+import System.IO (Handle, hClose, hFlush, hIsOpen, hIsWritable, openTempFile)
17+import System.IO.Unsafe (unsafePerformIO)
18+
19+-- Ensure that two potentially bottom values (in the sense of crashing
20+-- for some inputs, not looping infinitely) either both crash, or both
21+-- give comparable results for some input.
22+(=^=) :: (Eq a, Show a) => a -> a -> Bool
23+i =^= j = unsafePerformIO $ do
24+ x <- try (evaluate i)
25+ y <- try (evaluate j)
26+ case (x,y) of
27+ (Left (_ :: SomeException), Left (_ :: SomeException))
28+ -> return True
29+ (Right a, Right b) -> return (a == b)
30+ e -> trace ("*** Divergence: " ++ show e) return False
31+infix 4 =^=
32+{-# NOINLINE (=^=) #-}
1233
1334withTempFile :: (FilePath -> Handle -> IO a) -> IO a
1435withTempFile = bracket (openTempFile "." "crashy.txt") cleanupTemp . uncurry