Skip to content

Fix six correctness defects in Swagger 2 generation and capturing mocks - #540

Closed
Smaug123 wants to merge 1 commit into
mainfrom
swagger-correctness-fixes
Closed

Fix six correctness defects in Swagger 2 generation and capturing mocks#540
Smaug123 wants to merge 1 commit into
mainfrom
swagger-correctness-fixes

Conversation

@Smaug123

@Smaug123 Smaug123 commented Jul 9, 2026

Copy link
Copy Markdown
Owner

Fixes six review findings, each with a failing test written and observed before the fix. The suite grows from 769 to 788 tests, all passing.

Swagger 2 parsing (SwaggerV2.fs)

  • Parse the response schema. Endpoint responses fed the whole Response Object to Definition.Parse, so inline {description, schema} responses degraded to Unspecified and generated Task<unit> clients that discard the body. Responses now go through Response.Parse (moved above SwaggerEndpoint) and use its schema; $ref responses are handled as before. Inline endpoint schemas (both responses and parameters) are also now seeded into type generation, so anonymous inline object schemas get generated types instead of crashing renderType — Gitea's /users/search, /orgs/{org}/teams/search and the two signing-key.gpg endpoints now return real types.
  • Represent default responses. Response keys were unconditionally Int32.Parsed, so any valid spec with a default response aborted generation. Responses are now keyed by a ResponseKey DU (Code of int | Default), and the client generator explicitly ignores Default when selecting the success response.

Swagger 2 client generation (SwaggerClientGenerator.fs)

  • Honour int64 integer formats. "format": "int64" now renders as int64 in both defnToType and renderType instead of narrowing 64-bit IDs to int (e.g. IssueGetComments now takes index : int64).
  • Use Consumes for the request media type. Content-Type was derived from Produces and Consumes was dropped: Gitea's renderMarkdownRaw (consumes text/plain, produces text/html) sent StringContent tagged text/html. Content-Type now comes from Consumes and Produces is translated to an Accept header, both as full MIME strings; endpoint-level lists override the spec-global ones, and an ambiguous multi-entry global list prefers application/json or fails loudly. This made the StartsWith active pattern dead, so Text.fs is deleted.
  • Preserve optional parameters. SwaggerParameter.Required was parsed and discarded, so every generated parameter was mandatory. Query parameters without required: true are now option-typed (path parameters stay required per the spec; optional bodies are not modelled), e.g. AdminCronList(page : int option, limit : int option).

HTTP client generation (HttpClientGenerator.fs)

  • Option-typed [<Query>] parameters are supported: the query string is computed at runtime as a List.choose/String.concat over per-parameter string option components and appended (with separator) only when nonempty, so None is omitted and an all-None URL stays bare. Required-only query strings are byte-identical to before. (The joining lambda is deliberately not id, which Gitea methods shadow with a parameter of that name.)

Capturing mock generation (CapturingInterfaceMockGenerator.fs)

  • Property getters invoked the configured function but logged nothing, so Calls.Prop1/Calls.Prop2 stayed empty forever. They now record into Calls under a lock, mirroring method implementations.

Not addressed (pre-existing, noted during review)

List-typed query parameters (e.g. NotifyGetList's status_types : string list) are stringified with .ToString(), producing F# list syntax in the URL; that fix is coming separately.

🤖 Generated with Claude Code

Swagger 2 parsing (SwaggerV2.fs):
- Endpoint responses were fed whole Response Objects to Definition.Parse,
  so inline {description, schema} responses degraded to Unspecified and
  generated Task<unit> clients. Responses now go through Response.Parse
  and use its schema; $refs are handled as before. Inline endpoint
  schemas (responses and parameters) are also now seeded into type
  generation, so anonymous inline object schemas get generated types.
- Response keys were unconditionally Int32.Parsed, so any spec with a
  "default" response aborted generation. Responses are now keyed by a
  ResponseKey DU (Code of int | Default), and the generator explicitly
  ignores Default when selecting the success response.

Swagger 2 client generation (SwaggerClientGenerator.fs):
- Integer formats were ignored; "format": "int64" now renders as int64
  instead of narrowing 64-bit IDs to int.
- The request Content-Type header was derived from Produces, and
  Consumes was dropped entirely. Content-Type now comes from Consumes
  and Produces is sent as the Accept header, both as full MIME strings
  (endpoint-level lists override the spec-global ones). This made the
  StartsWith active pattern dead, so Text.fs is deleted.
- SwaggerParameter.Required was parsed and discarded, making every
  parameter mandatory. Query parameters without required: true are now
  option-typed, and None is omitted from the URL.

HTTP client generation (HttpClientGenerator.fs):
- Option-typed [<Query>] parameters are supported: the query string is
  now computed at runtime and appended (with separator) only when
  nonempty, so a URL with all-None query parameters stays bare.

Capturing mock generation (CapturingInterfaceMockGenerator.fs):
- Property getters logged nothing; they now record into Calls under a
  lock, like methods do.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@Smaug123

Smaug123 commented Jul 9, 2026

Copy link
Copy Markdown
Owner Author

Split into individual PRs for review: #542#543#544#545#546 (stacked, in that order), plus #547 (independent, off main). The union of #546's branch and #547 is byte-identical to this branch. #541 remains as-is.

@Smaug123 Smaug123 closed this Jul 9, 2026
@Smaug123
Smaug123 deleted the swagger-correctness-fixes branch July 9, 2026 22:04
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