Skip to content

docs: add option tables, fix 27 inaccuracies, add API sync CI test#343

Merged
erraggy merged 4 commits intomainfrom
docs/builder-walker-option-tables
Feb 22, 2026
Merged

docs: add option tables, fix 27 inaccuracies, add API sync CI test#343
erraggy merged 4 commits intomainfrom
docs/builder-walker-option-tables

Conversation

@erraggy
Copy link
Owner

@erraggy erraggy commented Feb 22, 2026

Summary

  • Add comprehensive option tables to builder and walker deep_dive.md files (8 new builder tables, 2 new walker tables), removing 58 exception entries from doctest
  • Fix 27 code example inaccuracies found via full audit across whitepaper, developer guide, README, and example READMEs (nonexistent functions, wrong signatures, internal package refs, deprecated usage)
  • Add TestDocCodeExampleAPISync CI test that scans 93 markdown files and verifies every package.Symbol reference in Go code examples against AST-extracted symbol tables for all 12 public packages

Closes #342

Details

Option Tables (commit 1)

Package Tables Added
builder Tag, Server, Server Variable, Response Detail, Response-Level Operation, Request Body Detail, Advanced Operation, Parameter Validation, Generic Naming, Schema Field Processing
walker Handler Registration (21 entries), Input Options

Inaccuracies Fixed (commit 2)

Category Count Examples
Nonexistent functions 7 WithDocument, ValidateParsed, Build, ToYAML, ResponseConfig
Wrong signatures 5 WithParameter positional args, WithRequestBody arg order, WithCollisionHandlerFor reversed
Internal package refs 2 severity.SeverityCriticaldiffer.SeverityCritical
Deprecated usage 2 WithMaxDepthWithMaxSchemaDepth
Pointer/value mismatches 2 WithParsed(result)WithParsed(*result)
Method vs function 2 joiner.WriteResult()j.WriteResult()
Other 7 Variadic args, renamed constants, entire code block rewrites

CI Verification Test (commit 3)

  • TestDocCodeExampleAPISync uses go/ast to build symbol tables for all 12 public packages
  • Scans all user-facing markdown files for Go fenced code blocks
  • Verifies every qualified reference (pkg.Symbol) exists as an exported symbol
  • Flags internal package references (e.g., severity.*, httputil.*)
  • Exception mechanism with staleness checks for intentional edge cases
  • Adds 93 new subtests (one per markdown file)

Test plan

  • make check passes (8498 tests)
  • TestDocCodeExampleAPISync passes with 93 subtests
  • TestDeepDiveOptionTables passes (58 fewer exceptions)
  • Security review: clean, no findings
  • Verify intentional breakage detected: introduced WithNonexistent in README.md, test caught both occurrences with file:line and clear message

🤖 Generated with Claude Code

erraggy and others added 3 commits February 21, 2026 19:05
Add comprehensive option tables to builder/deep_dive.md (8 new tables:
Tag, Server, Server Variable, Response Detail, Request Body Detail,
Advanced Operation, Parameter Validation, Generic Naming) and
walker/deep_dive.md (handler registration table, input options table).

Remove 58 sourceException entries from the doctest now that all builder
and walker With* functions are formally documented in option tables.

Closes #342

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Full audit found nonexistent functions (WithDocument, ValidateParsed,
Build, ToYAML, ResponseConfig), wrong signatures (WithParameter,
WithRequestBody, WithCollisionHandlerFor args reversed), internal
package refs (severity.SeverityCritical), deprecated usage (WithMaxDepth),
and pointer/value mismatches (WithParsed missing dereference).

Files fixed: whitepaper, developer-guide, benchmarks, breaking-changes,
README, example READMEs (quickstart, walker, workflows, programmatic-api),
and builder/walker deep_dive review improvements.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
New TestDocCodeExampleAPISync test in internal/doctest/ scans all
documentation markdown files (93 files) and verifies that Go code
examples reference symbols that actually exist in the public packages.

Catches: renamed/removed functions, nonexistent types/constants,
internal package references (e.g., severity.SeverityCritical).
Uses go/ast to build symbol tables for all 12 public packages.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@coderabbitai
Copy link

coderabbitai bot commented Feb 22, 2026

📝 Walkthrough

Walkthrough

This PR updates documentation and examples to reflect numerous public API changes (option-based APIs, WithParsed usage, renamed symbols), adds comprehensive builder and walker option tables, and introduces a doctest that validates documentation code examples reference exported public symbols.

Changes

Cohort / File(s) Summary
Top-level README & examples
README.md, examples/..., examples/programmatic-api/..., examples/quickstart/README.md, examples/workflows/*
Replace Document-based options with Parsed-based options (e.g., WithDocument(result)WithParsed(*result)), update pipeline calls to option-style APIs (ValidateWithOptions, FixWithOptions, etc.), and adjust example callsites (variadic file paths, dereferenced parse results).
Builder docs & examples
builder/deep_dive.md, examples/programmatic-api/builder/README.md
Add extensive builder option tables (tag/server/response/request/operation/parameter/naming), update examples to option-pattern usage (WithServerDescription, WithResponseRef, BuildResult).
Walker docs & examples
walker/deep_dive.md, examples/walker/*
Add handler registration option tables (With*Handler, post-visit variants) and WalkWithOptions input options (WithFilePath, WithParsed, WithMaxSchemaDepth, WithContext); update example usages (WithMaxDepth → WithMaxSchemaDepth, handler signatures).
Developer & whitepaper docs
docs/developer-guide.md, docs/whitepaper.md, docs/breaking-changes.md
Document public API signature changes (joiner variadic file paths, reordered collision handler args, builder renames like WithOperationDescription→WithDescription, parameter renames), update severity constant usage (severity.SeverityCriticaldiffer.SeverityCritical) and public naming constants.
Examples: programmatic & workflows
examples/programmatic-api/..., examples/workflows/*, examples/walker/reference-collector/*
Adjust examples to new method names and signatures (e.g., BuildResult, j.WriteResult, variadic WithFilePaths, dereferenced WithParsed invocations, log change in version-migration example).
Documentation tests
internal/doctest/doc_api_sync_test.go, internal/doctest/doc_test.go
Add new doctest TestDocCodeExampleAPISync that verifies fenced Go examples reference exported public symbols; remove builder/walker exceptions in existing doc tests to require table coverage.
Minor docs edits
builder/deep_dive.md, walker/deep_dive.md, other md files
Several markdown-only edits: new option tables, added examples, small wording and code-snippet adjustments.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related PRs

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title accurately describes the main changes: adding option tables to deep_dive files, fixing code example inaccuracies, and adding a CI test for API documentation sync.
Description check ✅ Passed The description comprehensively explains the PR objectives with clear sections on option tables, inaccuracies fixed, and the new CI test, directly relating to the changeset.
Linked Issues check ✅ Passed The PR fulfills issue #342's objectives: adds comprehensive option tables to builder and walker deep_dive.md, removes 58 exception entries, fixes 27 code example inaccuracies across documentation files, and adds TestDocCodeExampleAPISync CI test.
Out of Scope Changes check ✅ Passed All changes remain within scope: builder/walker deep_dive documentation, code example fixes across READMEs and docs, doctest exception removal, and new documentation-validation CI test per issue #342.
Docstring Coverage ✅ Passed Docstring coverage is 85.71% which is sufficient. The required threshold is 80.00%.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
  • 📝 Generate docstrings (stacked PR)
  • 📝 Generate docstrings (commit on current branch)
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch docs/builder-walker-option-tables

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@codecov
Copy link

codecov bot commented Feb 22, 2026

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 84.72%. Comparing base (3c4c769) to head (a4e7402).
⚠️ Report is 1 commits behind head on main.

Additional details and impacted files
@@           Coverage Diff           @@
##             main     #343   +/-   ##
=======================================
  Coverage   84.72%   84.72%           
=======================================
  Files         193      193           
  Lines       27273    27273           
=======================================
  Hits        23107    23107           
  Misses       2847     2847           
  Partials     1319     1319           
🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 4

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (3)
examples/walker/reference-collector/main.go (1)

3-8: ⚠️ Potential issue | 🟡 Minor

Update the header comment to the renamed option.

The bullet list still says “WithMaxDepth” while the code uses WithMaxSchemaDepth. Please update the comment to avoid confusion.

Suggested comment tweak
-//   - Configure WithMaxDepth for schema traversal
+//   - Configure WithMaxSchemaDepth for schema traversal

Also applies to: 63-66

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@examples/walker/reference-collector/main.go` around lines 3 - 8, Update the
header comment bullets to reference the renamed option WithMaxSchemaDepth
instead of WithMaxDepth; change any occurrences in the top-of-file comment and
the later comment block around lines referencing the schema traversal option
(the comment that currently mentions WithMaxDepth) so they consistently mention
WithMaxSchemaDepth to match the code that uses the option.
examples/walker/security-audit/README.md (1)

78-86: ⚠️ Potential issue | 🟡 Minor

currentPathTemplate is undefined in the snippet.

Either show where it’s set, or use wc.PathTemplate directly so the snippet is self-contained.

Example tweak
-    if len(op.Security) == 0 && !isInternalPath(currentPathTemplate) {
+    if len(op.Security) == 0 && !isInternalPath(wc.PathTemplate) {
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@examples/walker/security-audit/README.md` around lines 78 - 86, The snippet
references an undefined variable currentPathTemplate; update the
walker.WithOperationHandler block to use the WalkContext path template
(wc.PathTemplate) or explicitly show where currentPathTemplate is set so the
example is self-contained — specifically change the condition that checks
!isInternalPath(currentPathTemplate) to use !isInternalPath(wc.PathTemplate) (or
add a preceding assignment for currentPathTemplate) so the logic around
op.Security and isInternalPath is valid and locatable in the
walker.WithOperationHandler handler.
docs/developer-guide.md (1)

1314-1359: ⚠️ Potential issue | 🟡 Minor

Add missing imports to the builder example code.

The example code uses log.Fatal(), fmt.Println(), and yaml.Marshal() but the import block is missing fmt, log, and the YAML package. Add these imports so the example compiles as shown:

Required import additions
 import (
+    "fmt"
+    "log"
     "net/http"
+
+    "go.yaml.in/yaml/v4"
     "github.com/erraggy/oastools/builder"
     "github.com/erraggy/oastools/parser"
 )
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@docs/developer-guide.md` around lines 1314 - 1359, The example is missing
imports for packages used later (fmt, log, and the YAML package) which breaks
compilation; update the import block that currently lists "net/http",
"github.com/erraggy/oastools/builder", and "github.com/erraggy/oastools/parser"
to also include fmt, log, and the YAML package you intend to use (e.g.,
"gopkg.in/yaml.v3" or "sigs.k8s.io/yaml") so calls like fmt.Println, log.Fatal,
and yaml.Marshal in the code that builds the spec (builder.New, spec.BuildOAS3,
yaml.Marshal(doc), fmt.Println(string(data)), log.Fatal(err)) resolve correctly.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@builder/deep_dive.md`:
- Around line 1266-1267: The builder currently restricts
WithParamExclusiveMinimum(bool) and WithParamExclusiveMaximum(bool) to boolean
flags which prevents emitting OAS 3.1+ numeric exclusive bounds; update these
builder methods to accept a numeric-or-bool type (e.g., interface{} or
float64|bool union pattern) and adjust the spec generation/serialization logic
that emits ExclusiveMinimum/ExclusiveMaximum so it outputs a number for OAS 3.1+
targets and a boolean for OAS 2.0/3.0; ensure input validation in
WithParamExclusiveMinimum/WithParamExclusiveMaximum enforces allowed types and
update any downstream code that consumes the builder to handle the new value
type, or alternatively add a clear note in the builder docs next to
WithParamExclusiveMinimum/WithParamExclusiveMaximum describing the current
limitation and supported OAS versions.

In `@examples/walker/reference-collector/README.md`:
- Around line 154-161: Update the README section header to reflect the new API
name: change the "MaxDepth Configuration" heading to something like "Max Schema
Depth" or "WithMaxSchemaDepth Configuration" so it matches the documented
function walker.WithMaxSchemaDepth used in the example (and any references to
walker.Walk(parseResult, walker.WithMaxSchemaDepth(50), ...)); ensure the header
wording clearly references WithMaxSchemaDepth to avoid mismatch between heading
and code.

In `@examples/workflows/README.md`:
- Around line 176-181: The example currently ignores the error from
parser.ParseWithOptions and then dereferences parsed (a *parser.ParseResult)
when calling fixer.FixWithOptions(fixer.WithParsed(*parsed)) and
validator.ValidateWithOptions(validator.WithParsed(*parsed)), which can panic if
parsing failed; update the snippet to check the returned error and the parsed
value before dereferencing (e.g., if err != nil or parsed == nil, log/return),
and only call FixWithOptions/ValidateWithOptions with fixer.WithParsed(*parsed)
and validator.WithParsed(*parsed) after confirming parsed is non-nil.

In `@README.md`:
- Around line 52-55: The snippet risks nil-pointer panics because
parser.ParseWithOptions may return a nil *parser.ParseResult; update the flow
around parser.ParseWithOptions (the result variable) to capture and check the
error and ensure result != nil before dereferencing or passing *result into
validator.ValidateWithOptions and fixer.FixWithOptions; if parsing fails, handle
or return the error (or log and exit) so validator.ValidateWithOptions and
fixer.FixWithOptions never receive a nil dereference of result.

---

Outside diff comments:
In `@docs/developer-guide.md`:
- Around line 1314-1359: The example is missing imports for packages used later
(fmt, log, and the YAML package) which breaks compilation; update the import
block that currently lists "net/http", "github.com/erraggy/oastools/builder",
and "github.com/erraggy/oastools/parser" to also include fmt, log, and the YAML
package you intend to use (e.g., "gopkg.in/yaml.v3" or "sigs.k8s.io/yaml") so
calls like fmt.Println, log.Fatal, and yaml.Marshal in the code that builds the
spec (builder.New, spec.BuildOAS3, yaml.Marshal(doc), fmt.Println(string(data)),
log.Fatal(err)) resolve correctly.

In `@examples/walker/reference-collector/main.go`:
- Around line 3-8: Update the header comment bullets to reference the renamed
option WithMaxSchemaDepth instead of WithMaxDepth; change any occurrences in the
top-of-file comment and the later comment block around lines referencing the
schema traversal option (the comment that currently mentions WithMaxDepth) so
they consistently mention WithMaxSchemaDepth to match the code that uses the
option.

In `@examples/walker/security-audit/README.md`:
- Around line 78-86: The snippet references an undefined variable
currentPathTemplate; update the walker.WithOperationHandler block to use the
WalkContext path template (wc.PathTemplate) or explicitly show where
currentPathTemplate is set so the example is self-contained — specifically
change the condition that checks !isInternalPath(currentPathTemplate) to use
!isInternalPath(wc.PathTemplate) (or add a preceding assignment for
currentPathTemplate) so the logic around op.Security and isInternalPath is valid
and locatable in the walker.WithOperationHandler handler.

Update the package comment and README heading to use the renamed
WithMaxSchemaDepth, missed during the rename in the prior commit.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
examples/walker/reference-collector/README.md (1)

104-124: ⚠️ Potential issue | 🟡 Minor

Documentation examples omit the empty-name guard present in main.go.

Both snippets apply extractSchemaName without checking whether the result is "". For $ref strings that don't follow the #/components/schemas/<name> pattern, extractSchemaName returns "", causing a silent empty-key entry in the map. The actual implementation in main.go (lines 73 and 81–84) guards against this in both places.

📝 Suggested fix for the Reference Tracking snippet
 walker.WithSchemaHandler(func(wc *walker.WalkContext, schema *parser.Schema) walker.Action {
     if schema.Ref != "" {
         schemaName := extractSchemaName(schema.Ref)
-        refs[schemaName] = append(refs[schemaName], wc.JSONPath)
+        if schemaName != "" {
+            refs[schemaName] = append(refs[schemaName], wc.JSONPath)
+        }
     }
     return walker.Continue
 })
📝 Suggested fix for the Array Items snippet
 if items, ok := schema.Items.(map[string]any); ok {
     if ref, ok := items["$ref"].(string); ok {
         schemaName := extractSchemaName(ref)
-        collector.SchemaRefs[schemaName] = append(collector.SchemaRefs[schemaName], wc.JSONPath+".items")
+        if schemaName != "" {
+            collector.SchemaRefs[schemaName] = append(collector.SchemaRefs[schemaName], wc.JSONPath+".items")
+        }
     }
 }
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@examples/walker/reference-collector/README.md` around lines 104 - 124, The
documentation examples call extractSchemaName and then append into refs or
collector.SchemaRefs without checking for an empty result; update the
walker.WithSchemaHandler snippet (where refs[schemaName] = append(...,
wc.JSONPath)) and the Array Items snippet (where
collector.SchemaRefs[schemaName] = append(..., wc.JSONPath+".items")) to first
verify schemaName := extractSchemaName(...) is not empty (schemaName != "")
before modifying the map, matching the empty-name guard used in main.go.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Outside diff comments:
In `@examples/walker/reference-collector/README.md`:
- Around line 104-124: The documentation examples call extractSchemaName and
then append into refs or collector.SchemaRefs without checking for an empty
result; update the walker.WithSchemaHandler snippet (where refs[schemaName] =
append(..., wc.JSONPath)) and the Array Items snippet (where
collector.SchemaRefs[schemaName] = append(..., wc.JSONPath+".items")) to first
verify schemaName := extractSchemaName(...) is not empty (schemaName != "")
before modifying the map, matching the empty-name guard used in main.go.

---

Duplicate comments:
In `@examples/walker/reference-collector/README.md`:
- Around line 154-163: The README section "MaxSchemaDepth Configuration" and its
example call walker.WithMaxSchemaDepth(50) are correct and match the
walker.WithMaxSchemaDepth option defined in walker/options.go, so no code
changes are required; leave the heading and example usage as-is.

@erraggy
Copy link
Owner Author

erraggy commented Feb 22, 2026

Addressing outside-diff review comments

examples/walker/reference-collector/main.go:3-8 — Header comment says "WithMaxDepth"
Fixed in a4e7402 alongside the README heading fix. Comment now reads "Configure WithMaxSchemaDepth for schema traversal".

examples/walker/security-audit/README.md:78-86currentPathTemplate undefined in snippet
This is pre-existing code not modified by this PR. The variable is intentionally a closure-captured value set by a preceding path handler in the actual main.go — the snippet shows a partial extract. While wc.PathTemplate would work here too, changing unrelated code is out of scope.

docs/developer-guide.md:1314-1359 — Missing imports in builder example
This is outside the diff range. The developer guide examples consistently use abbreviated import blocks to focus on the API being demonstrated, not boilerplate. Adding fmt, log, and the YAML package import would be accurate but diverges from the established style throughout the guide.

@erraggy erraggy merged commit eecc3ce into main Feb 22, 2026
25 checks passed
@erraggy erraggy deleted the docs/builder-walker-option-tables branch February 22, 2026 04:54
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.

docs: add option tables for builder and walker With* functions

1 participant