layouttest

package
v0.4.2 Latest Latest
Warning

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

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

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type AllSelector

type AllSelector struct{}

AllSelector selects all nodes

func (*AllSelector) Description

func (s *AllSelector) Description() string

func (*AllSelector) Select

func (s *AllSelector) Select(layout *Layout) []*Node

type Edge

type Edge struct {
	From   string  `json:"from"`
	To     string  `json:"to"`
	Style  string  `json:"style"`
	Color  string  `json:"color"`
	Points []Point `json:"points,omitempty"`
	// SourceSide / TargetSide are the resolved attachment sides of the routed
	// endpoints ("top"|"bottom"|"left"|"right"), if known — used by edge rules.
	SourceSide string `json:"sourceSide,omitempty"`
	TargetSide string `json:"targetSide,omitempty"`
	// SourcePosition / TargetPosition are the fractional position (0..1) of the
	// routed endpoint along its side (0 = top/left end, 1 = bottom/right end).
	SourcePosition float64 `json:"sourcePosition,omitempty"`
	TargetPosition float64 `json:"targetPosition,omitempty"`
	// Visibility is the layout's rendering class ("" or "visible" = full
	// edge, "stubbed" = numbered stub pair) — used by visibility rules.
	Visibility string `json:"visibility,omitempty"`
}

Edge represents a connection between two nodes

func (*Edge) BendCount

func (e *Edge) BendCount() int

BendCount is the number of interior corners on the routed polyline — the bends between the source and target ports (Points = [source, …bends…, target], so bends = len(Points) - 2). A straight edge has 0. Used by the max-bends rules: bends usually signal a detour around an obstacle, so the fitness default expects 0 and a fixture opts specific edges into more.

type FirstTypeSelector

type FirstTypeSelector struct {
	Type string
}

FirstTypeSelector selects the first node of a specific type

func (*FirstTypeSelector) Description

func (s *FirstTypeSelector) Description() string

func (*FirstTypeSelector) Select

func (s *FirstTypeSelector) Select(layout *Layout) []*Node

type IDSelector

type IDSelector struct {
	ID string
}

IDSelector selects a single node by ID

func (*IDSelector) Description

func (s *IDSelector) Description() string

func (*IDSelector) Select

func (s *IDSelector) Select(layout *Layout) []*Node

type Layout

type Layout struct {
	Nodes []Node `json:"nodes"`
	Edges []Edge `json:"edges"`
}

Layout represents the complete layout output

func FromLayoutGraph

func FromLayoutGraph(graph *layout.Graph) *Layout

FromLayoutGraph converts an engine output graph into the rule engine's Layout structure.

The DSL rules address nodes by their NAME (e.g. #S, #e1, #tV) — the label authored in the .ipmt — while layout.Graph identifies nodes by an internal numeric ID and edges reference those IDs. The selector/edge matchers look up nodes by Node.ID, so the Layout handed to them must be NAME-addressed: Node.ID = label, and each edge's From/To = the label of its endpoint. This is what makes `#S,@e1 has type=leadsto` and friends actually resolve. Edges carry their routed geometry (points, sides, positions) so rules can reason about bends, met sides and crossings.

Every consumer that evaluates DSL rules against a layout (layout-test-runner, gen-test-md) must use THIS conversion — an ad-hoc unmarshal leaves numeric IDs behind and every #name selector silently misses.

func (*Layout) GetEdge

func (l *Layout) GetEdge(from, to string) *Edge

GetEdge returns an edge from->to, or nil if not found

func (*Layout) GetNode

func (l *Layout) GetNode(id string) *Node

GetNode returns a node by ID, or nil if not found

func (*Layout) GetNodesByType

func (l *Layout) GetNodesByType(nodeType string) []*Node

GetNodesByType returns all nodes of a given type

func (*Layout) HasEvents

func (l *Layout) HasEvents() bool

HasEvents returns true if the layout contains any event nodes

func (*Layout) HasNode

func (l *Layout) HasNode(id string) bool

HasNode returns true if a node with the given ID exists

type MultiIDSelector

type MultiIDSelector struct {
	IDs []string
}

MultiIDSelector selects multiple nodes by ID list

func (*MultiIDSelector) Description

func (s *MultiIDSelector) Description() string

func (*MultiIDSelector) Missing

func (s *MultiIDSelector) Missing(layout *Layout) []string

Missing reports the IDs in the list that do not resolve to a node — a rule referencing a nonexistent ID must FAIL, not silently shrink to a vacuous assertion (e.g. "all #S1,#E1 have same center-x" passing because neither node exists).

func (*MultiIDSelector) Select

func (s *MultiIDSelector) Select(layout *Layout) []*Node

type Node

type Node struct {
	ID     string `json:"id"`
	Type   string `json:"type"` // "event", "thing", "concept", "boundary"
	X      int    `json:"x"`
	Y      int    `json:"y"`
	Width  int    `json:"width"`
	Height int    `json:"height"`
	Color  string `json:"color"`
	Text   string `json:"text"`
}

Node represents a layout node (event, thing, concept, or boundary)

func (*Node) CenterX

func (n *Node) CenterX() int

CenterX returns the center X coordinate of the node

func (*Node) CenterY

func (n *Node) CenterY() int

CenterY returns the center Y coordinate of the node

func (*Node) GetProperty

func (n *Node) GetProperty(name string) string

GetProperty returns a property value by name

type Point

type Point struct {
	X int `json:"x"`
	Y int `json:"y"`
}

Point represents a 2D coordinate

type Rule

type Rule interface {
	// Apply validates the rule against the layout
	Apply(layout *Layout) error

	// LineNum returns the source specification line number for this rule
	LineNum() int

	// Description returns a human-readable description of the rule
	Description() string

	// Specificity returns the specificity score for rule compaction
	// Higher scores indicate more specific rules that override general ones
	// Spec: gl:docs/dev/layout-gen/dsl-reference.md#L319-L381
	Specificity() int

	// CompactionKey returns a unique key for rule compaction
	// Rules with the same key may override each other based on specificity
	// Format: "nodeID:property" or "type:property" for type-based rules
	CompactionKey() string
}

Rule represents a single validation rule that can be applied to a layout Spec: gl:docs/dev/layout-gen/dsl-reference.md

type RuleRegistry

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

RuleRegistry accumulates rules and applies them to layouts Spec: gl:docs/dev/layout-gen/dsl-reference.md#L319-L381

func NewRuleRegistry

func NewRuleRegistry() *RuleRegistry

NewRuleRegistry creates a new empty rule registry

func (*RuleRegistry) AddRule

func (r *RuleRegistry) AddRule(rule Rule)

AddRule adds a rule to the registry with default scope specificity (0 = global) If a rule with the same compaction key exists, the more specific rule wins If specificity is equal, the later rule (higher line number) wins

func (*RuleRegistry) AddRuleWithScopeSpecificity

func (r *RuleRegistry) AddRuleWithScopeSpecificity(rule Rule, scopeSpec int)

AddRuleWithScopeSpecificity adds a rule with explicit scope specificity Scope specificity: 0=global, 1=global+tags, 2=parent, 3=parent+tags, 4=local, 5=local+tags

func (*RuleRegistry) ApplyAll

func (r *RuleRegistry) ApplyAll(layout *Layout) error

ApplyAll validates all compacted rules against the layout Rules are applied in line number order (ascending) Returns error on first failing rule

func (*RuleRegistry) ApplyAllErrors

func (r *RuleRegistry) ApplyAllErrors(layout *Layout) []error

ApplyAllErrors applies every rule and returns all failures (not just the first), for surveying reconciliation work.

func (*RuleRegistry) Count

func (r *RuleRegistry) Count() int

Count returns the number of rules in the registry

type Selector

type Selector interface {
	// Select returns matching nodes from the layout
	Select(layout *Layout) []*Node

	// Description returns a human-readable description
	Description() string
}

Selector represents a way to select nodes from a layout

type TextLengthCondition

type TextLengthCondition struct {
	Operator string // ">", ">=", "<", "<=", "="
	Value    int
}

TextLengthCondition represents a condition on node label length Spec: gl:docs/dev/layout-gen/dsl-reference.md#L227-L252

func (*TextLengthCondition) Matches

func (c *TextLengthCondition) Matches(node *Node) bool

type TypeSelector

type TypeSelector struct {
	Type string
}

TypeSelector selects all nodes of a specific type

func (*TypeSelector) Description

func (s *TypeSelector) Description() string

func (*TypeSelector) Select

func (s *TypeSelector) Select(layout *Layout) []*Node

Jump to

Keyboard shortcuts

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