Provide initial plugin test infra for plugin devs

Summary:
This sets up the initial infra that is to be used by plugin devs to test plugins.

There is not much yet to see, as there is no state or message sending yet. But at least the life cycle of plugins can be test, things are strongly typed and everything is in the place where it should be :)

N.b. the import difference with these utils and the createFlipperMock utilities in Flipper are

1. this testing infra is entirely inside flipper-plugin package, so that plugin devs don't need flipper as a dependency
2. this testing infra doesn't provide abstractions for plugin / device / client switching; it tests plugins purely in isolation of the rest of the world (except for firing `onConnect` / `onDisconnect` which is normally the effect of switching plugins)

Reviewed By: nikoant

Differential Revision: D22255262

fbshipit-source-id: b94ccbab720d2b49428a646aed3c55af71a5bc80
This commit is contained in:
Michel Weststrate
2020-07-01 08:58:40 -07:00
committed by Facebook GitHub Bot
parent c902a27bce
commit df6a8cd031
14 changed files with 336 additions and 70 deletions

View File

@@ -45,7 +45,7 @@ export interface FlipperClient<
* Internal API exposed by Flipper, and wrapped by FlipperPluginInstance to be passed to the
* Plugin Factory. For internal purposes only
*/
interface RealFlipperClient {
export interface RealFlipperClient {
isBackgroundPlugin(pluginId: string): boolean;
initPlugin(pluginId: string): void;
deinitPlugin(pluginId: string): void;
@@ -69,6 +69,7 @@ export class SandyPluginInstance {
instanceApi: any;
connected = false;
destroyed = false;
events = new EventEmitter();
constructor(
@@ -93,6 +94,7 @@ export class SandyPluginInstance {
// the plugin is selected in the UI
activate() {
this.assertNotDestroyed();
const pluginId = this.definition.id;
if (!this.realClient.isBackgroundPlugin(pluginId)) {
this.realClient.initPlugin(pluginId); // will call connect() if needed
@@ -101,6 +103,7 @@ export class SandyPluginInstance {
// the plugin is deselected in the UI
deactivate() {
this.assertNotDestroyed();
const pluginId = this.definition.id;
if (!this.realClient.isBackgroundPlugin(pluginId)) {
this.realClient.deinitPlugin(pluginId);
@@ -108,6 +111,7 @@ export class SandyPluginInstance {
}
connect() {
this.assertNotDestroyed();
if (!this.connected) {
this.connected = true;
this.events.emit('connect');
@@ -115,6 +119,7 @@ export class SandyPluginInstance {
}
disconnect() {
this.assertNotDestroyed();
if (this.connected) {
this.connected = false;
this.events.emit('disconnect');
@@ -122,11 +127,20 @@ export class SandyPluginInstance {
}
destroy() {
this.assertNotDestroyed();
this.disconnect();
this.events.emit('destroy');
this.destroyed = true;
}
toJSON() {
this.assertNotDestroyed();
// TODO: T68683449
}
private assertNotDestroyed() {
if (this.destroyed) {
throw new Error('Plugin has been destroyed already');
}
}
}