bordacount-0.1.0.0: test/Spec.hs
{-# LANGUAGE ScopedTypeVariables #-}
import Test.Hspec
import Test.Hspec.QuickCheck (prop)
import Test.QuickCheck
import Data.List (nub)
import Data.Voting.BordaCount
main :: IO ()
main = hspec spec
spec :: Spec
spec = do
describe "duplicate checks" $
prop "properly detects duplicates" $ \(xs :: [Int]) ->
let dup = length xs /= length (nub xs) in
case findFirstDuplicateBy (==) xs of
Just (x, _) -> length (filter (== x) xs) > 1
Nothing -> not dup
describe "ballot" $ do
it "rejects duplicate options" $ do
ballot "" [Vote 0 "a", Vote 2 "b", Vote 1 "a"] `shouldBe` Left (DuplicateOption "a")
ballot "" [Vote 0 "a", Vote 2 "a", Vote 1 "a"] `shouldBe` Left (DuplicateOption "a")
ballot "" [Vote 0 "b", Vote 2 "a", Vote 1 "a"] `shouldBe` Left (DuplicateOption "a")
it "rejects duplicate rankings" $ do
ballot "" [Vote 0 "a", Vote 2 "b", Vote 2 "c"] `shouldBe` Left (DuplicateRanking "b" "c")
ballot "" [Vote 0 "a", Vote 3 "b", Vote 3 "c"] `shouldBe` Left (DuplicateRanking "b" "c")
it "accepts valid ballots" $ do
ballot "" [Vote 0 "a", Vote 0 "b", Vote 1 "c", Vote 4 "d"] `shouldSatisfy` anyRight
ballot "" ([] :: [Vote String]) `shouldSatisfy` anyRight
ballot "" [Vote 1 "c", Vote 2 "d", Vote 0 "x"] `shouldSatisfy` anyRight
describe "election" $ do
it "rejects duplicate participants" $
election' [Ballot "henri" [Vote 0 "x"],
Ballot "viktor" [Vote 1 "x"],
Ballot "henri" [Vote 0 "x"]] `shouldBe` Left (DuplicateParticipant "henri")
let ballots = [Ballot "henri" [Vote 0 "x", Vote 1 "y", Vote 2 "z"],
Ballot "viktor" [Vote 1 "x", Vote 2 "y", Vote 3 "z"],
Ballot "arno" [Vote 0 "x", Vote 0 "y", Vote 1 "z"]]
it "accepts valid ballot (uniform weight)" $
election' ballots `shouldBe` Right [
Result "x" 1 2
, Result "y" 3 1
, Result "z" 6 0]
it "accepts valid ballot (weighted)" $
let w "henri" = 5.0
w "viktor" = 2.0
w "arno" = 1.0
w p = error $ "unknown participant: " ++ p
in
election w ballots `shouldBe` Right [
Result "x" 2 6
, Result "y" 9 1
, Result "z" 17 0]
where
anyRight (Left _) = False
anyRight (Right _) = True