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
2 changes: 1 addition & 1 deletion jest.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ module.exports = {
testMatch: ['**/?(*.)+(test).ts'],
moduleFileExtensions: ['ts', 'js', 'json'],
moduleNameMapper: {
axios: 'axios/dist/node/axios.cjs'
'^axios$': require.resolve('axios'),
},
restoreMocks: true,
resetMocks: true,
Expand Down
4,099 changes: 1,913 additions & 2,186 deletions package-lock.json

Large diffs are not rendered by default.

36 changes: 18 additions & 18 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -15,26 +15,26 @@
"build": "tsc"
},
"devDependencies": {
"@babel/preset-env": "^7.21.4",
"@babel/preset-typescript": "^7.21.4",
"@types/jest": "27.4.1",
"@types/lodash": "^4.14.192",
"@types/node": "^18.0.0",
"@typescript-eslint/eslint-plugin": "^5.0.0",
"@typescript-eslint/parser": "^5.0.0",
"eslint": "^8.0.1",
"eslint-config-prettier": "^8.3.0",
"eslint-plugin-prettier": "^4.0.0",
"jest": "^27.2.5",
"prettier": "^2.3.2",
"ts-jest": "^27.1.5",
"ts-loader": "^9.2.3",
"ts-node": "^10.0.0",
"tsconfig-paths": "^3.10.1",
"typescript": "^4.3.5"
"@babel/preset-env": "^7.22.5",
"@babel/preset-typescript": "^7.22.5",
"@types/jest": "^29.5.2",
"@types/lodash": "^4.14.195",
"@types/node": "^20.3.1",
"@typescript-eslint/eslint-plugin": "^5.60.0",
"@typescript-eslint/parser": "^5.60.0",
"eslint": "^8.43.0",
"eslint-config-prettier": "^8.8.0",
"eslint-plugin-prettier": "^4.2.1",
"jest": "^29.5.0",
"prettier": "^2.8.8",
"ts-jest": "^29.1.0",
"ts-loader": "^9.4.3",
"ts-node": "^10.9.1",
"tsconfig-paths": "^4.2.0",
"typescript": "^5.1.3"
},
"dependencies": {
"axios": "^1.3.4",
"axios": "^1.4.0",
"lodash": "^4.17.21"
}
}
42 changes: 34 additions & 8 deletions src/01-simple-tests/index.test.ts
Original file line number Diff line number Diff line change
@@ -1,32 +1,58 @@
// Uncomment the code below and write your tests
// import { simpleCalculator, Action } from './index';

import { simpleCalculator, Action } from './index';

describe('simpleCalculator tests', () => {
test('should add two numbers', () => {
// Write your test here
expect(simpleCalculator({ a: 1, b: 2, action: Action.Add })).toBe(3);
expect(simpleCalculator({ a: 4, b: 4, action: Action.Add })).toBe(8);
expect(simpleCalculator({ a: 8, b: 2, action: Action.Add })).toBe(10);
});

test('should substract two numbers', () => {
// Write your test here
expect(simpleCalculator({ a: 4, b: 2, action: Action.Substract })).toBe(2);
expect(simpleCalculator({ a: 4, b: 4, action: Action.Substract })).toBe(0);
expect(simpleCalculator({ a: 5, b: 7, action: Action.Substract })).toBe(-2);
});

test('should multiply two numbers', () => {
// Write your test here
expect(simpleCalculator({ a: 4, b: 2, action: Action.Multiply })).toBe(8);
expect(simpleCalculator({ a: 1, b: 1, action: Action.Multiply })).toBe(1);
expect(simpleCalculator({ a: -3, b: -3, action: Action.Multiply })).toBe(9);
expect(simpleCalculator({ a: 0, b: 7, action: Action.Multiply })).toBe(0);
});

test('should divide two numbers', () => {
// Write your test here
expect(simpleCalculator({ a: 4, b: 2, action: Action.Divide })).toBe(2);
expect(simpleCalculator({ a: 4, b: 4, action: Action.Divide })).toBe(1);
expect(simpleCalculator({ a: 0, b: 7, action: Action.Divide })).toBe(0);
expect(simpleCalculator({ a: 7, b: 0, action: Action.Divide })).toBe(
Infinity,
);
});

test('should exponentiate two numbers', () => {
// Write your test here
expect(simpleCalculator({ a: 4, b: 2, action: Action.Exponentiate })).toBe(
16,
);
expect(simpleCalculator({ a: 1, b: 1, action: Action.Exponentiate })).toBe(
1,
);
expect(simpleCalculator({ a: 0, b: 7, action: Action.Exponentiate })).toBe(
0,
);
});

test('should return null for invalid action', () => {
// Write your test here
expect(simpleCalculator({ a: 4, b: 2, action: '#' })).toBeNull();
});

test('should return null for invalid arguments', () => {
// Write your test here
expect(simpleCalculator({ a: 'a', b: 2, action: Action.Divide })).toBeNull();
expect(simpleCalculator({ a: 8, b: 'b', action: Action.Substract }))
.toBeNull();
expect(
simpleCalculator({ a: null, b: undefined, action: Action.Exponentiate }),
).toBeNull();
});
});
36 changes: 26 additions & 10 deletions src/02-table-tests/index.test.ts
Original file line number Diff line number Diff line change
@@ -1,17 +1,33 @@
// Uncomment the code below and write your tests
/* import { simpleCalculator, Action } from './index';
import { simpleCalculator, Action } from './index';

const testCases = [
{ a: 1, b: 2, action: Action.Add, expected: 3 },
{ a: 2, b: 2, action: Action.Add, expected: 4 },
{ a: 3, b: 2, action: Action.Add, expected: 5 },
// continue cases for other actions
]; */
{ a: 1, b: 2, action: Action.Add, expected: 3 },
{ a: 2, b: 2, action: Action.Add, expected: 4 },
{ a: 3, b: 2, action: Action.Substract, expected: 1 },
{ a: 13, b: 24, action: Action.Substract, expected: -11 },
{ a: 2, b: 5, action: Action.Multiply, expected: 10 },
{ a: 0, b: 24, action: Action.Multiply, expected: 0 },
{ a: 24, b: 2, action: Action.Divide, expected: 12 },
{ a: -10, b: 10, action: Action.Divide, expected: -1 },
{ a: 5, b: 2, action: Action.Exponentiate, expected: 25 },
{ a: 12, b: 0, action: Action.Exponentiate, expected: 1 },
];

const nullTestCases = [
{ a: 1, b: 2, action: '6' },
{ a: 2, b: 'number', action: Action.Divide },
{ a: undefined, b: 2, action: Action.Substract },
];

describe('simpleCalculator', () => {
// This test case is just to run this test suite, remove it when you write your own tests
test('should blah-blah', () => {
expect(true).toBe(true);
test.each(testCases)(
'should test all actions in simple calculator',
({ a, b, action, expected }) => {
expect(simpleCalculator({ a, b, action })).toBe(expected);
},
);
test.each(nullTestCases)('should return null', ({ a, b, action }) => {
expect(simpleCalculator({ a, b, action })).toBeNull();
});
// Consider to use Jest table tests API to test all cases above
});
18 changes: 12 additions & 6 deletions src/03-error-handling-async/index.test.ts
Original file line number Diff line number Diff line change
@@ -1,30 +1,36 @@
// Uncomment the code below and write your tests
// import { throwError, throwCustomError, resolveValue, MyAwesomeError, rejectCustomError } from './index';
import {
throwError,
throwCustomError,
resolveValue,
MyAwesomeError,
rejectCustomError,
} from './index';

describe('resolveValue', () => {
test('should resolve provided value', async () => {
// Write your test here
return expect(resolveValue('value')).resolves.toBe('value');
});
});

describe('throwError', () => {
test('should throw error with provided message', () => {
// Write your test here
expect(() => throwError('error message')).toThrow('error message');
});

test('should throw error with default message if message is not provided', () => {
// Write your test here
expect(() => throwError()).toThrow('Oops!');
});
});

describe('throwCustomError', () => {
test('should throw custom error', () => {
// Write your test here
expect(() => throwCustomError()).toThrow(MyAwesomeError);
});
});

describe('rejectCustomError', () => {
test('should reject custom error', async () => {
// Write your test here
expect(rejectCustomError()).rejects.toThrow(MyAwesomeError);
});
});
73 changes: 60 additions & 13 deletions src/04-test-class/index.test.ts
Original file line number Diff line number Diff line change
@@ -1,44 +1,91 @@
// Uncomment the code below and write your tests
// import { getBankAccount } from '.';
import {
getBankAccount,
BankAccount,
InsufficientFundsError,
TransferFailedError,
SynchronizationFailedError,
} from './index';

describe('BankAccount', () => {
let newBankAcc: BankAccount;

beforeEach(() => {
newBankAcc = getBankAccount(1000);
});

afterEach(() => {
jest.restoreAllMocks();
});

test('should create account with initial balance', () => {
// Write your test here
expect(newBankAcc).toBeInstanceOf(BankAccount);
expect(newBankAcc.getBalance()).toBe(1000);
});

test('should throw InsufficientFundsError error when withdrawing more than balance', () => {
// Write your test here
expect(() => newBankAcc.withdraw(2000)).toThrow(InsufficientFundsError);
});

test('should throw TransferFailedError error when transferring more than balance', () => {
// Write your test here
test('should throw InsufficientFundsError error when transferring more than balance', () => {
const otherBankAcc = getBankAccount(0);
expect(() => newBankAcc.transfer(2000, otherBankAcc)).toThrow(
InsufficientFundsError,
);
});

test('should throw error when transferring to the same account', () => {
// Write your test here
test('should throw TransferFailedError when transferring to the same account', () => {
expect(() => newBankAcc.transfer(500, newBankAcc)).toThrow(
TransferFailedError,
);
});

test('should deposit money', () => {
// Write your test here
const depMoney = jest.spyOn(newBankAcc, 'deposit');
newBankAcc.deposit(1000);
expect(depMoney).toBeCalledTimes(1);
expect(newBankAcc.getBalance()).toBe(2000);
});

test('should withdraw money', () => {
// Write your test here
const witMoney = jest.spyOn(newBankAcc, 'withdraw');
newBankAcc.withdraw(500);
expect(witMoney).toBeCalledTimes(1);
expect(newBankAcc.getBalance()).toBe(500);
});

test('should transfer money', () => {
// Write your test here
const otherBankAcc = getBankAccount(0);
const transMoney = jest.spyOn(newBankAcc, 'transfer');
newBankAcc.transfer(500, otherBankAcc);
expect(transMoney).toBeCalledTimes(1);
expect(newBankAcc.getBalance()).toBe(500);
expect(otherBankAcc.getBalance()).toBe(500);
});

test('fetchBalance should return number in case if request did not failed', async () => {
// Write your tests here
const otherBankAcc = getBankAccount(0);
jest.spyOn(otherBankAcc, 'fetchBalance').mockResolvedValue(200);
const balance = await otherBankAcc.fetchBalance();
expect(balance).toEqual(expect.any(Number));
});

test('should set new balance if fetchBalance returned number', async () => {
// Write your tests here
const otherBankAcc = getBankAccount(0);
jest
.spyOn(otherBankAcc, 'fetchBalance')
.mockReturnValue(new Promise((res) => res(200)));
await otherBankAcc.synchronizeBalance();
expect(otherBankAcc.getBalance()).toEqual(200);
});

test('should throw SynchronizationFailedError if fetchBalance returned null', async () => {
// Write your tests here
const otherBankAcc = getBankAccount(0);
jest
.spyOn(otherBankAcc, 'fetchBalance')
.mockReturnValue(new Promise((res) => res(null)));
expect(async () => await otherBankAcc.synchronizeBalance()).rejects.toThrow(
SynchronizationFailedError,
);
});
});
23 changes: 12 additions & 11 deletions src/04-test-class/index.ts
Original file line number Diff line number Diff line change
@@ -1,32 +1,36 @@
import { random } from 'lodash';

export class BankAccount {
private balance: number;
private _balance: number;

constructor(initialBalance: number) {
this.balance = initialBalance;
this._balance = initialBalance;
}

public getBalance() {
return this._balance;
}

public deposit(amount: number): this {
this.balance += amount;
this._balance += amount;

return this;
}

public withdraw(amount: number): this {
if (amount > this.balance) {
throw new InsufficientFundsError(this.balance);
if (amount > this._balance) {
throw new InsufficientFundsError(this._balance);
}
this.balance -= amount;
this._balance -= amount;

return this;
}

public transfer(amount: number, toAccount: BankAccount): this {
this.withdraw(amount);
if (this === toAccount) {
throw new TransferFailedError();
}
this.withdraw(amount);
toAccount.deposit(amount);

return this;
Expand All @@ -35,10 +39,7 @@ export class BankAccount {
public async fetchBalance(): Promise<number | null> {
const balance = random(0, 100, false);

console.log('balance', balance);

const requestFailed = random(0, 1, false) === 0;
console.log('requestFailed', random(0, 1, false));

return requestFailed ? null : balance;
}
Expand All @@ -49,7 +50,7 @@ export class BankAccount {
throw new SynchronizationFailedError();
}

this.balance = balance;
this._balance = balance;
}
}

Expand Down
Loading