Remove duplicate test run
[darcs-mirrors/vector.git] / tests / Properties.hs
1 {-# LANGUAGE FlexibleContexts, Rank2Types, ScopedTypeVariables #-}
2
3 module Properties (tests) where
4
5 import Utilities
6
7 import qualified Data.Vector.IVector as V
8 import qualified Data.Vector
9 import qualified Data.Vector.Unboxed
10
11 import Test.QuickCheck
12
13 import Test.Framework
14 import Test.Framework.Providers.QuickCheck
15
16 import Text.Show.Functions
17 import Data.List (foldl', foldl1', unfoldr)
18
19 testVersusLists :: forall a v.
20 (Eq a, Ord a,
21 Eq (v a), Ord (v a),
22 Show a, Arbitrary a, Model a a,
23 -- This would be slightly nicer if we could put forall quantifiers in the class requirements!
24 Show (v a), Arbitrary (v a), Model (v a) [a], V.IVector v a,
25 Show (v Bool), Arbitrary (v Bool), Model (v Bool) [Bool], V.IVector v Bool)
26 => v a
27 -> [Test]
28 testVersusLists _ = [
29 testGroup "Prelude" prelude_tests,
30 testGroup "Data.List" data_list_tests,
31 testGroup "Extras" extra_tests
32 ]
33 where
34 prelude_tests = [
35 --testProperty "concat" prop_concat,
36 testProperty "length" prop_length,
37 testProperty "null" prop_null,
38 --testProperty "reverse" prop_reverse,
39 --testProperty "all" prop_all,
40 --testProperty "any" prop_any,
41 testProperty "and" prop_and,
42 testProperty "or" prop_or,
43 testProperty "(++)" prop_append,
44 --testProperty "break" prop_break,
45 testProperty "concatMap" prop_concatMap,
46 testProperty "(:)" prop_cons,
47 testProperty "drop" prop_drop,
48 testProperty "dropWhile" prop_dropWhile,
49 testProperty "take" prop_take,
50 testProperty "takeWhile" prop_takeWhile,
51 testProperty "filter" prop_filter,
52 testProperty "map" prop_map,
53 testProperty "replicate" prop_replicate,
54 --testProperty "span" prop_span,
55 --testProperty "splitAt" prop_splitAt,
56 testProperty "elem" prop_elem,
57 testProperty "notElem" prop_notElem,
58 testProperty "foldr" prop_foldr,
59 testProperty "foldl" prop_foldl,
60 testProperty "foldl'" prop_foldl',
61 --testProperty "lines" prop_lines,
62 testProperty "foldr1" prop_foldr1,
63 testProperty "foldl1" prop_foldl1,
64 testProperty "foldl1'" prop_foldl1',
65 testProperty "head" prop_head,
66 testProperty "tail" prop_tail,
67 testProperty "init" prop_init,
68 testProperty "last" prop_last,
69 --testProperty "maximum" prop_maximum,
70 --testProperty "minimum" prop_minimum,
71 testProperty "(==)" prop_eq,
72 testProperty "compare" prop_compare
73 ]
74
75 -- TODO: implement Vector equivalents for the commented out list functions from Prelude
76 --prop_concat = (V.concat :: [v a] -> v a) `eq1` concat
77 prop_length = (V.length :: v a -> Int) `eq1` length
78 prop_null = (V.null :: v a -> Bool) `eq1` null
79 --prop_reverse = (V.reverse :: v a -> v a) `eq1` reverse
80 --prop_all = (V.all :: (a -> Bool) -> v a -> Bool) `eq2` all
81 --prop_any = (V.any :: (a -> Bool) -> v a -> Bool) `eq2` any
82 prop_and = (V.and :: v Bool -> Bool) `eq1` and
83 prop_or = (V.or :: v Bool -> Bool) `eq1` or
84 prop_append = ((V.++) :: v a -> v a -> v a) `eq2` (++)
85 --prop_break = (V.break :: (a -> Bool) -> v a -> (v a, v a)) `eq2` break
86 prop_concatMap = (V.concatMap :: (a -> v a) -> v a -> v a) `eq2` concatMap
87 prop_cons = (V.cons :: a -> v a -> v a) `eq2` (:)
88 prop_drop = (V.drop :: Int -> v a -> v a) `eq2` drop
89 prop_dropWhile = (V.dropWhile :: (a -> Bool) -> v a -> v a) `eq2` dropWhile
90 prop_take = (V.take :: Int -> v a -> v a) `eq2` take
91 prop_takeWhile = (V.takeWhile :: (a -> Bool) -> v a -> v a) `eq2` takeWhile
92 prop_filter = (V.filter :: (a -> Bool) -> v a -> v a) `eq2` filter
93 prop_map = (V.map :: (a -> a) -> v a -> v a) `eq2` map
94 prop_replicate = (V.replicate :: Int -> a -> v a) `eq2` replicate
95 --prop_span = (V.span :: (a -> Bool) -> v a -> (v a, v a)) `eq2` span
96 --prop_splitAt = (V.splitAt :: Int -> v a -> (v a, v a)) `eq2` splitAt
97 prop_elem = (V.elem :: a -> v a -> Bool) `eq2` elem
98 prop_notElem = (V.notElem :: a -> v a -> Bool) `eq2` notElem
99 --prop_lines = (V.lines :: String -> [String]) `eq1` lines
100 prop_foldr = (V.foldr :: (a -> a -> a) -> a -> v a -> a) `eq3` foldr
101 prop_foldl = (V.foldl :: (a -> a -> a) -> a -> v a -> a) `eq3` foldl
102 prop_foldr1 = (V.foldr1 :: (a -> a -> a) -> v a -> a) `eqNotNull2` foldr1
103 prop_foldl1 = (V.foldl1 :: (a -> a -> a) -> v a -> a) `eqNotNull2` foldl1
104 prop_head = (V.head :: v a -> a) `eqNotNull1` head
105 prop_tail = (V.tail :: v a -> v a) `eqNotNull1` tail
106 prop_init = (V.init :: v a -> v a) `eqNotNull1` init
107 prop_last = (V.last :: v a -> a) `eqNotNull1` last
108 --prop_maximum = (V.maximum :: v a -> a) `eqNotNull1` maximum
109 --prop_minimum = (V.minimum :: v a -> a) `eqNotNull1` minimum
110 prop_eq = ((==) :: v a -> v a -> Bool) `eq2` (==)
111 prop_compare = (compare :: v a -> v a -> Ordering) `eq2` compare
112
113 data_list_tests = [
114 testProperty "foldl'" prop_foldl',
115 testProperty "foldl1'" prop_foldl1',
116 testProperty "unfoldr" prop_unfoldr
117 --testProperty "transpose" prop_transpose,
118 --testProperty "group" prop_group,
119 --testProperty "inits" prop_inits,
120 --testProperty "tails" prop_tails,
121 --testProperty "find" prop_find,
122 --testProperty "findIndices" prop_findIndices,
123 --testProperty "findIndex" prop_findIndex,
124 --testProperty "isPrefixOf" prop_isPrefixOf,
125 --testProperty "elemIndex" prop_elemIndex,
126 --testProperty "elemIndices" prop_elemIndices,
127 --testProperty "mapAccumL" prop_mapAccumL,
128 --testProperty "mapAccumR" prop_mapAccumR,
129 ]
130
131 -- TODO: implement Vector equivalents for some of the commented out list functions from Data.List
132 prop_foldl' = (V.foldl' :: (a -> a -> a) -> a -> v a -> a) `eq3` foldl'
133 prop_foldl1' = (V.foldl1' :: (a -> a -> a) -> v a -> a) `eqNotNull2` foldl1'
134 --prop_transpose = V.transpose `eq1` (transpose :: [v a] -> [v a])
135 --prop_group = V.group `eq1` (group :: v a -> [v a])
136 --prop_inits = V.inits `eq1` (inits :: v a -> [v a])
137 --prop_tails = V.tails `eq1` (tails :: v a -> [v a])
138 --prop_find = V.find `eq2` (find :: (a -> Bool) -> v a -> Maybe a)
139 --prop_findIndices = V.findIndices `eq2` (findIndices :: (a -> Bool) -> v a -> [Int])
140 --prop_findIndex = V.findIndex `eq2` (findIndex :: (a -> Bool) -> v a -> Maybe Int)
141 --prop_isPrefixOf = V.isPrefixOf `eq2` (isPrefixOf :: v a -> v a -> Bool)
142 --prop_elemIndex = V.elemIndex `eq2` (elemIndex :: a -> v a -> Maybe Int)
143 --prop_elemIndices = V.elemIndices `eq2` (elemIndices :: a -> v a -> [Int])
144 --
145 --prop_mapAccumL = eq3
146 -- (V.mapAccumL :: (X -> W -> (X,W)) -> X -> B -> (X, B))
147 -- ( mapAccumL :: (X -> W -> (X,W)) -> X -> [W] -> (X, [W]))
148 --
149 --prop_mapAccumR = eq3
150 -- (V.mapAccumR :: (X -> W -> (X,W)) -> X -> B -> (X, B))
151 -- ( mapAccumR :: (X -> W -> (X,W)) -> X -> [W] -> (X, [W]))
152
153 -- Because the vectors are strict, we need to be totally sure that the unfold eventually terminates. This
154 -- is achieved by injecting our own bit of state into the unfold - the maximum number of unfolds allowed.
155 limitUnfolds f (theirs, ours) | ours >= 0
156 , Just (out, theirs') <- f theirs = Just (out, (theirs', ours - 1))
157 | otherwise = Nothing
158 prop_unfoldr = ((\n f a -> V.unfoldr (limitUnfolds f) (a, n)) :: Int -> ((Int, Int) -> Maybe (a, (Int, Int))) -> (Int, Int) -> v a)
159 `eq3` (\n f a -> unfoldr (limitUnfolds f) (a, n))
160
161 extra_tests = [
162 testProperty "snoc" prop_snoc
163 ]
164
165 -- TODO: add tests for the other extra functions
166 snoc xs x = xs ++ [x]
167 prop_snoc = (V.snoc :: v a -> a -> v a) `eq2` snoc
168
169 tests = [
170 testGroup "Data.Vector.Vector" (testVersusLists (undefined :: Data.Vector.Vector Int)),
171 testGroup "Data.Vector.Unboxed.Vector (Int)" (testVersusLists (undefined :: Data.Vector.Unboxed.Vector Int)),
172 testGroup "Data.Vector.Unboxed.Vector (Bool)" (testVersusLists (undefined :: Data.Vector.Unboxed.Vector Bool))
173 ]