public void WhenAmountIsWithDrawnThenCashmachineShouldReturnCorrectNotesAndCoinsPairs() { INoteSelector noteSelector = new NoteSelectorAlogrithm1(); ICoinSelecotr coinSelector = new CoinSelector(); var availableNotes = new Dictionary <int, int> { { 50, 2 }, { 20, 2 }, { 10, 0 }, { 5, 0 }, { 2, 0 }, { 1, 0 } }; var availableCoins = new Dictionary <int, int> { { 50, 10 }, { 20, 10 }, { 10, 0 }, { 5, 5 }, { 2, 5 }, { 1, 5 } }; var cashMachine = new Cashmachine(noteSelector, coinSelector, availableNotes, availableCoins); var result = cashMachine.WithdrawCash(120.28m); Assert.AreEqual(result.Notes[50], 2); Assert.AreEqual(result.Notes[20], 1); Assert.AreEqual(result.Coins[20], 1); Assert.AreEqual(result.Coins[5], 1); Assert.AreEqual(result.Coins[2], 1); Assert.AreEqual(result.Coins[1], 1); }
public void WhenAlgo1IsUseThenCashmachineShouldUse50NotesIfAvailable() { INoteSelector noteSelector = new NoteSelectorAlogrithm1(); ICoinSelecotr coinSelector = new CoinSelector(); var availableNotes = new Dictionary <int, int> { { 50, 2 }, { 20, 2 }, { 10, 0 }, { 5, 0 }, { 2, 0 }, { 1, 0 } }; var availableCoins = new Dictionary <int, int> { { 50, 10 }, { 20, 10 }, { 10, 0 }, { 5, 5 }, { 2, 5 }, { 1, 5 } }; var cashMachine = new Cashmachine(noteSelector, coinSelector, availableNotes, availableCoins); var result = cashMachine.WithdrawCash(120.28m); Assert.AreEqual(result.Notes[50], 2); Assert.AreEqual(result.Notes[20], 1); Assert.AreEqual(result.Coins[20], 1); Assert.AreEqual(result.Coins[5], 1); Assert.AreEqual(result.Coins[2], 1); Assert.AreEqual(result.Coins[1], 1); }
public void WhenWithdrawCashThenAvailableBalanceMustBeUpdated() { INoteSelector noteSelector = new NoteSelectorAlogrithm1(); ICoinSelecotr coinSelector = new CoinSelector(); var availableNotes = new Dictionary <int, int> { { 50, 2 }, { 20, 5 }, { 10, 1 }, { 5, 1 }, { 2, 1 }, { 1, 1 } }; var availableCoins = new Dictionary <int, int> { { 50, 1 }, { 20, 1 }, { 10, 1 }, { 5, 1 }, { 2, 1 }, { 1, 1 } }; decimal beforeWithdrawBalance = (HelperMethods.GetBalance(availableNotes, availableCoins)); var cashMachine = new Cashmachine(noteSelector, coinSelector, availableNotes, availableCoins); var result = cashMachine.WithdrawCash(120.28m); decimal afterWithdrawBalance = (HelperMethods.GetBalance(availableNotes, availableCoins)); Assert.AreEqual(218.88m, beforeWithdrawBalance); Assert.AreEqual(98.6m, afterWithdrawBalance); }
private IEnumerable <ICoin> BuildTransaction( TransactionBuildingContext ctx, BuilderGroup group, IEnumerable <Builder> builders, IEnumerable <ICoin> coins) { var originalCtx = ctx.CreateMemento(); var target = builders.Concat(ctx.AdditionalBuilders).Select(b => b(ctx)).Sum(); if (ctx.CoverOnly != null) { target = ctx.CoverOnly + ctx.ChangeAmount; } var selection = CoinSelector.Select(coins, target); if (selection == null) { throw new NotEnoughFundsException("Not enough fund to cover the target"); } var total = selection.Select(s => s.Amount).Sum(); var change = total - target; if (change < Money.Zero) { throw new NotEnoughFundsException("Not enough fund to cover the target"); } if (change > ctx.Dust) { if (group.ChangeScript[(int)ctx.ChangeType] == null) { throw new InvalidOperationException("A change address should be specified (" + ctx.ChangeType + ")"); } ctx.RestoreMemento(originalCtx); ctx.ChangeAmount = change; try { return(BuildTransaction(ctx, group, builders, coins)); } finally { ctx.ChangeAmount = Money.Zero; } } foreach (var coin in selection) { var input = ctx.Transaction.AddInput(new TxIn(coin.Outpoint)); if (_LockTime != null && _LockTime.HasValue && !ctx.NonFinalSequenceSet) { input.Sequence = 0; ctx.NonFinalSequenceSet = true; } } return(selection); }