@samitouri / QOS-React-2 / commits / 349cf5acc3

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.

Andrew Clark committed Oct 19, 2019 at 16:08 UTC 349cf5acc3cda0010fa464a3c959c83a78a24bd7
2 files changed +58 -4
packages/react-dom/src/__tests__/ReactUpdates-test.js
+5 -4
@@ -1292,8 +1292,9 @@ describe('ReactUpdates', () => {
1292 expect(ops).toEqual(['Foo', 'Bar', 'Baz']);
1293 });
1294
1295 - if (__EXPERIMENTAL__) {
1296 - it('delays sync updates inside hidden subtrees in Concurrent Mode', () => {
1295 + it.experimental(
1296 + 'delays sync updates inside hidden subtrees in Concurrent Mode',
1297 + () => {
1298 const container = document.createElement('div');
1299
1300 function Baz() {
@@ -1368,8 +1369,8 @@ describe('ReactUpdates', () => {
1369 expect(Scheduler).toFlushAndYield(['Bar']);
1370 }
1371 expect(hiddenDiv.innerHTML).toBe('<p>bar 1</p>');
1371 - });
1372 - }
1372 + },
1373 + );
1374
1375 it('can render ridiculously large number of roots without triggering infinite update loop error', () => {
1376 class Foo extends React.Component {
scripts/jest/setupTests.js
+53
@@ -205,5 +205,58 @@ if (process.env.REACT_CLASS_EQUIVALENCE_TEST) {
205 global.Error = ErrorProxy;
206 }
207
208 + const expectExperimentalToFail = async callback => {
209 + if (callback.length > 0) {
210 + throw Error(
211 + 'Experimental test helpers do not support `done` callback. Return a ' +
212 + 'promise instead.'
213 + );
214 + }
215 + try {
216 + const maybePromise = callback();
217 + if (
218 + maybePromise !== undefined &&
219 + maybePromise !== null &&
220 + typeof maybePromise.then === 'function'
221 + ) {
222 + await maybePromise;
223 + }
224 + } catch (error) {
225 + // Failed as expected
226 + return;
227 + }
228 + throw Error(
229 + 'Tests marked experimental are expected to fail, but this one passed.'
230 + );
231 + };
232 +
233 + const it = global.it;
234 + const fit = global.fit;
235 + const xit = global.xit;
236 + if (__EXPERIMENTAL__) {
237 + it.experimental = it;
238 + fit.experimental = it.only.experimental = it.experimental.only = fit;
239 + xit.experimental = it.skip.experimental = it.experimental.skip = xit;
240 + } else {
241 + it.experimental = (message, callback) => {
242 + it(`[EXPERIMENTAL, SHOULD FAIL] ${message}`, () =>
243 + expectExperimentalToFail(callback));
244 + };
245 + fit.experimental = it.only.experimental = it.experimental.only = (
246 + message,
247 + callback
248 + ) => {
249 + fit(`[EXPERIMENTAL, SHOULD FAIL] ${message}`, () =>
250 + expectExperimentalToFail(callback));
251 + };
252 + xit.experimental = it.skip.experimental = it.experimental.skip = (
253 + message,
254 + callback
255 + ) => {
256 + xit(`[EXPERIMENTAL, SHOULD FAIL] ${message}`, () =>
257 + expectExperimentalToFail(callback));
258 + };
259 + }
260 +
261 require('jasmine-check').install();
262 }