/*** 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.** @emails react-core* @jest-environment node*/'use strict';
let React;
let ReactNative;
let createReactNativeComponentClass;
let computeComponentStackForErrorReporting;
function normalizeCodeLocInfo(str) {
return (
str &&
str.replace(/\n +(?:at|in) ([\S]+)[^\n]*/g, function (m, name) {
return '\n in ' + name + ' (at **)';
}));}describe('ReactNativeError', () => {
beforeEach(() => {
jest.resetModules();
React = require('react');
ReactNative = require('react-native-renderer');
createReactNativeComponentClass =
require('react-native/Libraries/ReactPrivate/ReactNativePrivateInterface')
.ReactNativeViewConfigRegistry.register;computeComponentStackForErrorReporting =
ReactNative.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED
.computeComponentStackForErrorReporting;});it('should throw error if null component registration getter is used', () => {
expect(() => {
try {
createReactNativeComponentClass('View', null);
} catch (e) {
throw new Error(e.toString());
}}).toThrow(
'View config getter callback for component `View` must be a function (received `null`)',
);});it('should be able to extract a component stack from a native view', () => {
const View = createReactNativeComponentClass('View', () => ({
validAttributes: {foo: true},
uiViewClassName: 'View',
}));const ref = React.createRef();
function FunctionComponent(props) {
return props.children;
}class ClassComponent extends React.Component {
render() {
return (
<FunctionComponent>
<View foo="test" ref={ref} />
</FunctionComponent>
);}}ReactNative.render(<ClassComponent />, 1);
const reactTag = ReactNative.findNodeHandle(ref.current);
const componentStack = normalizeCodeLocInfo(computeComponentStackForErrorReporting(reactTag),);expect(componentStack).toBe(
'\n' +
' in View (at **)\n' +
' in FunctionComponent (at **)\n' +
' in ClassComponent (at **)',
);});});