Skip to content

Commit

Permalink
Add support for focused and skipped tests in React Native integration…
Browse files Browse the repository at this point in the history
… tests (#47559)

Summary:
Pull Request resolved: #47559

Changelog: [internal]

Adds support for focused and skipped tests and describe blocks:
* `fdescribe` / `describe.only`
* `xdescribe` / `describe.skip`
* `fit` / `it.only` / `test.only`
* `xit` / `it.skip` / `xtest` / `test.skip`

Reviewed By: rshest

Differential Revision: D65769325
  • Loading branch information
rubennorte authored and facebook-github-bot committed Nov 13, 2024
1 parent 8204ac8 commit 1397099
Show file tree
Hide file tree
Showing 2 changed files with 108 additions and 35 deletions.
3 changes: 2 additions & 1 deletion jest/integration/runner/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -174,7 +174,8 @@ module.exports = async function runTest(
.length,
numFailingTests: testResults.filter(test => test.status === 'failed')
.length,
numPendingTests: 0,
numPendingTests: testResults.filter(test => test.status === 'pending')
.length,
numTodoTests: 0,
skipped: false,
testResults,
Expand Down
140 changes: 106 additions & 34 deletions jest/integration/runtime/setup.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,36 +9,97 @@
* @oncall react_native
*/

type TestResult = {
ancestorTitles: Array<string>,
title: string,
fullName: string,
status: 'passed' | 'failed' | 'pending',
duration: number,
failureMessages: Array<string>,
numPassingAsserts: number,
// location: string,
};

const tests: Array<{
title: string,
ancestorTitles: Array<string>,
implementation: () => mixed,
result?: {
ancestorTitles: Array<string>,
title: string,
fullName: string,
status: 'passed' | 'failed' | 'skipped',
duration: number,
failureMessages: Array<string>,
numPassingAsserts: number,
// location: string,
},
isFocused: boolean,
isSkipped: boolean,
result?: TestResult,
}> = [];

const ancestorTitles: Array<string> = [];

global.describe = (title: string, implementation: () => mixed) => {
const globalModifiers: Array<'focused' | 'skipped'> = [];

const globalDescribe = (global.describe = (
title: string,
implementation: () => mixed,
) => {
ancestorTitles.push(title);
implementation();
ancestorTitles.pop();
});

const globalIt =
(global.it =
global.test =
(title: string, implementation: () => mixed) =>
tests.push({
title,
implementation,
ancestorTitles: ancestorTitles.slice(),
isFocused:
globalModifiers.length > 0 &&
globalModifiers[globalModifiers.length - 1] === 'focused',
isSkipped:
globalModifiers.length > 0 &&
globalModifiers[globalModifiers.length - 1] === 'skipped',
}));

// $FlowExpectedError[prop-missing]
global.fdescribe = global.describe.only = (
title: string,
implementation: () => mixed,
) => {
globalModifiers.push('focused');
globalDescribe(title, implementation);
globalModifiers.pop();
};

global.it = (title: string, implementation: () => mixed) =>
tests.push({
title,
implementation,
ancestorTitles: ancestorTitles.slice(),
});
// $FlowExpectedError[prop-missing]
global.it.only =
global.fit =
// $FlowExpectedError[prop-missing]
global.test.only =
(title: string, implementation: () => mixed) => {
globalModifiers.push('focused');
globalIt(title, implementation);
globalModifiers.pop();
};

// $FlowExpectedError[prop-missing]
global.xdescribe = global.describe.skip = (
title: string,
implementation: () => mixed,
) => {
globalModifiers.push('skipped');
globalDescribe(title, implementation);
globalModifiers.pop();
};

// $FlowExpectedError[prop-missing]
global.it.skip =
global.xit =
// $FlowExpectedError[prop-missing]
global.test.skip =
global.xtest =
(title: string, implementation: () => mixed) => {
globalModifiers.push('skipped');
globalIt(title, implementation);
globalModifiers.pop();
};

// flowlint unsafe-getters-setters:off

Expand Down Expand Up @@ -123,29 +184,40 @@ function runWithGuard(fn: () => void) {
}

function executeTests() {
for (const test of tests) {
let status;
let error;

const start = Date.now();

try {
test.implementation();
status = 'passed';
} catch (e) {
error = e;
status = 'failed';
}
const hasFocusedTests = tests.some(test => test.isFocused);

test.result = {
for (const test of tests) {
const result: TestResult = {
title: test.title,
fullName: [...test.ancestorTitles, test.title].join(' '),
ancestorTitles: test.ancestorTitles,
status,
duration: Date.now() - start,
failureMessages: status === 'failed' && error ? [error.message] : [],
status: 'pending',
duration: 0,
failureMessages: [],
numPassingAsserts: 0,
};

test.result = result;

if (!test.isSkipped && (!hasFocusedTests || test.isFocused)) {
let status;
let error;

const start = Date.now();

try {
test.implementation();
status = 'passed';
} catch (e) {
error = e;
status = 'failed';
}

result.status = status;
result.duration = Date.now() - start;
result.failureMessages =
status === 'failed' && error ? [error.message] : [];
}
}

console.log(
Expand Down

0 comments on commit 1397099

Please sign in to comment.