Skip to content

Commit

Permalink
Test that Largest-First generates the correct change.
Browse files Browse the repository at this point in the history
  • Loading branch information
jonathanknowles committed May 8, 2020
1 parent 22f9d33 commit 5543454
Showing 1 changed file with 36 additions and 2 deletions.
38 changes: 36 additions & 2 deletions src/test/Cardano/CoinSelection/Algorithm/LargestFirstSpec.hs
Original file line number Diff line number Diff line change
Expand Up @@ -48,13 +48,14 @@ import Data.Function
import Data.Functor.Identity
( Identity (runIdentity) )
import Test.Hspec
( Spec, describe, it, shouldSatisfy )
( Spec, describe, it, shouldBe, shouldSatisfy )
import Test.QuickCheck
( Property, property, withMaxSuccess, (.&&.), (==>) )
( Property, checkCoverage, cover, property, withMaxSuccess, (.&&.), (==>) )

import qualified Data.List as L
import qualified Data.Map.Strict as Map
import qualified Data.Set as Set
import qualified Internal.Coin as C

spec :: Spec
spec = do
Expand Down Expand Up @@ -218,6 +219,12 @@ spec = do
$ withMaxSuccess 10_000
$ propSelectionMinimal @Int @Int)

it "The algorithm produces the correct set of change."
(checkCoverage
$ property
$ withMaxSuccess 10_000
$ propChangeCorrect @Int @Int)

--------------------------------------------------------------------------------
-- Properties
--------------------------------------------------------------------------------
Expand Down Expand Up @@ -274,6 +281,33 @@ propSelectionMinimal (CoinSelectionData inpsAvailable outsRequested) =
$ CoinSelectionParameters inpsAvailable outsRequested
$ CoinSelectionLimit $ const 1000

-- Verify that the algorithm generates the correct set of change.
propChangeCorrect
:: Ord i => CoinSelectionData i o -> Property
propChangeCorrect (CoinSelectionData inpsAvailable outsRequested) =
isRight result ==>
let Right (CoinSelectionResult selection _) = result in
prop selection
where
prop (CoinSelection inpsSelected _ changeGenerated) =
cover 8 (amountSelected > amountRequired)
"amountSelected > amountRequired" $
cover 1 (amountSelected == amountRequired)
"amountSelected = amountRequired" $
if amountSelected > amountRequired then
changeGenerated `shouldBe`
[amountSelected `C.distance` amountRequired]
else
changeGenerated `shouldSatisfy` null
where
amountSelected = coinMapValue inpsSelected
amountRequired = coinMapValue outsRequested
result = runIdentity
$ runExceptT
$ selectCoins largestFirst
$ CoinSelectionParameters inpsAvailable outsRequested
$ CoinSelectionLimit $ const 1000

--------------------------------------------------------------------------------
-- Utilities
--------------------------------------------------------------------------------
Expand Down

0 comments on commit 5543454

Please sign in to comment.