mirror of
https://github.com/facebook/react.git
synced 2026-02-26 07:55:55 +00:00
* Use relative paths in packages/react * Use relative paths in packages/react-art * Use relative paths in packages/react-cs * Use relative paths in other packages * Fix as many issues as I can This uncovered an interesting problem where ./b from package/src/a would resolve to a different instantiation of package/src/b in Jest. Either this is a showstopper or we can solve it by completely fobbidding remaining /src/. * Fix all tests It seems we can't use relative requires in tests anymore. Otherwise Jest becomes confused between real file and symlink. https://github.com/facebook/jest/issues/3830 This seems bad... Except that we already *don't* want people to create tests that import individual source files. All existing cases of us doing so are actually TODOs waiting to be fixed. So perhaps this requirement isn't too bad because it makes bad code looks bad. Of course, if we go with this, we'll have to lint against relative requires in tests. It also makes moving things more painful. * Prettier * Remove @providesModule * Fix remaining Haste imports I missed earlier * Fix up paths to reflect new flat structure * Fix Flow * Fix CJS and UMD builds * Fix FB bundles * Fix RN bundles * Prettier * Fix lint * Fix warning printing and error codes * Fix buggy return * Fix lint and Flow * Use Yarn on CI * Unbreak Jest * Fix lint * Fix aliased originals getting included in DEV Shouldn't affect correctness (they were ignored) but fixes DEV size regression. * Record sizes * Fix weird version in package.json * Tweak bundle labels * Get rid of output option by introducing react-dom/server.node * Reconciler should depend on prop-types * Update sizes last time
240 lines
6.6 KiB
JavaScript
240 lines
6.6 KiB
JavaScript
/**
|
|
* Copyright (c) 2014-present, Facebook, Inc.
|
|
*
|
|
* This source code is licensed under the MIT license found in the
|
|
* LICENSE file in the root directory of this source tree.
|
|
*
|
|
* @emails react-core
|
|
*/
|
|
|
|
'use strict';
|
|
|
|
var ReactErrorUtils;
|
|
|
|
describe('ReactErrorUtils', () => {
|
|
beforeEach(() => {
|
|
// TODO: can we express this test with only public API?
|
|
ReactErrorUtils = require('shared/ReactErrorUtils');
|
|
});
|
|
|
|
// Run tests in both DEV and production
|
|
describe(
|
|
'invokeGuardedCallback (development)',
|
|
invokeGuardedCallbackTests.bind(null, 'development'),
|
|
);
|
|
describe('invokeGuardedCallback (production)', () => {
|
|
let oldProcess;
|
|
beforeEach(() => {
|
|
__DEV__ = false;
|
|
|
|
// Mutating process.env.NODE_ENV would cause our babel plugins to do the
|
|
// wrong thing. If you change this, make sure to test with jest --no-cache.
|
|
oldProcess = process;
|
|
global.process = {
|
|
...process,
|
|
env: {...process.env, NODE_ENV: 'production'},
|
|
};
|
|
|
|
jest.resetModules();
|
|
ReactErrorUtils = require('shared/ReactErrorUtils');
|
|
});
|
|
|
|
afterEach(() => {
|
|
__DEV__ = true;
|
|
global.process = oldProcess;
|
|
});
|
|
|
|
invokeGuardedCallbackTests('production');
|
|
});
|
|
|
|
function invokeGuardedCallbackTests(environment) {
|
|
it(`it should rethrow caught errors (${environment})`, () => {
|
|
var err = new Error('foo');
|
|
var callback = function() {
|
|
throw err;
|
|
};
|
|
ReactErrorUtils.invokeGuardedCallbackAndCatchFirstError(
|
|
'foo',
|
|
callback,
|
|
null,
|
|
);
|
|
expect(ReactErrorUtils.hasCaughtError()).toBe(false);
|
|
expect(() => ReactErrorUtils.rethrowCaughtError()).toThrow(err);
|
|
});
|
|
|
|
it(`should call the callback the passed arguments (${environment})`, () => {
|
|
var callback = jest.fn();
|
|
ReactErrorUtils.invokeGuardedCallback(
|
|
'foo',
|
|
callback,
|
|
null,
|
|
'arg1',
|
|
'arg2',
|
|
);
|
|
expect(callback).toBeCalledWith('arg1', 'arg2');
|
|
});
|
|
|
|
it(`should call the callback with the provided context (${environment})`, () => {
|
|
var context = {didCall: false};
|
|
ReactErrorUtils.invokeGuardedCallback(
|
|
'foo',
|
|
function() {
|
|
this.didCall = true;
|
|
},
|
|
context,
|
|
);
|
|
expect(context.didCall).toBe(true);
|
|
});
|
|
|
|
it(`should catch errors (${environment})`, () => {
|
|
const error = new Error();
|
|
const returnValue = ReactErrorUtils.invokeGuardedCallback(
|
|
'foo',
|
|
function() {
|
|
throw error;
|
|
},
|
|
null,
|
|
'arg1',
|
|
'arg2',
|
|
);
|
|
expect(returnValue).toBe(undefined);
|
|
expect(ReactErrorUtils.hasCaughtError()).toBe(true);
|
|
expect(ReactErrorUtils.clearCaughtError()).toBe(error);
|
|
});
|
|
|
|
it(`should return false from clearCaughtError if no error was thrown (${environment})`, () => {
|
|
var callback = jest.fn();
|
|
ReactErrorUtils.invokeGuardedCallback('foo', callback, null);
|
|
expect(ReactErrorUtils.hasCaughtError()).toBe(false);
|
|
expect(ReactErrorUtils.clearCaughtError).toThrow(
|
|
__DEV__ ? 'no error was captured' : 'Minified React error #198',
|
|
);
|
|
});
|
|
|
|
it(`can nest with same debug name (${environment})`, () => {
|
|
const err1 = new Error();
|
|
let err2;
|
|
const err3 = new Error();
|
|
let err4;
|
|
ReactErrorUtils.invokeGuardedCallback(
|
|
'foo',
|
|
function() {
|
|
ReactErrorUtils.invokeGuardedCallback(
|
|
'foo',
|
|
function() {
|
|
throw err1;
|
|
},
|
|
null,
|
|
);
|
|
err2 = ReactErrorUtils.clearCaughtError();
|
|
throw err3;
|
|
},
|
|
null,
|
|
);
|
|
err4 = ReactErrorUtils.clearCaughtError();
|
|
|
|
expect(err2).toBe(err1);
|
|
expect(err4).toBe(err3);
|
|
});
|
|
|
|
it(`handles nested errors (${environment})`, () => {
|
|
const err1 = new Error();
|
|
let err2;
|
|
ReactErrorUtils.invokeGuardedCallback(
|
|
'foo',
|
|
function() {
|
|
ReactErrorUtils.invokeGuardedCallback(
|
|
'foo',
|
|
function() {
|
|
throw err1;
|
|
},
|
|
null,
|
|
);
|
|
err2 = ReactErrorUtils.clearCaughtError();
|
|
},
|
|
null,
|
|
);
|
|
// Returns null because inner error was already captured
|
|
expect(ReactErrorUtils.hasCaughtError()).toBe(false);
|
|
|
|
expect(err2).toBe(err1);
|
|
});
|
|
|
|
it('handles nested errors in separate renderers', () => {
|
|
const ReactErrorUtils1 = require('shared/ReactErrorUtils');
|
|
jest.resetModules();
|
|
const ReactErrorUtils2 = require('shared/ReactErrorUtils');
|
|
expect(ReactErrorUtils1).not.toEqual(ReactErrorUtils2);
|
|
|
|
let ops = [];
|
|
|
|
ReactErrorUtils1.invokeGuardedCallback(
|
|
null,
|
|
() => {
|
|
ReactErrorUtils2.invokeGuardedCallback(
|
|
null,
|
|
() => {
|
|
throw new Error('nested error');
|
|
},
|
|
null,
|
|
);
|
|
// ReactErrorUtils2 should catch the error
|
|
ops.push(ReactErrorUtils2.hasCaughtError());
|
|
ops.push(ReactErrorUtils2.clearCaughtError().message);
|
|
},
|
|
null,
|
|
);
|
|
|
|
// ReactErrorUtils1 should not catch the error
|
|
ops.push(ReactErrorUtils1.hasCaughtError());
|
|
|
|
expect(ops).toEqual([true, 'nested error', false]);
|
|
});
|
|
|
|
if (environment === 'production') {
|
|
// jsdom doesn't handle this properly, but Chrome and Firefox should. Test
|
|
// this with a fixture.
|
|
it('catches null values', () => {
|
|
ReactErrorUtils.invokeGuardedCallback(
|
|
null,
|
|
function() {
|
|
throw null; // eslint-disable-line no-throw-literal
|
|
},
|
|
null,
|
|
);
|
|
expect(ReactErrorUtils.hasCaughtError()).toBe(true);
|
|
expect(ReactErrorUtils.clearCaughtError()).toBe(null);
|
|
});
|
|
}
|
|
|
|
it(`can be shimmed (${environment})`, () => {
|
|
const ops = [];
|
|
// Override the original invokeGuardedCallback
|
|
ReactErrorUtils.injection.injectErrorUtils({
|
|
invokeGuardedCallback(name, func, context, a) {
|
|
ops.push(a);
|
|
try {
|
|
func.call(context, a);
|
|
} catch (error) {
|
|
this._hasCaughtError = true;
|
|
this._caughtError = error;
|
|
}
|
|
},
|
|
});
|
|
|
|
var err = new Error('foo');
|
|
var callback = function() {
|
|
throw err;
|
|
};
|
|
ReactErrorUtils.invokeGuardedCallbackAndCatchFirstError(
|
|
'foo',
|
|
callback,
|
|
null,
|
|
'somearg',
|
|
);
|
|
expect(() => ReactErrorUtils.rethrowCaughtError()).toThrow(err);
|
|
expect(ops).toEqual(['somearg']);
|
|
});
|
|
}
|
|
});
|