semcov

package
v0.87.2 Latest Latest
Warning

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

Go to latest
Published: Oct 12, 2026 License: MIT Imports: 11 Imported by: 0

Documentation

Overview

Package semcov is the semantic-coverage manifest: a record of what a test run actually exercised, as opposed to which lines it happened to execute.

Line coverage answers "did this statement run". It cannot answer the questions that decide whether a change is safe:

  • Did a request ever reach this route through the real router, the real middleware chain, and the real auth check?
  • Was this permission ever evaluated, not just present in a file that got loaded?
  • Did anything ever call this entity's Delete endpoint?

A handler can sit at 100% line coverage because a unit test called the function directly, while no request has ever reached it through the router. That handler is untested in every way that matters, and the coverage number says the opposite.

How it works

The shape is borrowed wholesale from framework/axecov, which solves the same problem for accessibility scans and has the operational behaviour already proven: tests write, tooling reads, the file lives under `.gofastr/` (gitignored, wiped by `make clean`) so it never ships, and both sides resolve the same directory through DefaultDir even when their working directories differ.

Recording is opt-in per process and free when off. `framework/testkit` turns it on for the app under test; production binaries never call Enable, so the hooks compile to an atomic load and a branch.

Index

Constants

View Source
const FileName = ".gofastr/semantic-coverage.json"

FileName is the manifest location relative to the coverage root.

View Source
const Version = 1

Version is the manifest schema version. A reader that finds a higher version reports the mismatch rather than guessing at the contents.

Variables

This section is empty.

Functions

func DefaultDir

func DefaultDir() string

DefaultDir resolves the coverage root the same way framework/axecov does, so a project has one place where its coverage artifacts live:

  1. GOFASTR_SEMANTIC_COVERAGE_DIR, when set.
  2. GOFASTR_AXE_COVERAGE_DIR, when set: sharing the override means an app that already pinned its axe manifest per-app gets the same isolation here without configuring it twice.
  3. The nearest ancestor holding go.work (Go's own workspace rule).
  4. Else the nearest ancestor holding go.mod.
  5. Else the working directory.

func Disable

func Disable()

Disable stops recording. Data already accumulated is retained so a deferred Flush still writes it.

func Enable

func Enable(root string)

Enable turns recording on and points it at a coverage root. Passing "" uses DefaultDir. Calling it twice is safe: the accumulated data is kept, so two test packages in one binary do not erase each other.

func Enabled

func Enabled() bool

Enabled reports whether recording is on.

func Flush

func Flush() error

Flush writes the accumulated manifest. It merges with whatever is on disk first, because `go test ./...` runs one process per package and each one only knows about its own requests, without the merge, the last package to finish would be the only one recorded.

func RecordEntityOp

func RecordEntityOp(entity, op string)

RecordEntityOp notes that an entity's CRUD operation ran. op is one of list, get, create, update, delete.

func RecordEvent

func RecordEvent(eventType string)

RecordEvent notes that an event type was published on the bus.

func RecordHook

func RecordHook(entity, hookType string)

RecordHook notes that a registered lifecycle hook ran for an entity.

func RecordPermission

func RecordPermission(permission string)

RecordPermission notes that a permission was evaluated.

func RecordRole

func RecordRole(role string)

RecordRole notes that a caller held a role during a permission check.

func RecordRoute

func RecordRoute(method, pattern string)

RecordRoute notes that a request was served by the given route pattern. The pattern is the router's registered pattern, not the request path.

func Reset

func Reset()

Reset clears in-process state. For tests of this package and of the harness that drives it.

Types

type Manifest

type Manifest struct {
	Version int `json:"version"`
	// Routes maps a route pattern to the HTTP methods exercised against
	// it. Keyed by *pattern*, not by request path, so one test hitting
	// /orders/42 credits the /orders/{id} route.
	Routes map[string][]string `json:"routes"`
	// Permissions are the permission strings that were evaluated,
	// whatever the verdict, a denial proves the boundary as well as a
	// grant does, and arguably better.
	Permissions []string `json:"permissions"`
	// Entities maps an entity name to the CRUD operations exercised
	// (list, get, create, update, delete).
	Entities map[string][]string `json:"entities"`
	// Hooks maps an entity name to the lifecycle hooks that actually
	// fired (beforecreate, afterupdate, …). A registered hook that never
	// runs is the classic silent break: the code is there, the tests are
	// green, and the behaviour it adds has never happened.
	Hooks map[string][]string `json:"hooks,omitempty"`
	// Events are the event types actually published during the run. A
	// subscriber registered for a type that never appears here has never
	// run, the same silent break as an unfired hook, one layer out.
	Events []string `json:"events,omitempty"`
	// Roles are the roles a caller actually held during a recorded
	// permission check. A granted role nothing ever authenticates as is an
	// authorization path no test has walked.
	Roles []string `json:"roles,omitempty"`
}

Manifest is what a test run proved it touched.

func Read

func Read(root string) (*Manifest, error)

Read loads the manifest under root. A missing manifest returns an error satisfying errors.Is(err, fs.ErrNotExist), so callers can distinguish "never recorded" (fine on a fresh clone) from "recorded and incomplete" (real drift).

func (*Manifest) CoveredEntity

func (m *Manifest) CoveredEntity(name string) bool

CoveredEntity reports whether the manifest records any operation on an entity.

func (*Manifest) CoveredEvent

func (m *Manifest) CoveredEvent(eventType string) bool

CoveredEvent reports whether an event type was published.

func (*Manifest) CoveredHook

func (m *Manifest) CoveredHook(entity, hookType string) bool

CoveredHook reports whether an entity's lifecycle hook fired.

func (*Manifest) CoveredPermission

func (m *Manifest) CoveredPermission(p string) bool

CoveredPermission reports whether a permission was evaluated.

func (*Manifest) CoveredRole

func (m *Manifest) CoveredRole(role string) bool

CoveredRole reports whether a caller ever held the role during a check.

func (*Manifest) CoveredRoute

func (m *Manifest) CoveredRoute(method, pattern string) bool

CoveredRoute reports whether the manifest records the method against the pattern.

Jump to

Keyboard shortcuts

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