test stability of sort and sortOn (#514)
authorDonnacha Oisín Kidney <oisdk@users.noreply.github.com>
Sat, 27 Jan 2018 19:06:18 +0000 (19:06 +0000)
committerDavid Feuer <David.Feuer@gmail.com>
Sat, 27 Jan 2018 19:06:18 +0000 (14:06 -0500)
The test may not be necessary for `sortOn`, but that's okay.

tests/seq-properties.hs

index 828bb29..86bd74b 100644 (file)
@@ -97,8 +97,10 @@ main = defaultMain
        , testProperty "partition" prop_partition
        , testProperty "filter" prop_filter
        , testProperty "sort" prop_sort
+       , testProperty "sortStable" prop_sortStable
        , testProperty "sortBy" prop_sortBy
        , testProperty "sortOn" prop_sortOn
+       , testProperty "sortOnStable" prop_sortOnStable
        , testProperty "unstableSort" prop_unstableSort
        , testProperty "unstableSortBy" prop_unstableSortBy
        , testProperty "unstableSortOn" prop_unstableSortOn
@@ -560,6 +562,30 @@ prop_sort :: Seq OrdA -> Bool
 prop_sort xs =
     toList' (sort xs) ~= Data.List.sort (toList xs)
 
+data UnstableOrd = UnstableOrd
+    { ordKey :: OrdA
+    , _ignored :: A
+    } deriving (Show)
+
+instance Eq UnstableOrd where
+    x == y = compare x y == EQ
+
+instance Ord UnstableOrd where
+    compare (UnstableOrd x _) (UnstableOrd y _) = compare x y
+
+instance Arbitrary UnstableOrd where
+    arbitrary = liftA2 UnstableOrd arbitrary arbitrary
+    shrink (UnstableOrd x y) =
+        [ UnstableOrd x' y'
+        | (x',y') <- shrink (x, y) ]
+
+prop_sortStable :: Seq UnstableOrd -> Bool
+prop_sortStable xs =
+    (fmap . fmap) unignore (toList' (sort xs)) ~=
+    fmap unignore (Data.List.sort (toList xs))
+  where
+    unignore (UnstableOrd x y) = (x, y)
+
 prop_sortBy :: Seq (OrdA, B) -> Bool
 prop_sortBy xs =
     toList' (sortBy f xs) ~= Data.List.sortBy f (toList xs)
@@ -575,6 +601,16 @@ prop_sortOn (Fun _ f) xs =
     listSortOn k = Data.List.sortBy (compare `on` k)
 #endif
 
+prop_sortOnStable :: Fun A UnstableOrd -> Seq A -> Bool
+prop_sortOnStable (Fun _ f) xs =
+    toList' (sortOn f xs) ~= listSortOn f (toList xs)
+  where
+#if MIN_VERSION_base(4,8,0)
+    listSortOn = Data.List.sortOn
+#else
+    listSortOn k = Data.List.sortBy (compare `on` k)
+#endif
+
 prop_unstableSort :: Seq OrdA -> Bool
 prop_unstableSort xs =
     toList' (unstableSort xs) ~= Data.List.sort (toList xs)