operators

package
v0.50.0 Latest Latest
Warning

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

Go to latest
Published: Aug 28, 2026 License: MIT Imports: 4 Imported by: 0

README

Operators

Evaluates assertion operators (equals, contains, greaterThan, between, …) against an extracted actual value and the assertion's expected value.

Model: one comparator per type, dispatched through a registry

OperatorType ("equals", "greaterThan", …)
        │
        ▼
  comparators map[OperatorType]Comparator      Comparator = func(actual, expected any) (bool, error)
        │
        ▼
  Compare(type, actual, expected) (bool, error)   // looks up + applies
  IsKnown(type) bool                              // is a comparator registered?
  • Built-in comparators are registered in registry.go.
  • Add an operator by registering a Comparator — built-ins inline, external ones via Register(type, comparator) from an init(). No dispatch switch to edit.
  • IsKnown lets the decode layer reject an unknown operator at flow-parse time (mirroring the extractor registry) instead of failing inside Compare at run.

Coercion contract (lenient, deliberate, tested)

Comparisons compare coerced forms, because the wire delivers expected values as strings while extracted actuals are typed (e.g. an int status code vs "200"):

  • string operators (equals, notEquals, contains, startsWith, endsWith, regex) compare toString(actual) vs toString(expected) — so 200 equals "200". equals is string equality, not type-aware equality.
  • numeric operators (greaterThan, lessThan, …OrEqual, between) coerce both sides via toFloat; non-numeric input is an error.
  • empty / notEmpty inspect nil / empty string / empty list / empty map.

This contract is pinned by table tests in registry_test.go. Changing it (e.g. making equals type-aware) is a behavior change visible to existing flows.

Files

  • types.goOperatorType + the built-in constants.
  • registry.go — the comparators registry, Compare, IsKnown, Register, and the coercion helpers (toString, toFloat, compareNumeric, between, isEmpty).

Documentation

Overview

Package operators evaluates assertion operators (equals, contains, greaterThan, between, ...) against an extracted actual value and the assertion's expected value.

One Comparator per operator type, dispatched through a registry: comparators maps an OperatorType to a func(actual, expected any) (bool, error). Compare looks up and applies it; IsKnown reports whether a type is registered (used to reject a bad operator at flow-decode rather than at execution). Adding an operator = register a Comparator (built-ins in registry.go; external ones via Register from an init()) — no switch to edit.

Comparisons are deliberately lenient: string operators compare stringified forms (so 200 == "200") and numeric operators coerce via toFloat. This mirrors the wire, which delivers expected values as strings. It is a tested contract, not type-aware equality — see Compare and registry_test.go.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func Compare

func Compare(operatorType OperatorType, actual, expected any) (bool, error)

Compare applies the registered comparator for operatorType, returning an error when the operator is unknown.

Coercion contract: comparisons are lenient. equals/notEquals/contains and the other string operators compare the stringified forms (toString), so the integer 200 and the string "200" are equal; the numeric operators (greaterThan/between/...) coerce both sides via toFloat. This matches the wire, which delivers expected values as strings. It is a deliberate, tested contract, not type-aware equality.

func IsKnown

func IsKnown(operatorType OperatorType) bool

IsKnown reports whether operatorType has a registered comparator. Callers use it to reject an unknown operator at flow-decode time (mirroring the extractor registry) instead of failing deep inside Compare during execution.

func Register

func Register(operatorType OperatorType, comparator Comparator)

Register adds (or overrides) the comparator for an operator type. Call from an init() so a new operator becomes available without editing the dispatch core.

Types

type Comparator

type Comparator func(actual, expected any) (bool, error)

Comparator applies an operator to an extracted actual value and the assertion's expected value. Comparisons are lenient (stringify/coerce) because the wire delivers expected values as strings while extracted actuals are typed (e.g. an int statusCode vs the string "200").

type OperatorType

type OperatorType string

OperatorType is the wire identifier for an assertion operator. Each value has one registered Comparator (see registry.go); the constants below are the built-ins.

const (
	OperatorTypeEquals             OperatorType = "equals"
	OperatorTypeNotEquals          OperatorType = "notEquals"
	OperatorTypeContains           OperatorType = "contains"
	OperatorTypeNotContains        OperatorType = "notContains"
	OperatorTypeStartsWith         OperatorType = "startsWith"
	OperatorTypeEndsWith           OperatorType = "endsWith"
	OperatorTypeRegex              OperatorType = "regex"
	OperatorTypeEmpty              OperatorType = "empty"
	OperatorTypeNotEmpty           OperatorType = "notEmpty"
	OperatorTypeGreaterThan        OperatorType = "greaterThan"
	OperatorTypeLessThan           OperatorType = "lessThan"
	OperatorTypeGreaterThanOrEqual OperatorType = "greaterThanOrEqual"
	OperatorTypeLessThanOrEqual    OperatorType = "lessThanOrEqual"
	OperatorTypeBetween            OperatorType = "between"
)

Jump to

Keyboard shortcuts

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