specfixture

package
v0.8.4 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Oct 9, 2026 License: Apache-2.0 Imports: 5 Imported by: 0

Documentation

Overview

Package specfixture loads acceptance-criteria fixtures out of a Specter spec so tests are driven by the spec rather than by numbers copied beside it.

Specter counts a criterion covered when a test carries its annotation, not when the test asserts what the criterion says. Nothing in the toolchain checks that a test consumed the criterion's inputs or expected_output, so an annotation on a test that hardcodes its values reports coverage it does not have. This package makes the YAML the input and fails when a supplied field goes unread.

It lives in a non-test file because three packages need it. It has no production callers and imports nothing but the standard library and yaml.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func Load

func Load(t TB, path, wantSpecID string) map[string]Criterion

Load reads a spec file and indexes its criteria by id, failing on a duplicate.

A duplicate id is fatal rather than last-wins: two criteria sharing one id let a single annotation report coverage for unrelated behavior, which is how OW-023's new criteria silently collided with the drift event-bus criteria.

func Path

func Path(depth int, rel string) string

Path builds a repository-relative spec path from a package directory depth.

Types

type Criterion

type Criterion struct {
	ID             string         `yaml:"id"`
	Description    string         `yaml:"description"`
	Priority       string         `yaml:"priority"`
	Inputs         map[string]any `yaml:"inputs"`
	ExpectedOutput map[string]any `yaml:"expected_output"`
}

Criterion is one acceptance criterion's executable content.

func Get

func Get(t TB, all map[string]Criterion, id string) Criterion

Get fetches one criterion and fails when it is missing or carries no fixture.

type Fields

type Fields struct {
	// contains filtered or unexported fields
}

Fields wraps one map and records which keys a test read.

func ExpectedOf

func ExpectedOf(t TB, ac Criterion) *Fields

func InputsOf

func InputsOf(t TB, ac Criterion) *Fields

InputsOf and ExpectedOf wrap the two halves of a criterion.

func (*Fields) AllConsumed

func (f *Fields) AllConsumed()

AllConsumed fails when the criterion supplies something no assertion read.

Call it only from a test that claims the criterion with an @ac annotation.

func (*Fields) Bool

func (f *Fields) Bool(k string) bool

Bool reads a boolean field.

func (*Fields) EmptyList

func (f *Fields) EmptyList(k string)

EmptyList requires an actual empty list. null is rejected: accepting it would let `violations: []` become `violations: null` with the test still passing.

func (*Fields) Has

func (f *Fields) Has(k string) bool

Has reports whether a key exists, without marking it read.

func (*Fields) Int

func (f *Fields) Int(k string) int

Int reads an integer field, rejecting a fractional value.

Truncating silently would let a spec say 2.5 hosts and a test assert 2, so the fixture and the assertion would disagree with nothing failing.

func (*Fields) IsNull

func (f *Fields) IsNull(k string)

IsNull asserts an explicit null. A missing key and a null are different claims, so get fails on the former.

func (*Fields) IsNullable

func (f *Fields) IsNullable(k string) bool

IsNullable reports whether a present key holds null, WITHOUT marking it read.

For a field that is legitimately either a value or null. The caller must still consume it: either IsNull to assert the null, or a typed accessor for the value. Peeking does not count as asserting.

func (*Fields) List

func (f *Fields) List(k string) []any

List reads a list field.

func (*Fields) Map

func (f *Fields) Map(k string) *Fields

Map reads a nested mapping and returns it wrapped, so nested fields are tracked too.

func (*Fields) MapList

func (f *Fields) MapList(k string) []*Fields

MapList reads a list of mappings and wraps each, so nested fixture entries are consumption-tracked individually.

func (*Fields) Num

func (f *Fields) Num(k string) float64

Num reads a numeric field.

func (*Fields) Raw

func (f *Fields) Raw() map[string]any

Raw returns the underlying mapping and marks every key read. For a nested fixture whose shape a caller interprets itself; prefer the typed accessors where the shape is fixed.

func (*Fields) Str

func (f *Fields) Str(k string) string

Str reads a string field.

func (*Fields) StrList

func (f *Fields) StrList(k string) []string

StrList reads a list expectation whose entries are all strings.

It exists so a caller does not have to type-assert each element and, more importantly, so a list holding a non-string fails loudly here rather than being silently skipped by a caller's type switch.

type TB

type TB interface {
	Helper()
	Fatalf(string, ...any)
	Errorf(string, ...any)
}

TB is the subset of testing.TB this package needs, so it can be used from any test package without importing testing into a production build.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL