irtest

package
v0.8.0 Latest Latest
Warning

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

Go to latest
Published: Sep 9, 2026 License: MIT Imports: 6 Imported by: 0

Documentation

Overview

Package irtest provides a recording ir.Backend for tests.

It lets a test assert on what a geom or the renderer actually emitted — which primitives, in which order, with which style — instead of inspecting rendered pixels or scraped SVG. That keeps model-layer tests independent of any backend.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func NullBackend

func NullBackend() ir.Backend

NullBackend returns an ir.Backend that draws nothing and remembers nothing, measuring with the same built-in table Recorder uses.

It is what a benchmark renders into when the thing being measured is figure's own work: with a real emitter most of a frame's time and memory belongs to the emitter, and a gate on figure's allocations would be reading someone else's.

func NullTarget

func NullTarget() ir.Target

NullTarget returns an ir.Target handing out NullBackend.

Types

type Call

type Call struct {
	Op       string
	Points   []ir.Point
	Path     *ir.Path
	Stroke   ir.Stroke
	Fill     ir.Fill
	Rule     ir.FillRule
	Text     ir.TextRun
	Marker   ir.Marker
	Style    ir.MarkerStyle
	Image    image.Image
	Rect     ir.Rect
	Affine   ir.Affine
	HasClip  bool
	ClipRect ir.Rect
}

Call is one recorded drawing operation.

type Recorder

type Recorder struct {
	Calls []Call
	Depth int

	// MaxDepth is the deepest the Push/Pop stack ever got, which is how a test
	// checks that clipping was actually applied around the data layers.
	MaxDepth int

	// Damaged is what each frame was told to repaint, one entry per call to
	// [Recorder.Damage], and Whole says which of those meant the whole frame.
	// Frames counts the frames flushed.
	Damaged [][]ir.Rect
	Whole   []bool
	Frames  int

	// Resized is the size the surface was told to take, one entry per call to
	// [Recorder.Resize], and Described is what it was told to say about itself.
	Resized   [][2]int
	Described []ir.Description
}

Recorder is an ir.Backend that remembers every call.

It measures with the same built-in metrics table the SVG backend falls back to, so layout in a test behaves like layout in a real stdlib-only render.

func New

func New() *Recorder

New returns an empty Recorder.

func (*Recorder) Count

func (r *Recorder) Count(op string) int

Count returns how many calls of the given op were recorded.

func (*Recorder) Damage

func (r *Recorder) Damage(rects []ir.Rect)

Damage implements ir.Partial: it records what a frame was told to repaint rather than repainting anything.

It is how a test checks damage tracking end to end — that a chart whose data moved repaints where it moved and not the whole canvas.

func (*Recorder) Describe

func (r *Recorder) Describe(d ir.Description)

Describe implements ir.Semantics: it records what the chart said about itself, so a test can check that it reached the backend at all.

func (*Recorder) FillPath

func (r *Recorder) FillPath(p *ir.Path, fill ir.Fill, rule ir.FillRule)

func (*Recorder) Filter

func (r *Recorder) Filter(op string) []Call

Filter returns the recorded calls of the given op.

func (*Recorder) Flush

func (r *Recorder) Flush() error

Flushes counts the frames completed on this Recorder.

func (*Recorder) Image

func (r *Recorder) Image(img image.Image, dst ir.Rect)

func (*Recorder) Markers

func (r *Recorder) Markers(shape ir.Marker, at []ir.Point, style ir.MarkerStyle)

func (*Recorder) Measure

func (r *Recorder) Measure(run ir.TextRun) ir.TextMetrics

func (*Recorder) Ops

func (r *Recorder) Ops() []string

Ops returns the recorded operation names, for a quick order assertion.

func (*Recorder) Polyline

func (r *Recorder) Polyline(pts []ir.Point, style ir.Stroke)

func (*Recorder) Pop

func (r *Recorder) Pop()

func (*Recorder) Push

func (r *Recorder) Push(clip *ir.Path, xform ir.Affine)

func (*Recorder) Reset

func (r *Recorder) Reset()

Reset clears the recording, keeping the memory. A test driving several frames through one Recorder calls it between them.

func (*Recorder) Resize

func (r *Recorder) Resize(s ir.Surface) error

Resize implements ir.Resizer: it records the size a surface was told to take rather than taking one, which is how a test checks that a chart being resized tells its backend so.

func (*Recorder) String

func (r *Recorder) String() string

String renders the recording as a short, diffable trace.

func (*Recorder) StrokePath

func (r *Recorder) StrokePath(p *ir.Path, style ir.Stroke)

func (*Recorder) Target

func (r *Recorder) Target() ir.Target

Target returns an ir.Target handing out r, so that a test can drive github.com/timzifer/figure.Plot.Render or Plot.Live through a recorder. Closing it does nothing: a recorder has nothing to finalise.

func (*Recorder) Text

func (r *Recorder) Text(run ir.TextRun)

func (*Recorder) Texts

func (r *Recorder) Texts() []string

Texts returns the strings of every recorded text run, in order.

func (*Recorder) Trace

func (r *Recorder) Trace() []string

Trace renders the recording one line per call, with the geometry and the style spelled out.

It is Recorder.String at the detail a comparison needs: two charts that produce the same trace are the same chart, which is how a spec round trip is checked without a golden file. Coordinates are printed to three decimals, the same precision the SVG emitter writes.

Jump to

Keyboard shortcuts

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