Skip to content

Test: cover CJS/ESM module-type resolution in the dev AgentLoader - #778

Open
AmaadMartin wants to merge 1 commit into
mainfrom
fix/agent-loader-test-package-json-module-type
Open

Test: cover CJS/ESM module-type resolution in the dev AgentLoader#778
AmaadMartin wants to merge 1 commit into
mainfrom
fix/agent-loader-test-package-json-module-type

Conversation

@AmaadMartin

@AmaadMartin AmaadMartin commented Aug 7, 2026

Copy link
Copy Markdown
Owner

Please ensure you have read the contribution guide before creating a pull request.

Link to Issue or Description of Change

  1. Link to an existing issue (if applicable):

N/A

  1. Or, if no issue exists, describe the change:

Problem: dev/test/utils/agent_loader_test.ts mocks file_utils.js with a factory that omits loadFileData, one of the seven exports agent_loader.ts imports. Vitest throws when the code under test reads that missing key, and the bare catch in getTypeFromPackageJson() turns the throw into FileModuleType.CJS. The suite therefore never evaluated the packageJson.type === 'module' comparison, never produced an .mjs outfile or format: 'esm', and never walked up to a parent directory. isFileExists was also mocked to () => true, so every directory looked like it held a package.json.

Solution: I added loadFileData to the mock factory and gave isFileExists and loadFileData implementations that read the real fixture tree, matching how isFile, isFolderExists and removeFolder are already mocked in the same beforeEach. Five new tests pin each branch of module-type resolution. No production file changes: the loader is correct, the harness was not.

Evidence for the claim above. I added a probe to the catch in getTypeFromPackageJson on the base commit and ran the suite. The probe fired 36 times, and every message was [vitest] No "loadFileData" export is defined on the "../../src/utils/file_utils.js" mock. — never a real package.json problem. After the change the probe fires once, on the malformed-package.json test, with a genuine SyntaxError.

Collision check. I listed the open PRs on the fork and read the file lists of the 14 that touch agent_loader, AgentFile or file_utils (#755, #733, #731, #726, #725, #708, #703, #674, #664, #662, #653, #633, #511, #480, #457). None adds loadFileData to the mock factory and none covers module-type resolution. #653 passes moduleType: FileModuleType.ESM explicitly, which short-circuits the detection this PR covers. Twelve of them edit the same test file for unrelated reasons, so expect textual conflicts, but no duplicated work.

Testing Plan

Unit Tests:

  • I have added or updated unit tests for my change.
  • All unit tests pass locally.

npx vitest run --project unit:dev dev/test/utils/agent_loader_test.ts reports 36 passed, up from 31. The 31 existing tests keep their exact assertions.

Mutation proof. I broke getTypeFromPackageJson six ways and re-ran the suite each time.

Mutation Edit Result
MutA the type === 'module' ternary -> return FileModuleType.CJS; 2 failed / 34 passed — kills the ESM and parent-walk tests
MutB the same ternary -> return FileModuleType.ESM; 13 failed / 23 passed — kills the CJS test plus the 12 existing AgentFile tests
MutC delete the try/catch, leaving the loadFileData call bare 1 failed / 35 passed — kills the malformed-package.json test
MutD return getTypeFromPackageJson(parentDir); -> return FileModuleType.CJS; 1 failed / 35 passed — kills the parent-walk test
MutE the root stop -> return FileModuleType.ESM; 1 failed / 35 passed — kills the root-stop test
MutH drop loadFileData from the mock factory again 36 failed / 0 passed — the harness fix is load-bearing

MutA failure message:

AssertionError: expected { …(10) } to match object { …(2) }
- Expected
+ Received
  {
-   "format": "esm",
-   "outfile": "/tmp/agent-loader-output-testoymHQ8/esm_agent.mjs",
+   "format": "cjs",
+   "outfile": "/tmp/agent-loader-output-testoymHQ8/esm_agent.cjs",
  }

MutB is the answer to whether the harness repair matters for the existing tests. Before this change those 12 tests passed under every mutation of that comparison, because they never reached it.

Coverage. New lines are test code. dev/src/utils/agent_loader.ts, measured from this suite alone, goes from 82.26% statements / 82.40% branches to 84.18% / 85.38%. Every statement and branch in getTypeFromPackageJson (agent_loader.ts:589-612) is now executed; the ESM arm runs twice and the catch and the root stop run once each.

Manual End-to-End (E2E) Tests:

From the repo root on this branch:

npm ci
npm run build
npx vitest run --project unit:dev dev/test/utils/agent_loader_test.ts   # 36 passed
npx vitest run --project unit:dev                                      # 249 passed, 1 pre-existing failure
npm run lint                                                           # clean
npm run format:check                                                   # clean

The one failure in the full unit:dev run is cli_create_test.ts > createAgent > Interactive Mode > should handle Vertex AI selection with gcloud defaults. It fails the same way on a clean checkout of the base commit with this change stashed, because this machine has gcloud defaults configured. It is unrelated to this PR and I did not touch it.

npx tsc --noEmit reports 287 errors on this branch and 287 on the base commit, none of them in dev/test/utils/agent_loader_test.ts. Those pre-existing errors are being cleared by other PRs.

CI result. All three matrix legs ran this file and logged unit:dev dev/test/utils/agent_loader_test.ts (36 tests) passing. run-tests (ubuntu-latest) is green. run-tests (macos-latest) fails on tests/integration/app_loader/app_loader_test.ts, which times out at 40000ms; run-tests (windows-latest) was then cancelled by the matrix fail-fast. That macOS timeout also happens on an unmodified copy of the base commit (run 31170814985, same job, same test, same timeout), so this PR did not cause it. #664 tracks the fix, and I left it alone.

Checklist

  • I have read the CONTRIBUTING.md document.
  • I have performed a self-review of my own code.
  • I have commented my code, particularly in hard-to-understand areas.
  • I have added tests that prove my fix is effective or that my feature works.
  • New and existing unit tests pass locally with my changes.

The vi.mock factory for file_utils omitted loadFileData, so every read of
that export threw inside getTypeFromPackageJson. The bare catch there
turned the error into FileModuleType.CJS, which made the ESM branch and
the parent-directory walk dead code in this suite.

Complete the mock factory, give isFileExists and loadFileData faithful
filesystem implementations, and add five tests that pin each branch of
module-type resolution.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant