-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathSortSpec.hs
56 lines (47 loc) · 1.92 KB
/
SortSpec.hs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
{-# LANGUAGE ScopedTypeVariables #-}
module SortSpec where
import Data.Array.Unboxed
import Data.Ord
import qualified Data.List as L
import Test.Hspec
import Test.Hspec.QuickCheck
import Test.QuickCheck
import Sort ( sort, sortBy, sortU, sortUBy, sortUABy, countingSortUA )
spec :: Spec
spec = do
prop "sort" $
forAll genWithIdxs $ \xs ->
sort xs `shouldBe` L.sort xs
prop "sortBy" $
forAll genWithIdxs $ \xs ->
sortBy (flip compare) xs `shouldBe` L.sortBy (flip compare) xs
prop "sortU" $
\(xs :: [Int]) -> sortU xs `shouldBe` L.sort xs
prop "sortUBy" $
\(xs :: [Int]) -> do
let xa = listArray (1, length xs) xs :: UArray Int Int
is = range (bounds xa)
sortUBy (comparing (xa!)) is `shouldBe` L.sortBy (comparing (xa!)) is
prop "sortUABy" $
forAll genArray $ \(_, xa) -> do
let ia = listArray (bounds xa) (range (bounds xa))
elems (sortUABy (comparing (xa!)) ia) `shouldBe` L.sortBy (comparing (xa!)) (elems ia)
prop "countingSortUA" $
forAll genArray $ \(b, xa) -> do
let ia = listArray (bounds xa) (range (bounds xa))
elems (countingSortUA b (xa!) ia) `shouldBe` L.sortBy (comparing (xa!)) (elems ia)
-- These tests check that the sorts are stable (except for sortU) by comparing against the known
-- stable Data.List.sort.
-- This is done by using WithIdx for boxed sorts and sorting indexes for unboxed ones.
data WithIdx a = WithIdx !a !Int deriving (Eq, Show)
-- Yes, this is unlawful wrt Eq.
instance Ord a => Ord (WithIdx a) where
WithIdx x _ `compare` WithIdx y _ = compare x y
genWithIdxs :: Gen [WithIdx Int]
genWithIdxs = zipWith (flip WithIdx) [0..] <$> arbitrary
genArray :: Gen (Int, UArray Int Int)
genArray = do
b <- getPositive <$> arbitrary
l <- arbitrary
xs <- listOf (choose (0, b-1))
pure (b, listArray (l, l + length xs - 1) xs)