visualizer API

visualizer

package

API reference for the visualizer package.

I
interface

VisualizerInterface

VisualizerInterface is implemented by objects that can render their FSM structure.

pkg/fsm/visualizer/visualizer.go:10-12
type VisualizerInterface interface

Methods

GetStructure
Method

Returns

initial string
transitions map[string][]string
wildcards []string
func GetStructure(...)
F
function

ToMermaid

ToMermaid renders the FSM as a Mermaid state diagram.

Parameters

Returns

string
pkg/fsm/visualizer/visualizer.go:15-46
func ToMermaid(v VisualizerInterface) string

{
	initial, transitions, wildcards := v.GetStructure()
	var sb strings.Builder
	sb.WriteString("stateDiagram-v2\n")

	if initial != "" {
		sb.WriteString(fmt.Sprintf("    [*] --> %s\n", initial))
	}

	var keys []string
	for k := range transitions {
		keys = append(keys, k)
	}
	sort.Strings(keys)

	for _, src := range keys {
		dsts := transitions[src]
		sort.Strings(dsts)
		for _, dst := range dsts {
			sb.WriteString(fmt.Sprintf("    %s --> %s\n", src, dst))
		}
	}

	if len(wildcards) > 0 {
		sort.Strings(wildcards)
		for _, dst := range wildcards {
			sb.WriteString(fmt.Sprintf("    [*] --> %s : (Wildcard)\n", dst))
		}
	}

	return sb.String()
}
F
function

ToGraphviz

ToGraphviz renders the FSM as a Graphviz DOT digraph.

Parameters

Returns

string
pkg/fsm/visualizer/visualizer.go:49-84
func ToGraphviz(v VisualizerInterface) string

{
	initial, transitions, wildcards := v.GetStructure()
	var sb strings.Builder
	sb.WriteString("digraph FSM {\n")
	sb.WriteString("    rankdir=LR;\n")
	sb.WriteString("    node [shape=box style=rounded];\n")

	if initial != "" {
		sb.WriteString("    start [shape=point];\n")
		sb.WriteString(fmt.Sprintf("    start -> %s;\n", initial))
	}

	var keys []string
	for k := range transitions {
		keys = append(keys, k)
	}
	sort.Strings(keys)

	for _, src := range keys {
		dsts := transitions[src]
		sort.Strings(dsts)
		for _, dst := range dsts {
			sb.WriteString(fmt.Sprintf("    %s -> %s;\n", src, dst))
		}
	}

	if len(wildcards) > 0 {
		sort.Strings(wildcards)
		for _, dst := range wildcards {
			sb.WriteString(fmt.Sprintf("    ANY_STATE -> %s [label=\"*\"];\n", dst))
		}
	}

	sb.WriteString("}\n")
	return sb.String()
}
S
struct

testFSM

pkg/fsm/visualizer/visualizer_test.go:8-12
type testFSM struct

Methods

GetStructure
Method

Returns

string
map[string][]string
[]string
func (*testFSM) GetStructure() (string, map[string][]string, []string)
{
	return t.initial, t.transitions, t.wildcards
}

Fields

Name Type Description
initial string
transitions map[string][]string
wildcards []string
F
function

TestToMermaid_Basic

Parameters

pkg/fsm/visualizer/visualizer_test.go:18-33
func TestToMermaid_Basic(t *testing.T)

{
	v := &testFSM{
		initial:     "draft",
		transitions: map[string][]string{"draft": {"paid"}, "paid": {"shipped"}},
	}
	out := ToMermaid(v)
	if !strings.Contains(out, "stateDiagram-v2") {
		t.Error("expected stateDiagram-v2 header")
	}
	if !strings.Contains(out, "[*] --> draft") {
		t.Error("expected initial state arrow")
	}
	if !strings.Contains(out, "draft --> paid") {
		t.Error("expected draft->paid transition")
	}
}
F
function

TestToMermaid_NoInitial

Parameters

pkg/fsm/visualizer/visualizer_test.go:35-43
func TestToMermaid_NoInitial(t *testing.T)

{
	v := &testFSM{
		transitions: map[string][]string{"a": {"b"}},
	}
	out := ToMermaid(v)
	if strings.Contains(out, "[*] -->") {
		t.Error("expected no initial state")
	}
}
F
function

TestToMermaid_Wildcards

Parameters

pkg/fsm/visualizer/visualizer_test.go:45-57
func TestToMermaid_Wildcards(t *testing.T)

{
	v := &testFSM{
		initial:   "active",
		wildcards: []string{"cancelled", "archived"},
	}
	out := ToMermaid(v)
	if !strings.Contains(out, "(Wildcard)") {
		t.Error("expected wildcard label")
	}
	if !strings.Contains(out, "cancelled") || !strings.Contains(out, "archived") {
		t.Error("expected both wildcard destinations")
	}
}
F
function

TestToGraphviz_Basic

Parameters

pkg/fsm/visualizer/visualizer_test.go:59-74
func TestToGraphviz_Basic(t *testing.T)

{
	v := &testFSM{
		initial:     "start",
		transitions: map[string][]string{"start": {"end"}},
	}
	out := ToGraphviz(v)
	if !strings.Contains(out, "digraph FSM") {
		t.Error("expected graphviz header")
	}
	if !strings.Contains(out, "start [shape=point]") {
		t.Error("expected start node")
	}
	if !strings.Contains(out, "start -> end") {
		t.Error("expected start->end edge")
	}
}
F
function

TestToGraphviz_Wildcards

Parameters

pkg/fsm/visualizer/visualizer_test.go:76-84
func TestToGraphviz_Wildcards(t *testing.T)

{
	v := &testFSM{
		wildcards: []string{"cancelled"},
	}
	out := ToGraphviz(v)
	if !strings.Contains(out, "ANY_STATE -> cancelled") {
		t.Error("expected wildcard edge from ANY_STATE")
	}
}