YWNTVA7PN7MC3HNTER3OCFHQAVKNJUK7KRQDZYFK24S5JLWHNU4AC LTSVBVA235BQAIU3SQURKSRHIAL33K47G4J6TSEP2K353OCHNJEAC UUR6SMCAJMA7O3ZFUCQMPZFDDIPUVQ5IHUAC5F252YVD6H3JIKPQC EFSXYZPOGA5M4DN65IEIDO7JK6U34DMQELAPHOIL2UAT6HRC66BAC HBULCDN6E75FAPILFVLTQIKABDEWL3HZTBLICLCWOIKDRYM6UIBQC LHJ2HFXVUQ4VG25I7DADWU73G5K5WNZBDQ3SVNKFYLZ5BEYM4XCQC GLFF5ZDKWI7WKPZSAEE3IUM27LL6DFOPIL4VPODXYXV3BCSCJ6GQC spec =lettestB0 = 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")indodescribe "bid ordering" $ doit "ensures that bids with lowest seconds/btc ratio are first" $ dobidOrder testB0 testB1 `shouldBe` LTbidOrder testB1 testB2 `shouldBe` LTbidOrder testB2 testB3 `shouldBe` LT
spec = dousers <- runIO $ fmap UserId <$> replicateM 5 U.nextRandomlet 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" $ doit "ensures that bids with lowest seconds/btc ratio are first" $ dobidOrder testB0 testB1 `shouldBe` LTbidOrder testB1 testB2 `shouldBe` LTbidOrder testB2 testB3 `shouldBe` LT
describe "winning bids" $ doit"determines a sufficient number of winners to fulfill the raise amount"$ letresult = 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]incase result ofWinningBids winners ->sortBy bidOrder winners `shouldBe` expected
describe "winning bids" $ doit"determines a sufficient number of winners to fulfill the raise amount"$ letresult = 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]incase result ofWinningBids 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 ofWinningBids 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 ofWinningBids xs -> bidsTotal xs == raiseAmount'InsufficientBids t -> t == (raiseAmount' `subs` bidsTotal bids)