Skip to content

Instantly share code, notes, and snippets.

@ygrenzinger
Last active June 10, 2022 03:36
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save ygrenzinger/2a8efabe6817e7cb5031e5573ca06e0d to your computer and use it in GitHub Desktop.
Save ygrenzinger/2a8efabe6817e7cb5031e5573ca06e0d to your computer and use it in GitHub Desktop.
Coderpad
"use strict";
const _ = require('lodash');
const assert = require('assert');
const Mocha = require('mocha')
const mocha = new Mocha();
mocha.suite.emit('pre-require', this, 'solution', mocha);
const sinon = require("sinon");
const OperationType = {
Deposit: 'deposit',
Withdrawal: 'withdrawal'
}
class Operation {
constructor(operationType, amount, date) {
this.operationType = operationType;
this.amount = amount;
this.date = date;
Object.freeze(this);
}
get value() {
switch(this.operationType) {
case OperationType.Deposit:
return this.amount;
case OperationType.Withdrawal:
return -this.amount;
}
}
}
class StatementLine {
constructor(date,operationType, amount, balance) {
this.date = date;
this.operationType = operationType;
this.amount = amount;
this.balance = balance;
Object.freeze(this);
}
}
class Statement {
lines = [];
addLine(statementLine) {
this.lines.push(statementLine);
}
#formatDate(date) {
const [month, day, year] = [date.getMonth()+1, date.getDate(), date.getFullYear()];
return `${day}/${month}/${year}`;
}
print(printer) {
printer.print("date || credit || debit || balance");
[...this.lines].reverse().forEach((line) => {
if (line.operationType == OperationType.Deposit) {
printer.print(`${this.#formatDate(line.date)} || ${line.amount} || || ${line.balance}`);
} else {
printer.print(`${this.#formatDate(line.date)} || || ${line.amount} || ${line.balance}`);
}
})
}
}
class BankAccount {
#operations = [];
get balance() {
return this.#operations.reduce(
(previous, current) => previous + current.value,
0
);
}
deposit(amount, date) {
this.#operations.push(new Operation(OperationType.Deposit, amount, date));
}
withdrawal(amount, date) {
this.#operations.push(new Operation(OperationType.Withdrawal, amount, date));
}
get statement() {
const statement = new Statement();
let balance = 0;
this.#operations.forEach(op => {
balance += op.value;
statement.addLine(new StatementLine(op.date, op.operationType, op.amount, balance));
});
return statement;
}
}
describe('Bank Account', function () {
it('should create an account with starting balance 0', function () {
assert.equal(new BankAccount().balance, 0);
});
it('should make a deposit', function () {
const bankAccount = new BankAccount();
bankAccount.deposit(1000, new Date());
assert.equal(bankAccount.balance, 1000);
});
it('should make a withdrawal', function () {
const bankAccount = new BankAccount();
bankAccount.deposit(100, new Date());
bankAccount.withdrawal(80, new Date());
assert.equal(bankAccount.balance, 20);
});
it('should print bank statement', function() {
const fakePrint = sinon.fake(function(line) { console.log(line); });
const printer = {
print: fakePrint
};
const bankAccount = new BankAccount();
bankAccount.deposit(1000, new Date(2012, 0, 10));
bankAccount.deposit(2000, new Date(2012, 0, 13));
bankAccount.withdrawal(500, new Date(2012, 0, 14));
bankAccount.statement.print(printer);
assert.equal(fakePrint.callCount, 4);
assert(fakePrint.calledWith("date || credit || debit || balance"));
assert(fakePrint.calledWith("14/1/2012 || || 500 || 2500"));
assert(fakePrint.calledWith("13/1/2012 || 2000 || || 3000"));
assert(fakePrint.calledWith("10/1/2012 || 1000 || || 1000"));
});
});
mocha.run()
"use strict";
const Mocha = require('mocha')
const mocha = new Mocha();
mocha.suite.emit('pre-require', this, 'solution', mocha);
const assert = require('assert');
const sinon = require("sinon");
const _ = require('lodash');
describe('xxx', function () {
it('should xxx', function () {
assert.equal(new BankAccount().balance, 0);
});
});
mocha.run()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment