Skip to content

Commit

Permalink
add test covering viz command, ensure deterministic output
Browse files Browse the repository at this point in the history
  • Loading branch information
benweint committed May 28, 2024
1 parent b37774a commit 4da9b5e
Show file tree
Hide file tree
Showing 3 changed files with 95 additions and 10 deletions.
65 changes: 65 additions & 0 deletions pkg/commands/testdata/cases/viz/expected.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
digraph {
rankdir=LR
ranksep=2
node [shape=box fontname=Courier]
n_Apple [shape=plain, label=<<TABLE>
<TR><TD COLSPAN="3" PORT="main" BGCOLOR="#fbb4ae">object Apple</TD></TR>
<TR><TD ROWSPAN="1">variety</TD><TD COLSPAN="2" PORT="p_variety">AppleVariety</TD></TR>
<TR><TD ROWSPAN="1">measurements</TD><TD COLSPAN="2" PORT="p_measurements">Measurements</TD></TR>
<TR><TD ROWSPAN="1">calories</TD><TD COLSPAN="2" PORT="p_calories">Int</TD></TR>

</TABLE>>]
n_AppleVariety [shape=plain, label=<<TABLE>
<TR><TD PORT="main" BGCOLOR="#decbe4">enum AppleVariety</TD></TR> <TR><TD>FUJI</TD></TR>\n <TR><TD>COSMIC_CRISP</TD></TR>\n <TR><TD>GRANNY_SMITH</TD></TR>\n</TABLE>>]
n_Biscuit [shape=plain, label=<<TABLE>
<TR><TD COLSPAN="3" PORT="main" BGCOLOR="#fbb4ae">object Biscuit</TD></TR>
<TR><TD ROWSPAN="1">calories</TD><TD COLSPAN="2" PORT="p_calories">Int</TD></TR>

</TABLE>>]
n_Edible [shape=plain, label=<<TABLE>
<TR><TD COLSPAN="3" PORT="main" BGCOLOR="#b3cde3">interface Edible</TD></TR>
<TR><TD ROWSPAN="1">calories</TD><TD COLSPAN="2" PORT="p_calories">Int</TD></TR>

</TABLE>>]
n_Filter [shape=plain, label=<<TABLE>
<TR><TD COLSPAN="2" PORT="main" BGCOLOR="#ccebc5">input Filter</TD></TR>
<TR><TD>nameLike</TD><TD PORT="p_nameLike">String</TD></TR>
<TR><TD>limit</TD><TD PORT="p_limit">Int</TD></TR>
</TABLE>>]
n_Fruit [shape=plain, label=<<TABLE>
<TR><TD PORT="main" BGCOLOR="#fed9a6">union Fruit</TD></TR> <TR><TD PORT="p_Apple">Apple</TD></TR>\n <TR><TD PORT="p_Orange">Orange</TD></TR>\n</TABLE>>]
n_Measurements [shape=plain, label=<<TABLE>
<TR><TD COLSPAN="3" PORT="main" BGCOLOR="#fbb4ae">object Measurements</TD></TR>
<TR><TD ROWSPAN="1">height</TD><TD COLSPAN="2" PORT="p_height">Int</TD></TR>
<TR><TD ROWSPAN="1">width</TD><TD COLSPAN="2" PORT="p_width">Int</TD></TR>
<TR><TD ROWSPAN="1">depth</TD><TD COLSPAN="2" PORT="p_depth">Int</TD></TR>

</TABLE>>]
n_Orange [shape=plain, label=<<TABLE>
<TR><TD COLSPAN="3" PORT="main" BGCOLOR="#fbb4ae">object Orange</TD></TR>
<TR><TD ROWSPAN="1">variety</TD><TD COLSPAN="2" PORT="p_variety">OrangeVariety</TD></TR>
<TR><TD ROWSPAN="1">calories</TD><TD COLSPAN="2" PORT="p_calories">Int</TD></TR>

</TABLE>>]
n_OrangeVariety [shape=plain, label=<<TABLE>
<TR><TD PORT="main" BGCOLOR="#decbe4">enum OrangeVariety</TD></TR> <TR><TD>VALENCIA</TD></TR>\n <TR><TD>NAVEL</TD></TR>\n <TR><TD>CARA_CARA</TD></TR>\n</TABLE>>]
n_Query [shape=plain, label=<<TABLE>
<TR><TD COLSPAN="3" PORT="main" BGCOLOR="#fbb4ae">object Query</TD></TR>
<TR><TD ROWSPAN="2">fruit</TD><TD COLSPAN="2" PORT="p_fruit">Fruit</TD></TR>
<TR><TD>name</TD><TD PORT="p_fruit_name">String</TD></TR>
<TR><TD ROWSPAN="2">edible</TD><TD COLSPAN="2" PORT="p_edible">Edible</TD></TR>
<TR><TD>name</TD><TD PORT="p_edible_name">String</TD></TR>
<TR><TD ROWSPAN="2">edibles</TD><TD COLSPAN="2" PORT="p_edibles">[Edible!]!</TD></TR>
<TR><TD>filter</TD><TD PORT="p_edibles_filter">Filter</TD></TR>

</TABLE>>]
n_Apple:p_variety -> n_AppleVariety:main
n_Apple:p_measurements -> n_Measurements:main
n_Fruit:p_Apple -> n_Apple:main
n_Fruit:p_Orange -> n_Orange:main
n_Orange:p_variety -> n_OrangeVariety:main
n_Query:p_fruit -> n_Fruit:main
n_Query:p_edible -> n_Edible:main
n_Query:p_edibles -> n_Edible:main
n_Query:p_edibles_filter -> n_Filter:main
}
1 change: 1 addition & 0 deletions pkg/commands/testdata/cases/viz/meta.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
args: ["viz", "testdata/in.graphql"]
39 changes: 29 additions & 10 deletions pkg/graph/graph.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package graph

import (
"fmt"
"sort"
"strings"

"github.com/benweint/gquil/pkg/astutil"
Expand Down Expand Up @@ -212,24 +213,33 @@ func (g *Graph) ReachableFrom(roots []*model.NameReference, maxDepth int) *Graph
}

func (g *Graph) ToDot() string {
var nodeDefs []string
for _, node := range g.nodes {
if astutil.IsBuiltinType(node.Name) && !g.renderBuiltins {
nodeDefs := g.buildNodeDefs()
edgeDefs := g.buildEdgeDefs()

return "digraph {\n rankdir=LR\n ranksep=2\n node [shape=box fontname=Courier]\n" + strings.Join(nodeDefs, "\n") + "\n" + strings.Join(edgeDefs, "\n") + "\n}\n"
}

func (g *Graph) buildNodeDefs() []string {
var result []string
for _, name := range sortedKeys(g.nodes) {
if astutil.IsBuiltinType(name) && !g.renderBuiltins {
continue
}
node := g.nodes[name]
if node.Kind == ast.Scalar {
continue
}
nodeDef := fmt.Sprintf(" %s [shape=plain, label=<%s>]", node.ID(), g.makeNodeLabel(node))
nodeDefs = append(nodeDefs, nodeDef)
result = append(result, nodeDef)
}

edgeDefs := g.buildEdgeDefs()

return "digraph {\nrankdir=LR\nranksep=2\nnode [shape=box fontname=Courier]\n" + strings.Join(nodeDefs, "\n") + "\n" + strings.Join(edgeDefs, "\n") + "\n}\n"
return result
}

func (g *Graph) buildEdgeDefs() []string {
var result []string

for _, edges := range g.edges {
var result []string
for _, sourceNodeName := range sortedKeys(g.edges) {
edges := g.edges[sourceNodeName]
for _, edge := range edges {
srcPortSuffix := ""
dstPortSuffix := ":main"
Expand Down Expand Up @@ -261,6 +271,15 @@ func (g *Graph) buildEdgeDefs() []string {
return result
}

func sortedKeys[T any](m map[string]T) []string {
var result []string
for k := range m {
result = append(result, k)
}
sort.Strings(result)
return result
}

func (g *Graph) makeNodeLabel(node *node) string {
switch normalizeKind(node.Kind, g.interfacesAsUnions) {
case ast.Object:
Expand Down

0 comments on commit 4da9b5e

Please sign in to comment.