Summary: Noticed in reviews during the convertathon there is still quite some boilerplate in things that happen on the boundary of UI and plugin state, such as setting up menu entries and providing common functionality like clear, master/detail layout, etc. This diff introduces the `MasterDetail` component, which takes a higher level approach by merely needing to provide the state atoms and desired features, and taking care of the wiring. Applied it to createTablePlugin, to prove that going from `createTablePlugin` to `MasterDetail` will be a much smaller step now. Verified on the funnel logger plugin Reviewed By: passy Differential Revision: D28090362 fbshipit-source-id: 146f8c315fea903901ad4e3e46711642f16cf0e6
123 lines
2.8 KiB
TypeScript
123 lines
2.8 KiB
TypeScript
/**
|
|
* 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 {readFile} from 'fs';
|
|
import {promisify} from 'util';
|
|
import * as FlipperPluginModule from '../index';
|
|
|
|
test('Correct top level API exposed', () => {
|
|
const exposedAPIs: string[] = [];
|
|
const exposedTypes: string[] = [];
|
|
Object.entries(FlipperPluginModule).forEach(([key, value]) => {
|
|
if (key[0] === '_') {
|
|
return;
|
|
}
|
|
if (value === undefined) {
|
|
exposedTypes.push(key);
|
|
} else {
|
|
exposedAPIs.push(key);
|
|
}
|
|
});
|
|
|
|
// Note, all `exposedAPIs` should be documented in `flipper-plugin.mdx`
|
|
expect(exposedAPIs.sort()).toMatchInlineSnapshot(`
|
|
Array [
|
|
"DataDescription",
|
|
"DataFormatter",
|
|
"DataInspector",
|
|
"DataList",
|
|
"DataSource",
|
|
"DataTable",
|
|
"DetailSidebar",
|
|
"ElementsInspector",
|
|
"Layout",
|
|
"MarkerTimeline",
|
|
"MasterDetail",
|
|
"NUX",
|
|
"Panel",
|
|
"Tab",
|
|
"Tabs",
|
|
"TestUtils",
|
|
"Toolbar",
|
|
"Tracked",
|
|
"TrackingScope",
|
|
"batch",
|
|
"createDataSource",
|
|
"createState",
|
|
"createTablePlugin",
|
|
"produce",
|
|
"renderReactRoot",
|
|
"sleep",
|
|
"styled",
|
|
"theme",
|
|
"useLocalStorageState",
|
|
"useLogger",
|
|
"useMemoize",
|
|
"usePlugin",
|
|
"useTrackedCallback",
|
|
"useValue",
|
|
"withTrackingScope",
|
|
]
|
|
`);
|
|
|
|
expect(exposedTypes.sort()).toMatchInlineSnapshot(`
|
|
Array [
|
|
"Atom",
|
|
"DataDescriptionType",
|
|
"DataInspectorExpanded",
|
|
"DataTableColumn",
|
|
"DataTableManager",
|
|
"DataValueExtractor",
|
|
"DefaultKeyboardAction",
|
|
"Device",
|
|
"DeviceLogEntry",
|
|
"DeviceLogListener",
|
|
"DevicePluginClient",
|
|
"DeviceType",
|
|
"Draft",
|
|
"ElementAttribute",
|
|
"ElementData",
|
|
"ElementExtraInfo",
|
|
"ElementID",
|
|
"ElementSearchResultSet",
|
|
"ElementsInspectorElement",
|
|
"ElementsInspectorProps",
|
|
"FlipperLib",
|
|
"HighlightManager",
|
|
"Idler",
|
|
"LogLevel",
|
|
"LogTypes",
|
|
"Logger",
|
|
"MenuEntry",
|
|
"NormalizedMenuEntry",
|
|
"Notification",
|
|
"PluginClient",
|
|
"TrackType",
|
|
]
|
|
`);
|
|
});
|
|
|
|
test('All APIs documented', async () => {
|
|
const docs = await promisify(readFile)(
|
|
__dirname + '/../../../../docs/extending/flipper-plugin.mdx',
|
|
'utf8',
|
|
);
|
|
Object.keys(FlipperPluginModule)
|
|
.filter(
|
|
(key) =>
|
|
!key.startsWith('_') && (FlipperPluginModule as any)[key] !== undefined,
|
|
)
|
|
.forEach((key) => {
|
|
// There should be a header with this identifier
|
|
if (!new RegExp(`# ${key}\\b`).test(docs)) {
|
|
fail(`Not documented: '${key}'`);
|
|
}
|
|
});
|
|
});
|