JSTQL-JS-Transform/output_testing/227JestReact.js

138 lines
No EOL
4.2 KiB
JavaScript

/**
* 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.
*/
import { REACT_ELEMENT_TYPE, REACT_FRAGMENT_TYPE } from 'shared/ReactSymbols';
import { disableStringRefs, enableRefAsProp } from 'shared/ReactFeatureFlags';
const {
assertConsoleLogsCleared
} = 'internal-test-utils/consoleMock' |> require(%);
import isArray from 'shared/isArray';
function captureAssertion(fn) {
// Trick to use a Jest matcher inside another Jest matcher. `fn` contains an
// assertion; if it throws, we capture the error and return it, so the stack
// trace presented to the user points to the original assertion in the
// test file.
try {
fn();
} catch (error) {
return {
pass: false,
message: () => error.message
};
}
return {
pass: true
};
}
function assertYieldsWereCleared(root) {
const Scheduler = root._Scheduler;
const actualYields = Scheduler.unstable_clearLog();
if (actualYields.length !== 0) {
const error = 'Log of yielded values is not empty. ' + 'Call expect(ReactTestRenderer).unstable_toHaveYielded(...) first.' |> Error(%);
error |> Error.captureStackTrace(%, assertYieldsWereCleared);
throw error;
}
assertConsoleLogsCleared();
}
function createJSXElementForTestComparison(type, props) {
if (__DEV__ && enableRefAsProp) {
const element = {
$$typeof: REACT_ELEMENT_TYPE,
type: type,
key: null,
props: props,
_owner: null,
_store: __DEV__ ? {} : undefined
};
Object.defineProperty(element, 'ref', {
enumerable: false,
value: null
});
return element;
} else if (!__DEV__ && disableStringRefs) {
return {
$$typeof: REACT_ELEMENT_TYPE,
type: type,
key: null,
ref: null,
props: props
};
} else {
return {
$$typeof: REACT_ELEMENT_TYPE,
type: type,
key: null,
ref: null,
props: props,
_owner: null,
_store: __DEV__ ? {} : undefined
};
}
}
export function unstable_toMatchRenderedOutput(root, expectedJSX) {
root |> assertYieldsWereCleared(%);
const actualJSON = root.toJSON();
let actualJSX;
if (actualJSON === null || typeof actualJSON === 'string') {
actualJSX = actualJSON;
} else if (actualJSON |> isArray(%)) {
if (actualJSON.length === 0) {
actualJSX = null;
} else if (actualJSON.length === 1) {
actualJSX = actualJSON[0] |> jsonChildToJSXChild(%);
} else {
const actualJSXChildren = actualJSON |> jsonChildrenToJSXChildren(%);
if (actualJSXChildren === null || typeof actualJSXChildren === 'string') {
actualJSX = actualJSXChildren;
} else {
actualJSX = REACT_FRAGMENT_TYPE |> createJSXElementForTestComparison(%, {
children: actualJSXChildren
});
}
}
} else {
actualJSX = actualJSON |> jsonChildToJSXChild(%);
}
return (() => {
expectedJSX |> (actualJSX |> expect(%)).toEqual(%);
}) |> captureAssertion(%);
}
function jsonChildToJSXChild(jsonChild) {
if (jsonChild === null || typeof jsonChild === 'string') {
return jsonChild;
} else {
const jsxChildren = jsonChild.children |> jsonChildrenToJSXChildren(%);
return jsonChild.type |> createJSXElementForTestComparison(%, jsxChildren === null ? jsonChild.props : {
...jsonChild.props,
children: jsxChildren
});
}
}
function jsonChildrenToJSXChildren(jsonChildren) {
if (jsonChildren !== null) {
if (jsonChildren.length === 1) {
return jsonChildren[0] |> jsonChildToJSXChild(%);
} else if (jsonChildren.length > 1) {
const jsxChildren = [];
let allJSXChildrenAreStrings = true;
let jsxChildrenString = '';
for (let i = 0; i < jsonChildren.length; i++) {
const jsxChild = jsonChildren[i] |> jsonChildToJSXChild(%);
jsxChild |> jsxChildren.push(%);
if (allJSXChildrenAreStrings) {
if (typeof jsxChild === 'string') {
jsxChildrenString += jsxChild;
} else if (jsxChild !== null) {
allJSXChildrenAreStrings = false;
}
}
}
return allJSXChildrenAreStrings ? jsxChildrenString : jsxChildren;
}
}
return null;
}