Skip to content

Commit f529fd6

Browse files
coadofacebook-github-bot
authored andcommitted
Add snapshot validation to build-types (#51893)
Summary: Pull Request resolved: #51893 This diff adds `--validate` flag that runs snapshot validation to determine if the `ReactNativeApi.d.ts` rollup has been changed (if JS public API has been touched). There was also an issue with `sortProperties` that reordered some properties (ex. in ImagePropsBase) after removing one of them (ex. accessible) which had negative impact on the displayed result. ### Motivation Compare previous snapshot with the one built on the current revision to determine the impact of made changes on the public API surface. Display differences in human readable format using `diff` method from the `jest-diff` library. For now `--validate` flag is not useful on its own. It should be used with `--withSnapshot` flag (which will be removed shortly and generating snapshot will be a default mechanism). Changelog: [General][Added] - Add `--validate` flag to `build-types` script for JS API snapshot validation. Reviewed By: huntie Differential Revision: D76135158 fbshipit-source-id: 53f5b142c66e3e3931961f741c3f2fab8ccdc228
1 parent 788c980 commit f529fd6

2 files changed

Lines changed: 48 additions & 8 deletions

File tree

scripts/build-types/BuildApiSnapshot.js

Lines changed: 45 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -23,9 +23,11 @@ const {
2323
} = require('@microsoft/api-extractor');
2424
const {promises: fs} = require('fs');
2525
const glob = require('glob');
26+
const {diff} = require('jest-diff');
2627
const path = require('path');
2728
const prettier = require('prettier');
2829
const osTempDir = require('temp-dir');
30+
const {styleText} = require('util');
2931

3032
const inputFilesPostTransforms: $ReadOnlyArray<PluginObj<mixed>> = [
3133
require('./transforms/renameDefaultExportedIdentifiers'),
@@ -37,7 +39,7 @@ const postTransforms: $ReadOnlyArray<PluginObj<mixed>> = [
3739
require('./transforms/sortUnions'),
3840
];
3941

40-
async function buildAPISnapshot() {
42+
async function buildAPISnapshot(validate: boolean) {
4143
const tempDirectory = await createTempDir('react-native-js-api-snapshot');
4244
const packages = await findPackagesWithTypedef();
4345

@@ -56,12 +58,23 @@ async function buildAPISnapshot() {
5658
if (extractorResult.succeeded) {
5759
const apiSnapshot = apiSnapshotTemplate(
5860
await getCleanedUpRollup(tempDirectory),
59-
);
61+
) as string;
6062

61-
await fs.writeFile(
62-
path.join(REACT_NATIVE_PACKAGE_DIR, 'ReactNativeApi.d.ts'),
63-
apiSnapshot,
64-
);
63+
if (validate) {
64+
const prevSnapshot = await fs.readFile(
65+
path.join(REACT_NATIVE_PACKAGE_DIR, 'ReactNativeApi.d.ts'),
66+
'utf-8',
67+
);
68+
const hasChanged = await validateSnapshots(prevSnapshot, apiSnapshot);
69+
if (hasChanged) {
70+
process.exitCode = 1;
71+
}
72+
} else {
73+
await fs.writeFile(
74+
path.join(REACT_NATIVE_PACKAGE_DIR, 'ReactNativeApi.d.ts'),
75+
apiSnapshot,
76+
);
77+
}
6578
} else {
6679
process.exitCode = 1;
6780
console.error(
@@ -73,6 +86,32 @@ async function buildAPISnapshot() {
7386
await fs.rm(tempDirectory, {recursive: true});
7487
}
7588

89+
async function validateSnapshots(
90+
prevSnapshot: string,
91+
newSnapshot: string,
92+
): Promise<boolean> {
93+
const hasChanged = newSnapshot !== prevSnapshot;
94+
if (hasChanged) {
95+
const options = {
96+
aAnnotation: 'Previous Snapshot',
97+
bAnnotation: 'New Snapshot',
98+
expand: false,
99+
emptyFirstOrLastLinePlaceholder: '↵',
100+
includeChangeCounts: true,
101+
aColor: (line: string) => styleText(['red'], line),
102+
bColor: (line: string) => styleText(['green'], line),
103+
};
104+
105+
const diffResult = diff(prevSnapshot, newSnapshot, options);
106+
console.error(
107+
`\n${styleText(['inverse'], ' VALIDATE ')} ReactNativeApi.d.ts has changed. Please re-run \`yarn build-types\` and commit the updated snapshot.\n\n`,
108+
diffResult,
109+
);
110+
}
111+
112+
return hasChanged;
113+
}
114+
76115
async function findPackagesWithTypedef() {
77116
const packagesWithGeneratedTypes = glob
78117
.sync(`${PACKAGES_DIR}/**/types_generated`, {nodir: false})

scripts/build-types/index.js

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,12 +20,13 @@ const config = {
2020
debug: {type: 'boolean'},
2121
help: {type: 'boolean'},
2222
withSnapshot: {type: 'boolean'},
23+
validate: {type: 'boolean'},
2324
},
2425
};
2526

2627
async function main() {
2728
const {
28-
values: {debug: debugEnabled, help, withSnapshot},
29+
values: {debug: debugEnabled, help, withSnapshot, validate},
2930
/* $FlowFixMe[incompatible-call] Natural Inference rollout. See
3031
* https://fburl.com/workplace/6291gfvu */
3132
} = parseArgs(config);
@@ -68,7 +69,7 @@ async function main() {
6869
'\n',
6970
);
7071

71-
await buildApiSnapshot();
72+
await buildApiSnapshot(validate);
7273
}
7374
}
7475

0 commit comments

Comments
 (0)