Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

visualiser: Allow spacing in node names #38

Merged
merged 3 commits into from
Sep 24, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 17 additions & 0 deletions internal/graph/graph.go
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
package graph

import "slices"

func New() *Graph {
return &Graph{
graph: make(map[int][]int),
Expand Down Expand Up @@ -75,6 +77,21 @@ type Info struct {
Transitions []Transition
}

func (g *Graph) Nodes() []int {
var nodes []int
for node, ok := range g.validNodes {
if !ok {
continue
}

nodes = append(nodes, node)
}

slices.Sort(nodes)

return nodes
}

func (g *Graph) Info() Info {
var i Info
for _, node := range g.nodeOrder {
Expand Down
4 changes: 4 additions & 0 deletions internal/graph/graph_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -53,4 +53,8 @@ func TestGraph(t *testing.T) {
},
}
require.Equal(t, expected, actual)

actualNodes := g.Nodes()
expectedNodes := []int{1, 2, 3, 4, 5}
require.Equal(t, expectedNodes, actualNodes)
}
15 changes: 15 additions & 0 deletions internal/util/util.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
package util

import "unicode"

func CamelCaseToSpacing(s string) string {
var result []rune
for i, r := range s {
if unicode.IsUpper(r) && i > 0 {
result = append(result, ' ')
}

result = append(result, r)
}
return string(result)
}
31 changes: 31 additions & 0 deletions internal/util/util_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
package util_test

import (
"fmt"
"testing"

"github.com/stretchr/testify/require"

"github.com/luno/workflow/internal/util"
)

func TestCamelCaseToSpacing(t *testing.T) {
tests := []struct {
input string
expected string
}{
{"camelCase", "camel Case"},
{"thisIsATest", "this Is A Test"},
{"helloWorld", "hello World"},
{"singleWord", "single Word"},
{"Lowercase", "Lowercase"}, // No change if no camel case
{"", ""}, // Empty string case
}

for i, test := range tests {
t.Run(fmt.Sprintf("case %v: %v", i+1, test.input), func(t *testing.T) {
result := util.CamelCaseToSpacing(test.input)
require.Equal(t, test.expected, result)
})
}
}
11 changes: 8 additions & 3 deletions testdata/graph-visualisation.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,12 @@ title: Diagram of example Workflow
stateDiagram-v2
direction LR

start-->middle
start-->end
middle-->end
9: Start
10: Middle
11: End


9-->10
9-->11
10-->11
```
39 changes: 24 additions & 15 deletions visualiser.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ import (
"os"
"strings"
"text/template"

"github.com/luno/workflow/internal/util"
)

// CreateDiagram creates a diagram in a md file for communicating a workflow's set of steps in an easy-to-understand
Expand Down Expand Up @@ -39,21 +41,21 @@ func mermaidDiagram[Type any, Status StatusType](a API[Type, Status], path strin

graphInfo := w.statusGraph.Info()

var starting []string
var starting []int
for _, node := range graphInfo.StartingNodes {
starting = append(starting, statusToString(Status(node)))
starting = append(starting, node)
}

var terminal []string
var terminal []int
for _, node := range graphInfo.TerminalNodes {
terminal = append(terminal, statusToString(Status(node)))
terminal = append(terminal, node)
}

var transitions []MermaidTransition
for _, transition := range graphInfo.Transitions {
transitions = append(transitions, MermaidTransition{
From: statusToString(Status(transition.From)),
To: statusToString(Status(transition.To)),
From: transition.From,
To: transition.To,
})
}

Expand All @@ -63,22 +65,25 @@ func mermaidDiagram[Type any, Status StatusType](a API[Type, Status], path strin
StartingPoints: starting,
TerminalPoints: terminal,
Transitions: transitions,
Nodes: w.statusGraph.Nodes(),
}

return template.Must(template.New("").Parse("```"+mermaidTemplate+"```")).Execute(file, mf)
return template.Must(template.New("").Funcs(map[string]any{
"Description": description[Status],
}).Parse("```"+mermaidTemplate+"```")).Execute(file, mf)
}

func statusToString[Status StatusType](s Status) string {
str := strings.ToLower(s.String())
str = strings.Replace(str, " ", "_", -1)
return str
func description[Status StatusType](val int) string {
s := Status(val).String()
return util.CamelCaseToSpacing(s)
}

type MermaidFormat struct {
WorkflowName string
Direction MermaidDirection
StartingPoints []string
TerminalPoints []string
Nodes []int
StartingPoints []int
TerminalPoints []int
Transitions []MermaidTransition
}

Expand All @@ -93,8 +98,8 @@ const (
)

type MermaidTransition struct {
From string
To string
From int
To int
}

var mermaidTemplate = `mermaid
Expand All @@ -103,6 +108,10 @@ title: Diagram of {{.WorkflowName}} Workflow
---
stateDiagram-v2
direction {{.Direction}}
{{range $key, $value := .Nodes }}
{{$value}}: {{Description $value}}
{{- end }}

{{range $key, $value := .Transitions }}
{{$value.From}}-->{{$value.To}}
{{- end }}
Expand Down
Loading