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
3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,8 @@
"format": "prettier --write \"src/**/*.ts\"",
"lint": "eslint \"src/**/*.ts\" --fix",
"test": "jest --silent",
"test:verbose": "jest",
"test:verbose": "jest --verbose --runInBand --detectOpenHandles",
"test:verbose:coverage": "jest --verbose --runInBand --detectOpenHandles --collectCoverage",
"build": "tsc"
},
"devDependencies": {
Expand Down
6 changes: 3 additions & 3 deletions src/01-simple-tests/index.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,9 @@ describe('simpleCalculator tests', () => {

test('should subtract two numbers', () => {
// Write your test here
const [a, b] = [5, 10];
const result = simpleCalculator({ a: a, b: b, action: Action.Add });
expect(result).toBe(a + b);
const [a, b] = [10, 5];
const result = simpleCalculator({ a: a, b: b, action: Action.Subtract });
expect(result).toBe(a - b);
});

test('should multiply two numbers', () => {
Expand Down
40 changes: 30 additions & 10 deletions src/02-table-tests/index.test.ts
Original file line number Diff line number Diff line change
@@ -1,17 +1,37 @@
// 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.Add, expected: 5 },

{ a: 5, b: 1, action: Action.Subtract, expected: 4 },
{ a: 4, b: 2, action: Action.Subtract, expected: 2 },
{ a: 8, b: 3, action: Action.Subtract, expected: 5 },

{ a: 2, b: 3, action: Action.Multiply, expected: 6 },
{ a: 3, b: 4, action: Action.Multiply, expected: 12 },
{ a: 5, b: 2, action: Action.Multiply, expected: 10 },

{ a: 8, b: 2, action: Action.Divide, expected: 4 },
{ a: 10, b: 5, action: Action.Divide, expected: 2 },
{ a: 15, b: 3, action: Action.Divide, expected: 5 },

{ a: 5, b: 2, action: Action.Exponentiate, expected: 25 },
{ a: 3, b: 3, action: Action.Exponentiate, expected: 27 },
{ a: 2, b: 5, action: Action.Exponentiate, expected: 32 },

// Invalid cases
{ a: 2, b: 5, action: 'wrong action', expected: null },
{ a: '2', b: 5, action: Action.Exponentiate, expected: null },
{ a: 2, b: '5', action: Action.Exponentiate, expected: null },
// continue cases for other actions
];

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);
});
// Consider to use Jest table tests API to test all cases above
test.each(testCases)('$a $action $b', ({ a, b, action, expected }) => {
expect(simpleCalculator({ a, b, action })).toBe(expected);
});
});
23 changes: 22 additions & 1 deletion src/03-error-handling-async/index.test.ts
Original file line number Diff line number Diff line change
@@ -1,30 +1,51 @@
// 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
expect.assertions(1);
expect(resolveValue(10)).resolves.toBe(10);
});
});

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

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

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.assertions(1);
await expect(rejectCustomError()).rejects.toThrow(MyAwesomeError);
});
});
87 changes: 84 additions & 3 deletions src/04-test-class/index.test.ts
Original file line number Diff line number Diff line change
@@ -1,44 +1,125 @@
// Uncomment the code below and write your tests
// import { getBankAccount } from '.';
import {
getBankAccount,
BankAccount,
InsufficientFundsError,
// SynchronizationFailedError,
TransferFailedError,
SynchronizationFailedError,
} from '.';

import { random } from 'lodash';

jest.mock('lodash', () => ({
random: jest.fn(),
}));

describe('BankAccount', () => {
const initialBalance = 1000;

test('should create account with initial balance', () => {
// Write your test here
const account = getBankAccount(initialBalance);

expect(account).toBeInstanceOf(BankAccount);
expect(account.getBalance()).toBe(initialBalance);
});

test('should throw InsufficientFundsError error when withdrawing more than balance', () => {
// Write your test here
const account = getBankAccount(initialBalance);

expect(() => {
account.withdraw(account.getBalance() + 1000);
}).toThrow(InsufficientFundsError);
});

test('should throw error when transferring more than balance', () => {
// Write your test here
const account = getBankAccount(initialBalance);
const accountToTransfer = getBankAccount(initialBalance);

expect(() => {
account.transfer(account.getBalance() + 1000, accountToTransfer);
}).toThrow(InsufficientFundsError);
});

test('should throw error when transferring to the same account', () => {
// Write your test here
const account = getBankAccount(initialBalance);

expect(() => {
account.transfer(account.getBalance() + 1000, account);
}).toThrow(TransferFailedError);
});

test('should deposit money', () => {
// Write your test here
const account = getBankAccount(initialBalance);
const deposit = 2000;
account.deposit(deposit);

expect(account.getBalance()).toBe(initialBalance + deposit);
});

test('should withdraw money', () => {
// Write your test here
const account = getBankAccount(initialBalance);
const withdrawAmount = 200;
account.withdraw(withdrawAmount);

expect(account.getBalance()).toBe(initialBalance - withdrawAmount);
});

test('should transfer money', () => {
// Write your test here
const account = getBankAccount(initialBalance);
const accountToTransfer = getBankAccount(initialBalance);
const transferAmount = 300;
account.transfer(transferAmount, accountToTransfer);

expect(account.getBalance()).toBe(initialBalance - transferAmount);
expect(accountToTransfer.getBalance()).toBe(
initialBalance + transferAmount,
);
});

test('fetchBalance should return number in case if request did not failed', async () => {
// Write your tests here

const account = getBankAccount(initialBalance);

(random as jest.Mock)
.mockImplementationOnce(() => 77)
.mockImplementationOnce(() => 1);

const balance = await account.fetchBalance();

expect(typeof balance).toBe('number');
});

test('should set new balance if fetchBalance returned number', async () => {
test('synchronizeBalance should set new balance if fetchBalance returned number', async () => {
// Write your tests here
const account = getBankAccount(initialBalance);
(random as jest.Mock)
.mockImplementationOnce(() => 77)
.mockImplementationOnce(() => 1);

await account.synchronizeBalance();
expect(account.getBalance()).not.toBe(initialBalance);
});

test('should throw SynchronizationFailedError if fetchBalance returned null', async () => {
test('synchronizeBalance should throw SynchronizationFailedError if fetchBalance returned null', async () => {
// Write your tests here
const account = getBankAccount(initialBalance);

(random as jest.Mock)
.mockImplementationOnce(() => 77)
.mockImplementationOnce(() => 0);

expect.assertions(1);
await expect(account.synchronizeBalance()).rejects.toThrow(
SynchronizationFailedError,
);
});
});
1 change: 0 additions & 1 deletion src/04-test-class/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,6 @@ export class BankAccount {

public async fetchBalance(): Promise<number | null> {
const balance = random(0, 100, false);

const requestFailed = random(0, 1, false) === 0;

return requestFailed ? null : balance;
Expand Down
25 changes: 22 additions & 3 deletions src/05-partial-mocking/index.test.ts
Original file line number Diff line number Diff line change
@@ -1,20 +1,39 @@
// Uncomment the code below and write your tests
// import { mockOne, mockTwo, mockThree, unmockedFunction } from './index';
import { mockOne, mockTwo, mockThree, unmockedFunction } from './index';

jest.mock('./index', () => {
// const originalModule = jest.requireActual<typeof import('./index')>('./index');
const originalModule =
jest.requireActual<typeof import('./index')>('./index');

return {
mockOne: jest.fn(),
mockTwo: jest.fn(),
mockThree: jest.fn(),
unmockedFunction: originalModule.unmockedFunction,
};
});

describe('partial mocking', () => {
afterAll(() => {
jest.unmock('./index');
});

test('mockOne, mockTwo, mockThree should not log into console', () => {
test('mockOne, mockTwo, mockTwo should not log into console', () => {
// Write your test here
const logSpy = jest.spyOn(console, 'log').mockImplementation(() => {});

mockOne();
mockTwo();
mockThree();

expect(logSpy).not.toHaveBeenCalled();
});

test('unmockedFunction should log into console', () => {
// Write your test here
const logSpy = jest.spyOn(console, 'log').mockImplementation(() => {});
unmockedFunction();

expect(logSpy).toHaveBeenCalled();
});
});
Loading