Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[devtools][tests] add support for @gate pragma #28479

Merged
merged 1 commit into from
Mar 1, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions .eslintrc.js
Original file line number Diff line number Diff line change
Expand Up @@ -381,6 +381,13 @@ module.exports = {
'jest/valid-expect-in-promise': ERROR,
},
},
{
// disable no focused tests for test setup helper files even if they are inside __tests__ directory
files: ['**/setupTests.js'],
rules: {
'jest/no-focused-tests': OFF,
},
},
{
files: [
'**/__tests__/**/*.js',
Expand Down
18 changes: 18 additions & 0 deletions packages/react-devtools-shared/src/__tests__/gate-test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
/**
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @flow
*/

describe('gate', () => {
//@gate false
it('should expect an error for this test', () => {
throw new Error('This test should fail');
});

//@gate true
it('should not an error for this test', () => {});
});
71 changes: 71 additions & 0 deletions packages/react-devtools-shared/src/__tests__/setupTests.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import type {
BackendBridge,
FrontendBridge,
} from 'react-devtools-shared/src/bridge';
const {getTestFlags} = require('../../../../scripts/jest/TestFlags');

// Argument is serialized when passed from jest-cli script through to setupTests.
const compactConsole = process.env.compactConsole === 'true';
Expand All @@ -32,6 +33,76 @@ if (compactConsole) {
global.console = new CustomConsole(process.stdout, process.stderr, formatter);
}

const expectTestToFail = async (callback, error) => {
if (callback.length > 0) {
throw Error(
'Gated test helpers do not support the `done` callback. Return a ' +
'promise instead.',
);
}
try {
const maybePromise = callback();
if (
maybePromise !== undefined &&
maybePromise !== null &&
typeof maybePromise.then === 'function'
) {
await maybePromise;
}
} catch (testError) {
return;
}
throw error;
};

const gatedErrorMessage = 'Gated test was expected to fail, but it passed.';
global._test_gate = (gateFn, testName, callback) => {
let shouldPass;
try {
const flags = getTestFlags();
shouldPass = gateFn(flags);
} catch (e) {
test(testName, () => {
throw e;
});
return;
}
if (shouldPass) {
test(testName, callback);
} else {
const error = new Error(gatedErrorMessage);
Error.captureStackTrace(error, global._test_gate);
test(`[GATED, SHOULD FAIL] ${testName}`, () =>
expectTestToFail(callback, error));
}
};
global._test_gate_focus = (gateFn, testName, callback) => {
let shouldPass;
try {
const flags = getTestFlags();
shouldPass = gateFn(flags);
} catch (e) {
test.only(testName, () => {
throw e;
});
return;
}
if (shouldPass) {
test.only(testName, callback);
} else {
const error = new Error(gatedErrorMessage);
Error.captureStackTrace(error, global._test_gate_focus);
test.only(`[GATED, SHOULD FAIL] ${testName}`, () =>
expectTestToFail(callback, error));
}
};

// Dynamic version of @gate pragma
global.gate = fn => {
const flags = getTestFlags();
return fn(flags);
};

beforeEach(() => {
global.mockClipboardCopy = jest.fn();

Expand Down