Add Stream tests
[darcs-mirrors/vector.git] / tests / Tests / Stream.hs
1 module Tests.Stream ( tests ) where
2
3 import Boilerplater
4 import Utilities
5
6 import qualified Data.Vector.Fusion.Stream as S
7
8 import Test.QuickCheck
9
10 import Test.Framework
11 import Test.Framework.Providers.QuickCheck2
12
13 import Text.Show.Functions ()
14 import Data.List (foldl', foldl1', unfoldr, find, findIndex)
15 import System.Random (Random)
16
17 #define COMMON_CONTEXT(a) \
18 VANILLA_CONTEXT(a)
19
20 #define VANILLA_CONTEXT(a) \
21 Eq a, Show a, Arbitrary a, CoArbitrary a, TestData a, Model a ~ a, EqTest a ~ Property
22
23 testPolymorphicFunctions :: forall a. (COMMON_CONTEXT(a)) => S.Stream a -> [Test]
24 testPolymorphicFunctions _ = $(testProperties [
25 'prop_eq,
26
27 'prop_length, 'prop_null,
28
29 'prop_empty, 'prop_singleton, 'prop_replicate,
30 'prop_cons, 'prop_snoc, 'prop_append,
31
32 'prop_head, 'prop_last, 'prop_index,
33
34 'prop_extract, 'prop_init, 'prop_tail, 'prop_take, 'prop_drop,
35
36 'prop_map, 'prop_zipWith, 'prop_zipWith3,
37 'prop_filter, 'prop_takeWhile, 'prop_dropWhile,
38
39 'prop_elem, 'prop_notElem,
40 'prop_find, 'prop_findIndex,
41
42 'prop_foldl, 'prop_foldl1, 'prop_foldl', 'prop_foldl1',
43 'prop_foldr, 'prop_foldr1,
44
45 'prop_prescanl, 'prop_prescanl',
46 'prop_postscanl, 'prop_postscanl',
47 'prop_scanl, 'prop_scanl', 'prop_scanl1, 'prop_scanl1',
48
49 'prop_concatMap,
50 'prop_unfoldr
51 ])
52 where
53 -- Prelude
54 prop_eq :: P (S.Stream a -> S.Stream a -> Bool) = (==) `eq` (==)
55
56 prop_length :: P (S.Stream a -> Int) = S.length `eq` length
57 prop_null :: P (S.Stream a -> Bool) = S.null `eq` null
58 prop_empty :: P (S.Stream a) = S.empty `eq` []
59 prop_singleton :: P (a -> S.Stream a) = S.singleton `eq` singleton
60 prop_replicate :: P (Int -> a -> S.Stream a)
61 = (\n _ -> n < 1000) ===> S.replicate `eq` replicate
62 prop_cons :: P (a -> S.Stream a -> S.Stream a) = S.cons `eq` (:)
63 prop_snoc :: P (S.Stream a -> a -> S.Stream a) = S.snoc `eq` snoc
64 prop_append :: P (S.Stream a -> S.Stream a -> S.Stream a) = (S.++) `eq` (++)
65
66 prop_head :: P (S.Stream a -> a) = not . S.null ===> S.head `eq` head
67 prop_last :: P (S.Stream a -> a) = not . S.null ===> S.last `eq` last
68 prop_index = \xs ->
69 not (S.null xs) ==>
70 forAll (choose (0, S.length xs-1)) $ \i ->
71 unP prop xs i
72 where
73 prop :: P (S.Stream a -> Int -> a) = (S.!!) `eq` (!!)
74
75 prop_extract = \xs ->
76 forAll (choose (0, S.length xs)) $ \i ->
77 forAll (choose (0, S.length xs - i)) $ \n ->
78 unP prop xs i n
79 where
80 prop :: P (S.Stream a -> Int -> Int -> S.Stream a) = S.extract `eq` slice
81
82 prop_tail :: P (S.Stream a -> S.Stream a) = not . S.null ===> S.tail `eq` tail
83 prop_init :: P (S.Stream a -> S.Stream a) = not . S.null ===> S.init `eq` init
84 prop_take :: P (Int -> S.Stream a -> S.Stream a) = S.take `eq` take
85 prop_drop :: P (Int -> S.Stream a -> S.Stream a) = S.drop `eq` drop
86
87 prop_map :: P ((a -> a) -> S.Stream a -> S.Stream a) = S.map `eq` map
88 prop_zipWith :: P ((a -> a -> a) -> S.Stream a -> S.Stream a -> S.Stream a) = S.zipWith `eq` zipWith
89 prop_zipWith3 :: P ((a -> a -> a -> a) -> S.Stream a -> S.Stream a -> S.Stream a -> S.Stream a)
90 = S.zipWith3 `eq` zipWith3
91
92 prop_filter :: P ((a -> Bool) -> S.Stream a -> S.Stream a) = S.filter `eq` filter
93 prop_takeWhile :: P ((a -> Bool) -> S.Stream a -> S.Stream a) = S.takeWhile `eq` takeWhile
94 prop_dropWhile :: P ((a -> Bool) -> S.Stream a -> S.Stream a) = S.dropWhile `eq` dropWhile
95
96 prop_elem :: P (a -> S.Stream a -> Bool) = S.elem `eq` elem
97 prop_notElem :: P (a -> S.Stream a -> Bool) = S.notElem `eq` notElem
98 prop_find :: P ((a -> Bool) -> S.Stream a -> Maybe a) = S.find `eq` find
99 prop_findIndex :: P ((a -> Bool) -> S.Stream a -> Maybe Int)
100 = S.findIndex `eq` findIndex
101
102 prop_foldl :: P ((a -> a -> a) -> a -> S.Stream a -> a) = S.foldl `eq` foldl
103 prop_foldl1 :: P ((a -> a -> a) -> S.Stream a -> a) = notNullS2 ===>
104 S.foldl1 `eq` foldl1
105 prop_foldl' :: P ((a -> a -> a) -> a -> S.Stream a -> a) = S.foldl' `eq` foldl'
106 prop_foldl1' :: P ((a -> a -> a) -> S.Stream a -> a) = notNullS2 ===>
107 S.foldl1' `eq` foldl1'
108 prop_foldr :: P ((a -> a -> a) -> a -> S.Stream a -> a) = S.foldr `eq` foldr
109 prop_foldr1 :: P ((a -> a -> a) -> S.Stream a -> a) = notNullS2 ===>
110 S.foldr1 `eq` foldr1
111
112 prop_prescanl :: P ((a -> a -> a) -> a -> S.Stream a -> S.Stream a)
113 = S.prescanl `eq` prescanl
114 prop_prescanl' :: P ((a -> a -> a) -> a -> S.Stream a -> S.Stream a)
115 = S.prescanl' `eq` prescanl
116 prop_postscanl :: P ((a -> a -> a) -> a -> S.Stream a -> S.Stream a)
117 = S.postscanl `eq` postscanl
118 prop_postscanl' :: P ((a -> a -> a) -> a -> S.Stream a -> S.Stream a)
119 = S.postscanl' `eq` postscanl
120 prop_scanl :: P ((a -> a -> a) -> a -> S.Stream a -> S.Stream a)
121 = S.scanl `eq` scanl
122 prop_scanl' :: P ((a -> a -> a) -> a -> S.Stream a -> S.Stream a)
123 = S.scanl' `eq` scanl
124 prop_scanl1 :: P ((a -> a -> a) -> S.Stream a -> S.Stream a) = notNullS2 ===>
125 S.scanl1 `eq` scanl1
126 prop_scanl1' :: P ((a -> a -> a) -> S.Stream a -> S.Stream a) = notNullS2 ===>
127 S.scanl1' `eq` scanl1
128
129 prop_concatMap = forAll arbitrary $ \xs ->
130 forAll (sized (\n -> resize (n `div` S.length xs) arbitrary)) $ \f -> unP prop f xs
131 where
132 prop :: P ((a -> S.Stream a) -> S.Stream a -> S.Stream a) = S.concatMap `eq` concatMap
133
134 limitUnfolds f (theirs, ours) | ours >= 0
135 , Just (out, theirs') <- f theirs = Just (out, (theirs', ours - 1))
136 | otherwise = Nothing
137 prop_unfoldr :: P (Int -> (Int -> Maybe (a,Int)) -> Int -> S.Stream a)
138 = (\n f a -> S.unfoldr (limitUnfolds f) (a, n))
139 `eq` (\n f a -> unfoldr (limitUnfolds f) (a, n))
140
141 testBoolFunctions :: [Test]
142 testBoolFunctions = $(testProperties ['prop_and, 'prop_or])
143 where
144 prop_and :: P (S.Stream Bool -> Bool) = S.and `eq` and
145 prop_or :: P (S.Stream Bool -> Bool) = S.or `eq` or
146
147 testStreamFunctions = testPolymorphicFunctions (undefined :: S.Stream Int)
148 ++ testBoolFunctions
149
150 tests = [ testGroup "Data.Vector.Fusion.Stream" testStreamFunctions ]
151