ass

package module
v0.1.0 Latest Latest
Warning

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

Go to latest
Published: Sep 29, 2025 License: MIT Imports: 1 Imported by: 0

README

ass

Runtime assertions for your Go programs.

Go provides assert only for testing, but it is often valuable to test invariants at runtime, especially in simulation, stateful systems, or safety-critical code.

ass is largely inspired by Tiger Style from TigerBeetle's dev team.
Read more about Tiger Style


Installation

go get github.com/bxrne/ass

Features

  • Define invariants as reusable, named predicates over your state.
  • Group invariants into suites for convenient batch checking.
  • Fluent API to define invariants: NewInv().Check().Msg().
  • Automatic invariant checking on state updates via AutoInv.
  • Optional error messages for clearer diagnostics.

Usage

Manual invariant checking
package main

import (
    "fmt"

    "github.com/bxrne/ass"
)

type Counter struct {
    Value int
}

func main() {
    // Define an invariant
    inv := ass.NewInv[Counter]("NonNegativeCounter").
        Check(func(c Counter) bool { return c.Value >= 0 }).
        Msg("Counter value cannot go below zero")

    // Example state
    c := Counter{Value: -1}

    // Create a suite and check all invariants
    suite := ass.InvSuite[Counter]{inv}
    errs := suite.Check(c)
    for _, err := range errs {
        fmt.Println(err)
    }
}

Output:

Invariant NonNegativeCounter violated: Counter value cannot go below zero

Automatic invariant checking
package main

import (
    "github.com/bxrne/ass"
)

type Counter struct {
    Value int
}

func main() {
    inv := ass.NewInv[Counter]("NonNegative").
        Check(func(c Counter) bool { return c.Value >= 0 }).
        Msg("Counter cannot be negative")

    counter := Counter{Value: 0}

    // Wrap state for automatic invariant checking
    wrapped := ass.NewAutoInv(counter, ass.InvSuite[Counter]{inv})

    wrapped.Set(Counter{Value: 5})  // ✅ passes

    wrapped.Set(Counter{Value: -1}) // ⚠ panics (in automatic mode)
}

Note: AutoInv automatically checks invariants whenever state is updated. By default, violations panic, but this behavior can be customized by providing an OnViolate callback.


License

MIT License

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type AutoInv

type AutoInv[T any] struct {
	// contains filtered or unexported fields
}

AutoInv wraps a state and auto-checks invariants

func NewAuto

func NewAuto[T any](state T, suite InvSuite[T]) *AutoInv[T]

NewAutoInv creates a new wrapper with invariants

func (*AutoInv[T]) Get

func (a *AutoInv[T]) Get() T

Get returns the current state

func (*AutoInv[T]) Set

func (a *AutoInv[T]) Set(newState T)

Set replaces the state and auto-checks invariants

type Inv

type Inv[T any] struct {
	Name      string
	Condition func(T) bool
	ErrMsg    string
}

Inv represents a software invariant testable by a condition

func New

func New[T any](name string) *Inv[T]

NewInv creates a new invariant with a name

func (*Inv[T]) Check

func (inv *Inv[T]) Check(f func(T) bool) *Inv[T]

Check sets the condition for the invariant (fluent style)

func (*Inv[T]) Msg

func (inv *Inv[T]) Msg(msg string) *Inv[T]

Msg sets an optional error message

func (*Inv[T]) Validate

func (inv *Inv[T]) Validate(state T) error

Validate checks the invariant against the state

type InvSuite

type InvSuite[T any] []*Inv[T]

InvSuite represents many invariants

func (InvSuite[T]) Check

func (suite InvSuite[T]) Check(state T) []error

Check checks all invariants in the suite

Directories

Path Synopsis
examples
automatic command
manual command

Jump to

Keyboard shortcuts

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