public void CannotGiveChange_2()
        {
            VendingMachine machine = new GreedyVendingMachine();
            machine.Add
            (
                Change.TwoPence(3),
                Change.FivePence(1),
                Change.TwentyPence(3),
                Change.FiftyPence(1)
            );

            int totalValueMachineBeforeVend = machine.Balance.TotalValue();

            // The change here is 66p and we've got the right coins, 3 x 20p and 3 x 2p
            // However, the greedy approach will fail here as it will take the 50p but not be able to make up the 16p
            VendingResult result = machine.Vend(34, Change.OnePound(1));
            Assert.IsNotNull(result);
            Assert.IsTrue(result.Failed);

            // We should have 6p change...
            Assert.AreEqual(result.Change.TotalValue(), 0);

            // ...and the machine should have 14p more than before then vend
            Assert.AreEqual(machine.Balance.TotalValue(), totalValueMachineBeforeVend);
        }
        public void RemoveChangeItem()
        {
            VendingMachine machine = new GreedyVendingMachine();
            machine.Add
            (
                Change.TenPence(5),
                Change.TwentyPence(1)
            );

            int preBalance = machine.Balance.TotalValue();

            // Take out 20p and make sure the balance is right
            machine.Remove(Change.TenPence(2));
            Assert.AreEqual(machine.Balance.TotalValue(), preBalance - 20);
        }
        public void Add()
        {
            VendingMachine machine = new GreedyVendingMachine();
            machine.Add
            (
                Change.TenPence(5),
                Change.TwentyPence(1),
                Change.OnePence(3),
                Change.FiftyPence(1),
                Change.TwoPence(3)
            );

            // The balance order should be from high to low
            CompareBalanceOrder(machine.Balance, 50, 20, 10, 2, 1);
        }
        public void RemoveAllChangeItem()
        {
            VendingMachine machine = new GreedyVendingMachine();
            machine.Add
            (
                Change.TenPence(5),
                Change.TwentyPence(1)
            );

            int preBalance = machine.Balance.TotalValue();

            // Take out 20p and make sure the balance is right
            machine.Remove(Change.TenPence(5));
            Assert.AreEqual(machine.Balance.TotalValue(), preBalance - 50);

            // There shouldn't be any 10p items in the machine
            Assert.IsFalse(machine.Balance.Any(c => c.Denomination == 10));
        }
        public void CanGiveChange()
        {
            VendingMachine machine = new GreedyVendingMachine();
            machine.Add
            (
                Change.OnePence(100),
                Change.FivePence(50),
                Change.TenPence(50)
            );

            int totalValueMachineBeforeVend = machine.Balance.TotalValue();

            VendingResult result = machine.Vend(25, Change.TwentyPence(2));
            Assert.IsNotNull(result);
            Assert.IsTrue(result.Success);
            Assert.IsNotNull(result.Change);

            // We should have 15p in change...
            Assert.AreEqual(result.Change.TotalValue(), 15);

            // ...and the machine should have 25p more than before then vend
            Assert.AreEqual(machine.Balance.TotalValue(), 25 + totalValueMachineBeforeVend);
        }
        public void CannotGiveChange()
        {
            VendingMachine machine = new GreedyVendingMachine();
            machine.Add
            (
                Change.TwoPence(3),
                Change.FivePence(1)
            );

            int totalValueMachineBeforeVend = machine.Balance.TotalValue();

            // The change here is 6p.
            // We've got the right coins, 3 x 2p, but the gready algorithm
            // will take the 5p and then not be able to find a 1p
            VendingResult result = machine.Vend(14, Change.TenPence(2));
            Assert.IsNotNull(result);
            Assert.IsTrue(result.Failed);

            // We shouldn't have any change...
            Assert.AreEqual(result.Change.TotalValue(), 0);

            // ...and the machine should have the same balance as before the vend
            Assert.AreEqual(machine.Balance.TotalValue(), totalValueMachineBeforeVend);
        }
        public void ExactAmountTendered()
        {
            VendingMachine machine = new GreedyVendingMachine();
            machine.Add
            (
                Change.OnePence(100),
                Change.FivePence(50),
                Change.TenPence(50)
            );

            int totalValueMachineBeforeVend = machine.Balance.TotalValue();

            VendingResult result = machine.Vend(60, Change.FiftyPence(1), Change.TenPence(1));
            Assert.IsNotNull(result);
            Assert.IsTrue(result.Success);
            Assert.IsNotNull(result.Change);

            // We should have no change...
            Assert.AreEqual(result.Change.TotalValue(), 0);

            // ...and the machine should have 60p more than before then vend
            Assert.AreEqual(machine.Balance.TotalValue(), 60 + totalValueMachineBeforeVend);
        }
        public void RemoveChangeItem_DoesNotExist()
        {
            VendingMachine machine = new GreedyVendingMachine();
            machine.Add
            (
                Change.TenPence(5),
                Change.TwentyPence(1)
            );

            // Take out 5p. This isn't in the machine, so should fail
            machine.Remove(Change.FivePence(1));
        }
        public void RemoveChangeItem_TooManySpecified()
        {
            VendingMachine machine = new GreedyVendingMachine();
            machine.Add
            (
                Change.TenPence(5),
                Change.TwentyPence(1)
            );

            // Take out 6 x 10p. That's more than is in the machine, so should fail
            machine.Remove(Change.TenPence(6));
        }
        public void RemoveChangeItem_Rollback()
        {
            VendingMachine machine = new GreedyVendingMachine();
            machine.Add
            (
                Change.TenPence(5),
                Change.TwentyPence(3),
                Change.FiftyPence(1)
            );

            int preBalance = machine.Balance.TotalValue();

            Change[] changeToRemove =
            {
                Change.FiftyPence(1),
                Change.TwentyPence(4)
            };

            bool caughtException = false;

            try
            {
                machine.Remove(changeToRemove);
            }
            catch(ArgumentException)
            {
                caughtException = true;
            }

            Assert.IsTrue(caughtException);

            // The balance should be the same
            Assert.AreEqual(preBalance, machine.Balance.TotalValue());

            // And the coins should be the same
            Assert.AreEqual(3, machine.Balance.Count());

            Assert.IsTrue(machine.Balance.FirstOrDefault(c => c.Denomination == 10 && c.Quantity == 5) != null);
            Assert.IsTrue(machine.Balance.FirstOrDefault(c => c.Denomination == 20 && c.Quantity == 3) != null);
            Assert.IsTrue(machine.Balance.FirstOrDefault(c => c.Denomination == 50 && c.Quantity == 1) != null);
        }