make sure plugins can be loaded into Flipper
Summary: Make sure Sandy plugins are loaded properly from disk Reviewed By: jknoxville Differential Revision: D22186275 fbshipit-source-id: fd2f560a7bed959b18e05db2a087909ad876ab9d
This commit is contained in:
committed by
Facebook GitHub Bot
parent
1029a6c97c
commit
12ac29685d
24
desktop/app/src/dispatcher/__tests__/SandyTestPlugin.tsx
Normal file
24
desktop/app/src/dispatcher/__tests__/SandyTestPlugin.tsx
Normal file
@@ -0,0 +1,24 @@
|
||||
/**
|
||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*
|
||||
* @format
|
||||
*/
|
||||
|
||||
import * as React from 'react';
|
||||
|
||||
import {FlipperClient} from 'flipper-plugin';
|
||||
|
||||
type Events = {
|
||||
inc: {delta: number};
|
||||
};
|
||||
|
||||
export function plugin(_client: FlipperClient<Events, {}>) {
|
||||
return {};
|
||||
}
|
||||
|
||||
export function Component() {
|
||||
return <h1>Sandy high fives Flipper</h1>;
|
||||
}
|
||||
@@ -29,6 +29,7 @@ import configureStore from 'redux-mock-store';
|
||||
import {TEST_PASSING_GK, TEST_FAILING_GK} from '../../fb-stubs/GK';
|
||||
import TestPlugin from './TestPlugin';
|
||||
import {resetConfigForTesting} from '../../utils/processConfig';
|
||||
import {SandyPluginDefinition} from 'flipper-plugin';
|
||||
|
||||
const mockStore = configureStore<State, {}>([])(
|
||||
reducers(undefined, {type: 'INIT'}),
|
||||
@@ -239,3 +240,50 @@ test('bundled versions are used when env var FLIPPER_DISABLE_PLUGIN_AUTO_UPDATE
|
||||
delete process.env.FLIPPER_DISABLE_PLUGIN_AUTO_UPDATE;
|
||||
}
|
||||
});
|
||||
|
||||
test('requirePlugin loads valid Sandy plugin', () => {
|
||||
const name = 'pluginID';
|
||||
const requireFn = requirePlugin([], {}, require);
|
||||
const plugin = requireFn({
|
||||
...samplePluginDetails,
|
||||
name,
|
||||
entry: path.join(__dirname, 'SandyTestPlugin'),
|
||||
version: '1.0.0',
|
||||
flipperSDKVersion: '0.0.0',
|
||||
}) as SandyPluginDefinition;
|
||||
expect(plugin).not.toBeNull();
|
||||
// @ts-ignore
|
||||
expect(plugin).toBeInstanceOf(SandyPluginDefinition);
|
||||
expect(plugin.id).toBe('Sample');
|
||||
expect(plugin.details).toMatchObject({
|
||||
flipperSDKVersion: '0.0.0',
|
||||
id: 'Sample',
|
||||
isDefault: false,
|
||||
main: 'dist/bundle.js',
|
||||
name: 'pluginID',
|
||||
source: 'src/index.js',
|
||||
specVersion: 2,
|
||||
title: 'Sample',
|
||||
version: '1.0.0',
|
||||
});
|
||||
expect(typeof plugin.module.Component).toBe('function');
|
||||
expect(plugin.module.Component.displayName).toBe('FlipperPlugin(Sample)');
|
||||
expect(typeof plugin.module.plugin).toBe('function');
|
||||
});
|
||||
|
||||
test('requirePlugin errors on invalid Sandy plugin', () => {
|
||||
const name = 'pluginID';
|
||||
const failedPlugins: any[] = [];
|
||||
const requireFn = requirePlugin(failedPlugins, {}, require);
|
||||
requireFn({
|
||||
...samplePluginDetails,
|
||||
name,
|
||||
// Intentionally the wrong file:
|
||||
entry: path.join(__dirname, 'TestPlugin'),
|
||||
version: '1.0.0',
|
||||
flipperSDKVersion: '0.0.0',
|
||||
});
|
||||
expect(failedPlugins[0][1]).toMatchInlineSnapshot(
|
||||
`"Flipper plugin 'Sample' should export named function called 'plugin'"`,
|
||||
);
|
||||
});
|
||||
|
||||
@@ -38,6 +38,7 @@ import * as FlipperPluginSDK from 'flipper-plugin';
|
||||
|
||||
// eslint-disable-next-line import/no-unresolved
|
||||
import getPluginIndex from '../utils/getDefaultPluginsIndex';
|
||||
import {SandyPluginDefinition} from 'flipper-plugin';
|
||||
|
||||
const Paragraph = styled.p({
|
||||
marginBottom: '0.1em',
|
||||
@@ -271,6 +272,13 @@ const requirePluginInternal = (
|
||||
let plugin = pluginDetails.isDefault
|
||||
? defaultPluginsIndex[pluginDetails.name]
|
||||
: reqFn(pluginDetails.entry);
|
||||
|
||||
if (pluginDetails.flipperSDKVersion) {
|
||||
// Sandy plugin
|
||||
// TODO: suppor device Plugins T68738317
|
||||
return new SandyPluginDefinition(pluginDetails, plugin);
|
||||
} else {
|
||||
// classic plugin
|
||||
if (plugin.default) {
|
||||
plugin = plugin.default;
|
||||
}
|
||||
@@ -280,7 +288,6 @@ const requirePluginInternal = (
|
||||
|
||||
plugin.id = plugin.id || pluginDetails.id;
|
||||
plugin.packageName = pluginDetails.name;
|
||||
plugin.flipperSDKVersion = pluginDetails.flipperSDKVersion;
|
||||
plugin.details = pluginDetails;
|
||||
|
||||
// set values from package.json as static variables on class
|
||||
@@ -289,5 +296,6 @@ const requirePluginInternal = (
|
||||
plugin[key] = plugin[key] || pluginDetails[key as keyof PluginDetails];
|
||||
}
|
||||
});
|
||||
}
|
||||
return plugin;
|
||||
};
|
||||
|
||||
@@ -113,7 +113,6 @@ export abstract class FlipperBasePlugin<
|
||||
static category: string | null = null;
|
||||
static id: string = '';
|
||||
static packageName: string = '';
|
||||
static flipperSDKVersion: string | undefined = undefined;
|
||||
static version: string = '';
|
||||
static icon: string | null = null;
|
||||
static gatekeeper: string | null = null;
|
||||
|
||||
@@ -64,6 +64,12 @@ export class FlipperPluginInstance {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A sandy plugin definitions represents a loaded plugin definition, storing two things:
|
||||
* the loaded JS module, and the meta data (typically coming from package.json).
|
||||
*
|
||||
* Also delegates some of the standard plugin functionality to have a similar public static api as FlipperPlugin
|
||||
*/
|
||||
export class SandyPluginDefinition {
|
||||
id: string;
|
||||
module: FlipperPluginModule;
|
||||
@@ -86,12 +92,12 @@ export class SandyPluginDefinition {
|
||||
this.details = details;
|
||||
if (!module.plugin || typeof module.plugin !== 'function') {
|
||||
throw new Error(
|
||||
`Sandy plugin ${this.id} doesn't export a named function called 'plugin'`,
|
||||
`Flipper plugin '${this.id}' should export named function called 'plugin'`,
|
||||
);
|
||||
}
|
||||
if (!module.Component || typeof module.Component !== 'function') {
|
||||
throw new Error(
|
||||
`Sandy plugin ${this.id} doesn't export a named function called 'Component'`,
|
||||
`Flipper plugin '${this.id}' should export named function called 'Component'`,
|
||||
);
|
||||
}
|
||||
this.module = module;
|
||||
|
||||
Reference in New Issue
Block a user