From cc69c3e6e1e4e29bf614041bad1d8cac0fc24f7a Mon Sep 17 00:00:00 2001 From: Amaad Martin Date: Wed, 29 Jul 2026 02:45:03 -0700 Subject: [PATCH 1/7] fix(integrations): assert version against package.json, not a literal integrations/test/version_test.ts hardcoded `expect(version).toBe('1.3.0')` while integrations/src/version.ts exports '1.4.0', so the test is currently red. It went stale unnoticed because the vitest project that owns it (`unit:integrations`) is invoked by no npm script and no workflow, so the file has never actually run. Bumping the literal to '1.4.0' would only re-rot on the next release: the release automation rewrites integrations/src/version.ts (via the x-release-please-version annotation) but never touches test literals. Assert against the version declared in integrations/package.json instead. Both sides are updated in the same release commit, so the assertion is self-maintaining, and it guards the invariant actually worth guarding: the exported constant must not drift from the published package version. --- integrations/test/version_test.ts | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/integrations/test/version_test.ts b/integrations/test/version_test.ts index 9f5a6900a..d2db73df0 100644 --- a/integrations/test/version_test.ts +++ b/integrations/test/version_test.ts @@ -6,9 +6,10 @@ import {version} from '@google/adk-integrations'; import {describe, expect, it} from 'vitest'; +import packageJson from '../package.json' with {type: 'json'}; describe('version', () => { - it('should return the correct version', () => { - expect(version).toBe('1.3.0'); + it('should match the version declared in package.json', () => { + expect(version).toBe(packageJson.version); }); }); From a2c057a8b11990a3de813fa224b72ad79c995f81 Mon Sep 17 00:00:00 2001 From: Amaad Martin Date: Wed, 29 Jul 2026 02:45:14 -0700 Subject: [PATCH 2/7] fix: run the unit:integrations vitest project from the root test scripts vitest.config.ts declares a `unit:integrations` project owning integrations/test/**/*_test.ts, but the name appeared nowhere else in the repository: no npm script and no workflow invoked it, so those tests never ran. validation.yaml runs `npm run test:coverage` and cross-language-integration.yml runs `npm run test:cross-language`, which between them reached every project except this one. Add `--project unit:integrations` to `test`, `test:unit` and `test:coverage`, positioned after `unit:dev` to match the declaration order in vitest.config.ts. No `test:integrations` script is added on purpose: it would sit one character from the existing `test:integration` (which runs the unrelated `integration` project over tests/integration/) and invite mistakes. `unit:core` and `unit:dev` have no individual scripts either. The coverage thresholds are deliberately left untouched. coverage.include already lists integrations/src/**/*.ts and coverage.all defaults to true, so those files were already in the denominator scored at 0%; running the project only adds to the numerator. Measured over `unit:core + unit:dev` (v8), All files goes 88.94/88.11/89.58/88.94 to 88.95/88.14/89.73/88.95 statements/branches/functions/lines - every metric up. --- package.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/package.json b/package.json index 86cee8241..d5b10ea5d 100644 --- a/package.json +++ b/package.json @@ -24,12 +24,12 @@ "docs:generate": "typedoc", "docs:serve": "http-server api-reference/typescript", "docs:check": "typedoc --emit none --treatWarningsAsErrors", - "test": "vitest --project unit:core --project unit:dev --project integration --project e2e", - "test:unit": "vitest --project unit:core --project unit:dev", + "test": "vitest --project unit:core --project unit:dev --project unit:integrations --project integration --project e2e", + "test:unit": "vitest --project unit:core --project unit:dev --project unit:integrations", "test:integration": "vitest --project integration", "test:e2e": "vitest --project e2e", "test:cross-language": "vitest --project cross-language", - "test:coverage": "vitest run --project unit:core --project unit:dev --project integration --project e2e --coverage", + "test:coverage": "vitest run --project unit:core --project unit:dev --project unit:integrations --project integration --project e2e --coverage", "prepare": "husky" }, "workspaces": [ From ce0cbd8835c90836e3722de45d97201650ba3d0c Mon Sep 17 00:00:00 2001 From: Amaad Martin Date: Fri, 31 Jul 2026 21:53:57 -0700 Subject: [PATCH 3/7] chore(test): distinguish the unit:integrations and integration vitest projects The two project names differ by one character and by scope: unit:integrations owns the integrations/ workspace package, integration owns the cross-component suite in tests/integration/. That similarity is part of why the former was overlooked by the root test scripts for three releases. Comments only; no project definition, glob, or threshold changes. --- vitest.config.ts | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/vitest.config.ts b/vitest.config.ts index 0e27b0364..9635af4a6 100644 --- a/vitest.config.ts +++ b/vitest.config.ts @@ -48,6 +48,10 @@ export default defineConfig({ }, { test: { + // Unit tests for the `integrations/` workspace package + // (`@google/adk-integrations`). Distinct from the `integration` + // project below, which runs the cross-component suite in + // `tests/integration/`. name: 'unit:integrations', environment: 'node', alias: { @@ -62,6 +66,9 @@ export default defineConfig({ }, { test: { + // Cross-component tests in `tests/integration/`. Distinct from the + // `unit:integrations` project above, which unit-tests the + // `integrations/` workspace package. name: 'integration', environment: 'node', alias: { From a9358eca256f652d5e0f9337b033290921f56403 Mon Sep 17 00:00:00 2001 From: Amaad Martin Date: Sat, 1 Aug 2026 13:27:45 -0700 Subject: [PATCH 4/7] chore(test): keep one project-name comment instead of a mirrored pair The disambiguation between unit:integrations and integration was written twice, once from each side, and each copy restated the include glob two lines below it. Keep the comment on unit:integrations -- the project this change wires in, and the less obvious of the two -- and drop the mirror. --- vitest.config.ts | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/vitest.config.ts b/vitest.config.ts index 9635af4a6..85b330b86 100644 --- a/vitest.config.ts +++ b/vitest.config.ts @@ -48,10 +48,8 @@ export default defineConfig({ }, { test: { - // Unit tests for the `integrations/` workspace package - // (`@google/adk-integrations`). Distinct from the `integration` - // project below, which runs the cross-component suite in - // `tests/integration/`. + // Unit-tests the `integrations/` package; the `integration` project + // below owns the cross-component suite in `tests/integration/`. name: 'unit:integrations', environment: 'node', alias: { @@ -66,9 +64,6 @@ export default defineConfig({ }, { test: { - // Cross-component tests in `tests/integration/`. Distinct from the - // `unit:integrations` project above, which unit-tests the - // `integrations/` workspace package. name: 'integration', environment: 'node', alias: { From 20e6644752460cc72cb9ff0ffba373e7ecd31b10 Mon Sep 17 00:00:00 2001 From: Amaad Martin Date: Sat, 1 Aug 2026 15:09:16 -0700 Subject: [PATCH 5/7] chore(test): drop the out-of-scope vitest.config.ts comment The approved spec scopes this change to the three root test-script strings in package.json and the integrations version test, touching vitest.config.ts "at most" for the coverage thresholds block -- whose expected outcome is no edit at all. The project-naming comment added earlier sits outside that ceiling, so it is removed and the diff is now exactly the two files the fix requires. No behaviour change: the comment never affected project resolution. --- vitest.config.ts | 2 -- 1 file changed, 2 deletions(-) diff --git a/vitest.config.ts b/vitest.config.ts index 85b330b86..0e27b0364 100644 --- a/vitest.config.ts +++ b/vitest.config.ts @@ -48,8 +48,6 @@ export default defineConfig({ }, { test: { - // Unit-tests the `integrations/` package; the `integration` project - // below owns the cross-component suite in `tests/integration/`. name: 'unit:integrations', environment: 'node', alias: { From 940babf5b4655d51b63f8bad343e2d28fb38c351 Mon Sep 17 00:00:00 2001 From: Amaad Martin Date: Sun, 2 Aug 2026 08:22:47 -0700 Subject: [PATCH 6/7] test(integrations): pin the web entry point to the node public surface integrations/build.js compiles src/index.ts and src/index_web.ts into separate published artifacts -- dist/esm and dist/cjs from the first, the dist/web bundle the package's browser field points at from the second -- so an export added to one entry point and forgotten in the other ships a browser bundle silently missing the symbol. Nothing guarded that, and index_web.ts was the one integrations source file no test reached, sitting at 0% coverage even after the project was wired into the root scripts. Assert the two entry points expose the same export names and the same version binding. The key-set assertion is guarded against passing vacuously if both entry points ever resolve to nothing. --- integrations/test/index_web_test.ts | 31 +++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) create mode 100644 integrations/test/index_web_test.ts diff --git a/integrations/test/index_web_test.ts b/integrations/test/index_web_test.ts new file mode 100644 index 000000000..3af197699 --- /dev/null +++ b/integrations/test/index_web_test.ts @@ -0,0 +1,31 @@ +/** + * @license + * Copyright 2026 Google LLC + * SPDX-License-Identifier: Apache-2.0 + */ + +import {describe, expect, it} from 'vitest'; +import * as nodeEntry from '../src/index.js'; +import * as webEntry from '../src/index_web.js'; + +/** + * `build.js` compiles `src/index.ts` and `src/index_web.ts` into separate + * published artifacts (`dist/esm` + `dist/cjs`, and the `dist/web` bundle the + * `browser` field points at), so an export added to one entry point and + * forgotten in the other ships a browser bundle silently missing the symbol. + * Both entry points are imported by relative path because + * `integrations/package.json` declares only the `"."` subpath export, leaving + * `index_web` unreachable by package specifier. + */ +describe('index_web', () => { + it('exposes the same public surface as the node entry point', () => { + const nodeExports = Object.keys(nodeEntry).sort(); + + expect(nodeExports).not.toHaveLength(0); + expect(Object.keys(webEntry).sort()).toEqual(nodeExports); + }); + + it('re-exports the same version binding as the node entry point', () => { + expect(webEntry.version).toBe(nodeEntry.version); + }); +}); From 05cfab7f736a4260c89c2c113eb555069a37256c Mon Sep 17 00:00:00 2001 From: Amaad Martin Date: Tue, 4 Aug 2026 00:54:29 -0700 Subject: [PATCH 7/7] revert(test): drop the integrations web entry-point parity test The plan scoped this change to three edits and named index_web.ts coverage as out of scope. The test also asserted the wrong invariant: it required the web entry point to export exactly the node surface, but core/src/index_web.ts re-exports only ./common.js against a 60-line core/src/index.ts, because node-only symbols such as GcsArtifactService and UnsafeLocalCodeExecutor must not reach a browser bundle. The surfaces are meant to diverge, so the first node-only export added to integrations would have failed the test and pushed the wrong fix. --- integrations/test/index_web_test.ts | 31 ----------------------------- 1 file changed, 31 deletions(-) delete mode 100644 integrations/test/index_web_test.ts diff --git a/integrations/test/index_web_test.ts b/integrations/test/index_web_test.ts deleted file mode 100644 index 3af197699..000000000 --- a/integrations/test/index_web_test.ts +++ /dev/null @@ -1,31 +0,0 @@ -/** - * @license - * Copyright 2026 Google LLC - * SPDX-License-Identifier: Apache-2.0 - */ - -import {describe, expect, it} from 'vitest'; -import * as nodeEntry from '../src/index.js'; -import * as webEntry from '../src/index_web.js'; - -/** - * `build.js` compiles `src/index.ts` and `src/index_web.ts` into separate - * published artifacts (`dist/esm` + `dist/cjs`, and the `dist/web` bundle the - * `browser` field points at), so an export added to one entry point and - * forgotten in the other ships a browser bundle silently missing the symbol. - * Both entry points are imported by relative path because - * `integrations/package.json` declares only the `"."` subpath export, leaving - * `index_web` unreachable by package specifier. - */ -describe('index_web', () => { - it('exposes the same public surface as the node entry point', () => { - const nodeExports = Object.keys(nodeEntry).sort(); - - expect(nodeExports).not.toHaveLength(0); - expect(Object.keys(webEntry).sort()).toEqual(nodeExports); - }); - - it('re-exports the same version binding as the node entry point', () => { - expect(webEntry.version).toBe(nodeEntry.version); - }); -});