Make sure that test stuff doesn't end up in bundles

Summary: When bundling a production bundle of flipper-ui / flipper-server, noticed that a lot of irrelevant stuff ends up. Like: `jest`, `metro`, `testing-library`. The whole jungle basically. Will add safety checks in the next diffs that this no longer happens

Reviewed By: passy

Differential Revision: D33186531

fbshipit-source-id: 1e2034153c8c4a3fac02cd9ce27d99224223df7a
This commit is contained in:
Michel Weststrate
2021-12-17 14:11:20 -08:00
committed by Facebook GitHub Bot
parent e0afebeb32
commit e46fcba0b2
29 changed files with 167 additions and 137 deletions

View File

@@ -110,7 +110,6 @@ test('Correct top level API exposed', () => {
"InteractionReporter",
"Logger",
"MenuEntry",
"MockedConsole",
"NormalizedMenuEntry",
"Notification",
"PluginClient",

View File

@@ -13,7 +13,6 @@ export const styled = styledImport;
import './plugin/PluginBase';
import * as TestUtilites from './test-utils/test-utils';
export {MockedConsole} from './test-utils/test-utils';
export {
SandyPluginInstance as _SandyPluginInstance,

View File

@@ -8,11 +8,7 @@
*/
import * as React from 'react';
import {
render,
RenderResult,
act as testingLibAct,
} from '@testing-library/react';
import type {RenderResult} from '@testing-library/react';
import {queries} from '@testing-library/dom';
import {
BundledPluginDetails,
@@ -32,7 +28,6 @@ import {
FlipperDevicePluginModule,
} from '../plugin/SandyPluginDefinition';
import {SandyPluginRenderer} from '../plugin/PluginRenderer';
import {act} from '@testing-library/react';
import {
SandyDevicePluginInstance,
Device,
@@ -43,13 +38,15 @@ import {FlipperLib} from '../plugin/FlipperLib';
import {stubLogger} from '../utils/Logger';
import {Idler} from '../utils/Idler';
import {createState} from '../state/atom';
import baseMockConsole from 'jest-mock-console';
import {
DeviceLogEntry,
FlipperServer,
FlipperServerCommands,
} from 'flipper-common';
declare const process: any;
declare const electronRequire: any;
type Renderer = RenderResult<typeof queries>;
interface StartPluginOptions {
@@ -184,10 +181,22 @@ interface StartDevicePluginResult<Module extends FlipperDevicePluginModule>
sendLogEntry(logEntry: DeviceLogEntry): void;
}
export function createStubFunction(): jest.Mock<any, any> {
// we shouldn't be usign jest.fn() outside a unit test, as it would not resolve / cause jest to be bundled up!
if (typeof jest !== 'undefined') {
return jest.fn();
}
return (() => {
console.warn('Using a stub function outside a test environment!');
}) as any;
}
export function startPlugin<Module extends FlipperPluginModule<any>>(
module: Module,
options?: StartPluginOptions,
): StartPluginResult<Module> {
const {act} = electronRequire('@testing-library/react');
const definition = new SandyPluginDefinition(
createMockPluginDetails(),
module,
@@ -198,7 +207,7 @@ export function startPlugin<Module extends FlipperPluginModule<any>>(
);
}
const sendStub = jest.fn();
const sendStub = createStubFunction();
const flipperUtils = createMockFlipperLib(options);
const testDevice = createMockDevice(options);
const appName = 'TestApplication';
@@ -291,6 +300,8 @@ export function renderPlugin<Module extends FlipperPluginModule<any>>(
renderer: Renderer;
act: (cb: () => void) => void;
} {
// prevent bundling in UI bundle
const {render, act} = electronRequire('@testing-library/react');
const res = startPlugin(module, options);
const pluginInstance: SandyPluginInstance = (res as any)._backingInstance;
@@ -299,7 +310,7 @@ export function renderPlugin<Module extends FlipperPluginModule<any>>(
return {
...res,
renderer,
act: testingLibAct,
act,
destroy: () => {
renderer.unmount();
pluginInstance.destroy();
@@ -311,6 +322,8 @@ export function startDevicePlugin<Module extends FlipperDevicePluginModule>(
module: Module,
options?: StartPluginOptions,
): StartDevicePluginResult<Module> {
const {act} = electronRequire('@testing-library/react');
const definition = new SandyPluginDefinition(
createMockPluginDetails({pluginType: 'device'}),
module,
@@ -356,6 +369,8 @@ export function renderDevicePlugin<Module extends FlipperDevicePluginModule>(
renderer: Renderer;
act: (cb: () => void) => void;
} {
const {render, act} = electronRequire('@testing-library/react');
const res = startDevicePlugin(module, options);
// @ts-ignore hidden api
const pluginInstance: SandyDevicePluginInstance = (res as any)
@@ -366,7 +381,7 @@ export function renderDevicePlugin<Module extends FlipperDevicePluginModule>(
return {
...res,
renderer,
act: testingLibAct,
act,
destroy: () => {
renderer.unmount();
pluginInstance.destroy();
@@ -378,20 +393,18 @@ export function createMockFlipperLib(options?: StartPluginOptions): FlipperLib {
return {
isFB: false,
logger: stubLogger,
enableMenuEntries: jest.fn(),
createPaste: jest.fn(),
enableMenuEntries: createStubFunction(),
createPaste: createStubFunction(),
GK(gk: string) {
return options?.GKs?.includes(gk) || false;
},
selectPlugin: jest.fn(),
writeTextToClipboard: jest.fn(),
openLink: jest.fn(),
showNotification: jest.fn(),
exportFile: jest.fn(),
importFile: jest.fn(),
selectPlugin: createStubFunction(),
writeTextToClipboard: createStubFunction(),
openLink: createStubFunction(),
showNotification: createStubFunction(),
exportFile: createStubFunction(),
importFile: createStubFunction(),
paths: {
// @ts-ignore process not known outside unit tests / Node, but this function should not be used
// outside a node context, so that is ok
appPath: process.cwd(),
homePath: `/dev/null`,
tempPath: `/dev/null`,
@@ -405,24 +418,24 @@ export function createMockFlipperLib(options?: StartPluginOptions): FlipperLib {
},
remoteServerContext: {
childProcess: {
exec: jest.fn(),
exec: createStubFunction(),
},
fs: {
access: jest.fn(),
pathExists: jest.fn(),
unlink: jest.fn(),
mkdir: jest.fn(),
rm: jest.fn(),
copyFile: jest.fn(),
access: createStubFunction(),
pathExists: createStubFunction(),
unlink: createStubFunction(),
mkdir: createStubFunction(),
rm: createStubFunction(),
copyFile: createStubFunction(),
constants: fsConstants,
stat: jest.fn(),
readlink: jest.fn(),
readFile: jest.fn(),
readFileBinary: jest.fn(),
writeFile: jest.fn(),
writeFileBinary: jest.fn(),
stat: createStubFunction(),
readlink: createStubFunction(),
readFile: createStubFunction(),
readFileBinary: createStubFunction(),
writeFile: createStubFunction(),
writeFileBinary: createStubFunction(),
},
downloadFile: jest.fn(),
downloadFile: createStubFunction(),
},
};
}
@@ -555,15 +568,15 @@ function createMockDevice(options?: StartPluginOptions): Device & {
addLogEntry(entry: DeviceLogEntry) {
logListeners.forEach((f) => f?.(entry));
},
executeShell: jest.fn(),
clearLogs: jest.fn(),
forwardPort: jest.fn(),
executeShell: createStubFunction(),
clearLogs: createStubFunction(),
forwardPort: createStubFunction(),
get isConnected() {
return this.connected.get();
},
navigateToLocation: jest.fn(),
screenshot: jest.fn(),
sendMetroCommand: jest.fn(),
navigateToLocation: createStubFunction(),
screenshot: createStubFunction(),
sendMetroCommand: createStubFunction(),
};
}
@@ -582,52 +595,13 @@ function createStubIdler(): Idler {
};
}
/**
* Mockes the current console. Inspect results through e.g.
* console.errorCalls etc.
*
* Or, alternatively, expect(mockedConsole.error).toBeCalledWith...
*
* Don't forgot to call .unmock when done!
*/
export function mockConsole() {
const restoreConsole = baseMockConsole();
// The mocked console methods, make sure they remain available after unmocking
const {log, error, warn} = console as any;
return {
get logCalls(): any[][] {
return log.mock.calls;
},
get errorCalls(): any[][] {
return error.mock.calls;
},
get warnCalls(): any[][] {
return warn.mock.calls;
},
get log(): jest.Mock<any, any> {
return log as any;
},
get warn(): jest.Mock<any, any> {
return warn as any;
},
get error(): jest.Mock<any, any> {
return error as any;
},
unmock() {
restoreConsole();
},
};
}
export type MockedConsole = ReturnType<typeof mockConsole>;
export function createFlipperServerMock(
overrides?: Partial<FlipperServerCommands>,
): FlipperServer {
return {
async connect() {},
on: jest.fn(),
off: jest.fn(),
on: createStubFunction(),
off: createStubFunction(),
exec: jest
.fn()
.mockImplementation(
@@ -641,6 +615,6 @@ export function createFlipperServerMock(
return undefined;
},
),
close: jest.fn(),
close: createStubFunction(),
};
}

View File

@@ -58,6 +58,7 @@
"@types/redux-mock-store": "^1.0.3",
"@types/uuid": "^8.3.1",
"flipper-test-utils": "0.0.0",
"jest-mock-console": "^1.2.3",
"redux-mock-store": "^1.0.1"
},
"scripts": {

View File

@@ -12,7 +12,7 @@
import React from 'react';
import produce from 'immer';
import {FlipperPlugin} from '../plugin';
import {renderMockFlipperWithPlugin} from '../test-utils/createMockFlipperWithPlugin';
import {renderMockFlipperWithPlugin} from './test-utils/createMockFlipperWithPlugin';
import {
_SandyPluginDefinition,
PluginClient,

View File

@@ -7,7 +7,7 @@
* @format
*/
import {createMockFlipperWithPlugin} from '../test-utils/createMockFlipperWithPlugin';
import {createMockFlipperWithPlugin} from './test-utils/createMockFlipperWithPlugin';
import {FlipperPlugin} from '../plugin';
import {TestIdler} from '../utils/Idler';
import {getAllClients} from '../reducers/connections';

View File

@@ -10,7 +10,7 @@
jest.useFakeTimers();
import React from 'react';
import {renderMockFlipperWithPlugin} from '../test-utils/createMockFlipperWithPlugin';
import {renderMockFlipperWithPlugin} from './test-utils/createMockFlipperWithPlugin';
import {
_SandyPluginDefinition,
PluginClient,

View File

@@ -7,7 +7,7 @@
* @format
*/
import {createMockFlipperWithPlugin} from '../test-utils/createMockFlipperWithPlugin';
import {createMockFlipperWithPlugin} from './test-utils/createMockFlipperWithPlugin';
import {
TestUtils,
_SandyPluginDefinition,
@@ -16,7 +16,7 @@ import {
PluginClient,
} from 'flipper-plugin';
import {handleClientConnected} from '../dispatcher/flipperServer';
import {TestDevice} from '../test-utils/TestDevice';
import {TestDevice} from '../devices/TestDevice';
test('Devices can disconnect', async () => {
const deviceplugin = new _SandyPluginDefinition(

View File

@@ -8,27 +8,26 @@
*/
import {createStore} from 'redux';
import BaseDevice from '../devices/BaseDevice';
import {createRootReducer} from '../reducers';
import {Store} from '../reducers/index';
import Client, {ClientConnection} from '../Client';
import BaseDevice from '../../devices/BaseDevice';
import {createRootReducer} from '../../reducers';
import {Store} from '../../reducers/index';
import Client, {ClientConnection} from '../../Client';
import {
Logger,
buildClientId,
FlipperServer,
ClientResponseType,
} from 'flipper-common';
import {PluginDefinition} from '../plugin';
import {pluginsInitialized, registerPlugins} from '../reducers/plugins';
import {PluginDefinition} from '../../plugin';
import {pluginsInitialized, registerPlugins} from '../../reducers/plugins';
import {getLogger} from 'flipper-common';
import {initializeFlipperLibImplementation} from '../utils/flipperLibImplementation';
import pluginManager from '../dispatcher/pluginManager';
import {initializeFlipperLibImplementation} from '../../utils/flipperLibImplementation';
import pluginManager from '../../dispatcher/pluginManager';
import {PluginDetails} from 'flipper-common';
import ArchivedDevice from '../devices/ArchivedDevice';
import ArchivedDevice from '../../devices/ArchivedDevice';
import {ClientQuery, DeviceOS} from 'flipper-common';
import {TestDevice} from './TestDevice';
import {getRenderHostInstance} from '../RenderHost';
import {waitFor} from '../utils/waitFor';
import {TestDevice} from '../../devices/TestDevice';
import {getRenderHostInstance} from '../../RenderHost';
export interface AppOptions {
plugins?: PluginDefinition[];

View File

@@ -20,24 +20,28 @@ import {
selectPlugin,
selectDevice,
selectClient,
} from '../reducers/connections';
import BaseDevice from '../devices/BaseDevice';
} from '../../reducers/connections';
import BaseDevice from '../../devices/BaseDevice';
import {Store} from '../reducers/index';
import Client from '../Client';
import {Store} from '../../reducers/index';
import Client from '../../Client';
import {ClientQuery, FlipperServer, Logger} from 'flipper-common';
import {FlipperDevicePlugin, FlipperPlugin, PluginDefinition} from '../plugin';
import PluginContainer from '../PluginContainer';
import {isDevicePluginDefinition} from '../utils/pluginUtils';
import {getPluginKey} from '../utils/pluginKey';
import {
FlipperDevicePlugin,
FlipperPlugin,
PluginDefinition,
} from '../../plugin';
import PluginContainer from '../../PluginContainer';
import {isDevicePluginDefinition} from '../../utils/pluginUtils';
import {getPluginKey} from '../../utils/pluginKey';
import MockFlipper from './MockFlipper';
import {switchPlugin} from '../reducers/pluginManager';
import {createSandyPluginFromClassicPlugin} from '../dispatcher/plugins';
import {createMockActivatablePluginDetails} from '../utils/testUtils';
import {switchPlugin} from '../../reducers/pluginManager';
import {createSandyPluginFromClassicPlugin} from '../../dispatcher/plugins';
import {createMockActivatablePluginDetails} from '../../utils/testUtils';
import {_SandyPluginDefinition} from 'flipper-plugin';
import {awaitPluginCommandQueueEmpty} from '../dispatcher/pluginManager';
import {awaitPluginCommandQueueEmpty} from '../../dispatcher/pluginManager';
export type MockFlipperResult = {
client: Client;

View File

@@ -0,0 +1,49 @@
/**
* 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 baseMockConsole from 'jest-mock-console';
/**
* Mockes the current console. Inspect results through e.g.
* console.errorCalls etc.
*
* Or, alternatively, expect(mockedConsole.error).toBeCalledWith...
*
* Don't forgot to call .unmock when done!
*/
export function mockConsole() {
const restoreConsole = baseMockConsole();
// The mocked console methods, make sure they remain available after unmocking
const {log, error, warn} = console as any;
return {
get logCalls(): any[][] {
return log.mock.calls;
},
get errorCalls(): any[][] {
return error.mock.calls;
},
get warnCalls(): any[][] {
return warn.mock.calls;
},
get log(): jest.Mock<any, any> {
return log as any;
},
get warn(): jest.Mock<any, any> {
return warn as any;
},
get error(): jest.Mock<any, any> {
return error as any;
},
unmock() {
restoreConsole();
},
};
}
export type MockedConsole = ReturnType<typeof mockConsole>;

View File

@@ -119,8 +119,7 @@ export {Logger} from 'flipper-common';
export {getLogger} from 'flipper-common';
export {callVSCode} from './utils/vscodeUtils';
export {IDEFileResolver, IDEType} from './fb-stubs/IDEFileResolver';
export {renderMockFlipperWithPlugin} from './test-utils/createMockFlipperWithPlugin';
export {Tracked} from 'flipper-plugin'; // To be able to use it in legacy plugins
export {RequireLogin} from './ui/components/RequireLogin';
export {TestDevice} from './test-utils/TestDevice';
export {TestDevice} from './devices/TestDevice';
export {connect} from 'react-redux';

View File

@@ -9,7 +9,7 @@
import {DeviceOS, DeviceType} from 'flipper-plugin';
import {DeviceSpec} from 'flipper-common';
import BaseDevice from '../devices/BaseDevice';
import BaseDevice from './BaseDevice';
import {getRenderHostInstance} from '../RenderHost';
export class TestDevice extends BaseDevice {

View File

@@ -7,10 +7,10 @@
* @format
*/
import * as DeviceTestPluginModule from '../../test-utils/DeviceTestPlugin';
import * as DeviceTestPluginModule from '../../__tests__/test-utils/DeviceTestPlugin';
import {TestUtils, _SandyPluginDefinition} from 'flipper-plugin';
import {createMockFlipperWithPlugin} from '../../test-utils/createMockFlipperWithPlugin';
import {TestDevice} from '../../test-utils/TestDevice';
import {createMockFlipperWithPlugin} from '../../__tests__/test-utils/createMockFlipperWithPlugin';
import {TestDevice} from '../../devices/TestDevice';
import ArchivedDevice from '../../devices/ArchivedDevice';
const physicalDevicePluginDetails = TestUtils.createMockPluginDetails({

View File

@@ -10,7 +10,7 @@
jest.useFakeTimers();
import React from 'react';
import {renderMockFlipperWithPlugin} from '../../test-utils/createMockFlipperWithPlugin';
import {renderMockFlipperWithPlugin} from '../../__tests__/test-utils/createMockFlipperWithPlugin';
import {
_SandyPluginDefinition,
PluginClient,

View File

@@ -16,9 +16,9 @@ import {
import {requirePlugin} from '../plugins';
import {mocked} from 'ts-jest/utils';
import {TestUtils} from 'flipper-plugin';
import * as TestPlugin from '../../test-utils/TestPlugin';
import * as TestPlugin from '../../__tests__/test-utils/TestPlugin';
import {_SandyPluginDefinition as SandyPluginDefinition} from 'flipper-plugin';
import MockFlipper from '../../test-utils/MockFlipper';
import MockFlipper from '../../__tests__/test-utils/MockFlipper';
import Client from '../../Client';
import React from 'react';
import BaseDevice from '../../devices/BaseDevice';

View File

@@ -13,21 +13,24 @@ import {
_SandyPluginDefinition,
_setFlipperLibImplementation,
TestUtils,
MockedConsole,
} from 'flipper-plugin';
import {TestDevice} from '../../test-utils/TestDevice';
import {TestDevice} from '../../devices/TestDevice';
import {
createMockFlipperWithPlugin,
MockFlipperResult,
} from '../../test-utils/createMockFlipperWithPlugin';
} from '../../__tests__/test-utils/createMockFlipperWithPlugin';
import {Store} from '..';
import {getActiveClient, getActiveDevice} from '../../selectors/connections';
import BaseDevice from '../../devices/BaseDevice';
import Client from '../../Client';
import {
mockConsole,
MockedConsole,
} from '../../__tests__/test-utils/mockConsole';
let mockedConsole: MockedConsole;
beforeEach(() => {
mockedConsole = TestUtils.mockConsole();
mockedConsole = mockConsole();
_setFlipperLibImplementation(TestUtils.createMockFlipperLib());
});

View File

@@ -7,7 +7,7 @@
* @format
*/
import {createMockFlipperWithPlugin} from '../../test-utils/createMockFlipperWithPlugin';
import {createMockFlipperWithPlugin} from '../../__tests__/test-utils/createMockFlipperWithPlugin';
import {
_SandyPluginDefinition,
TestUtils,

View File

@@ -15,7 +15,7 @@ import {
} from '../plugins';
import {FlipperPlugin, FlipperDevicePlugin, BaseAction} from '../../plugin';
import {InstalledPluginDetails} from 'flipper-common';
import {wrapSandy} from '../../test-utils/createMockFlipperWithPlugin';
import {wrapSandy} from '../../__tests__/test-utils/createMockFlipperWithPlugin';
const testPluginOrig = class extends FlipperPlugin<any, BaseAction, any> {
static id = 'TestPlugin';

View File

@@ -7,7 +7,7 @@
* @format
*/
import {createMockFlipperWithPlugin} from '../../test-utils/createMockFlipperWithPlugin';
import {createMockFlipperWithPlugin} from '../../__tests__/test-utils/createMockFlipperWithPlugin';
import {Store} from '../../reducers/';
import {selectPlugin} from '../../reducers/connections';
import {

View File

@@ -7,7 +7,7 @@
* @format
*/
import {createMockFlipperWithPlugin} from '../../test-utils/createMockFlipperWithPlugin';
import {createMockFlipperWithPlugin} from '../../__tests__/test-utils/createMockFlipperWithPlugin';
import Client from '../../Client';
import {Store} from '../../reducers';
import {registerPlugins} from '../../reducers/plugins';

View File

@@ -10,7 +10,7 @@
import {
createMockFlipperWithPlugin,
MockFlipperResult,
} from '../../../test-utils/createMockFlipperWithPlugin';
} from '../../../__tests__/test-utils/createMockFlipperWithPlugin';
import {FlipperPlugin} from '../../../plugin';
import BaseDevice from '../../../devices/BaseDevice';
import {_SandyPluginDefinition} from 'flipper-plugin';
@@ -32,7 +32,7 @@ import {
getMetroDevice,
getPluginLists,
} from '../../../selectors/connections';
import {TestDevice} from '../../../test-utils/TestDevice';
import {TestDevice} from '../../../devices/TestDevice';
const createMockPluginDetails = TestUtils.createMockPluginDetails;

View File

@@ -24,7 +24,7 @@ import {selectedPlugins, State as PluginsState} from '../../reducers/plugins';
import {
createMockFlipperWithPlugin,
wrapSandy,
} from '../../test-utils/createMockFlipperWithPlugin';
} from '../../__tests__/test-utils/createMockFlipperWithPlugin';
import {
Notification,
TestUtils,
@@ -37,7 +37,7 @@ import {
} from 'flipper-plugin';
import {selectPlugin, getAllClients} from '../../reducers/connections';
import {TestIdler} from '../Idler';
import {TestDevice} from '../../test-utils/TestDevice';
import {TestDevice} from '../../devices/TestDevice';
const testIdler = new TestIdler();

View File

@@ -15,7 +15,7 @@ import {registerLoadedPlugins} from '../../reducers/plugins';
import {TestUtils} from 'flipper-plugin';
import {getLogger} from 'flipper-common';
import {selectPlugin} from '../../reducers/connections';
import {renderMockFlipperWithPlugin} from '../../test-utils/createMockFlipperWithPlugin';
import {renderMockFlipperWithPlugin} from '../../__tests__/test-utils/createMockFlipperWithPlugin';
const networkPluginDetails = TestUtils.createMockPluginDetails({
id: 'Network',

View File

@@ -11,7 +11,7 @@ import {FlipperPlugin} from '../../plugin';
import {
createMockFlipperWithPlugin,
wrapSandy,
} from '../../test-utils/createMockFlipperWithPlugin';
} from '../../__tests__/test-utils/createMockFlipperWithPlugin';
import {sleep} from 'flipper-common';
import {Store} from '../../reducers';
import Client from '../../Client';

View File

@@ -9,7 +9,7 @@
import {getPluginKey} from '../pluginKey';
import {FlipperPlugin, FlipperDevicePlugin} from '../../plugin';
import {createMockFlipperWithPlugin} from '../../test-utils/createMockFlipperWithPlugin';
import {createMockFlipperWithPlugin} from '../../__tests__/test-utils/createMockFlipperWithPlugin';
import {getExportablePlugins} from '../../selectors/connections';
function createMockFlipperPluginWithDefaultPersistedState(id: string) {

View File

@@ -11,6 +11,9 @@
// eslint-disable-next-line
global.fetch = require('jest-fetch-mock');
// @ts-ignore
global.electronRequire = require;
// make sure test run everywhere in the same timezone!
// +11, somewhere in the middle of nowhere, so this deviates for everyone and will fail early :)
const timezone = 'Pacific/Pohnpei';