Move RenderHost initialisation to Jest

Summary:
This diff moves RenderHost initialisation to jest, which is thereby treated as just another 'Host' like flipper-ui, the electron app etc. A benefit is that it provides a mocked flipperServer by default that can be used to mock or intercept requests. See LaunchEmulator.spec as example.

Also made the jest setup scripts strongly typed by converting them to TS.

This change allows the test stub configuration, which was OS dependent, out of flipper-ui-core.

Reviewed By: nikoant

Differential Revision: D32668632

fbshipit-source-id: fac0c09812b000fd7d1acb75010c35573087c99f
This commit is contained in:
Michel Weststrate
2021-12-08 04:25:28 -08:00
committed by Facebook GitHub Bot
parent e7f841b6d2
commit f9b72ac69e
14 changed files with 237 additions and 270 deletions

View File

@@ -1,72 +0,0 @@
/**
* 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
*/
// jest-setup-after will run after Jest has been initialized, so that it can be adapted.
import {cleanup} from '@testing-library/react';
const test = global.test;
if (!test) {
throw new Error('Failed jest test object');
}
/**
* This test will not be executed on Github / SandCastle,
* since, for example, it relies on precise timer reliability
*/
test.local = function local() {
const fn = process.env.SANDCASTLE || process.env.CI ? test.skip : test;
// eslint-disable-next-line
return fn.apply(null, arguments);
};
/**
* This test will only run on non-windows machines
*/
test.unix = function local() {
const fn = process.platform === 'win32' ? test.skip : test;
// eslint-disable-next-line
return fn.apply(null, arguments);
};
afterEach(cleanup);
console.debug = function () {
// Intentional noop, we don't want debug statements in Jest runs
};
// make perf tools available in Node (it is available in Browser / Electron just fine)
const {PerformanceObserver, performance} = require('perf_hooks');
Object.freeze(performance);
Object.freeze(Object.getPrototypeOf(performance));
// Something in our unit tests is messing with the performance global
// This fixes that.....
Object.defineProperty(global, 'performance', {
get() {
return performance;
},
set() {
throw new Error('Attempt to overwrite global.performance');
},
});
global.PerformanceObserver = PerformanceObserver;
// https://jestjs.io/docs/manual-mocks#mocking-methods-which-are-not-implemented-in-jsdom
Object.defineProperty(window, 'matchMedia', {
writable: true,
value: jest.fn().mockImplementation((query) => ({
matches: false,
media: query,
onchange: null,
addListener: jest.fn(), // deprecated
removeListener: jest.fn(), // deprecated
addEventListener: jest.fn(),
removeEventListener: jest.fn(),
dispatchEvent: jest.fn(),
})),
});

View File

@@ -0,0 +1,172 @@
/**
* 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
*/
// jest-setup-after will run after Jest has been initialized, so that it can be adapted.
import {cleanup} from '@testing-library/react';
import {resolve} from 'path';
import {tmpdir} from 'os';
window.FlipperRenderHostInstance = createStubRenderHost();
require('../flipper-ui-core/src/fb-stubs/Logger').init(undefined, {
isTest: true,
});
import {TestUtils} from 'flipper-plugin';
import {FlipperServerConfig, ReleaseChannel, Tristate} from 'flipper-common';
import type {RenderHost} from 'flipper-ui-core';
const test = global.test;
if (!test) {
throw new Error('Failed jest test object');
}
/**
* This test will not be executed on Github / SandCastle,
* since, for example, it relies on precise timer reliability
*/
(test as any).local = function local() {
const fn = process.env.SANDCASTLE || process.env.CI ? test.skip : test;
// eslint-disable-next-line
return fn.apply(null, arguments as any);
};
/**
* This test will only run on non-windows machines
*/
(test as any).unix = function local() {
const fn = process.platform === 'win32' ? test.skip : test;
// eslint-disable-next-line
return fn.apply(null, arguments as any);
};
beforeEach(() => {
// Fresh mock flipperServer for every test
window.FlipperRenderHostInstance = createStubRenderHost();
});
afterEach(cleanup);
console.debug = function () {
// Intentional noop, we don't want debug statements in Jest runs
};
// make perf tools available in Node (it is available in Browser / Electron just fine)
const {PerformanceObserver, performance} = require('perf_hooks');
Object.freeze(performance);
Object.freeze(Object.getPrototypeOf(performance));
// Something in our unit tests is messing with the performance global
// This fixes that.....
Object.defineProperty(global, 'performance', {
get() {
return performance;
},
set() {
throw new Error('Attempt to overwrite global.performance');
},
});
global.PerformanceObserver = PerformanceObserver;
// https://jestjs.io/docs/manual-mocks#mocking-methods-which-are-not-implemented-in-jsdom
Object.defineProperty(window, 'matchMedia', {
writable: true,
value: jest.fn().mockImplementation((query) => ({
matches: false,
media: query,
onchange: null,
addListener: jest.fn(), // deprecated
removeListener: jest.fn(), // deprecated
addEventListener: jest.fn(),
removeEventListener: jest.fn(),
dispatchEvent: jest.fn(),
})),
});
function createStubRenderHost(): RenderHost {
const rootPath = resolve(__dirname, '..');
const stubConfig: FlipperServerConfig = {
env: {...process.env},
gatekeepers: {
TEST_PASSING_GK: true,
TEST_FAILING_GK: false,
},
isProduction: false,
launcherSettings: {
ignoreLocalPin: false,
releaseChannel: ReleaseChannel.DEFAULT,
},
paths: {
appPath: rootPath,
desktopPath: `/dev/null`,
execPath: process.execPath,
homePath: `/dev/null`,
staticPath: resolve(rootPath, 'static'),
tempPath: tmpdir(),
},
processConfig: {
disabledPlugins: new Set(),
lastWindowPosition: null,
launcherEnabled: false,
launcherMsg: null,
screenCapturePath: `/dev/null`,
},
settings: {
androidHome: `/dev/null`,
darkMode: 'light',
enableAndroid: false,
enableIOS: false,
enablePhysicalIOS: false,
enablePrefetching: Tristate.False,
idbPath: `/dev/null`,
reactNative: {
shortcuts: {enabled: false, openDevMenu: '', reload: ''},
},
showWelcomeAtStartup: false,
suppressPluginErrors: false,
},
validWebSocketOrigins: [],
};
return {
processId: -1,
isProduction: false,
readTextFromClipboard() {
return '';
},
writeTextToClipboard() {},
async importFile() {
return undefined;
},
async exportFile() {
return undefined;
},
registerShortcut() {
return () => undefined;
},
hasFocus() {
return true;
},
onIpcEvent() {},
sendIpcEvent() {},
shouldUseDarkColors() {
return false;
},
restartFlipper() {},
openLink() {},
serverConfig: stubConfig,
loadDefaultPlugins() {
return {};
},
GK(gk: string) {
return stubConfig.gatekeepers[gk] ?? false;
},
flipperServer: TestUtils.createFlipperServerMock(),
};
}

View File

@@ -23,12 +23,11 @@ if (process.env.TZ !== timezone) {
// Make sure we have identical formatting of Dates everywhere
const toLocaleString = Date.prototype.toLocaleString;
// eslint-disable-next-line no-extend-native
Date.prototype.toLocaleString = function (_locale, ...args) {
(Date as any).prototype.toLocaleString = function (
_locale: any,
...args: any[]
) {
return toLocaleString.call(this, 'en-US', ...args);
};
require('immer').enableMapSet();
require('../flipper-ui-core/src/fb-stubs/Logger').init(undefined, {
isTest: true,
});