Documentation
¶
Overview ¶
Package openapitest holds the test scaffolding every test package under compilers/openapi would otherwise carry as its own copy.
Go test files cannot share unexported helpers across packages, so the split into one package per lowering stage duplicated the scaffolding instead of retiring it: the same sourceOf, requireNoErrorDiags and componentSpec ended up defined once per package, byte for byte. A helper that exists once cannot drift; five copies held in step only by review can.
It sits here rather than in the repo-root internal/testspec, which holds the fixture spec strings the engine and CLI tests share: that package cannot import compilers/openapi/internal/..., and this one needs diag for the diagnostic codes it matches on.
What may live here ¶
A helper belongs here only if it is reachable from every test package under compilers/openapi, internal and external alike. That bounds the imports to ir, compilers, diag and third-party libraries — packages no test package under compilers/openapi sits inside. Reaching any further would make this package unimportable from the internal tests of whatever it reached, because an internal test file may not import a package that imports its own.
Two families of scaffolding are therefore absent by necessity, not oversight:
- parseFull, which drives the whole compiler, needs compilers/openapi, and that package's own internal tests could then not import this one.
- The lowerer fixture needs lowering.Ctx and schema.AnchorIndex, which would shut out the internal tests of load, resolve, annotation, schema and everything else beneath them.
Both stay with the packages that drive them, each built on a single field-initialising constructor so the fixture cannot drift within a package even where it must be repeated across them.
A third family is absent for a different reason. componentID and typeByName spell a type ID out as a string, and internal/archtest's ID-grammar sweep permits that in a test file while refusing it in a production file — which is what these are. Deriving the ID through compile instead would satisfy the sweep by making the lookup agree with the compiler by construction, and a lookup that cannot disagree is no longer an oracle, so those two stay in the test files that spell them.
Index ¶
- Constants
- func AssertHasCode(t TB, diags []ir.Diagnostic, code string, sev ir.Severity)
- func AssertInfoDiagAt(t TB, diags []ir.Diagnostic, pointer string)
- func AssertProbeDocsKept(t TB, d ir.Docs)
- func AssertProbeExample(t TB, examples []ir.Example)
- func BodyTarget(t TB, payload *ir.Payload) ir.TypeID
- func ComponentSpec(schemas string) string
- func ComponentSpecVer(version, schemas string) string
- func CountDiagsAt(diags []ir.Diagnostic, code string, sev ir.Severity) int
- func DiagMessageAt(t TB, diags []ir.Diagnostic, code string, sev ir.Severity, pointer string) string
- func DocDeclaring(names ...string) *soa.OpenAPI
- func EmptyEitherSchema() *oas3.JSONSchema[oas3.Referenceable]
- func FindOp(t TB, doc *ir.Document, source string) ir.Operation
- func FirstDegradedWarning(diags []ir.Diagnostic) (ir.Diagnostic, bool)
- func FirstOp(t TB, svc ir.Service) ir.Operation
- func HasDiag(diags []ir.Diagnostic, code string) bool
- func HasDiagAt(diags []ir.Diagnostic, code string, sev ir.Severity) bool
- func HasDiagCodeAt(diags []ir.Diagnostic, code, pointer string) bool
- func IndexBy[T any, K comparable](items []T, key func(T) K) map[K]T
- func PathsSpec(paths string) string
- func PathsSpecVer(version, paths string) string
- func PropsByWire(props []ir.Property) map[string]ir.Property
- func RequireNoErrorDiags(t TB, diags []ir.Diagnostic)
- func ScalarNode(tag, val string) *yaml.Node
- func SourceOf(src string) compilers.Source
- func StrNode(val string) *yaml.Node
- func YAMLNode(t TB, src string) *yaml.Node
- type TB
Constants ¶
const InlineProbeBody = `{type: string, title: SUM, description: DOC, ` +
`externalDocs: {url: 'https://e.example', description: ED}, deprecated: true, ` +
`example: abc, x-vendor: V, xml: {name: X}, not: {const: N}, maxLength: 3}`
InlineProbeBody is the body every inline-position case writes: one annotation of each kind the declared-annotation reader takes, one validation-only keyword, and one value constraint — all of them position-scoped, so a position that lowers this to the shared string primitive loses every one. All three documentation keywords are here because a home that keeps only the description passes a probe that writes only a description.
Variables ¶
This section is empty.
Functions ¶
func AssertHasCode ¶
AssertHasCode requires diags to carry a diagnostic with the given code at the given severity.
func AssertInfoDiagAt ¶
func AssertInfoDiagAt(t TB, diags []ir.Diagnostic, pointer string)
AssertInfoDiagAt requires one info diagnostic stamped at pointer.
func AssertProbeDocsKept ¶
AssertProbeDocsKept checks all three documentation keywords InlineProbeBody writes reached d, wherever the position's home turned out to be.
func AssertProbeExample ¶
AssertProbeExample checks the single example InlineProbeBody writes reached the home under test with its value intact.
func BodyTarget ¶
BodyTarget returns the type a single-media-type payload refers to.
The two requires are the reason this is a function rather than the indexing expression it wraps: written inline, a payload that is nil or that grew a second media type panics on a line that says nothing about which of the two happened.
func ComponentSpec ¶
ComponentSpec wraps a components/schemas block in a minimal 3.1 document.
func ComponentSpecVer ¶
ComponentSpecVer wraps a components/schemas block in a minimal document of the given OpenAPI version.
func CountDiagsAt ¶
CountDiagsAt counts the diagnostics in diags matching code and sev exactly. code is an exact match with no wildcard: CountDiagsAt(diags, "", ir.SeverityError) matches only diagnostics whose code is literally empty — it is not a way to spell "every error," and reads dangerously like one, so callers who want that must filter on severity alone instead.
func DiagMessageAt ¶
func DiagMessageAt(t TB, diags []ir.Diagnostic, code string, sev ir.Severity, pointer string) string
DiagMessageAt returns the message of the single diagnostic matching code, severity and provenance pointer. Tests that only compare a diagnostic's code cannot tell two lowerings apart when both report the same code with different reasons, so the reason itself needs an assertable handle.
func DocDeclaring ¶
DocDeclaring builds a document declaring the named component schemas, with no parser and no fixture — the shape a test wants when what it needs from the document is only which components it declares.
func EmptyEitherSchema ¶
func EmptyEitherSchema() *oas3.JSONSchema[oas3.Referenceable]
EmptyEitherSchema is a JSONSchema whose either-value has neither a Left schema nor a Right bool set: IsSchema() is true (IsLeft defaults true) yet GetSchema() is nil. The parser never produces this, so it drives the nil-schema guards.
func FirstDegradedWarning ¶
func FirstDegradedWarning(diags []ir.Diagnostic) (ir.Diagnostic, bool)
FirstDegradedWarning returns the first diag.DegradedConstruct warning in diags, and whether one was found — the pointer/message inspection counterpart to HasDiagAt/CountDiagsAt.
func FirstOp ¶
FirstOp returns the operation at svc.Groups[0].Operations[0], requiring both to be non-empty first rather than letting a malformed fixture fail with a bare index-out-of-range panic.
func HasDiag ¶
func HasDiag(diags []ir.Diagnostic, code string) bool
HasDiag reports whether diags contains a diagnostic with the exact code, at any severity. It is the existential half of the vocabulary: use it where a test only needs to know a diagnostic fired, not how many or at what severity.
func HasDiagAt ¶
HasDiagAt reports whether diags contains a diagnostic with the exact code at the exact severity.
func HasDiagCodeAt ¶
func HasDiagCodeAt(diags []ir.Diagnostic, code, pointer string) bool
HasDiagCodeAt reports whether diags carries code at exactly pointer.
func IndexBy ¶
func IndexBy[T any, K comparable](items []T, key func(T) K) map[K]T
IndexBy builds a lookup keyed by key(item), the shape behind every hand-rolled "m := map[K]T{}; for _, x := range xs { m[key(x)] = x }" loop these suites used to repeat per test.
func PathsSpecVer ¶
PathsSpecVer wraps a paths block in a minimal document of the given OpenAPI version, with no components.
func PropsByWire ¶
PropsByWire indexes a model's properties by wire name.
func RequireNoErrorDiags ¶
func RequireNoErrorDiags(t TB, diags []ir.Diagnostic)
RequireNoErrorDiags fails the test if any diagnostic has error severity, reporting the first offending diagnostic.
func ScalarNode ¶
ScalarNode builds a bare scalar yaml.Node with the given tag and value.
Types ¶
type TB ¶
type TB interface {
Helper()
Errorf(format string, args ...any)
FailNow()
Fatalf(format string, args ...any)
}
TB is the subset of *testing.T these helpers need.
It is an interface rather than *testing.T so this package's own tests can drive the failure branches with a recording stub, the way ir/irtest does: a helper that aborts a real test cannot have its abort path covered.