uitest

package
v0.1.16 Latest Latest
Warning

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

Go to latest
Published: Apr 30, 2026 License: MIT Imports: 7 Imported by: 0

Documentation

Overview

Package uitest provides reusable testing utilities for the gogpu/ui toolkit.

This package eliminates the need for each test file to define its own mock Canvas and Context implementations. It provides:

Example usage:

func TestButton_Draw(t *testing.T) {
    btn := button.New(button.Text("OK"))
    btn.SetBounds(geometry.NewRect(0, 0, 100, 40))

    canvas := &uitest.MockCanvas{}
    ctx := uitest.NewMockContext()
    btn.Draw(ctx, canvas)

    if len(canvas.Texts) == 0 {
        t.Fatal("expected text to be drawn")
    }
    if canvas.Texts[0].Text != "OK" {
        t.Errorf("text = %q, want %q", canvas.Texts[0].Text, "OK")
    }
}

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func AssertColorEqual

func AssertColorEqual(t *testing.T, got, want widget.Color)

AssertColorEqual checks that two colors are approximately equal within floating-point tolerance.

func AssertCursor

func AssertCursor(t *testing.T, ctx *MockContext, expected widget.CursorType)

AssertCursor checks that the context cursor matches the expected type.

func AssertDrawnText

func AssertDrawnText(t *testing.T, canvas *MockCanvas, expected string)

AssertDrawnText checks that the canvas contains at least one DrawText call with the expected text string. It fails the test if no matching text is found.

func AssertFocused

func AssertFocused(t *testing.T, ctx *MockContext, w widget.Widget)

AssertFocused checks that the given widget currently has focus in the context.

func AssertInvalidated

func AssertInvalidated(t *testing.T, ctx *MockContext)

AssertInvalidated checks that the context was invalidated at least once.

func AssertNoDrawnText

func AssertNoDrawnText(t *testing.T, canvas *MockCanvas, text string)

AssertNoDrawnText checks that the canvas does not contain a DrawText call with the given text string. It fails the test if the text is found.

func AssertNotFocused

func AssertNotFocused(t *testing.T, ctx *MockContext, w widget.Widget)

AssertNotFocused checks that the given widget does NOT have focus.

func AssertNotInvalidated

func AssertNotInvalidated(t *testing.T, ctx *MockContext)

AssertNotInvalidated checks that the context was not invalidated.

func AssertRectDrawn

func AssertRectDrawn(t *testing.T, canvas *MockCanvas, expected geometry.Rect)

AssertRectDrawn checks that a rectangle was drawn at the expected bounds. It compares using approximate float32 equality.

func Click

func Click(x, y float32) *event.MouseEvent

Click creates a left mouse button press event at the given position.

Both Position and GlobalPosition are set to (x, y) with no modifiers.

func DoubleClick

func DoubleClick(x, y float32) *event.MouseEvent

DoubleClick creates a double-click event at the given position.

Both Position and GlobalPosition are set to (x, y) with ClickCount=2.

func FocusGained

func FocusGained() *event.FocusEvent

FocusGained creates a focus gained event.

func FocusLost

func FocusLost() *event.FocusEvent

FocusLost creates a focus lost event.

func KeyPress

func KeyPress(code event.Key, mods event.Modifiers) *event.KeyEvent

KeyPress creates a key press event for the given key code with no modifiers.

func KeyRelease

func KeyRelease(code event.Key, mods event.Modifiers) *event.KeyEvent

KeyRelease creates a key release event for the given key code.

func KeyType

func KeyType(code event.Key, r rune, mods event.Modifiers) *event.KeyEvent

KeyType creates a key press event that also produces a character (rune).

Use this for simulating text input where both the key code and the typed character matter.

func LayoutWidget

func LayoutWidget(w widget.Widget, width, height float32) geometry.Size

LayoutWidget performs layout on a widget with the given available dimensions and returns the resulting size.

The constraints are set to a loose box from (0,0) to (width, height). This simulates the common case where a parent offers available space and the widget sizes itself within those bounds.

func LayoutWidgetTight

func LayoutWidgetTight(w widget.Widget, width, height float32) geometry.Size

LayoutWidgetTight performs layout on a widget with tight constraints (the widget must be exactly the given size) and returns the resulting size.

func MouseDrag

func MouseDrag(x, y float32) *event.MouseEvent

MouseDrag creates a mouse drag event at the given position with the left button held.

func MouseEnter

func MouseEnter(x, y float32) *event.MouseEvent

MouseEnter creates a mouse enter event at the given position.

func MouseLeave

func MouseLeave(x, y float32) *event.MouseEvent

MouseLeave creates a mouse leave event at the given position.

func MouseMove

func MouseMove(x, y float32) *event.MouseEvent

MouseMove creates a mouse move event at the given position.

func Release

func Release(x, y float32) *event.MouseEvent

Release creates a left mouse button release event at the given position.

Both Position and GlobalPosition are set to (x, y) with no modifiers.

func RightClick

func RightClick(x, y float32) *event.MouseEvent

RightClick creates a right mouse button press event at the given position.

func SimulateClick

func SimulateClick(w widget.Widget, x, y float32) bool

SimulateClick sends a press+release sequence at (x, y) to the widget and returns true if the press event was consumed.

This simulates a complete click gesture: MousePress followed by MouseRelease at the same position.

func SimulateClickWithContext

func SimulateClickWithContext(w widget.Widget, ctx widget.Context, x, y float32) bool

SimulateClickWithContext sends a press+release sequence using the provided context.

func SimulateKeyPress

func SimulateKeyPress(w widget.Widget, code event.Key) bool

SimulateKeyPress sends a key press event to the widget and returns true if the event was consumed.

func SimulateKeyPressWithMods

func SimulateKeyPressWithMods(w widget.Widget, code event.Key, mods event.Modifiers) bool

SimulateKeyPressWithMods sends a key press event with modifiers to the widget and returns true if the event was consumed.

func WheelScroll

func WheelScroll(x, y, deltaY float32) *event.WheelEvent

WheelScroll creates a wheel scroll event at position (x, y) with the given vertical delta.

Positive deltaY scrolls up (content moves down), negative scrolls down.

func WheelScrollH

func WheelScrollH(x, y, deltaX, deltaY float32) *event.WheelEvent

WheelScrollH creates a wheel scroll event with both horizontal and vertical deltas.

Types

type ClipRoundRectCall

type ClipRoundRectCall struct {
	Bounds geometry.Rect
	Radius float32
}

ClipRoundRectCall records a single PushClipRoundRect invocation.

type DrawCircleCall

type DrawCircleCall struct {
	Center geometry.Point
	Radius float32
	Color  widget.Color
}

DrawCircleCall records a single DrawCircle invocation.

type DrawImageCall

type DrawImageCall struct {
	Image image.Image
	At    geometry.Point
}

DrawImageCall records a single DrawImage invocation.

type DrawLineCall

type DrawLineCall struct {
	From        geometry.Point
	To          geometry.Point
	Color       widget.Color
	StrokeWidth float32
}

DrawLineCall records a single DrawLine invocation.

type DrawRectCall

type DrawRectCall struct {
	Bounds geometry.Rect
	Color  widget.Color
}

DrawRectCall records a single DrawRect invocation.

type DrawRoundRectCall

type DrawRoundRectCall struct {
	Bounds geometry.Rect
	Color  widget.Color
	Radius float32
}

DrawRoundRectCall records a single DrawRoundRect invocation.

type DrawTextCall

type DrawTextCall struct {
	Text     string
	Bounds   geometry.Rect
	FontSize float32
	Color    widget.Color
	Bold     bool
	Align    widget.TextAlign
}

DrawTextCall records a single DrawText invocation.

type MockCanvas

type MockCanvas struct {
	// Clears records arguments passed to Clear.
	Clears []widget.Color

	// Rects records arguments passed to DrawRect.
	Rects []DrawRectCall

	// StrokeRects records arguments passed to StrokeRect.
	StrokeRects []StrokeRectCall

	// RoundRects records arguments passed to DrawRoundRect.
	RoundRects []DrawRoundRectCall

	// StrokeRoundRects records arguments passed to StrokeRoundRect.
	StrokeRoundRects []StrokeRoundRectCall

	// Circles records arguments passed to DrawCircle.
	Circles []DrawCircleCall

	// StrokeCircles records arguments passed to StrokeCircle.
	StrokeCircles []StrokeCircleCall

	// StrokeArcs records arguments passed to StrokeArc.
	StrokeArcs []StrokeArcCall

	// StrokeArcStyleds records arguments passed to StrokeArcStyled.
	StrokeArcStyleds []StrokeArcStyledCall

	// Lines records arguments passed to DrawLine.
	Lines []DrawLineCall

	// Texts records arguments passed to DrawText.
	Texts []DrawTextCall

	// Images records arguments passed to DrawImage.
	Images []DrawImageCall

	// Clips records arguments passed to PushClip.
	Clips []geometry.Rect

	// ClipRoundRects records arguments passed to PushClipRoundRect.
	ClipRoundRects []ClipRoundRectCall

	// Transforms records arguments passed to PushTransform.
	Transforms []geometry.Point

	// PopClipCount tracks how many times PopClip was called.
	PopClipCount int

	// PopTransformCount tracks how many times PopTransform was called.
	PopTransformCount int
	// contains filtered or unexported fields
}

MockCanvas records all draw calls for verification in tests.

It implements widget.Canvas and stores each invocation in typed slices. Use MockCanvas.Reset to clear all recorded calls between test phases.

Example:

canvas := &uitest.MockCanvas{}
myWidget.Draw(ctx, canvas)
if len(canvas.Rects) != 1 {
    t.Errorf("expected 1 rect, got %d", len(canvas.Rects))
}

func DrawWidget

func DrawWidget(w widget.Widget) *MockCanvas

DrawWidget performs a draw on the widget using a fresh MockCanvas and MockContext, then returns the canvas for inspection.

The widget should have its bounds set before calling this function (typically via SetBounds or after a Layout call).

func DrawWidgetWithContext

func DrawWidgetWithContext(w widget.Widget, ctx widget.Context) *MockCanvas

DrawWidgetWithContext performs a draw on the widget using a fresh MockCanvas and the provided context, then returns the canvas for inspection.

func (*MockCanvas) Clear

func (c *MockCanvas) Clear(color widget.Color)

Clear records the color argument.

func (*MockCanvas) ClipBounds added in v0.1.14

func (c *MockCanvas) ClipBounds() geometry.Rect

ClipBounds returns a large default clip rectangle.

func (*MockCanvas) DrawCircle

func (c *MockCanvas) DrawCircle(center geometry.Point, radius float32, color widget.Color)

DrawCircle records the center, radius, and color arguments.

func (*MockCanvas) DrawImage

func (c *MockCanvas) DrawImage(img image.Image, at geometry.Point)

DrawImage records the image and position arguments.

func (*MockCanvas) DrawLine

func (c *MockCanvas) DrawLine(from, to geometry.Point, color widget.Color, strokeWidth float32)

DrawLine records the from, to, color, and stroke width arguments.

func (*MockCanvas) DrawRect

func (c *MockCanvas) DrawRect(r geometry.Rect, color widget.Color)

DrawRect records the rect and color arguments.

func (*MockCanvas) DrawRoundRect

func (c *MockCanvas) DrawRoundRect(r geometry.Rect, color widget.Color, radius float32)

DrawRoundRect records the rect, color, and radius arguments.

func (*MockCanvas) DrawText

func (c *MockCanvas) DrawText(text string, bounds geometry.Rect, fontSize float32, color widget.Color, bold bool, align widget.TextAlign)

DrawText records all text drawing arguments.

func (*MockCanvas) FillRectDirect added in v0.1.14

func (c *MockCanvas) FillRectDirect(r geometry.Rect, color widget.Color)

FillRectDirect records as DrawRect — mock does not distinguish CPU/GPU path.

func (*MockCanvas) MeasureText

func (c *MockCanvas) MeasureText(text string, fontSize float32, _ bool) float32

MeasureText returns an approximate width for the given text. Uses average character width (0.5 * fontSize) for test predictability.

func (*MockCanvas) PopClip

func (c *MockCanvas) PopClip()

PopClip increments the pop clip counter.

func (*MockCanvas) PopTransform

func (c *MockCanvas) PopTransform()

PopTransform restores the previous transform offset.

func (*MockCanvas) PushClip

func (c *MockCanvas) PushClip(r geometry.Rect)

PushClip records the clip rectangle.

func (*MockCanvas) PushClipRoundRect

func (c *MockCanvas) PushClipRoundRect(r geometry.Rect, radius float32)

PushClipRoundRect records the clip rounded rectangle and radius.

func (*MockCanvas) PushTransform

func (c *MockCanvas) PushTransform(offset geometry.Point)

PushTransform records the translation offset and updates the cumulative offset.

func (*MockCanvas) ReplayScene added in v0.1.14

func (c *MockCanvas) ReplayScene(_ *scene.Scene)

ReplayScene is a no-op for the mock canvas.

func (*MockCanvas) Reset

func (c *MockCanvas) Reset()

Reset clears all recorded calls, returning the canvas to its initial state.

func (*MockCanvas) StrokeArc added in v0.1.14

func (c *MockCanvas) StrokeArc(center geometry.Point, radius float32,
	startAngle, sweepAngle float64, color widget.Color, strokeWidth float32)

StrokeArc records the center, radius, angles, color, and stroke width arguments.

func (*MockCanvas) StrokeArcStyled added in v0.1.14

func (c *MockCanvas) StrokeArcStyled(center geometry.Point, radius float32,
	startAngle, sweepAngle float64, color widget.Color, strokeWidth float32, lineCap widget.LineCap)

StrokeArcStyled records the center, radius, angles, color, stroke width, and line cap.

func (*MockCanvas) StrokeCircle

func (c *MockCanvas) StrokeCircle(center geometry.Point, radius float32, color widget.Color, strokeWidth float32)

StrokeCircle records the center, radius, color, and stroke width arguments.

func (*MockCanvas) StrokeRect

func (c *MockCanvas) StrokeRect(r geometry.Rect, color widget.Color, strokeWidth float32)

StrokeRect records the rect, color, and stroke width arguments.

func (*MockCanvas) StrokeRoundRect

func (c *MockCanvas) StrokeRoundRect(r geometry.Rect, color widget.Color, radius float32, strokeWidth float32)

StrokeRoundRect records the rect, color, radius, and stroke width arguments.

func (*MockCanvas) TotalDrawCalls

func (c *MockCanvas) TotalDrawCalls() int

TotalDrawCalls returns the total number of recorded draw operations (excluding clip and transform operations).

func (*MockCanvas) TransformOffset

func (c *MockCanvas) TransformOffset() geometry.Point

TransformOffset returns the current cumulative transform offset.

type MockContext

type MockContext struct {
	// FocusedVal is the widget that currently has focus.
	FocusedVal widget.Widget

	// TimeVal is returned by Now(). Defaults to a fixed time.
	TimeVal time.Time

	// DeltaVal is returned by DeltaTime(). Defaults to 16ms.
	DeltaVal time.Duration

	// ScaleVal is returned by Scale(). Defaults to 1.0.
	ScaleVal float32

	// CursorVal is returned by Cursor() and set by SetCursor().
	CursorVal widget.CursorType

	// ThemeVal is returned by ThemeProvider(). Defaults to nil.
	ThemeVal widget.ThemeProvider

	// OverlayVal is returned by OverlayManager(). Defaults to nil.
	OverlayVal widget.OverlayManager

	// WindowSizeVal is returned by WindowSize(). Defaults to 800x600.
	WindowSizeVal geometry.Size

	// SchedulerVal is returned by Scheduler(). Defaults to nil.
	SchedulerVal widget.SchedulerRef

	// Invalidated is set to true when Invalidate() is called.
	Invalidated bool

	// InvalidatedRects collects all rectangles passed to InvalidateRect().
	InvalidatedRects []geometry.Rect

	// InvalidateCount tracks how many times Invalidate() was called.
	InvalidateCount int
}

MockContext provides a configurable test implementation of widget.Context.

All fields are exported for direct configuration. Use NewMockContext for sensible defaults, then override fields as needed.

Example:

ctx := uitest.NewMockContext()
ctx.ScaleVal = 2.0  // HiDPI
myWidget.Draw(ctx, canvas)
if ctx.Invalidated {
    t.Log("widget requested redraw")
}

func NewMockContext

func NewMockContext() *MockContext

NewMockContext creates a MockContext with sensible defaults for testing.

Defaults:

  • Scale: 1.0
  • DeltaTime: 16ms
  • WindowSize: 800x600
  • Time: 2025-01-01 00:00:00 UTC (deterministic for tests)

func (*MockContext) Cursor

func (c *MockContext) Cursor() widget.CursorType

Cursor returns CursorVal.

func (*MockContext) DeltaTime

func (c *MockContext) DeltaTime() time.Duration

DeltaTime returns DeltaVal.

func (*MockContext) FocusedWidget

func (c *MockContext) FocusedWidget() widget.Widget

FocusedWidget returns the currently focused widget.

func (*MockContext) Invalidate

func (c *MockContext) Invalidate()

Invalidate sets Invalidated to true and increments InvalidateCount.

func (*MockContext) InvalidateRect

func (c *MockContext) InvalidateRect(r geometry.Rect)

InvalidateRect appends the rectangle to InvalidatedRects.

func (*MockContext) IsFocused

func (c *MockContext) IsFocused(w widget.Widget) bool

IsFocused returns true if w is the currently focused widget.

func (*MockContext) Now

func (c *MockContext) Now() time.Time

Now returns TimeVal.

func (*MockContext) OverlayManager

func (c *MockContext) OverlayManager() widget.OverlayManager

OverlayManager returns OverlayVal.

func (*MockContext) ReleaseFocus

func (c *MockContext) ReleaseFocus(w widget.Widget)

ReleaseFocus clears focus if the given widget currently has it.

func (*MockContext) RequestFocus

func (c *MockContext) RequestFocus(w widget.Widget)

RequestFocus sets FocusedVal to the given widget.

func (*MockContext) Reset

func (c *MockContext) Reset()

Reset clears all recorded state (invalidation, cursor) while preserving configuration.

func (*MockContext) Scale

func (c *MockContext) Scale() float32

Scale returns ScaleVal.

func (*MockContext) Scheduler

func (c *MockContext) Scheduler() widget.SchedulerRef

Scheduler returns SchedulerVal.

func (*MockContext) SetCursor

func (c *MockContext) SetCursor(cursor widget.CursorType)

SetCursor sets CursorVal.

func (*MockContext) ThemeProvider

func (c *MockContext) ThemeProvider() widget.ThemeProvider

ThemeProvider returns ThemeVal.

func (*MockContext) WindowSize

func (c *MockContext) WindowSize() geometry.Size

WindowSize returns WindowSizeVal.

type StrokeArcCall added in v0.1.14

type StrokeArcCall struct {
	Center      geometry.Point
	Radius      float32
	StartAngle  float64
	SweepAngle  float64
	Color       widget.Color
	StrokeWidth float32
}

StrokeArcCall records a single StrokeArc invocation.

type StrokeArcStyledCall added in v0.1.14

type StrokeArcStyledCall struct {
	Center      geometry.Point
	Radius      float32
	StartAngle  float64
	SweepAngle  float64
	Color       widget.Color
	StrokeWidth float32
	Cap         widget.LineCap
}

StrokeArcStyledCall records a single StrokeArcStyled invocation.

type StrokeCircleCall

type StrokeCircleCall struct {
	Center      geometry.Point
	Radius      float32
	Color       widget.Color
	StrokeWidth float32
}

StrokeCircleCall records a single StrokeCircle invocation.

type StrokeRectCall

type StrokeRectCall struct {
	Bounds      geometry.Rect
	Color       widget.Color
	StrokeWidth float32
}

StrokeRectCall records a single StrokeRect invocation.

type StrokeRoundRectCall

type StrokeRoundRectCall struct {
	Bounds      geometry.Rect
	Color       widget.Color
	Radius      float32
	StrokeWidth float32
}

StrokeRoundRectCall records a single StrokeRoundRect invocation.

Jump to

Keyboard shortcuts

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