Help us shape the future of Go! Take the 2026 Go Developer Survey

unique

package
v0.4.0 Latest Latest
Warning

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

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

Documentation

Overview

Package unique generates collision-resistant names, contexts, and other test-owned identifiers, so parallel runners never collide on a shared literal.

Package unique generates collision-free resource identifiers.

Hardcoded resource names are the single largest obstacle to running scenarios concurrently. Two scenarios that both create "TestAPI" collide the moment they overlap — and the failure is rarely legible: one scenario's create fails as a duplicate, or worse, one deletes the other's resource mid-flight and the victim fails somewhere unrelated.

So names are unique BY CONSTRUCTION rather than by convention. A feature author never writes a literal name; they ask for one.

Index

Constants

View Source
const ContextPlaceholder = "${CTX:"

ContextPlaceholder is the marker a feature file uses to reference a value the scenario stored.

Written as ${CTX:name} in Gherkin. Resolution is delegated to ContextValue, because which names are addressable is a property of the suite, not of this package.

View Source
const Placeholder = "${UNIQUE:"

Placeholder is the marker a feature file uses to request a generated name.

Written as ${UNIQUE:base} in Gherkin, so a feature never contains a literal resource name and cannot reintroduce the collision this package exists to prevent.

Variables

View Source
var ContextValue func(ctx context.Context, name string) (string, error)

ContextValue resolves a ${CTX:name} placeholder. A suite sets this once at start-up; nil means the suite exposes nothing, and any ${CTX:} reference is then an error rather than an empty substitution.

Functions

func Expand

func Expand(ctx context.Context, s string) (string, error)

Expand replaces every ${UNIQUE:base} in a string with a generated name.

Repeated occurrences of the SAME base within one string resolve to the same name, so a step can reference one resource twice in a payload. Different bases resolve differently.

func Install

func Install(ctx context.Context, g *Generator) error

Install attaches a generator to a runner's local scope. Called once per runner.

func Unique

func Unique(ctx context.Context, base string) (string, error)

Unique returns a unique name using the runner's generator.

func UniqueContext

func UniqueContext(ctx context.Context, base string) (string, error)

UniqueContext returns a unique API context path using the runner's generator.

Types

type Generator

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

Generator produces unique names within one runner.

The suffix is per RUNNER, not per name: every resource a runner creates shares it, which makes a stray resource attributable to the runner that leaked it. Without that, a leftover named with a fresh random token tells you nothing about where it came from.

func NewGenerator

func NewGenerator() (*Generator, error)

NewGenerator returns a generator with a fresh suffix.

func Of

func Of(ctx context.Context) (*Generator, error)

Of returns the runner's generator, creating one lazily if none was installed.

Lazy creation means a step never fails merely because a generator was not wired up — but it is guarded, because two concurrent scenarios in one runner racing to create the first generator would otherwise produce two suffixes and lose the attribution property.

func (*Generator) Suffix

func (g *Generator) Suffix() string

Suffix is the runner's shared token, exposed so a cleanup sweep can recognise its own resources by convention when a registry entry was somehow lost.

func (*Generator) Unique

func (g *Generator) Unique(base string) string

Unique returns a name derived from base.

Shape is base_suffix_counter: the base keeps it readable in a failing test's output, the suffix attributes it to a runner, and the counter separates repeated calls within one runner — a scenario that creates three APIs needs three distinct names.

func (*Generator) UniqueContext

func (g *Generator) UniqueContext(base string) string

UniqueContext returns a name that is also a legal API context path.

Separate from Unique because a context has different legality rules from a display name: it becomes part of a URL, so it must be lowercase and free of characters that would need escaping.

Jump to

Keyboard shortcuts

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