mirror of
https://github.com/facebook/react-native.git
synced 2025-11-01 09:14:26 +00:00
95f950de2a
Summary: This function is only used by the RNHostComponentList route. Let's move it into the route, so that we could keep the StaticViewConfigValidator slim. This will also allow us to more heavily customize this function for the route. Changelog: [Internal] Reviewed By: p-sun Differential Revision: D34026073 fbshipit-source-id: c3b3a93aed6007fadda2993afa52c28c028f6327
164 lines
3.9 KiB
JavaScript
164 lines
3.9 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.
|
|
*
|
|
* @flow strict
|
|
* @format
|
|
*/
|
|
|
|
import {type ViewConfig} from '../Renderer/shims/ReactNativeTypes';
|
|
import {isIgnored} from './ViewConfigIgnore';
|
|
|
|
export type Difference =
|
|
| {
|
|
type: 'missing',
|
|
path: Array<string>,
|
|
nativeValue: mixed,
|
|
}
|
|
| {
|
|
type: 'unequal',
|
|
path: Array<string>,
|
|
nativeValue: mixed,
|
|
staticValue: mixed,
|
|
}
|
|
| {
|
|
type: 'unexpected',
|
|
path: Array<string>,
|
|
staticValue: mixed,
|
|
};
|
|
|
|
export type ValidationResult = ValidResult | InvalidResult;
|
|
type ValidResult = {
|
|
type: 'valid',
|
|
};
|
|
type InvalidResult = {
|
|
type: 'invalid',
|
|
differences: Array<Difference>,
|
|
};
|
|
|
|
/**
|
|
* During the migration from native view configs to static view configs, this is
|
|
* used to validate that the two are equivalent.
|
|
*/
|
|
export function validate(
|
|
name: string,
|
|
nativeViewConfig: ViewConfig,
|
|
staticViewConfig: ViewConfig,
|
|
): ValidationResult {
|
|
const differences = [];
|
|
accumulateDifferences(
|
|
differences,
|
|
[],
|
|
{
|
|
bubblingEventTypes: nativeViewConfig.bubblingEventTypes,
|
|
directEventTypes: nativeViewConfig.directEventTypes,
|
|
uiViewClassName: nativeViewConfig.uiViewClassName,
|
|
validAttributes: nativeViewConfig.validAttributes,
|
|
},
|
|
{
|
|
bubblingEventTypes: staticViewConfig.bubblingEventTypes,
|
|
directEventTypes: staticViewConfig.directEventTypes,
|
|
uiViewClassName: staticViewConfig.uiViewClassName,
|
|
validAttributes: staticViewConfig.validAttributes,
|
|
},
|
|
);
|
|
|
|
if (differences.length === 0) {
|
|
return {type: 'valid'};
|
|
}
|
|
|
|
return {
|
|
type: 'invalid',
|
|
differences,
|
|
};
|
|
}
|
|
|
|
export function stringifyValidationResult(
|
|
name: string,
|
|
validationResult: InvalidResult,
|
|
): string {
|
|
const {differences} = validationResult;
|
|
return [
|
|
`StaticViewConfigValidator: Invalid static view config for '${name}'.`,
|
|
'',
|
|
...differences.map(difference => {
|
|
const {type, path} = difference;
|
|
switch (type) {
|
|
case 'missing':
|
|
return `- '${path.join('.')}' is missing.`;
|
|
case 'unequal':
|
|
return `- '${path.join('.')}' is the wrong value.`;
|
|
case 'unexpected':
|
|
return `- '${path.join('.')}' is present but not expected to be.`;
|
|
}
|
|
}),
|
|
'',
|
|
].join('\n');
|
|
}
|
|
|
|
function accumulateDifferences(
|
|
differences: Array<Difference>,
|
|
path: Array<string>,
|
|
nativeObject: {...},
|
|
staticObject: {...},
|
|
): void {
|
|
for (const nativeKey in nativeObject) {
|
|
const nativeValue = nativeObject[nativeKey];
|
|
|
|
if (!staticObject.hasOwnProperty(nativeKey)) {
|
|
differences.push({
|
|
path: [...path, nativeKey],
|
|
type: 'missing',
|
|
nativeValue,
|
|
});
|
|
continue;
|
|
}
|
|
|
|
const staticValue = staticObject[nativeKey];
|
|
|
|
const nativeValueIfObject = ifObject(nativeValue);
|
|
if (nativeValueIfObject != null) {
|
|
const staticValueIfObject = ifObject(staticValue);
|
|
if (staticValueIfObject != null) {
|
|
path.push(nativeKey);
|
|
accumulateDifferences(
|
|
differences,
|
|
path,
|
|
nativeValueIfObject,
|
|
staticValueIfObject,
|
|
);
|
|
path.pop();
|
|
continue;
|
|
}
|
|
}
|
|
|
|
if (nativeValue !== staticValue) {
|
|
differences.push({
|
|
path: [...path, nativeKey],
|
|
type: 'unequal',
|
|
nativeValue,
|
|
staticValue,
|
|
});
|
|
}
|
|
}
|
|
|
|
for (const staticKey in staticObject) {
|
|
if (
|
|
!nativeObject.hasOwnProperty(staticKey) &&
|
|
!isIgnored(staticObject[staticKey])
|
|
) {
|
|
differences.push({
|
|
path: [...path, staticKey],
|
|
type: 'unexpected',
|
|
staticValue: staticObject[staticKey],
|
|
});
|
|
}
|
|
}
|
|
}
|
|
|
|
function ifObject(value: mixed): ?{...} {
|
|
return typeof value === 'object' && !Array.isArray(value) ? value : null;
|
|
}
|