Merge pull request #31 from Microsoft/caabreut/unit-tests
Add unit tests for some of the extension's 'backend' functionality
This commit is contained in:
Коммит
01cf04ea72
|
@ -30,7 +30,8 @@ module.exports = {
|
|||
|
||||
// An array of regexp pattern strings used to skip coverage collection
|
||||
coveragePathIgnorePatterns: [
|
||||
'\\\\node_modules\\\\'
|
||||
'\\\\node_modules\\\\',
|
||||
'index.js'
|
||||
],
|
||||
|
||||
// A list of reporter names that Jest uses when writing coverage reports
|
||||
|
|
|
@ -4,6 +4,10 @@
|
|||
* @param {string} filepath - The filepath to the script to be injected.
|
||||
*/
|
||||
function injectScript (filepath) {
|
||||
if (filepath == null) {
|
||||
throw Error('filepath must not be null or undefined');
|
||||
}
|
||||
|
||||
const bodyTag = document.getElementsByTagName('body')[0];
|
||||
const scriptTag = document.createElement('script');
|
||||
scriptTag.setAttribute('type', 'text/javascript');
|
||||
|
|
|
@ -0,0 +1,25 @@
|
|||
import injectScript from './injectScript';
|
||||
|
||||
describe('injectScript.js', () => {
|
||||
it('should throw an Error when the filepath parameter is null', () => {
|
||||
expect(() => injectScript(null)).toThrow();
|
||||
});
|
||||
|
||||
it('should throw an Error when the filepath parameter is undefined', () => {
|
||||
expect(() => injectScript(undefined)).toThrow();
|
||||
});
|
||||
|
||||
it('should inject the code from the provided filepath into document.body as a script tag', () => {
|
||||
document.body.innerHTML = '';
|
||||
|
||||
const filepath = 'some/file/path';
|
||||
const expected = document.createElement('script');
|
||||
expected.src = filepath;
|
||||
expected.setAttribute('type', 'text/javascript');
|
||||
expected.setAttribute('src', filepath);
|
||||
|
||||
injectScript('some/file/path');
|
||||
|
||||
expect(document.body.childNodes[0]).toEqual(expected);
|
||||
});
|
||||
});
|
|
@ -5,6 +5,18 @@
|
|||
* @listens CustomEvent
|
||||
*/
|
||||
function forwardTimingEvent (timingEvent) {
|
||||
if (timingEvent == null) {
|
||||
throw Error('timingEvent must not be null or undefined');
|
||||
}
|
||||
|
||||
if (!(timingEvent instanceof CustomEvent)) {
|
||||
throw Error('timingEvent must be an instance of CustomEvent');
|
||||
}
|
||||
|
||||
if (timingEvent.detail == null) {
|
||||
throw Error('timingEvent.detail must not be null or undefined');
|
||||
}
|
||||
|
||||
chrome.runtime.sendMessage({
|
||||
action: 'timing',
|
||||
payload: timingEvent.detail
|
||||
|
|
|
@ -0,0 +1,55 @@
|
|||
import forwardTimingEvent from './forwardTimingEvent';
|
||||
|
||||
describe('forwardTimingEvent.js', () => {
|
||||
beforeAll(() => {
|
||||
global.chrome = {
|
||||
runtime: {
|
||||
sendMessage: jest.fn()
|
||||
}
|
||||
};
|
||||
});
|
||||
|
||||
it('should throw an Error when the timingEvent parameter is null', () => {
|
||||
expect(() => forwardTimingEvent(null)).toThrow();
|
||||
});
|
||||
|
||||
it('should throw an Error when the timingEvent parameter is undefined', () => {
|
||||
expect(() => forwardTimingEvent(undefined)).toThrow();
|
||||
});
|
||||
|
||||
it('should throw an Error when the timingEvent parameter is not an instance of CustomEvent', () => {
|
||||
const input = { name: 'not a CustomEvent' };
|
||||
expect(() => forwardTimingEvent(input)).toThrow();
|
||||
});
|
||||
|
||||
it('should throw an Error when the timingEvent parameter\'s detail property is null', () => {
|
||||
const input = new CustomEvent('timing', { detail: null });
|
||||
expect(() => forwardTimingEvent(input)).toThrow();
|
||||
});
|
||||
|
||||
it('should throw an Error when the timingEvent parameter\'s detail property is undefined', () => {
|
||||
const input = new CustomEvent('timing');
|
||||
expect(() => forwardTimingEvent(input)).toThrow();
|
||||
});
|
||||
|
||||
it('should send the requested message via chrome.runtime', () => {
|
||||
const expectedTimingEvent = new CustomEvent('timing', {
|
||||
detail: { a: 1, b: 2, c: 3 }
|
||||
});
|
||||
const expectedMessage = {
|
||||
action: 'timing',
|
||||
payload: expectedTimingEvent.detail
|
||||
};
|
||||
|
||||
// Has side-effects
|
||||
forwardTimingEvent(expectedTimingEvent);
|
||||
|
||||
// Verify that chrome.runtime.sendMessage was only called once
|
||||
// with a single argument: the expectedMessage object
|
||||
expect(global.chrome.runtime.sendMessage.mock.calls).toEqual([[expectedMessage]]);
|
||||
});
|
||||
|
||||
afterAll(() => {
|
||||
delete global.chrome;
|
||||
});
|
||||
});
|
|
@ -3,6 +3,10 @@
|
|||
* @param {string} action - The value indicating the meaning of the message.
|
||||
*/
|
||||
function sendSimpleMessage (action) {
|
||||
if (action == null) {
|
||||
throw Error('action must not be null or undefined');
|
||||
}
|
||||
|
||||
chrome.runtime.sendMessage({
|
||||
action: action
|
||||
});
|
||||
|
|
|
@ -0,0 +1,37 @@
|
|||
import sendSimpleMessage from './sendSimpleMessage';
|
||||
|
||||
describe('sendSimpleMessage.js', () => {
|
||||
beforeAll(() => {
|
||||
global.chrome = {
|
||||
runtime: {
|
||||
sendMessage: jest.fn()
|
||||
}
|
||||
};
|
||||
});
|
||||
|
||||
it('should throw an Error when the action parameter is null', () => {
|
||||
expect(() => sendSimpleMessage(null)).toThrow();
|
||||
});
|
||||
|
||||
it('should throw an Error when the action parameter is undefined', () => {
|
||||
expect(() => sendSimpleMessage(null)).toThrow();
|
||||
});
|
||||
|
||||
it('should send the requested message via chrome.runtime', () => {
|
||||
const expectedAction = 'abc';
|
||||
const expectedMessage = {
|
||||
action: expectedAction
|
||||
};
|
||||
|
||||
// Has side-effects
|
||||
sendSimpleMessage(expectedAction);
|
||||
|
||||
// Verify that chrome.runtime.sendMessage was only called once
|
||||
// with a single argument: the expectedMessage object
|
||||
expect(global.chrome.runtime.sendMessage.mock.calls).toEqual([[expectedMessage]]);
|
||||
});
|
||||
|
||||
afterAll(() => {
|
||||
delete global.chrome;
|
||||
});
|
||||
});
|
|
@ -3,6 +3,14 @@
|
|||
* @param {CustomEvent} event - The event to dispatch via the document.
|
||||
*/
|
||||
function sendEventViaDocument (event) {
|
||||
if (event == null) {
|
||||
throw Error('event must not be null or undefined');
|
||||
}
|
||||
|
||||
if (!(event instanceof CustomEvent)) {
|
||||
throw Error('event must be an instance of CustomEvent');
|
||||
}
|
||||
|
||||
// This call to setTimeOut with 0 delay schedules this call to occur after
|
||||
// already existing events in the browser's queue, which includes rendering events.
|
||||
// This is to minimize the performance impact on the page due to the extension.
|
||||
|
|
|
@ -0,0 +1,23 @@
|
|||
import sendEventViaDocument from './sendEventViaDocument';
|
||||
|
||||
describe('sendEventViaDocument.js', () => {
|
||||
beforeEach(() => {
|
||||
jest.useFakeTimers();
|
||||
document.dispatchEvent = jest.fn();
|
||||
});
|
||||
|
||||
it('should throw an error when the event parameter is null', () => {
|
||||
expect(() => sendEventViaDocument(null)).toThrow();
|
||||
});
|
||||
|
||||
it('should throw an error when the event parameter is undefined', () => {
|
||||
expect(() => sendEventViaDocument(undefined)).toThrow();
|
||||
});
|
||||
|
||||
it('should throw an Error when the event parameter is not an instance of CustomEvent', () => {
|
||||
const input = { name: 'not a CustomEvent' };
|
||||
expect(() => sendEventViaDocument(input)).toThrow();
|
||||
});
|
||||
|
||||
// TODO: need to figure out how to properly mock and spy on setTimeOut and its callback
|
||||
});
|
Загрузка…
Ссылка в новой задаче