Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
48 changes: 0 additions & 48 deletions account.js

This file was deleted.

20 changes: 0 additions & 20 deletions printer.js

This file was deleted.

48 changes: 48 additions & 0 deletions src/account.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
module.exports = class Account {
#transactions = [];
#transaction;
#printer;

constructor(transaction, printer) {
this.#transaction = transaction;
this.#printer = printer;
}

getBalance() {
if (this.#transactions[this.#transactions.length - 1]) {
return this.#transactions[this.#transactions.length - 1].getBalance();
} else return 0;
}

deposit(amount) {
this.#checkDepositValue(amount);
this.#transactions.push(
new this.#transaction({
credit: amount,
balance: this.getBalance() + amount,
})
);
}

withdraw(amount) {
this.#checkSufficientFunds(amount);
this.#transactions.push(
new this.#transaction({
debit: amount,
balance: this.getBalance() - amount,
})
);
}

printStatement() {
return this.#printer.printStatement(this.#transactions);
}

#checkSufficientFunds(amount) {
if (amount > this.getBalance()) throw "Withdraw failed: Insufficient funds";
}

#checkDepositValue(amount) {
if (amount <= 0) throw "Deposit failed: Amount must be positive";
}
};
24 changes: 10 additions & 14 deletions account.test.js → src/account.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,18 +18,16 @@ describe("Account", () => {
});

describe("getBalance", () => {
it("should return the balance of the account", () => {
expect(accountWithCash.getBalance()).toEqual(500);
});
});
it("should call the latest transaction for the current balance", () => {
const spy = jest.spyOn(Transaction.prototype, "getBalance");

describe(".deposit", () => {
it("should increase the balance by the amount deposited", () => {
emptyAccount.deposit(500);
accountWithCash.getBalance();

expect(emptyAccount.getBalance()).toEqual(500);
expect(spy).toHaveBeenCalledTimes(1);
});
});

describe(".deposit", () => {
it("should create a new transaction", () => {
emptyAccount.deposit(500);

Expand All @@ -47,19 +45,17 @@ describe("Account", () => {
});

describe(".withdraw", () => {
it("should decrease the balance by the amount deposited", () => {
accountWithCash.withdraw(250);

expect(accountWithCash.getBalance()).toEqual(250);
});

it("should throw an error if amount to withdraw is greater than current balance", () => {
expect(() => emptyAccount.withdraw(500)).toThrow(
"Withdrawal failed: Insufficient funds"
);
});

it("should create a new transaction", () => {
jest.spyOn(Transaction.prototype, "getBalance").mockImplementation(() => {
return 500;
});

accountWithCash.withdraw(250);

expect(Transaction).toHaveBeenCalledWith({
Expand Down
4 changes: 0 additions & 4 deletions feature.test.js → src/feature.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,6 @@ beforeAll(() => {
jest.setSystemTime(new Date("2022-06-20"));
});

afterAll(() => {
jest.useRealTimers();
});

it("should allow deposits, withdrawals and be able to print statement showing those transactions", () => {
const account = new Account(Transaction, new Printer());

Expand Down
33 changes: 33 additions & 0 deletions src/printer.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
module.exports = class Printer {
#header = "date || credit || debit || balance";

printStatement(transactions) {
return this.#header + "\n" + this.#formatTransactions(transactions);
}

#formatTransactions(transactions) {
return transactions
.reverse()
.map(this.#getTransactionData)
.map(this.#formatTransactionData)
.join("\n");
}

#getTransactionData(transaction) {
return [
transaction.getDate(),
transaction.getCredit(),
transaction.getDebit(),
transaction.getBalance(),
];
}

#formatTransactionData(entries) {
return entries
.map((entry) => {
if (typeof entry == "number") return entry.toFixed(2);
else return entry;
})
.join(" || ");
}
};
2 changes: 1 addition & 1 deletion printer.test.js → src/printer.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ describe("Printer", () => {
});

it("should handle multiple transactions", () => {
expect(printer.printStatement([secondTransaction, transaction])).toEqual(
expect(printer.printStatement([transaction, secondTransaction])).toEqual(
"date || credit || debit || balance\n20/06/2022 || 500.00 || || 1000.00\n19/06/2022 || 500.00 || || 500.00"
);
});
Expand Down
26 changes: 26 additions & 0 deletions src/transaction.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
module.exports = class Transaction {
#date = new Date(Date.now()).toLocaleDateString();
#credit;
#debit;
#balance;

constructor({ credit = null, debit = null, balance = null } = {}) {
[this.#credit, this.#debit, this.#balance] = [credit, debit, balance];
}

getDate() {
return this.#date;
}

getCredit() {
return this.#credit;
}

getDebit() {
return this.#debit;
}

getBalance() {
return this.#balance;
}
};
6 changes: 3 additions & 3 deletions transaction.test.js → src/transaction.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,19 +24,19 @@ describe("Transaction", () => {

describe("getCredit", () => {
it("should return the credit amount formatted as a float to 2 decimals", () => {
expect(creditTransaction.getCredit()).toEqual("500.00");
expect(creditTransaction.getCredit()).toEqual(500);
});
});

describe("getDebit()", () => {
it("should return the debt amount formatted as a float to 2 decimals", () => {
expect(debitTransaction.getDebit()).toEqual("500.00");
expect(debitTransaction.getDebit()).toEqual(500);
});
});

describe("getBalance()", () => {
it("should return the balance amount formatted as a float to 2 decimals", () => {
expect(debitTransaction.getBalance()).toEqual("1000.00");
expect(debitTransaction.getBalance()).toEqual(1000);
});
});
});
36 changes: 0 additions & 36 deletions transaction.js

This file was deleted.