blocktest

package
v0.7.0 Latest Latest
Warning

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

Go to latest
Published: Aug 29, 2026 License: Apache-2.0 Imports: 14 Imported by: 0

Documentation

Overview

Package blocktest builds fully populated content.Block fixtures by reflection so every copy, encode, and decode path in the workspace can be tested for FIELD-BY-FIELD completeness rather than for the handful of fields whose names a hand-written fixture happened to mention.

It lives beside the sealed unions it guards rather than inside any one consumer. The defect it prevents is a property of content itself — a struct literal or a type switch that enumerates a union's members by hand — and it occurs wherever content blocks are copied or translated: Harness copies and re-encodes them in three independent places (the loop runtime's message clone, the hook payload clone, and the compaction wire codec), the inference codecs build them in every decode path and consume them in every encode path, and foreignloops, acp, tui and mcp each carry a copy of their own. A literal silently drops any field added to content afterwards: the code still compiles, the existing tests still pass, and the new field is simply gone. That is exactly how ThinkingBlock.ProviderState and ToolUseBlock.ProviderState — the provider-private reasoning state whose loss makes signature replay impossible — went missing from all three Harness copies.

Being a sibling of content rather than an internal of one consumer is the whole point: an internal package can only defend the six packages that may import it, and the drift it detects is not confined to those six.

The fixtures here are therefore built by walking the struct with reflect and assigning every exported field a distinctive non-zero value. A field added to core is populated automatically, so a copy or codec that forgets it fails the round-trip assertion loudly instead of dropping it silently. A field whose type this package cannot yet populate fails the test with an explicit "extend blocktest" message rather than being skipped.

The fixture LIST is guarded the same way. A hand-maintained slice literal of variants is blind to a variant added to core in exactly the way a struct literal is blind to a field: nothing fails, the new variant is simply never exercised by any consumer's round-trip test. Blocks and Chunks therefore check themselves against the sealed unions as core's own source declares them — the content.BlockType constants and the isBlock/isChunk marker methods — so a new core variant fails here automatically instead of being noticed by luck.

This package is test support only. It is deliberately not under a _test.go file because several separate packages, in several separate modules, consume it. It imports testing, so it must never be imported by non-test code.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func AssertIndependent

func AssertIndependent(t *testing.T, orig, clone any)

AssertIndependent fails when clone reaches any mutable byte slice — or any nested block — that orig also reaches. Field equality alone does not prove a clone: a struct copy compares equal while still aliasing the original's backing arrays and sharing its nested pointers, which is the mutation leak every clone in Harness exists to prevent.

The parameters are untyped on purpose. The traversal is driven entirely by reflection and is indifferent to the sealed union a value belongs to, so narrowing it to content.Block would exclude content.Chunk values for no reason beyond the signature.

func Blocks

func Blocks(t *testing.T) []content.Block

Blocks returns one fully populated value of every content.Block variant, in the order the sealed union declares them. Every exported field of every returned block is non-zero, so a copy or codec that fails to carry a field forward is detectable by comparing against the fixture.

The list is checked against core's own declarations before it is returned (see assertBlocksComplete), so a variant added to core fails every consumer of this fixture rather than silently going untested.

func Chunks

func Chunks(t *testing.T) []content.Chunk

Chunks returns one fully populated value of every content.Chunk variant, in the order the sealed union declares them. Chunks have no wire codec, but they are copied and re-dispatched by the loop's streaming fold and by the live SSE transport, so the same field- and variant-completeness guarantees matter: a chunk field a fold forgets is a token that never reaches the accumulated block, and a chunk variant a dispatcher forgets is a delta the loop drops while still emitting a live event for it.

The list is checked against core's isChunk marker methods before it is returned (see assertChunksComplete).

func Populate

func Populate(t *testing.T, ptr any)

Populate fills every exported field of the struct behind ptr with a distinctive non-zero value derived from the field's path, so a copy that assigns the right type to the wrong field is caught alongside one that drops the field entirely. It fails the test when a field's type is not yet supported: an unsupported field must never be silently left at its zero value, because that is the failure mode this package exists to prevent.

Types

This section is empty.

Jump to

Keyboard shortcuts

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