Adding test converage for plugin loading
Summary: Adds test for the plugin reducer and dispatcher Reviewed By: jknoxville, passy Differential Revision: D13082652 fbshipit-source-id: 4af2c7721c4d88abbd332d610ff71d5db78e721c
This commit is contained in:
committed by
Facebook Github Bot
parent
1edc91512d
commit
0b43d219c3
10
src/dispatcher/__tests__/TestPlugin.js
Normal file
10
src/dispatcher/__tests__/TestPlugin.js
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
/**
|
||||||
|
* Copyright 2018-present Facebook.
|
||||||
|
* This source code is licensed under the MIT license found in the
|
||||||
|
* LICENSE file in the root directory of this source tree.
|
||||||
|
* @format
|
||||||
|
*/
|
||||||
|
|
||||||
|
import {FlipperPlugin} from '../../plugin.js';
|
||||||
|
|
||||||
|
export default class extends FlipperPlugin {}
|
||||||
121
src/dispatcher/__tests__/plugins.electron.js
Normal file
121
src/dispatcher/__tests__/plugins.electron.js
Normal file
@@ -0,0 +1,121 @@
|
|||||||
|
/**
|
||||||
|
* Copyright 2018-present Facebook.
|
||||||
|
* This source code is licensed under the MIT license found in the
|
||||||
|
* LICENSE file in the root directory of this source tree.
|
||||||
|
* @format
|
||||||
|
*/
|
||||||
|
|
||||||
|
import dispatcher, {
|
||||||
|
getDynamicPlugins,
|
||||||
|
checkDisabled,
|
||||||
|
checkGK,
|
||||||
|
requirePlugin,
|
||||||
|
} from '../plugins';
|
||||||
|
import path from 'path';
|
||||||
|
import {remote} from 'electron';
|
||||||
|
import {FlipperPlugin} from '../../plugin';
|
||||||
|
import reducers from '../../reducers/index.js';
|
||||||
|
import Logger from '../../fb-stubs/Logger.js';
|
||||||
|
import configureStore from 'redux-mock-store';
|
||||||
|
import {TEST_PASSING_GK, TEST_FAILING_GK} from '../../fb-stubs/GK';
|
||||||
|
|
||||||
|
const mockStore = configureStore([])(reducers(undefined, {type: 'INIT'}));
|
||||||
|
const logger = new Logger();
|
||||||
|
|
||||||
|
test('dispatcher dispatches REGISTER_PLUGINS', () => {
|
||||||
|
dispatcher(mockStore, logger);
|
||||||
|
const actions = mockStore.getActions();
|
||||||
|
expect(actions[0].type).toBe('REGISTER_PLUGINS');
|
||||||
|
});
|
||||||
|
|
||||||
|
test('getDynamicPlugins returns empty array', () => {
|
||||||
|
// $FlowFixMe process.env not defined in electron API spec
|
||||||
|
remote.process.env.PLUGINS = null;
|
||||||
|
const res = getDynamicPlugins();
|
||||||
|
expect(res).toEqual([]);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('getDynamicPlugins returns empty array for invalid JSON', () => {
|
||||||
|
// $FlowFixMe process.env not defined in electron API spec
|
||||||
|
remote.process.env.PLUGINS = 'invalid JOSN }}[]';
|
||||||
|
const res = getDynamicPlugins();
|
||||||
|
expect(res).toEqual([]);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('getDynamicPlugins from env', () => {
|
||||||
|
const plugins = [{name: 'test'}];
|
||||||
|
// $FlowFixMe process.env not defined in electron API spec
|
||||||
|
remote.process.env.PLUGINS = JSON.stringify(plugins);
|
||||||
|
const res = getDynamicPlugins();
|
||||||
|
expect(res).toEqual(plugins);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('checkDisabled', () => {
|
||||||
|
const disabledPlugin = 'pluginName';
|
||||||
|
const config = {disabledPlugins: [disabledPlugin]};
|
||||||
|
// $FlowFixMe process.env not defined in electron API spec
|
||||||
|
remote.process.env.CONFIG = JSON.stringify(config);
|
||||||
|
const disabled = checkDisabled();
|
||||||
|
|
||||||
|
expect(
|
||||||
|
disabled({
|
||||||
|
name: 'other Name',
|
||||||
|
out: './test/index.js',
|
||||||
|
}),
|
||||||
|
).toBeTruthy();
|
||||||
|
|
||||||
|
expect(
|
||||||
|
disabled({
|
||||||
|
name: disabledPlugin,
|
||||||
|
out: './test/index.js',
|
||||||
|
}),
|
||||||
|
).toBeFalsy();
|
||||||
|
});
|
||||||
|
|
||||||
|
test('checkGK for plugin without GK', () => {
|
||||||
|
expect(
|
||||||
|
checkGK({
|
||||||
|
name: 'pluginID',
|
||||||
|
out: './test/index.js',
|
||||||
|
}),
|
||||||
|
).toBeTruthy();
|
||||||
|
});
|
||||||
|
|
||||||
|
test('checkGK for passing plugin', () => {
|
||||||
|
expect(
|
||||||
|
checkGK({
|
||||||
|
name: 'pluginID',
|
||||||
|
gatekeeper: TEST_PASSING_GK,
|
||||||
|
out: './test/index.js',
|
||||||
|
}),
|
||||||
|
).toBeTruthy();
|
||||||
|
});
|
||||||
|
|
||||||
|
test('checkGK for failing plugin', () => {
|
||||||
|
expect(
|
||||||
|
checkGK({
|
||||||
|
name: 'pluginID',
|
||||||
|
gatekeeper: TEST_FAILING_GK,
|
||||||
|
out: './test/index.js',
|
||||||
|
}),
|
||||||
|
).toBeFalsy();
|
||||||
|
});
|
||||||
|
|
||||||
|
test('requirePlugin returns null for invalid requires', () => {
|
||||||
|
const plugin = requirePlugin(require)({
|
||||||
|
name: 'pluginID',
|
||||||
|
out: 'this/path/does not/exist',
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(plugin).toBeNull();
|
||||||
|
});
|
||||||
|
|
||||||
|
test('requirePlugin loads plugin', () => {
|
||||||
|
const plugin = requirePlugin(require)({
|
||||||
|
name: 'pluginID',
|
||||||
|
out: path.join(__dirname, 'TestPlugin.js'),
|
||||||
|
// $FlowFixMe Electron require returns default exports wrapped in an object
|
||||||
|
}).default;
|
||||||
|
|
||||||
|
expect(plugin.prototype).toBeInstanceOf(FlipperPlugin);
|
||||||
|
});
|
||||||
@@ -37,7 +37,7 @@ export default (store: Store, logger: Logger) => {
|
|||||||
> = [...getBundledPlugins(), ...getDynamicPlugins()]
|
> = [...getBundledPlugins(), ...getDynamicPlugins()]
|
||||||
.filter(disabled)
|
.filter(disabled)
|
||||||
.filter(checkGK)
|
.filter(checkGK)
|
||||||
.map(requirePlugin)
|
.map(requirePlugin())
|
||||||
.filter(Boolean);
|
.filter(Boolean);
|
||||||
|
|
||||||
store.dispatch(registerPlugins(initialPlugins));
|
store.dispatch(registerPlugins(initialPlugins));
|
||||||
@@ -69,7 +69,7 @@ function getBundledPlugins(): Array<PluginDefinition> {
|
|||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
function getDynamicPlugins() {
|
export function getDynamicPlugins() {
|
||||||
let dynamicPlugins: Array<PluginDefinition> = [];
|
let dynamicPlugins: Array<PluginDefinition> = [];
|
||||||
try {
|
try {
|
||||||
// $FlowFixMe process.env not defined in electron API spec
|
// $FlowFixMe process.env not defined in electron API spec
|
||||||
@@ -80,7 +80,7 @@ function getDynamicPlugins() {
|
|||||||
return dynamicPlugins;
|
return dynamicPlugins;
|
||||||
}
|
}
|
||||||
|
|
||||||
function checkGK(plugin: PluginDefinition): boolean {
|
export function checkGK(plugin: PluginDefinition): boolean {
|
||||||
const result = plugin.gatekeeper && !GK.get(plugin.gatekeeper);
|
const result = plugin.gatekeeper && !GK.get(plugin.gatekeeper);
|
||||||
if (!result) {
|
if (!result) {
|
||||||
console.warn(
|
console.warn(
|
||||||
@@ -92,7 +92,7 @@ function checkGK(plugin: PluginDefinition): boolean {
|
|||||||
return !result;
|
return !result;
|
||||||
}
|
}
|
||||||
|
|
||||||
function checkDisabled(): (plugin: PluginDefinition) => boolean {
|
export function checkDisabled(): (plugin: PluginDefinition) => boolean {
|
||||||
let disabledPlugins: Set<string> = new Set();
|
let disabledPlugins: Set<string> = new Set();
|
||||||
try {
|
try {
|
||||||
disabledPlugins = new Set(
|
disabledPlugins = new Set(
|
||||||
@@ -106,11 +106,14 @@ function checkDisabled(): (plugin: PluginDefinition) => boolean {
|
|||||||
return (plugin: PluginDefinition) => !disabledPlugins.has(plugin.name);
|
return (plugin: PluginDefinition) => !disabledPlugins.has(plugin.name);
|
||||||
}
|
}
|
||||||
|
|
||||||
function requirePlugin(
|
export function requirePlugin(
|
||||||
|
requireFunction: Function = window.electronRequire,
|
||||||
|
) {
|
||||||
|
return (
|
||||||
pluginDefinition: PluginDefinition,
|
pluginDefinition: PluginDefinition,
|
||||||
): ?Class<FlipperPlugin<> | FlipperDevicePlugin<>> {
|
): ?Class<FlipperPlugin<> | FlipperDevicePlugin<>> => {
|
||||||
try {
|
try {
|
||||||
const plugin = window.electronRequire(pluginDefinition.out);
|
const plugin = requireFunction(pluginDefinition.out);
|
||||||
if (!plugin.prototype instanceof FlipperBasePlugin) {
|
if (!plugin.prototype instanceof FlipperBasePlugin) {
|
||||||
throw new Error(`Plugin ${plugin.name} is not a FlipperBasePlugin`);
|
throw new Error(`Plugin ${plugin.name} is not a FlipperBasePlugin`);
|
||||||
}
|
}
|
||||||
@@ -119,4 +122,5 @@ function requirePlugin(
|
|||||||
console.error(pluginDefinition, e);
|
console.error(pluginDefinition, e);
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
71
src/reducers/__tests__/plugins.node.js
Normal file
71
src/reducers/__tests__/plugins.node.js
Normal file
@@ -0,0 +1,71 @@
|
|||||||
|
/**
|
||||||
|
* Copyright 2018-present Facebook.
|
||||||
|
* This source code is licensed under the MIT license found in the
|
||||||
|
* LICENSE file in the root directory of this source tree.
|
||||||
|
* @format
|
||||||
|
*/
|
||||||
|
|
||||||
|
import {default as reducer, registerPlugins} from '../plugins';
|
||||||
|
import {
|
||||||
|
FlipperBasePlugin,
|
||||||
|
FlipperPlugin,
|
||||||
|
FlipperDevicePlugin,
|
||||||
|
} from '../../plugin.js';
|
||||||
|
|
||||||
|
const testBasePlugin = class extends FlipperBasePlugin {
|
||||||
|
static id = 'TestPlugin';
|
||||||
|
};
|
||||||
|
|
||||||
|
const testPlugin = class extends FlipperPlugin {
|
||||||
|
static id = 'TestPlugin';
|
||||||
|
};
|
||||||
|
|
||||||
|
const testDevicePlugin = class extends FlipperDevicePlugin {
|
||||||
|
static id = 'TestDevicePlugin';
|
||||||
|
};
|
||||||
|
|
||||||
|
test('add clientPlugin', () => {
|
||||||
|
const res = reducer(
|
||||||
|
{
|
||||||
|
devicePlugins: new Map(),
|
||||||
|
clientPlugins: new Map(),
|
||||||
|
},
|
||||||
|
registerPlugins([testPlugin]),
|
||||||
|
);
|
||||||
|
expect(res.clientPlugins.get(testPlugin.id)).toBe(testPlugin);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('add devicePlugin', () => {
|
||||||
|
const res = reducer(
|
||||||
|
{
|
||||||
|
devicePlugins: new Map(),
|
||||||
|
clientPlugins: new Map(),
|
||||||
|
},
|
||||||
|
registerPlugins([testDevicePlugin]),
|
||||||
|
);
|
||||||
|
expect(res.devicePlugins.get(testDevicePlugin.id)).toBe(testDevicePlugin);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('do not add plugin twice', () => {
|
||||||
|
const res = reducer(
|
||||||
|
{
|
||||||
|
devicePlugins: new Map(),
|
||||||
|
clientPlugins: new Map(),
|
||||||
|
},
|
||||||
|
registerPlugins([testPlugin, testPlugin]),
|
||||||
|
);
|
||||||
|
expect(res.clientPlugins.size).toEqual(1);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('do not add other classes', () => {
|
||||||
|
const res = reducer(
|
||||||
|
{
|
||||||
|
devicePlugins: new Map(),
|
||||||
|
clientPlugins: new Map(),
|
||||||
|
},
|
||||||
|
// $FlowFixMe testing wrong classes on purpose here
|
||||||
|
registerPlugins([testBasePlugin]),
|
||||||
|
);
|
||||||
|
expect(res.devicePlugins.size).toEqual(0);
|
||||||
|
expect(res.devicePlugins.size).toEqual(0);
|
||||||
|
});
|
||||||
Reference in New Issue
Block a user