コード例 #1
0
        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);
        }
コード例 #2
0
        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);
        }
コード例 #3
0
        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);
        }
コード例 #4
0
        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);
        }