test: check the real API, and detect the spec drifting under a published version - #13
Merged
Conversation
…hed version Every suite in this repo proves a request body is legal against a vendored snapshot. None prove the API honors the option, or that the snapshot still matches reality — the gap that let the 2.x types rot for two months while all 18 tests stayed green. 3.0.0 is published now, so that gap is a live risk rather than a latent one. tests/live/ sends real requests and validates the responses with the same ajv validators the contract suite uses. A response that stops matching the vendored spec therefore fails here even though nothing in this repo changed, which makes this the upstream drift detector the parity tests cannot be: those read a pinned snapshot and only move when somebody runs `pnpm spec:refresh`. Verified load-bearing rather than assumed. Adding a bogus required property to SearchResponse in the vendored spec (via a YAML round-trip, so the document stays valid) makes the drift test fail; restoring it makes it pass. A first attempt at that proof broke the YAML and silently ran no tests, which is worth knowing if someone repeats it. The 16 tests cover what shipped in 3.0.0 and had never touched a real API: that a query-only body is accepted and returns the same shape and result count as one restating the old fast/US/en-US defaults, that all ten new search options are accepted rather than 400ing the way deferDataRetrieval did, that includeDomains and excludeDomains actually filter, that both contentFormat values are honored and populate the matching payload field, and that quoteOnly returns a price with no content while an over-ceiling maxRows clamps instead of failing. Run against a live API: 16 passed in 14s. Guardrails, because this suite costs money: - Excluded from `pnpm test` by vitest.config.ts and included only by vitest.live.config.ts, so it cannot run by accident. - Skips without a key instead of failing, so a contributor with no key sees no red. - Scheduled weekly plus manual dispatch, never on pull_request: a fork cannot read secrets, so it would fail for every outside contributor. - Serial with one retry, since the tests compare responses across requests and Tako throttles per key. - No host or token literal is committed; the base url comes from the environment and defaults to the same host the SDK does. Also fixes lint:package, added in the previous change, which assumed dist/ already existed. CI hid it because `pnpm build` runs first, but on a fresh checkout it reported five "file does not exist" errors that look like packaging faults and are not. It now builds first, matching test:package. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
ignaeche
approved these changes
Aug 4, 2026
jed326
approved these changes
Aug 4, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Why
3.0.0 is published. Every suite in this repo proves a request body is legal against a vendored snapshot of the OpenAPI document. None prove the API honors the option, or that the snapshot still matches reality — precisely the gap that let the 2.x types rot for two months while all 18 tests stayed green. With a published version depending on it, that is a live risk rather than a latent one.
tests/live/closes it from the other side: real requests, validated with the same ajv validators the contract suite uses. A response that stops matching the vendored spec fails here even though nothing in this repo changed — which makes this the upstream drift detector the parity tests cannot be. Those read a pinned snapshot and only move when someone runspnpm spec:refresh.Verified load-bearing, not assumed
Adding a bogus required property to
SearchResponsein the vendored spec, via a YAML round-trip so the document stays valid:A first attempt at that proof broke the YAML and silently ran no tests — worth knowing if anyone repeats it, because "no tests" reads as green at a glance.
What the 16 tests cover
All of this shipped in 3.0.0 and had never touched a real API. Run against a live API: 16 passed in 14s.
fast/US/en-USdefaults. This is the check that matters most — 3.0.0 stopped sending those three on the evidence that the spec documents them, and "the document says X is the default" is a different claim from "the API applies X when the key is absent."deferDataRetrievalsilently did.includeDomains/excludeDomainsactually filter. An empty result set counts as a pass; a leak is the failure.contentFormatvalues are honored and populate the matching payload field.quoteOnlyreturns a price with no content, and an over-ceilingmaxRowsclamps rather than failing — the behavior the README warns about and nothing could previously verify.Guardrails, because this suite costs money
pnpm testbyvitest.config.ts; included only byvitest.live.config.ts. Verified: the default run is still 8 files / 84 tests with no live file.pull_request. Weekly cron plus manual dispatch only — a fork cannot read secrets, so a PR trigger would fail for every outside contributor.Also fixes a defect I shipped last time
lint:package, added in #11, assumeddist/already existed. CI hid it becausepnpm buildruns first, but on a fresh checkout it reported five "file does not exist" errors that look like packaging faults and are not — I hit it setting up this worktree. It now builds first, matchingtest:package.Verification
typecheck, conformance compile,lint:package,test:packageall clean — the last two now from adist-less treeTAKO_API_KEYin repo secrets plusLIVE_TESTS_ENABLED=truein repo variables before it willWhat this does not do
No routing eval. Tool descriptions changed in #9 and again in #11 with zero measurement; this suite tests the API, not which tool a model picks. Still the largest untested surface, and it needs a fixture set and a model budget rather than a slot in this PR.
nodeIds/strictare covered for acceptance only — real pinning needs ids from/v1/graph/search, which this SDK does not wrap, and the spec 400s on a malformed id.🤖 Generated with Claude Code