Skip to content

Commit

Permalink
typescript: logger unit test
Browse files Browse the repository at this point in the history
  • Loading branch information
Victor R. Braga de Sales Mascarenhas authored and KiranNiranjan committed Apr 2, 2019
1 parent 36213a6 commit a0a3d77
Show file tree
Hide file tree
Showing 5 changed files with 218 additions and 5 deletions.
16 changes: 14 additions & 2 deletions jest.unit.config.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,18 @@
{
"testMatch": [
"**/*.test.js"
"roots": [
"<rootDir>/spec"
],
"transform": {
"^.+\\.tsx?$": "ts-jest"
},
"testRegex": "(test|spec)\\.tsx?$",
"moduleFileExtensions": [
"ts",
"tsx",
"js",
"jsx",
"json",
"node"
],
"verbose": true,
"collectCoverage": true,
Expand Down
6 changes: 4 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,7 @@
"devDependencies": {
"@types/auto-launch": "^5.0.0",
"@types/ffi": "0.2.1",
"@types/jest": "23.3.12",
"@types/lodash.omit": "^4.5.4",
"@types/node": "10.11.4",
"@types/react": "16.4.18",
Expand All @@ -95,6 +96,7 @@
"browserify": "16.2.3",
"chromedriver": "2.45.0",
"cross-env": "5.2.0",
"del": "3.0.0",
"electron": "4.0.8",
"electron-builder": "20.38.4",
"electron-builder-squirrel-windows": "20.38.3",
Expand All @@ -118,10 +120,10 @@
"robotjs": "0.5.1",
"selenium-webdriver": "3.6.0",
"spectron": "5.0.0",
"ts-jest": "23.10.5",
"tslint": "5.11.0",
"typescript": "3.1.1",
"wdio-selenium-standalone-service": "0.0.12",
"del": "latest"
"wdio-selenium-standalone-service": "0.0.12"
},
"dependencies": {
"@types/ffi": "0.2.1",
Expand Down
95 changes: 95 additions & 0 deletions spec/__mocks__/electron.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
import { EventEmitter } from 'events';
import * as path from 'path';
const ipcEmitter = new EventEmitter();

const appName: string = 'Symphony';
const executableName = '/Symphony.exe';
interface IApp {
getAppPath(): string;
getPath(type: string): string;
getName(): string;
}
interface IIpcMain {
on(event: any, cb: any): void;
send(event: any, cb: any): void;
}
interface IIpcRenderer {
sendSync(event: any, cb: any): any;
on(eventName: any, cb: any): void;
send(event: any, cb: any): void;
removeListener(eventName: any, cb: any): void;
}

// use config provided by test framework
const pathToConfigDir = (): string => {
return path.join(__dirname, '/..') as string;
};

// electron app mock...
const app: IApp = {
getAppPath: pathToConfigDir,
getPath: (type) => {
if (type === 'exe') {
return path.join(pathToConfigDir(), executableName);
}
return pathToConfigDir();
},
getName: () => appName,
};

// simple ipc mocks for render and main process ipc using
// nodes' EventEmitter
const ipcMain: IIpcMain = {
on: (event, cb) => {
ipcEmitter.on(event, cb);
},
send: (event, args) => {
const senderEvent = {
sender: {
send: (eventSend, arg) => {
ipcEmitter.emit(eventSend, arg);
},
},
};
ipcEmitter.emit(event, senderEvent, args);
},
};

const ipcRenderer: IIpcRenderer = {
sendSync: (event, args) => {
const listeners = ipcEmitter.listeners(event);
if (listeners.length > 0) {
const listener = listeners[0];
const eventArg = {};
listener(eventArg, args);
return eventArg;
}
return null;
},
send: (event, args) => {
const senderEvent = {
sender: {
send: (eventSend, arg) => {
ipcEmitter.emit(eventSend, arg);
},
},
};
ipcEmitter.emit(event, senderEvent, args);
},
on: (eventName, cb) => {
ipcEmitter.on(eventName, cb);
},
removeListener: (eventName, cb) => {
ipcEmitter.removeListener(eventName, cb);
},
};

export = {
app,
ipcMain,
ipcRenderer,
require: jest.fn(),
match: jest.fn(),
remote: jest.fn(),
dialog: jest.fn(),
};
97 changes: 97 additions & 0 deletions spec/log.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
import { ILogMsg } from '../src/common/logger';

describe('logger', () => {
let instance;
beforeEach(() => {
// I did it for reset module imported between tests
const { logger } = require('../src/common/logger');
instance = logger;
jest.resetModules();
});

it('when no logger registered then queue items', () => {
instance.debug('test');
instance.debug('test2');
const queue: ILogMsg[] = instance.getLogQueue();
expect(queue.length).toBe(2);
});

it('should call send when logger get registered', () => {
instance.debug('test');
instance.debug('test2');

const mock = jest.fn<Electron.WebContents>(() => ({
send: jest.fn(),
}));
const mockWin = new mock();
instance.setLoggerWindow(mockWin);
expect(mockWin.send).toHaveBeenCalled();
});

it('should call `logger.error` correctly', () => {
const spy = jest.spyOn(instance, 'log');

instance.error('test error', { error: 'test error' });

expect(spy).toBeCalledWith('error', 'test error', [{ error: 'test error' }]);
});

it('should call `logger.warn` correctly', () => {
const spy = jest.spyOn(instance, 'log');

instance.warn('test warn', { warn: 'test warn' });

expect(spy).toBeCalledWith('warn', 'test warn', [{ warn: 'test warn' }]);
});

it('should call `logger.debug` correctly', () => {
const spy = jest.spyOn(instance, 'log');

instance.debug('test debug', { debug: 'test debug' });

expect(spy).toBeCalledWith('debug', 'test debug', [{ debug: 'test debug' }]);
});

it('should call `logger.info` correctly', () => {
const spy = jest.spyOn(instance, 'log');

instance.info('test info', { info: 'test info' });

expect(spy).toBeCalledWith('info', 'test info', [{ info: 'test info' }]);
});

it('should call `logger.verbose` correctly', () => {
const spy = jest.spyOn(instance, 'log');

instance.verbose('test verbose', { verbose: 'test verbose' });

expect(spy).toBeCalledWith('verbose', 'test verbose', [{ verbose: 'test verbose' }]);
});

it('should call `logger.silly` correctly', () => {
const spy = jest.spyOn(instance, 'log');

instance.silly('test silly', { silly: 'test silly' });

expect(spy).toBeCalledWith('silly', 'test silly', [{ silly: 'test silly' }]);
});

it('should call `logger.sendToCloud` when `logger.debug` is called', () => {
const spyLog = jest.spyOn(instance, 'log');
const spySendToCloud = jest.spyOn(instance, 'sendToCloud');
instance.debug('test');

expect(spyLog).toBeCalled();
expect(spySendToCloud).toBeCalled();

});

it('should cap at 100 queued log messages', () => {
for (let i = 0; i < 110; i++) {
instance.debug('test' + i);
}
const queue = instance.getLogQueue();
expect(queue.length).toBe(100);
});

});
9 changes: 8 additions & 1 deletion src/common/logger.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import * as util from 'util';
import { isElectronQA } from './env';
import { getCommandLineArgs } from './utils';

interface ILogMsg {
export interface ILogMsg {
level: LogLevel;
details: any;
showInConsole: boolean;
Expand Down Expand Up @@ -59,6 +59,13 @@ class Logger {
this.cleanupOldLogs();
}

/**
* get instance of logQueue
*/
public getLogQueue(): ILogMsg[] {
return this.logQueue;
}

/**
* Log error
*
Expand Down

0 comments on commit a0a3d77

Please sign in to comment.