Experimental test helper: it.experimental (#17149)

Special version of Jest's `it` for experimental tests. Tests marked as
experimental will run **both** stable and experimental modes. In
experimental mode, they work the same as the normal Jest methods. In
stable mode, they are **expected to fail**. This means we can detect
when a test previously marked as experimental can be un-marked when the
feature becomes stable. It also reduces the chances that we accidentally
add experimental APIs to the stable builds before we intend.

I added corresponding methods for the focus and skip APIs:

- `fit` -> `fit.experimental`
- `it.only` -> `it.only.experimental` or `it.experimental.only`
- `xit` -> `xit.experimental`
- `it.skip` -> `it.skip.experimental` or `it.experimental.skip`

Since `it` is an alias of `test`, `test.experimental` works, too.
This commit is contained in:
Andrew Clark
2019-10-19 16:08:08 -07:00
committed by GitHub
parent edc234c730
commit 349cf5acc3
2 changed files with 58 additions and 4 deletions
+5 -4
View File
@@ -1292,8 +1292,9 @@ describe('ReactUpdates', () => {
expect(ops).toEqual(['Foo', 'Bar', 'Baz']);
});
if (__EXPERIMENTAL__) {
it('delays sync updates inside hidden subtrees in Concurrent Mode', () => {
it.experimental(
'delays sync updates inside hidden subtrees in Concurrent Mode',
() => {
const container = document.createElement('div');
function Baz() {
@@ -1368,8 +1369,8 @@ describe('ReactUpdates', () => {
expect(Scheduler).toFlushAndYield(['Bar']);
}
expect(hiddenDiv.innerHTML).toBe('<p>bar 1</p>');
});
}
},
);
it('can render ridiculously large number of roots without triggering infinite update loop error', () => {
class Foo extends React.Component {
+53
View File
@@ -205,5 +205,58 @@ if (process.env.REACT_CLASS_EQUIVALENCE_TEST) {
global.Error = ErrorProxy;
}
const expectExperimentalToFail = async callback => {
if (callback.length > 0) {
throw Error(
'Experimental test helpers do not support `done` callback. Return a ' +
'promise instead.'
);
}
try {
const maybePromise = callback();
if (
maybePromise !== undefined &&
maybePromise !== null &&
typeof maybePromise.then === 'function'
) {
await maybePromise;
}
} catch (error) {
// Failed as expected
return;
}
throw Error(
'Tests marked experimental are expected to fail, but this one passed.'
);
};
const it = global.it;
const fit = global.fit;
const xit = global.xit;
if (__EXPERIMENTAL__) {
it.experimental = it;
fit.experimental = it.only.experimental = it.experimental.only = fit;
xit.experimental = it.skip.experimental = it.experimental.skip = xit;
} else {
it.experimental = (message, callback) => {
it(`[EXPERIMENTAL, SHOULD FAIL] ${message}`, () =>
expectExperimentalToFail(callback));
};
fit.experimental = it.only.experimental = it.experimental.only = (
message,
callback
) => {
fit(`[EXPERIMENTAL, SHOULD FAIL] ${message}`, () =>
expectExperimentalToFail(callback));
};
xit.experimental = it.skip.experimental = it.experimental.skip = (
message,
callback
) => {
xit(`[EXPERIMENTAL, SHOULD FAIL] ${message}`, () =>
expectExperimentalToFail(callback));
};
}
require('jasmine-check').install();
}