From e7f080eb046d15ae84dd576054780bef5590b366 Mon Sep 17 00:00:00 2001 From: Charles Lyding <19598772+clydin@users.noreply.github.com> Date: Fri, 24 Apr 2026 13:47:19 -0400 Subject: [PATCH] feat(bazel): add diff output to failing api-golden tests This commit adds unified diff output when `api_golden_test` fails, using the `diff` NPM package. --- bazel/api-golden/BUILD.bazel | 1 + bazel/api-golden/index_npm_packages.cts | 20 +++++++++++++++++--- bazel/package.json | 1 + pnpm-lock.yaml | 9 +++++++++ 4 files changed, 28 insertions(+), 3 deletions(-) diff --git a/bazel/api-golden/BUILD.bazel b/bazel/api-golden/BUILD.bazel index 184555a9b8..0c6f572e07 100644 --- a/bazel/api-golden/BUILD.bazel +++ b/bazel/api-golden/BUILD.bazel @@ -21,6 +21,7 @@ ts_project( deps = [ "//bazel:node_modules/@microsoft/api-extractor", "//bazel:node_modules/@types/node", + "//bazel:node_modules/diff", "//bazel:node_modules/piscina", "//bazel:node_modules/typescript", ], diff --git a/bazel/api-golden/index_npm_packages.cts b/bazel/api-golden/index_npm_packages.cts index 1415d8a2fd..3af8158ec8 100644 --- a/bazel/api-golden/index_npm_packages.cts +++ b/bazel/api-golden/index_npm_packages.cts @@ -14,6 +14,7 @@ import {testApiGolden} from './test_api_report.js'; import * as fs from 'fs'; import {Piscina} from 'piscina'; import {styleText} from 'util'; +import {createPatch} from 'diff'; /** Interface describing contents of a `package.json`. */ export interface PackageJson { @@ -89,7 +90,8 @@ async function main( const expected = await fs.promises.readFile(goldenFilePath, 'utf8'); if (actual !== expected) { // Keep track of outdated goldens for error message. - outdatedGoldens.push(goldenName); + const patch = createPatch(goldenName, expected, actual); + outdatedGoldens.push({name: goldenName, diff: patch}); return false; } } @@ -97,7 +99,7 @@ async function main( return true; }; - const outdatedGoldens: string[] = []; + const outdatedGoldens: {name: string; diff: string}[] = []; const tasks: Promise[] = []; // Process in batches. Otherwise we risk out of memory errors. const batchSize = 10; @@ -122,7 +124,11 @@ async function main( console.error(Array(80).fill('=').join('')); console.error(`${Array(35).fill('=').join('')} RESULTS ${Array(36).fill('=').join('')}`); console.error(Array(80).fill('=').join('')); + if (singleFileMode) { + console.error(red(`Diff:`)); + console.error(outdatedGoldens[0].diff); + console.info(); console.error( red( `The golden is out of date and can be updated by running:\n - bazel run ${process.env.TEST_TARGET}.accept`, @@ -130,8 +136,16 @@ async function main( ); } else { console.error(red(`The following goldens are outdated:`)); - outdatedGoldens.forEach((name) => console.info(`- ${name}`)); + outdatedGoldens.forEach(({name}) => console.info(`- ${name}`)); console.info(); + + console.error(red(`Diffs:`)); + outdatedGoldens.forEach(({name, diff}) => { + console.error(`\n--- Diff for ${name} ---`); + console.error(diff); + }); + console.info(); + console.info( yellow( `The goldens can be updated by running:\n - bazel run ${process.env.TEST_TARGET}.accept`, diff --git a/bazel/package.json b/bazel/package.json index 2209cbf511..bc11d28287 100644 --- a/bazel/package.json +++ b/bazel/package.json @@ -2,6 +2,7 @@ "name": "@devinfra/bazel", "dependencies": { "@microsoft/api-extractor": "7.58.2", + "diff": "^9.0.0", "@types/babel__core": "7.20.5", "@types/browser-sync": "2.29.1", "@types/node": "24.12.2", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index d4e7901fa6..eb2c704292 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -239,6 +239,9 @@ importers: browser-sync: specifier: 3.0.4 version: 3.0.4(bufferutil@4.1.0)(utf-8-validate@6.0.6) + diff: + specifier: ^9.0.0 + version: 9.0.0 get-tsconfig: specifier: 4.14.0 version: 4.14.0 @@ -3416,6 +3419,10 @@ packages: resolution: {integrity: sha512-DPi0FmjiSU5EvQV0++GFDOJ9ASQUVFh5kD+OzOnYdi7n3Wpm9hWWGfB/O2blfHcMVTL5WkQXSnRiK9makhrcnw==} engines: {node: '>=0.3.1'} + diff@9.0.0: + resolution: {integrity: sha512-svtcdpS8CgJyqAjEQIXdb3OjhFVVYjzGAPO8WGCmRbrml64SPw/jJD4GoE98aR7r25A0XcgrK3F02yw9R/vhQw==} + engines: {node: '>=0.3.1'} + discontinuous-range@1.0.0: resolution: {integrity: sha512-c68LpLbO+7kP/b1Hr1qs8/BJ09F5khZGTxqxZuhzxpmwJKOgRFHJWIb9/KmqnqHhLdO55aOxFH/EGBvUQbL/RQ==} @@ -9502,6 +9509,8 @@ snapshots: diff@8.0.4: {} + diff@9.0.0: {} + discontinuous-range@1.0.0: {} dot-prop@5.3.0: