Skip to content

Commit

Permalink
add a few tests
Browse files Browse the repository at this point in the history
  • Loading branch information
mitchellwrosen committed Oct 17, 2023
1 parent 7b2cbf0 commit 9b5ba2a
Show file tree
Hide file tree
Showing 4 changed files with 84 additions and 9 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
Session.vim
cabal.project.local
dist-newstyle/
4 changes: 2 additions & 2 deletions bench/Main.hs
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
module Main (main) where

import Control.DeepSeq (deepseq, force)
import Control.DeepSeq (force)
import Control.Exception (evaluate)
import List.Shuffle qualified as List
import System.Random qualified as Random
import Test.Tasty.Bench (bench, defaultMain, nf, whnf)
import Test.Tasty.Bench (bench, defaultMain, whnf)

main :: IO ()
main = do
Expand Down
31 changes: 24 additions & 7 deletions list-shuffle.cabal
Original file line number Diff line number Diff line change
Expand Up @@ -2,28 +2,45 @@ cabal-version: 2.4
name: list-shuffle
version: 0

library
build-depends:
base,
primitive,
random,
common component
default-extensions:
BlockArguments
LambdaCase
OverloadedStrings
PatternSynonyms
default-language: GHC2021
hs-source-dirs: src
ghc-options: -Wall

library
import: component
build-depends:
base,
primitive,
random,
hs-source-dirs: src
exposed-modules: List.Shuffle

test-suite test
import: component
build-depends:
base,
containers,
hedgehog ^>= 1.4,
list-shuffle,
random,
ghc-options: -rtsopts -threaded "-with-rtsopts=-N4"
hs-source-dirs: test
main-is: Main.hs
type: exitcode-stdio-1.0

benchmark bench
import: component
build-depends:
base,
deepseq,
list-shuffle,
random,
tasty-bench,
default-language: GHC2021
ghc-options: -O "-with-rtsopts=-A32m -T"
hs-source-dirs: bench
main-is: Main.hs
Expand Down
57 changes: 57 additions & 0 deletions test/Main.hs
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
module Main (main) where

import Data.List qualified as List
import Data.Ord (clamp)
import Data.Word
import Hedgehog
import Hedgehog.Gen qualified as Gen
import Hedgehog.Main
import Hedgehog.Range qualified as Range
import List.Shuffle qualified as List
import System.Random qualified as Random

main :: IO ()
main = do
defaultMain [checkParallel (Group "tests" (map (\(name, prop) -> (name, withTests 10000 (property prop))) tests))]

tests :: [(PropertyName, PropertyT IO ())]
tests =
[ ( "shuffle preserves list elements",
do
list <- generateList
gen <- generateGen
List.sort (List.shuffle_ list gen) === List.sort list
),
( "sample returns the requested number of elements",
do
list <- generateList
gen <- generateGen
n <- forAll (Gen.int (Range.linearFrom 0 (-30) (30)))
length (List.sample_ n list gen) === clamp (0, length list) n
),
( "sample returns a subset of list elements",
do
list <- generateList
gen <- generateGen
n <- forAll (Gen.int (Range.linearFrom 0 (-30) (30)))
assert (List.sort (List.sample_ n list gen) `isSubsetOf` List.sort list)
)
]

generateList :: PropertyT IO [Word8]
generateList =
forAll (Gen.list (Range.linear 0 200) (Gen.word8 Range.linearBounded))

generateGen :: PropertyT IO Random.StdGen
generateGen =
Random.mkStdGen <$> forAll (Gen.int Range.constantBounded)

-- precondition: lists are sorted
isSubsetOf :: (Ord a) => [a] -> [a] -> Bool
isSubsetOf [] _ = True
isSubsetOf (_ : _) [] = False
isSubsetOf (x : xs) (y : ys) =
case compare x y of
LT -> False
EQ -> isSubsetOf xs ys
GT -> isSubsetOf (x : xs) ys

0 comments on commit 9b5ba2a

Please sign in to comment.