on master help sign in
First QuickCheck test of I/O
db99fe3Bryan O'Sullivan
tests/Makefile+2−2
@@ -33,11 +33,11 @@ else
33endif
33endif
34
34
35Properties.o Regressions.o qc qc-hpc: ghc-flags += $(ghc-test-flags)
35Properties.o Regressions.o qc qc-hpc: ghc-flags += $(ghc-test-flags)
36−Properties.o: QuickCheckUtils.o SlowFunctions.o
36+Properties.o: QuickCheckUtils.o SlowFunctions.o TestUtils.o
37
37
38QuickCheckUtils.o: $(lib)
38QuickCheckUtils.o: $(lib)
39
39
40−qc: Properties.o QuickCheckUtils.o SlowFunctions.o
40+qc: Properties.o QuickCheckUtils.o SlowFunctions.o TestUtils.o
41 $(ghc) $(ghc-flags) -threaded -o $@ $^ $(lib)
41 $(ghc) $(ghc-flags) -threaded -o $@ $^ $(lib)
42
42
43sb: SearchBench.o SlowFunctions.o
43sb: SearchBench.o SlowFunctions.o
tests/Properties.hs+20−1
@@ -3,6 +3,7 @@
3{-# OPTIONS_GHC -fno-enable-rewrite-rules #-}
3{-# OPTIONS_GHC -fno-enable-rewrite-rules #-}
4
4
5import Test.QuickCheck
5import Test.QuickCheck
6+import Test.QuickCheck.Monadic
6import Text.Show.Functions ()
7import Text.Show.Functions ()
7
8
8import qualified Data.Bits as Bits (shiftL, shiftR)
9import qualified Data.Bits as Bits (shiftL, shiftR)
@@ -13,6 +14,7 @@ import Debug.Trace (trace)
13import Control.Arrow ((***), second)
14import Control.Arrow ((***), second)
14import Data.Word (Word8, Word16, Word32)
15import Data.Word (Word8, Word16, Word32)
15import qualified Data.Text as T
16import qualified Data.Text as T
17+import qualified Data.Text.IO as T
16import qualified Data.Text.Lazy as TL
18import qualified Data.Text.Lazy as TL
17import qualified Data.Text.Lazy.Builder as TB
19import qualified Data.Text.Lazy.Builder as TB
18import qualified Data.Text.Encoding as E
20import qualified Data.Text.Encoding as E
@@ -26,6 +28,7 @@ import qualified Data.Text.Lazy.Fusion as SL
26import qualified Data.Text.UnsafeShift as U
28import qualified Data.Text.UnsafeShift as U
27import qualified Data.List as L
29import qualified Data.List as L
28import Prelude hiding (replicate)
30import Prelude hiding (replicate)
31+import System.IO
29import System.IO.Unsafe (unsafePerformIO)
32import System.IO.Unsafe (unsafePerformIO)
30import Test.Framework (defaultMain, testGroup)
33import Test.Framework (defaultMain, testGroup)
31import Test.Framework.Providers.QuickCheck2 (testProperty)
34import Test.Framework.Providers.QuickCheck2 (testProperty)
@@ -34,6 +37,7 @@ import qualified Data.Text.Lazy.Search as S (indices)
34import qualified SlowFunctions as Slow
37import qualified SlowFunctions as Slow
35
38
36import QuickCheckUtils (NotEmpty(..), small, genUnicode)
39import QuickCheckUtils (NotEmpty(..), small, genUnicode)
40+import TestUtils (withTempFile)
37
41
38-- Ensure that two potentially bottom values (in the sense of crashing
42-- Ensure that two potentially bottom values (in the sense of crashing
39-- for some inputs, not looping infinitely) either both crash, or both
43-- for some inputs, not looping infinitely) either both crash, or both
@@ -565,7 +569,8 @@ shiftR_Int = shiftR :: Int -> Property
565shiftR_Word16 = shiftR :: Word16 -> Property
569shiftR_Word16 = shiftR :: Word16 -> Property
566shiftR_Word32 = shiftR :: Word32 -> Property
570shiftR_Word32 = shiftR :: Word32 -> Property
567
571
568−-- Builder
572+-- Builder.
573+
569t_builderSingleton = id `eqP` (unpackS . TB.toLazyText . mconcat . map TB.singleton)
574t_builderSingleton = id `eqP` (unpackS . TB.toLazyText . mconcat . map TB.singleton)
570t_builderFromText = L.concat `eq` (unpackS . TB.toLazyText . mconcat . map (TB.fromText . packS))
575t_builderFromText = L.concat `eq` (unpackS . TB.toLazyText . mconcat . map (TB.fromText . packS))
571t_builderAssociative s1 s2 s3 = TB.toLazyText (b1 `mappend` (b2 `mappend` b3)) ==
576t_builderAssociative s1 s2 s3 = TB.toLazyText (b1 `mappend` (b2 `mappend` b3)) ==
@@ -574,6 +579,16 @@ t_builderAssociative s1 s2 s3 = TB.toLazyText (b1 `mappend` (b2 `mappend` b3)) =
574 b2 = TB.fromText (packS s2)
579 b2 = TB.fromText (packS s2)
575 b3 = TB.fromText (packS s3)
580 b3 = TB.fromText (packS s3)
576
581
582+-- Input and output.
583+
584+t_write_read (NotEmpty t) = monadicIO $ do
585+ r <- run act
586+ assert (r == t)
587+ where act = withTempFile $ \path h -> do
588+ T.hPutStr h t
589+ hClose h
590+ T.readFile path
591+
577-- Low-level.
592-- Low-level.
578
593
579t_dropWord16 m t = dropWord16 m t `T.isSuffixOf` t
594t_dropWord16 m t = dropWord16 m t `T.isSuffixOf` t
@@ -965,6 +980,10 @@ tests = [
965 testProperty "t_builderAssociative" t_builderAssociative
980 testProperty "t_builderAssociative" t_builderAssociative
966 ],
981 ],
967
982
983+ testGroup "io" [
984+ testProperty "t_write_read" t_write_read
985+ ],
986+
968 testGroup "lowlevel" [
987 testGroup "lowlevel" [
969 testProperty "t_dropWord16" t_dropWord16,
988 testProperty "t_dropWord16" t_dropWord16,
970 testProperty "t_takeWord16" t_takeWord16,
989 testProperty "t_takeWord16" t_takeWord16,