©Vladimir Levin

Vending Machine Iteration 1

TestVendingMachine.java
package vending;

import junit.framework.TestCase;

import java.util.ArrayList;

public class TestVendingMachine extends TestCase {
    VendingMachine machine;
    public void setUp() throws Exception  {
        machine = new VendingMachine();
    }

    public void testCreateVendingMachine() {
        assertEquals(0, machine.getSlots().size());
    }

    public void testAddSlot() {
        machine.addSlot(new Slot("mars bar", 100, 10));

        Slot slot = (Slot) machine.getSlots().get(0);
        assertEquals("mars bar", slot.getName());
        assertEquals(100, slot.getPriceInCents());
        assertEquals(10, slot.getQuantity());
    }

    public void testPurchaseItem() {
        machine.addSlot(new Slot("mars bar", 100, 10));
        machine.addSlot(new Slot("potato chips", 100, 10));

        PurchaseStatus purchaseStatus = machine.purchase(0, 100);

        Slot slot = (Slot) machine.getSlots().get(0);
        assertEquals(VendingMachine.SUCCESSFUL, purchaseStatus.getStatus());
        assertEquals(9, slot.getQuantity());
    }

    public void testPurchaseItemNotEnoughMoney() {
        machine.addSlot(new Slot("mars bar", 100, 10));
        machine.addSlot(new Slot("potato chips", 100, 10));

        PurchaseStatus purchaseStatus = machine.purchase(0, 90);

        Slot slot = (Slot) machine.getSlots().get(0);
        assertEquals(VendingMachine.NOT_ENOUGH_MONEY, purchaseStatus.getStatus());
        assertEquals(10, slot.getQuantity());
    }

    public void testAddCoins() {
        machine.addCoin(VendingMachine.FIVE_CENTS);
        machine.addCoin(VendingMachine.TEN_CENTS);
        machine.addCoin(VendingMachine.TWENTY_FIVE_CENTS);
        machine.addCoin(VendingMachine.DOLLAR);
        machine.addCoin(VendingMachine.TWO_DOLLARS);

        ArrayList coins = machine.getInsertedCoins();
        assertEquals(340, machine.getMoneyInsertedInCents());
        assertEquals(5, coins.size());
    }

    public void testPurchaseItemOk() {
        machine.addSlot(new Slot("mars bar", 100, 10));
        machine.addSlot(new Slot("potato chips", 100, 10));

        machine.addCoin(VendingMachine.DOLLAR);
        PurchaseStatus purchaseStatus = machine.purchase(1);

        Slot slot = (Slot) machine.getSlots().get(1);
        assertEquals(VendingMachine.SUCCESSFUL, purchaseStatus.getStatus());
        assertEquals(9, slot.getQuantity());
    }

    public void testPurchaseItemChange() {
        machine.addSlot(new Slot("chewing gum", 90, 50));
        machine.addSlot(new Slot("potato chips", 100, 10));

        machine.addCoin(VendingMachine.DOLLAR);
        PurchaseStatus purchaseStatus = machine.purchase(0);

        Slot slot = (Slot) machine.getSlots().get(0);
        assertEquals(VendingMachine.SUCCESSFUL, purchaseStatus.getStatus());
        assertEquals(49, slot.getQuantity());

        ArrayList change = purchaseStatus.getChange();
        assertEquals(1, change.size());
        assertTrue(change.contains(
                new Integer(VendingMachine.TEN_CENTS)));
    }
}

VendingMachine.java
package vending;

import java.util.ArrayList;

public class VendingMachine {
    public static final int SUCCESSFUL = 0;
    public static final int NOT_ENOUGH_MONEY = 1;

    public static final int FIVE_CENTS = 5;
    public static final int TEN_CENTS = 10;
    public static final int TWENTY_FIVE_CENTS = 25;
    public static final int DOLLAR = 100;
    public static final int TWO_DOLLARS = 200;

    private ArrayList slots = new ArrayList();
    private ArrayList insertedCoins = new ArrayList();

    public void addSlot(Slot slot) {
        slots.add(slot);
    }

    ArrayList getSlots() {
        return slots;
    }

    public PurchaseStatus purchase(int slotIndex) {
        return purchase(slotIndex, getMoneyInsertedInCents());
    }

    PurchaseStatus purchase(int slotIndex, int moneyInserted) {
        Slot slot = (Slot) slots.get(slotIndex);
        int priceInCents = slot.getPriceInCents();
        if (moneyInserted == priceInCents) {
            slot.decrementQuantity();
            return new PurchaseStatus(VendingMachine.SUCCESSFUL);
        } else if (moneyInserted > priceInCents) {
            slot.decrementQuantity();
            ArrayList change = new ArrayList();
            int changeInCents = moneyInserted - priceInCents;

            int twoDollarChange = changeInCents / VendingMachine.TWO_DOLLARS;
            int remainder = changeInCents % VendingMachine.TWO_DOLLARS;
            if (twoDollarChange > 0) {
                for (int i=0; i<twoDollarChange; i++) {
                    change.add(new Integer(VendingMachine.TWO_DOLLARS));
                }
            }

            int oneDollarChange = remainder / VendingMachine.DOLLAR;
            remainder = remainder % VendingMachine.DOLLAR;
            if (oneDollarChange > 0) {
                for (int i=0; i<oneDollarChange; i++) {
                    change.add(new Integer(VendingMachine.DOLLAR));
                }
            }

            int twentyFiveCentsChange = remainder / VendingMachine.TWENTY_FIVE_CENTS;
            remainder = remainder % VendingMachine.TWENTY_FIVE_CENTS;
            if (twentyFiveCentsChange > 0) {
                for (int i=0; i<twentyFiveCentsChange; i++) {
                    change.add(new Integer(VendingMachine.TWENTY_FIVE_CENTS));
                }
            }

            int tenCentsChange = remainder / VendingMachine.TEN_CENTS;
            remainder = remainder % VendingMachine.TEN_CENTS;
            if (tenCentsChange > 0) {
                for (int i=0; i<tenCentsChange; i++) {
                    change.add(new Integer(VendingMachine.TEN_CENTS));
                }
            }

            int fiveCentsChange = remainder / VendingMachine.FIVE_CENTS;
            remainder = remainder % VendingMachine.FIVE_CENTS;
            if (fiveCentsChange > 0) {
                for (int i=0; i<fiveCentsChange; i++) {
                    change.add(new Integer(VendingMachine.FIVE_CENTS));
                }
            }

            return new PurchaseStatus(VendingMachine.SUCCESSFUL, change);
        }

        return new PurchaseStatus(VendingMachine.NOT_ENOUGH_MONEY);
    }

    public void addCoin(int coin) {
        insertedCoins.add(new Integer(coin));
    }

    int getMoneyInsertedInCents() {
        int total = 0;
        for (int i=0; i<insertedCoins.size(); i++) {
            total += ((Integer) insertedCoins.get(i)).intValue();
        }

        return total;
    }

    ArrayList getInsertedCoins() {
        return insertedCoins;
    }

}

Slot.java
package vending;

public class Slot {
    private String name;
    private int priceInCents;
    private int quantity;

    public Slot(String name, int priceInCents, int quantity) {
        this.name = name;
        this.priceInCents = priceInCents;
        this.quantity = quantity;
    }

    public String getName() {
        return name;
    }

    public int getPriceInCents() {
        return priceInCents;
    }

    public int getQuantity() {
        return quantity;
    }

    public void decrementQuantity() {
        quantity--;
    }
}

PurchaseStatus.java
package vending;

import java.util.ArrayList;

public class PurchaseStatus {
    private int status;
    private ArrayList change;

    public PurchaseStatus(int status) {
        this.status = status;
        this.change = new ArrayList();
    }

    public PurchaseStatus(int status, ArrayList change) {
        this.status = status;
        this.change = change;
    }

    public int getStatus() {
        return status;
    }

    public ArrayList getChange() {
        return change;
    }
}