YWNTVA7PN7MC3HNTER3OCFHQAVKNJUK7KRQDZYFK24S5JLWHNU4AC
LTSVBVA235BQAIU3SQURKSRHIAL33K47G4J6TSEP2K353OCHNJEAC
UUR6SMCAJMA7O3ZFUCQMPZFDDIPUVQ5IHUAC5F252YVD6H3JIKPQC
EFSXYZPOGA5M4DN65IEIDO7JK6U34DMQELAPHOIL2UAT6HRC66BAC
HBULCDN6E75FAPILFVLTQIKABDEWL3HZTBLICLCWOIKDRYM6UIBQC
LHJ2HFXVUQ4VG25I7DADWU73G5K5WNZBDQ3SVNKFYLZ5BEYM4XCQC
GLFF5ZDKWI7WKPZSAEE3IUM27LL6DFOPIL4VPODXYXV3BCSCJ6GQC
spec =
let
testB0 = Bid (UserId nil)
(Seconds 3)
(Satoshi 100)
(read "2016-03-05 15:59:26.033176 UTC")
testB1 = Bid (UserId nil)
(Seconds 60)
(Satoshi 1000)
(read "2016-03-05 15:59:26.033177 UTC")
testB2 = Bid (UserId nil)
(Seconds 60)
(Satoshi 100)
(read "2016-03-05 15:59:26.033178 UTC")
testB3 = Bid (UserId nil)
(Seconds 90)
(Satoshi 100)
(read "2016-03-05 15:59:26.033179 UTC")
testB4 = Bid (UserId nil)
(Seconds 60)
(Satoshi 100)
(read "2016-03-05 15:59:26.033180 UTC")
in
do
describe "bid ordering" $ do
it "ensures that bids with lowest seconds/btc ratio are first" $ do
bidOrder testB0 testB1 `shouldBe` LT
bidOrder testB1 testB2 `shouldBe` LT
bidOrder testB2 testB3 `shouldBe` LT
spec = do
users <- runIO $ fmap UserId <$> replicateM 5 U.nextRandom
let testB0 = Bid (users !! 0)
(Seconds 3)
(Satoshi 100)
(read "2016-03-05 15:59:20.000000 UTC")
testB1 = Bid (users !! 1)
(Seconds 60)
(Satoshi 1000)
(read "2016-03-05 15:59:21.000000 UTC")
testB2 = Bid (users !! 2)
(Seconds 60)
(Satoshi 100)
(read "2016-03-05 15:59:22.000000 UTC")
testB3 = Bid (users !! 3)
(Seconds 90)
(Satoshi 100)
(read "2016-03-05 15:59:23.000000 UTC")
testB4 = Bid (users !! 4)
(Seconds 60)
(Satoshi 100)
(read "2016-03-05 15:59:24.000000 UTC")
describe "bid ordering" $ do
it "ensures that bids with lowest seconds/btc ratio are first" $ do
bidOrder testB0 testB1 `shouldBe` LT
bidOrder testB1 testB2 `shouldBe` LT
bidOrder testB2 testB3 `shouldBe` LT
describe "winning bids" $ do
it
"determines a sufficient number of winners to fulfill the raise amount"
$ let
result = runAuction' (Satoshi 1250)
[testB0, testB1, testB2, testB3, testB4]
split =
Bid (UserId nil) (Seconds 30) (Satoshi 50) (testB4 ^. bidTime)
expected = sortBy bidOrder [testB0, testB1, testB2, split]
in
case result of
WinningBids winners ->
sortBy bidOrder winners `shouldBe` expected
describe "winning bids" $ do
it
"determines a sufficient number of winners to fulfill the raise amount"
$ let
result = runAuction' (Satoshi 1250)
[testB0, testB1, testB2, testB3, testB4]
split =
Bid (users !! 4) (Seconds 31) (Satoshi 50) (testB4 ^. bidTime)
expected = sortBy bidOrder [testB0, testB1, testB2, split]
in
case result of
WinningBids winners ->
sortBy bidOrder winners `shouldBe` expected
it "ensures that the raise amount is fully consumed by the winning bids"
$ forAll ((,) <$> arbitrarySatoshi btc <*> listOf genBid)
$ \(raiseAmount', bids) -> case runAuction' raiseAmount' bids of
WinningBids xs -> bidsTotal xs == raiseAmount'
InsufficientBids t -> t == (raiseAmount' `subs` bidsTotal bids)
it "ensures that the raise amount is fully consumed by the winning bids"
$ forAll ((,) <$> arbitrarySatoshi btc <*> listOf genBid)
$ \(raiseAmount', bids) -> case runAuction' raiseAmount' bids of
WinningBids xs -> bidsTotal xs == raiseAmount'
InsufficientBids t -> t == (raiseAmount' `subs` bidsTotal bids)