Documentation
¶
Overview ¶
Package helpers provides building blocks for hook unit tests.
It complements the heavier-weight testing/framework package: where the framework spins up a fake Kubernetes cluster and exercises the full hook pipeline (snapshots → handler → patches), the helpers in this package are aimed at small, focused unit tests that mock just the dependencies the hook touches.
Typical usage:
func TestMyHook(t *testing.T) {
in := helpers.NewInputBuilder(t).
WithSnapshot("nodes", helpers.SnapshotJSON(`{"name":"n1"}`)).
WithValuesJSON(`{"my":{"field":"value"}}`).
Build()
err := MyHookHandler(context.Background(), in)
require.NoError(t, err)
require.Equal(t, "value", in.Values.Get("my.field").String())
}
Helpers are intentionally minimal and orthogonal:
- InputBuilder - assembles a *pkg.HookInput / *pkg.ApplicationHookInput.
- StaticSnapshots - in-memory pkg.Snapshots backed by JSON literals.
- JQRun - apply a JQ filter to JSON or to a Go value.
- PreparePatchCollector - construct a patch collector mock with sane defaults.
- PatchOperations - decode the operations a hook recorded on a PatchCollector.
All helpers play nicely with both *testing.T and Ginkgo's GinkgoT().
Index ¶
- func JQRunOnObject(ctx context.Context, filter string, input, target any) error
- func JQRunOnString(ctx context.Context, filter, jsonInput string, target any) error
- func MarshalValues(v pkg.PatchableValuesCollector) []byte
- func NewValues(initial map[string]any) pkg.PatchableValuesCollector
- func NewValuesFromJSON(raw string) pkg.PatchableValuesCollector
- func NewValuesFromYAML(raw string) pkg.PatchableValuesCollector
- func SnapshotFromObject(v any) pkg.Snapshot
- func SnapshotFromObjects[T any](items []T) []pkg.Snapshot
- func SnapshotJSON(raw string) pkg.Snapshot
- func SnapshotYAML(raw string) pkg.Snapshot
- type InputBuilder
- func (b *InputBuilder) Build() *pkg.HookInput
- func (b *InputBuilder) ConfigValues() pkg.PatchableValuesCollector
- func (b *InputBuilder) LogBuffer() *bytes.Buffer
- func (b *InputBuilder) RecordingPatchCollector() *RecordingPatchCollector
- func (b *InputBuilder) Snapshots() StaticSnapshots
- func (b *InputBuilder) Values() pkg.PatchableValuesCollector
- func (b *InputBuilder) WithCapturedLogger() *InputBuilder
- func (b *InputBuilder) WithConfigValues(v pkg.PatchableValuesCollector) *InputBuilder
- func (b *InputBuilder) WithConfigValuesJSON(raw string) *InputBuilder
- func (b *InputBuilder) WithConfigValuesYAML(raw string) *InputBuilder
- func (b *InputBuilder) WithDependencyContainer(dc pkg.DependencyContainer) *InputBuilder
- func (b *InputBuilder) WithLogger(l pkg.Logger) *InputBuilder
- func (b *InputBuilder) WithMetricsCollector(c pkg.MetricsCollector) *InputBuilder
- func (b *InputBuilder) WithPatchCollector(c pkg.PatchCollector) *InputBuilder
- func (b *InputBuilder) WithRecordingPatchCollector() *InputBuilder
- func (b *InputBuilder) WithSnapshot(key string, snaps ...pkg.Snapshot) *InputBuilder
- func (b *InputBuilder) WithSnapshots(s StaticSnapshots) *InputBuilder
- func (b *InputBuilder) WithValues(v pkg.PatchableValuesCollector) *InputBuilder
- func (b *InputBuilder) WithValuesJSON(raw string) *InputBuilder
- func (b *InputBuilder) WithValuesMap(m map[string]any) *InputBuilder
- func (b *InputBuilder) WithValuesYAML(raw string) *InputBuilder
- type RecordedOp
- type RecordingPatchCollector
- func (c *RecordingPatchCollector) Create(object any)
- func (c *RecordingPatchCollector) CreateIfNotExists(object any)
- func (c *RecordingPatchCollector) CreateOrUpdate(object any)
- func (c *RecordingPatchCollector) Delete(apiVersion, kind, namespace, name string)
- func (c *RecordingPatchCollector) DeleteInBackground(apiVersion, kind, namespace, name string)
- func (c *RecordingPatchCollector) DeleteNonCascading(apiVersion, kind, namespace, name string)
- func (c *RecordingPatchCollector) Filter(ops ...string) []*RecordedOp
- func (c *RecordingPatchCollector) JQFilter(jqfilter, apiVersion, kind, namespace, name string, ...)
- func (c *RecordingPatchCollector) JSONPatch(jsonPatch any, apiVersion, kind, namespace, name string, ...)
- func (c *RecordingPatchCollector) MergePatch(mergePatch any, apiVersion, kind, namespace, name string, ...)
- func (c *RecordingPatchCollector) Operations() []pkg.PatchCollectorOperation
- func (c *RecordingPatchCollector) PatchWithJQ(jqfilter, apiVersion, kind, namespace, name string, ...)
- func (c *RecordingPatchCollector) PatchWithJSON(jsonPatch any, apiVersion, kind, namespace, name string, ...)
- func (c *RecordingPatchCollector) PatchWithMerge(mergePatch any, apiVersion, kind, namespace, name string, ...)
- func (c *RecordingPatchCollector) Recorded() []*RecordedOp
- type StaticSnapshots
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func JQRunOnObject ¶
JQRunOnObject applies the given JQ filter to a Go value (which must be JSON-serialisable) and decodes the result into target.
func JQRunOnString ¶
JQRunOnString applies the given JQ filter to a JSON string and decodes the result into target. target must be a non-nil pointer.
This is a small convenience over manually constructing a jq.Query — it keeps unit tests focused on the assertions instead of the boilerplate.
func MarshalValues ¶
func MarshalValues(v pkg.PatchableValuesCollector) []byte
MarshalValues returns the JSON encoding of the patch operations recorded on the values collector. It is a small convenience for snapshot-style assertions:
require.JSONEq(t, `[{"op":"add","path":"/foo","value":"bar"}]`,
string(helpers.MarshalValues(values)))
func NewValues ¶
func NewValues(initial map[string]any) pkg.PatchableValuesCollector
NewValues constructs a real pkg.PatchableValuesCollector seeded with the provided map. Use it when the hook under test should observe a working values store rather than a mock.
Tests can then assert on the patches the hook produced via GetPatches().
func NewValuesFromJSON ¶
func NewValuesFromJSON(raw string) pkg.PatchableValuesCollector
NewValuesFromJSON is like NewValues but parses a JSON document. Empty or whitespace-only input is treated as `{}`.
func NewValuesFromYAML ¶
func NewValuesFromYAML(raw string) pkg.PatchableValuesCollector
NewValuesFromYAML is like NewValues but parses a YAML document. Empty or whitespace-only input is treated as `{}`.
func SnapshotFromObject ¶
SnapshotFromObject builds a pkg.Snapshot by JSON-encoding the given Go value. It panics if the value cannot be marshalled (which would be a programmer error in test code).
func SnapshotFromObjects ¶
SnapshotFromObjects is the bulk variant of SnapshotFromObject.
func SnapshotJSON ¶
SnapshotJSON builds a pkg.Snapshot from a JSON string.
func SnapshotYAML ¶
SnapshotYAML builds a pkg.Snapshot from a YAML string. The YAML is converted to canonical JSON internally so that UnmarshalTo behaves the same as for SnapshotJSON.
Types ¶
type InputBuilder ¶
type InputBuilder struct {
// contains filtered or unexported fields
}
InputBuilder is a fluent builder for *pkg.HookInput. It bundles together the most common boilerplate of unit tests:
- StaticSnapshots seeded with JSON / YAML / Go-value snapshots
- real PatchableValuesCollector for Values / ConfigValues
- a RecordingPatchCollector for assertions
- a real metric.Collector
- a logger that can either be silent or write to a captured buffer
Anything you don't configure has a sensible default, so a zero-config builder still produces a usable HookInput.
func NewInputBuilder ¶
func NewInputBuilder(tb testing.TB) *InputBuilder
NewInputBuilder returns a builder bound to the given testing.TB. The TB is currently used for failing the test if an internal helper call fails; pass nil from non-test code.
func (*InputBuilder) Build ¶
func (b *InputBuilder) Build() *pkg.HookInput
Build assembles the *pkg.HookInput. Calling Build twice is allowed and returns the same shared values / patch collector references.
func (*InputBuilder) ConfigValues ¶
func (b *InputBuilder) ConfigValues() pkg.PatchableValuesCollector
ConfigValues returns the config values collector that will be used.
func (*InputBuilder) LogBuffer ¶
func (b *InputBuilder) LogBuffer() *bytes.Buffer
LogBuffer returns the buffer behind WithCapturedLogger or nil.
func (*InputBuilder) RecordingPatchCollector ¶
func (b *InputBuilder) RecordingPatchCollector() *RecordingPatchCollector
RecordingPatchCollector returns the typed RecordingPatchCollector if one was attached via WithRecordingPatchCollector or implicitly by Build. Returns nil when the user supplied a different PatchCollector.
func (*InputBuilder) Snapshots ¶
func (b *InputBuilder) Snapshots() StaticSnapshots
Snapshots returns the StaticSnapshots backing the input. Useful if you want to add more snapshots after the input is built.
func (*InputBuilder) Values ¶
func (b *InputBuilder) Values() pkg.PatchableValuesCollector
Values returns the values collector that will be used by the input.
func (*InputBuilder) WithCapturedLogger ¶
func (b *InputBuilder) WithCapturedLogger() *InputBuilder
WithCapturedLogger installs a *log.Logger writing into a private buffer. The buffer is accessible via LogBuffer after Build.
func (*InputBuilder) WithConfigValues ¶
func (b *InputBuilder) WithConfigValues(v pkg.PatchableValuesCollector) *InputBuilder
WithConfigValues replaces the config values collector.
func (*InputBuilder) WithConfigValuesJSON ¶
func (b *InputBuilder) WithConfigValuesJSON(raw string) *InputBuilder
WithConfigValuesJSON seeds the config values collector from JSON.
func (*InputBuilder) WithConfigValuesYAML ¶
func (b *InputBuilder) WithConfigValuesYAML(raw string) *InputBuilder
WithConfigValuesYAML seeds the config values collector from YAML.
func (*InputBuilder) WithDependencyContainer ¶
func (b *InputBuilder) WithDependencyContainer(dc pkg.DependencyContainer) *InputBuilder
WithDependencyContainer replaces the dependency container.
func (*InputBuilder) WithLogger ¶
func (b *InputBuilder) WithLogger(l pkg.Logger) *InputBuilder
WithLogger replaces the logger used by the hook.
func (*InputBuilder) WithMetricsCollector ¶
func (b *InputBuilder) WithMetricsCollector(c pkg.MetricsCollector) *InputBuilder
WithMetricsCollector replaces the metrics collector.
func (*InputBuilder) WithPatchCollector ¶
func (b *InputBuilder) WithPatchCollector(c pkg.PatchCollector) *InputBuilder
WithPatchCollector replaces the patch collector with a custom one (for example, a minimock-generated mock).
func (*InputBuilder) WithRecordingPatchCollector ¶
func (b *InputBuilder) WithRecordingPatchCollector() *InputBuilder
WithRecordingPatchCollector wires a fresh RecordingPatchCollector into the input. The collector itself is returned by RecordingPatchCollector after Build.
func (*InputBuilder) WithSnapshot ¶
func (b *InputBuilder) WithSnapshot(key string, snaps ...pkg.Snapshot) *InputBuilder
WithSnapshot adds one or more snapshots under the given key. May be called multiple times; snapshots are appended.
func (*InputBuilder) WithSnapshots ¶
func (b *InputBuilder) WithSnapshots(s StaticSnapshots) *InputBuilder
WithSnapshots replaces the entire snapshots map with the provided one. Use this when you have an already-constructed StaticSnapshots.
func (*InputBuilder) WithValues ¶
func (b *InputBuilder) WithValues(v pkg.PatchableValuesCollector) *InputBuilder
WithValues replaces the values collector with the given one. By default, the builder constructs an empty PatchableValuesCollector lazily on Build.
func (*InputBuilder) WithValuesJSON ¶
func (b *InputBuilder) WithValuesJSON(raw string) *InputBuilder
WithValuesJSON seeds the values collector from a JSON string.
func (*InputBuilder) WithValuesMap ¶
func (b *InputBuilder) WithValuesMap(m map[string]any) *InputBuilder
WithValuesMap seeds the values collector from a Go map.
func (*InputBuilder) WithValuesYAML ¶
func (b *InputBuilder) WithValuesYAML(raw string) *InputBuilder
WithValuesYAML seeds the values collector from a YAML string.
type RecordedOp ¶
type RecordedOp struct {
Op string
Object any
APIVersion string
Kind string
Namespace string
Name string
Patch any
JQFilter string
Options []pkg.PatchCollectorOption
}
RecordedOp captures the parameters of a single PatchCollector call.
The fields are populated only for the operation that is relevant for the type:
- Op = "Create" / "CreateOrUpdate" / "CreateIfNotExists" → Object
- Op = "Delete*" → APIVersion, Kind, Namespace, Name
- Op = "JSONPatch" / "MergePatch" / "JQFilter" → APIVersion, Kind, Namespace, Name, Patch
RecordedOp also implements pkg.PatchCollectorOperation so it can be used in code paths that expect that interface.
func (*RecordedOp) Description ¶
func (r *RecordedOp) Description() string
Description implements pkg.PatchCollectorOperation.
func (*RecordedOp) SetObjectPrefix ¶
func (r *RecordedOp) SetObjectPrefix(prefix string)
SetObjectPrefix implements pkg.PatchCollectorOperation. It mirrors the real implementation by prefixing the recorded Name when set.
type RecordingPatchCollector ¶
type RecordingPatchCollector struct {
// contains filtered or unexported fields
}
RecordingPatchCollector is a pkg.PatchCollector that records every call and exposes the recorded operations for assertions.
It is intentionally simple — no replay against a fake cluster, no validation. For full end-to-end testing prefer testing/framework.
func NewRecordingPatchCollector ¶
func NewRecordingPatchCollector() *RecordingPatchCollector
NewRecordingPatchCollector returns an empty RecordingPatchCollector.
func (*RecordingPatchCollector) Create ¶
func (c *RecordingPatchCollector) Create(object any)
Create implements pkg.PatchCollector.
func (*RecordingPatchCollector) CreateIfNotExists ¶
func (c *RecordingPatchCollector) CreateIfNotExists(object any)
CreateIfNotExists implements pkg.PatchCollector.
func (*RecordingPatchCollector) CreateOrUpdate ¶
func (c *RecordingPatchCollector) CreateOrUpdate(object any)
CreateOrUpdate implements pkg.PatchCollector.
func (*RecordingPatchCollector) Delete ¶
func (c *RecordingPatchCollector) Delete(apiVersion, kind, namespace, name string)
Delete implements pkg.PatchCollector.
func (*RecordingPatchCollector) DeleteInBackground ¶
func (c *RecordingPatchCollector) DeleteInBackground(apiVersion, kind, namespace, name string)
DeleteInBackground implements pkg.PatchCollector.
func (*RecordingPatchCollector) DeleteNonCascading ¶
func (c *RecordingPatchCollector) DeleteNonCascading(apiVersion, kind, namespace, name string)
DeleteNonCascading implements pkg.PatchCollector.
func (*RecordingPatchCollector) Filter ¶
func (c *RecordingPatchCollector) Filter(ops ...string) []*RecordedOp
Filter returns the subset of recorded operations whose Op equals one of the provided values. It is a small convenience for assertions:
deletes := pc.Filter("Delete", "DeleteInBackground")
func (*RecordingPatchCollector) JQFilter ¶
func (c *RecordingPatchCollector) JQFilter(jqfilter, apiVersion, kind, namespace, name string, opts ...pkg.PatchCollectorOption)
JQFilter implements pkg.PatchCollector (deprecated alias).
func (*RecordingPatchCollector) JSONPatch ¶
func (c *RecordingPatchCollector) JSONPatch(jsonPatch any, apiVersion, kind, namespace, name string, opts ...pkg.PatchCollectorOption)
JSONPatch implements pkg.PatchCollector (deprecated alias).
func (*RecordingPatchCollector) MergePatch ¶
func (c *RecordingPatchCollector) MergePatch(mergePatch any, apiVersion, kind, namespace, name string, opts ...pkg.PatchCollectorOption)
MergePatch implements pkg.PatchCollector (deprecated alias).
func (*RecordingPatchCollector) Operations ¶
func (c *RecordingPatchCollector) Operations() []pkg.PatchCollectorOperation
Operations implements pkg.PatchCollector.
func (*RecordingPatchCollector) PatchWithJQ ¶
func (c *RecordingPatchCollector) PatchWithJQ(jqfilter, apiVersion, kind, namespace, name string, opts ...pkg.PatchCollectorOption)
PatchWithJQ implements pkg.PatchCollector.
func (*RecordingPatchCollector) PatchWithJSON ¶
func (c *RecordingPatchCollector) PatchWithJSON(jsonPatch any, apiVersion, kind, namespace, name string, opts ...pkg.PatchCollectorOption)
PatchWithJSON implements pkg.PatchCollector.
func (*RecordingPatchCollector) PatchWithMerge ¶
func (c *RecordingPatchCollector) PatchWithMerge(mergePatch any, apiVersion, kind, namespace, name string, opts ...pkg.PatchCollectorOption)
PatchWithMerge implements pkg.PatchCollector.
func (*RecordingPatchCollector) Recorded ¶
func (c *RecordingPatchCollector) Recorded() []*RecordedOp
Recorded returns a copy of the recorded operations in the order they were issued by the hook.
type StaticSnapshots ¶
StaticSnapshots is an in-memory implementation of pkg.Snapshots backed by raw JSON payloads. It is the simplest possible Snapshots stub: every snapshot is a JSON document that UnmarshalTo will decode into the caller-supplied struct.
Construct a StaticSnapshots with NewSnapshots:
snaps := helpers.NewSnapshots().
Add("nodes", helpers.SnapshotJSON(`{"name":"n1"}`)).
Add("nodes", helpers.SnapshotYAML(`name: n2`))
func NewSnapshots ¶
func NewSnapshots() StaticSnapshots
NewSnapshots returns an empty StaticSnapshots.
func (StaticSnapshots) Add ¶
func (s StaticSnapshots) Add(key string, snaps ...pkg.Snapshot) StaticSnapshots
Add appends one or more snapshots to the bucket identified by key. It returns the receiver for chaining.
func (StaticSnapshots) Get ¶
func (s StaticSnapshots) Get(key string) []pkg.Snapshot
Get implements pkg.Snapshots.
func (StaticSnapshots) Set ¶
func (s StaticSnapshots) Set(key string, snaps ...pkg.Snapshot) StaticSnapshots
Set replaces the bucket identified by key with the given snapshots. It returns the receiver for chaining.