Skip to content

test: deduplicate the agent and openai test suites - #422

Open
LarsArtmann wants to merge 3 commits into
charmbracelet:mainfrom
LarsArtmann:dedupe-test-suites
Open

LarsArtmann wants to merge 3 commits into
charmbracelet:mainfrom
LarsArtmann:dedupe-test-suites

Conversation

@LarsArtmann

Copy link
Copy Markdown
Contributor

Stacked on #420. CI does not lint tests (run.tests: false is upstream's own setting), so this is a one-time manual pass: dupl run over the tests at the same 75-token threshold #420 uses for production code, fixing what is worth fixing without turning test linting on.

103 findings → 69, and the touched test files net −450 lines.

What was extracted

Setups only — no test cases were merged, no assertions moved out of the test that owns them:

  • agent_test.go / agent_stream_test.go: the repeated mock models became builders — twoStepToolCallModel (request tool, then answer; the image/audio/screenshot/metadata family), scriptedGenerateModel (ordered responses, fails on extra calls, exposes the call count as a getter so the one test that asserts it keeps asserting it), capturingGenerateModel + generateCapture (system-prompt/tool-choice/tool-name capture), verifyingToolCallModel, expectProviderDefinedToolModel, textAndToolCallModel, doneTextStream, streamToolCallStep, and streamingToolCallModel.
  • providers/openai/openai_test.go: the mock-server harness — newGenerateTestModel, generateAgainstMockServer, streamAgainstMockServer, generateWithUsage, and testFunctionTool — collapsing the "should send X setting" family (generate and streaming variants) to one call plus its specific assertion.

json_test.go and tool_test.go gained small round-trip/media assertion helpers for their flagged pairs.

What is deliberately left (the remaining 69)

  • openai message-conversion subtests: the prompt construction is the test.
  • jsonrepair pairs: parallel repair corpora, like prompttest in chore: enable the dupl linter and remove the duplication it reports #420.
  • providertests cross-provider scaffolds and the anthropic/openaicompat buckets: shared-suite infrastructure worth its own pass.
  • sibling rows inside one family (e.g. the two usage tests): the residual similarity is the t.Run scaffolding itself at this threshold.

Verification

  • go test ./... -count=1 green except providers/kronk (the local libffi.so.8 panic, unchanged; go test -c compiles).

  • gofmt, gofumpt, go vet, and the repo golangci-lint run (production, dupl at 75): clean.

  • dupl-with-tests re-measured after each file; the two sibling-row residuals are disclosed above rather than nolint'd.

  • I have read CONTRIBUTING.md.

  • I have created a discussion that was approved by a maintainer (for new features).

💘 Generated with Crush

…formats

Characterization tests for the code the dedup PRs refactor next:
object had no tests at all; the content codecs' provider metadata/options
decode and openrouter's reasoning format labels were only pinned
implicitly. Each test fails when the branch it covers is disabled.
dupl was not part of the enabled linter set, so clone detection never ran
in CI. It now runs at a 75-token threshold, because the default 150 only
catches whole-function copies, and the tree is clean at 75: 19 findings,
12 of them real copies.

- content_json: the four text and reasoning codecs share one decoder, and
  the two tool-part marshals share one encoder.
- object: the end-of-stream emission becomes one helper, and
  EmitParsedObject is exported so providers can drop their own copies.
- openai: both JSON-mode streamers call EmitParsedObject instead of
  inlining the parse, validate, repair and emit block.
- kronk: the usage fold is shared by Generate and Stream.
- Two single-text-part fast paths stay mirrored, with the reason inline.

New tests cover object streaming, the codec decoding and the openrouter
reasoning label.
dupl ran manually over the tests at the same 75-token threshold charmbracelet#420 uses
for production code (CI still excludes tests; that is upstream's own
run.tests: false). 103 findings became 69, and the test trees shrank by
~450 lines, by extracting setups rather than merging test cases.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant