Documentation
¶
Overview ¶
Package goldengen is a test-only helper that sweeps a consumer-supplied version universe, classifies versions into behaviorally-distinct gating regimes by firing-set, generates the minimal goldens covering them, and asserts per-fixture mutation gating.
It is opt-in: a consumer that does not import it pays nothing, and the core Build/ApplyIntent path never references it.
Index ¶
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func CheckGating ¶
CheckGating verifies a fixture's Requires/Forbids expectations against its per-version firing-sets. The lattice is:
- Requires with empty For: the name fires at some swept version.
- Requires with For=v: the name fires at v.
- Forbids with empty For: the name fires at no swept version.
- Forbids with For=v: the name does not fire at v.
It returns a descriptive error on the first violation.
Types ¶
type ComponentPreviewer ¶
type ComponentPreviewer interface {
RegisteredMutations() []string
FiringSet() ([]string, error)
Preview() ([]client.Object, error)
}
ComponentPreviewer is a built component: introspectable and rendered to many client.Objects. *component.Component satisfies it.
type Config ¶
type Config[T any] struct { // Dir is the root directory for generated goldens and the manifest. Dir string // Versions is the version universe to sweep, in supplied order. Representative // selection uses this order. Versions []string // Exclude lists registered mutation Names deliberately left unaccounted by the // completeness check. It does not affect gating or golden generation. Exclude []string // Fixtures are the specs to build and assert across the version sweep. Fixtures []Fixture[T] // Build materializes a Unit from a fixture spec at a version. Build func(version string, spec T) (Unit, error) }
Config declares the whole version matrix: the versions to sweep, the fixtures to build, the scheme to serialize with, and the Build function that materializes a Unit from a fixture spec at a version.
func LoadMatrix ¶
func LoadMatrix[T any]( path string, newSpec func() T, build func(version string, spec T) (Unit, error), ) (Config[T], error)
LoadMatrix reads a YAML matrix file at path and returns a Config ready to run. The file mirrors Config without its Go-only Build, which is supplied here as an argument. Each fixture's CR comes from either an inline spec or an external specFile (exactly one of the two); the CR is unmarshalled into a fresh T from newSpec. A specFile path is resolved relative to the matrix file's directory. Supplying both spec and specFile, or neither, is a load error. The resulting Config is validated via Config.Validate before it is returned, so invariants such as every Expect.For being a member of versions are enforced.
The scheme used to serialize rendered objects is supplied by the build function, which passes it to goldengen.Resource or goldengen.Component when it constructs each Unit.
type Expect ¶
type Expect struct {
// Name is the registered mutation Name the expectation applies to.
Name string
// For optionally pins the expectation to a single version from Config.Versions.
For string
}
Expect is an assertion that a named mutation fires (Requires) or does not fire (Forbids) over a fixture's version sweep. For is optional; when set it must be a concrete version drawn from Config.Versions and pins the assertion to that version instead of quantifying over the whole sweep.
type Fixture ¶
type Fixture[T any] struct { // Name identifies the fixture and names its golden subdirectory. Name string // Spec is the input passed to Config.Build for every version. Spec T // Requires lists mutations that must fire, existentially or pinned via For. Requires []Expect // Forbids lists mutations that must not fire, existentially or pinned via For. Forbids []Expect }
Fixture is one spec and the gating expectations the author asserts for it.
type FixtureManifest ¶
type FixtureManifest struct {
Name string `json:"name"`
Regimes []RegimeManifest `json:"regimes"`
}
FixtureManifest records all regimes derived for one fixture.
type Generator ¶
type Generator[T any] struct { // contains filtered or unexported fields }
Generator runs a version matrix: per-fixture gating assertions, minimal goldens, and a coverage manifest, all derived from one Config.
func (*Generator[T]) AssertComplete ¶
AssertComplete proves that every registered mutation is consciously accounted for: each one is either exercised by at least one fixture, by being named in that fixture's Requires (which makes Run assert it actually fires), or it is explicitly listed in Config.Exclude as deliberately not covered. Nothing registered may slip through both untested and unexcluded. It is the guard that a newly added mutation forces exactly one decision: cover it or exclude it.
It is called from the consumer's TestMain so its result gates the package's exit code:
func TestMain(m *testing.M) { os.Exit(gen.AssertComplete(m.Run())) }
Concretely, accounting holds when union(Requires names across all fixtures) plus Config.Exclude equals the set of registered mutation Names. The registered universe is gathered by building each fixture once (registration is version-independent). Forbids does not count toward coverage: forbidding a mutation asserts where it must not fire, which is not evidence that it works, so a mutation that only ever appears in Forbids is still unaccounted.
It returns code unchanged when code is already nonzero (the tests failed, so accounting noise would only obscure that) or when accounting holds. Otherwise it prints the violations to stderr and returns a nonzero code. Violations are: a registered mutation neither required by any fixture nor excluded; a stale Exclude or Requires name not registered by any fixture; and an empty registered mutation Name.
func (*Generator[T]) Run ¶
Run validates the config, asserts per-fixture gating, and writes (or compares) one golden per regime at <Dir>/<fixture>/<representative>.yaml plus the coverage manifest at <Dir>/manifest.yaml. It honors WithUpdate.
func (*Generator[T]) WithUpdate ¶
WithUpdate controls whether Run overwrites goldens and the manifest. Wire it to a -update test flag: gen.WithUpdate(*update).
type Manifest ¶
type Manifest struct {
Fixtures []FixtureManifest `json:"fixtures"`
}
Manifest is the reviewable coverage map: per fixture, the distinct gating regimes with their representative version and firing-set.
type Regime ¶
type Regime struct {
// Representative is the first version in supplied order within the group.
Representative string
// Versions are all versions in this regime, in supplied order.
Versions []string
// Firing is the shared firing-set, sorted.
Firing []string
}
Regime is a group of swept versions sharing an identical firing-set.
func ClassifyRegimes ¶
ClassifyRegimes groups versions (in supplied order) by identical firing-set. Two versions belong to the same regime when their firing-sets are equal as sets, independent of order. Regimes are returned in order of first appearance; the representative of each is the first version in supplied order belonging to it.
type RegimeManifest ¶
type RegimeManifest struct {
Representative string `json:"representative"`
Versions []string `json:"versions"`
Firing []string `json:"firing"`
}
RegimeManifest records one behaviorally-distinct regime of a fixture: its representative version, the versions it covers, and the shared firing-set.
type ResourcePreviewer ¶
type ResourcePreviewer interface {
concepts.MutationInspector
concepts.Previewable
}
ResourcePreviewer is a built single-resource primitive: it can be introspected and rendered to one client.Object. Every built-in primitive satisfies it.
type Unit ¶
type Unit interface {
// RegisteredMutations returns the deduplicated Names of every registered mutation.
RegisteredMutations() []string
// FiringSet returns the Names of mutations enabled at the built version.
FiringSet() ([]string, error)
// RenderYAML renders the unit's desired state as canonical golden YAML.
RenderYAML() ([]byte, error)
}
Unit is a built resource or component the generator can introspect and render.