Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(194)

Side by Side Diff: mojom/mojom_tool/utils/wellfounded_graphs_test.go

Issue 1915413002: Mojom frontend: Detect Ill-founded Types (Closed) Base URL: https://github.com/domokit/mojo.git@master
Patch Set: Fix comments as per code review. Created 4 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « mojom/mojom_tool/utils/wellfounded_graphs.go ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 package utils 1 package utils
2 2
3 import ( 3 import (
4 "bytes" 4 "bytes"
5 "fmt" 5 "fmt"
6 "strings" 6 "strings"
7 "testing" 7 "testing"
8 ) 8 )
9 9
10 //////////////////////////////////////////////////// 10 ////////////////////////////////////////////////////
11 // SimpleNode type 11 // SimpleNode type
12 //////////////////////////////////////////////////// 12 ////////////////////////////////////////////////////
13 13
14 // SimpleNode is a simple implementation of the |Node| interface used 14 // SimpleNode is a simple implementation of the |Node| interface used
15 // for testing. 15 // for testing.
16 type SimpleNode struct { 16 type SimpleNode struct {
17 // The value of this node 17 // The value of this node
18 value int 18 value int
19 19
20 // Is this node a square node? 20 // Is this node a square node?
21 isSquare bool 21 isSquare bool
22 22
23 » // The list of out-edges. The elements will be *SimpleNodes. 23 » // The list of out-edges.
24 » edges []Node 24 » edges []OutEdge
25 25
26 // Cache the fact that |SetKnownWellFounded| has been invoked. 26 // Cache the fact that |SetKnownWellFounded| has been invoked.
27 knownWellFounded bool 27 knownWellFounded bool
28 } 28 }
29 29
30 func (node *SimpleNode) DebugName() string { 30 func (node *SimpleNode) Name() string {
31 return fmt.Sprintf("Node%d", node.value) 31 return fmt.Sprintf("Node%d", node.value)
32 } 32 }
33 33
34 func (node *SimpleNode) OutEdges() []Node { 34 func (node *SimpleNode) OutEdges() []OutEdge {
35 return node.edges 35 return node.edges
36 } 36 }
37 37
38 func (node *SimpleNode) IsSquare() bool { 38 func (node *SimpleNode) IsSquare() bool {
39 return node.isSquare 39 return node.isSquare
40 } 40 }
41 41
42 func (node *SimpleNode) KnownWellFounded() bool { 42 func (node *SimpleNode) KnownWellFounded() bool {
43 return node.knownWellFounded 43 return node.knownWellFounded
44 } 44 }
45 45
46 func (node *SimpleNode) SetKnownWellFounded() { 46 func (node *SimpleNode) SetKnownWellFounded() {
47 if node.knownWellFounded { 47 if node.knownWellFounded {
48 » » panic(fmt.Sprintf("SetKnownWellFounded invoked twice on %s", nod e.DebugName())) 48 » » panic(fmt.Sprintf("SetKnownWellFounded invoked twice on %s", nod e.Name()))
49 } 49 }
50 node.knownWellFounded = true 50 node.knownWellFounded = true
51 } 51 }
52 52
53 //Creates a new SimpleNode. 53 //Creates a new SimpleNode.
54 func NewNode(value, numEdges int, isSquare bool) *SimpleNode { 54 func NewNode(value, numEdges int, isSquare bool) *SimpleNode {
55 node := new(SimpleNode) 55 node := new(SimpleNode)
56 node.value = value 56 node.value = value
57 » node.edges = make([]Node, numEdges) 57 » node.edges = make([]OutEdge, numEdges)
58 node.isSquare = isSquare 58 node.isSquare = isSquare
59 return node 59 return node
60 } 60 }
61 61
62 //////////////////////////////////////////////////// 62 ////////////////////////////////////////////////////
63 // Test Utilities 63 // Test Utilities
64 //////////////////////////////////////////////////// 64 ////////////////////////////////////////////////////
65 65
66 // Builds a test graph containing only circle nodes. 66 // Builds a test graph containing only circle nodes.
67 // The connection matrix should have the following form: 67 // The connection matrix should have the following form:
(...skipping 14 matching lines...) Expand all
82 squareMap[n] = true 82 squareMap[n] = true
83 } 83 }
84 } 84 }
85 nodes = make([]*SimpleNode, len(connectionMatrix)) 85 nodes = make([]*SimpleNode, len(connectionMatrix))
86 for index, connectionList := range connectionMatrix { 86 for index, connectionList := range connectionMatrix {
87 _, isSquare := squareMap[index] 87 _, isSquare := squareMap[index]
88 nodes[index] = NewNode(index, len(connectionList), isSquare) 88 nodes[index] = NewNode(index, len(connectionList), isSquare)
89 } 89 }
90 for index, connectionList := range connectionMatrix { 90 for index, connectionList := range connectionMatrix {
91 for i, target := range connectionList { 91 for i, target := range connectionList {
92 » » » nodes[index].edges[i] = nodes[target] 92 » » » nodes[index].edges[i] = OutEdge{"", nodes[target]}
93 } 93 }
94 } 94 }
95 return 95 return
96 } 96 }
97 97
98 // expectedDebugData is used to store an expectation for the value of the |debug Data| populated 98 // expectedDebugData is used to store an expectation for the value of the |debug Data| populated
99 // by the ethod |checkWellFounded|. This data captures the result of phase 1 of the algorithm. 99 // by the ethod |checkWellFounded|. This data captures the result of phase 1 of the algorithm.
100 type expectedDebugData struct { 100 type expectedDebugData struct {
101 initialPendingSet []string 101 initialPendingSet []string
102 initialFoundationSet []string 102 initialFoundationSet []string
(...skipping 10 matching lines...) Expand all
113 return compareNodeSlice(expected.initialFoundationSet, actual.initialFou ndationSet, "initialFoundationSet") 113 return compareNodeSlice(expected.initialFoundationSet, actual.initialFou ndationSet, "initialFoundationSet")
114 } 114 }
115 115
116 func compareNodeSlice(expected []string, actual []Node, name string) error { 116 func compareNodeSlice(expected []string, actual []Node, name string) error {
117 expectedMap := make(map[string]bool) 117 expectedMap := make(map[string]bool)
118 actualMap := make(map[string]bool) 118 actualMap := make(map[string]bool)
119 for _, n := range expected { 119 for _, n := range expected {
120 expectedMap[n] = true 120 expectedMap[n] = true
121 } 121 }
122 for _, n := range actual { 122 for _, n := range actual {
123 » » actualMap[n.DebugName()] = true 123 » » actualMap[n.Name()] = true
124 } 124 }
125 for _, n := range expected { 125 for _, n := range expected {
126 if _, ok := actualMap[n]; !ok { 126 if _, ok := actualMap[n]; !ok {
127 return fmt.Errorf("%s: missing %s, actual: %s", name, n, NodeSliceToString(actual)) 127 return fmt.Errorf("%s: missing %s, actual: %s", name, n, NodeSliceToString(actual))
128 } 128 }
129 } 129 }
130 for _, n := range actual { 130 for _, n := range actual {
131 » » if _, ok := expectedMap[n.DebugName()]; !ok { 131 » » if _, ok := expectedMap[n.Name()]; !ok {
132 » » » return fmt.Errorf("%s: unexpected: %s, expected: %v, act ual: %s", name, n.DebugName(), expected, NodeSliceToString(actual)) 132 » » » return fmt.Errorf("%s: unexpected: %s, expected: %v, act ual: %s", name, n.Name(), expected, NodeSliceToString(actual))
133 } 133 }
134 } 134 }
135 return nil 135 return nil
136 } 136 }
137 137
138 func NodeSliceToString(nodeSlice []Node) string { 138 func NodeSliceToString(nodeSlice []Node) string {
139 var buffer bytes.Buffer 139 var buffer bytes.Buffer
140 fmt.Fprintf(&buffer, "[") 140 fmt.Fprintf(&buffer, "[")
141 first := true 141 first := true
142 for _, n := range nodeSlice { 142 for _, n := range nodeSlice {
143 if !first { 143 if !first {
144 fmt.Fprintf(&buffer, ", ") 144 fmt.Fprintf(&buffer, ", ")
145 } 145 }
146 » » fmt.Fprintf(&buffer, "%s", n.DebugName()) 146 » » fmt.Fprintf(&buffer, "%s", n.Name())
147 first = false 147 first = false
148 } 148 }
149 fmt.Fprintln(&buffer, "]") 149 fmt.Fprintln(&buffer, "]")
150 return buffer.String() 150 return buffer.String()
151 } 151 }
152 152
153 //////////////////////////////////////////////////// 153 ////////////////////////////////////////////////////
154 // Tests 154 // Tests
155 //////////////////////////////////////////////////// 155 ////////////////////////////////////////////////////
156 156
(...skipping 294 matching lines...) Expand 10 before | Expand all | Expand 10 after
451 } 451 }
452 if len(c.expectedPathA) == 0 { 452 if len(c.expectedPathA) == 0 {
453 if cycleDescription != nil { 453 if cycleDescription != nil {
454 t.Fatalf("Case %dA: Detected a cycle: %s", i, cy cleDescription) 454 t.Fatalf("Case %dA: Detected a cycle: %s", i, cy cleDescription)
455 } 455 }
456 } else { 456 } else {
457 if cycleDescription == nil { 457 if cycleDescription == nil {
458 t.Fatalf("Case %d: Expected a cycle.", i) 458 t.Fatalf("Case %d: Expected a cycle.", i)
459 } 459 }
460 if !strings.Contains(cycleDescription.String(), fmt.Spri ntf("first:%s", c.expectedFirstA)) { 460 if !strings.Contains(cycleDescription.String(), fmt.Spri ntf("first:%s", c.expectedFirstA)) {
461 » » » » t.Fatalf("Case %d: got=%s expectedFirst=%q", i, cycleDescription.String(), c.expectedFirstA) 461 » » » » t.Fatalf("Case %d: got=%s expectedFirstA=%q", i, cycleDescription.String(), c.expectedFirstA)
462 } 462 }
463 if !strings.Contains(cycleDescription.String(), fmt.Spri ntf("last:%s", c.expectedLastA)) { 463 if !strings.Contains(cycleDescription.String(), fmt.Spri ntf("last:%s", c.expectedLastA)) {
464 » » » » t.Fatalf("Case %d: got=%s expectedLast=%q", i, c ycleDescription.String(), c.expectedLastA) 464 » » » » t.Fatalf("Case %d: got=%s expectedLastA=%q", i, cycleDescription.String(), c.expectedLastA)
465 } 465 }
466 if !strings.Contains(cycleDescription.String(), fmt.Spri ntf("{%s}", c.expectedPathA)) { 466 if !strings.Contains(cycleDescription.String(), fmt.Spri ntf("{%s}", c.expectedPathA)) {
467 » » » » t.Fatalf("Case %d: got=%s expectedPath=%q", i, c ycleDescription.String(), c.expectedPathA) 467 » » » » t.Fatalf("Case %d: got=%s expectedPathA=%q", i, cycleDescription.String(), c.expectedPathA)
468 } 468 }
469 } 469 }
470 470
471 // Test from root=Node1 471 // Test from root=Node1
472 if len(graph) > 1 { 472 if len(graph) > 1 {
473 dbgData := debugData{} 473 dbgData := debugData{}
474 cycleDescription := checkWellFounded(graph[1], &dbgData) 474 cycleDescription := checkWellFounded(graph[1], &dbgData)
475 if err := compareDebugData(&c.expectedDebugDataB, &dbgDa ta); err != nil { 475 if err := compareDebugData(&c.expectedDebugDataB, &dbgDa ta); err != nil {
476 t.Fatalf("Case %dB: %s", i, err.Error()) 476 t.Fatalf("Case %dB: %s", i, err.Error())
477 } 477 }
478 if len(c.expectedPathB) == 0 { 478 if len(c.expectedPathB) == 0 {
479 if cycleDescription != nil { 479 if cycleDescription != nil {
480 t.Fatalf("Case %dB: Detected a cycle: %s ", i, cycleDescription) 480 t.Fatalf("Case %dB: Detected a cycle: %s ", i, cycleDescription)
481 } 481 }
482 } else { 482 } else {
483 if cycleDescription == nil { 483 if cycleDescription == nil {
484 t.Fatalf("Case %dB: Expected a cycle.", i) 484 t.Fatalf("Case %dB: Expected a cycle.", i)
485 } 485 }
486 if !strings.Contains(cycleDescription.String(), fmt.Sprintf("first:%s", c.expectedFirstB)) { 486 if !strings.Contains(cycleDescription.String(), fmt.Sprintf("first:%s", c.expectedFirstB)) {
487 » » » » » t.Fatalf("Case %dB: got=%s expectedFirst =%q", i, cycleDescription.String(), c.expectedFirstB) 487 » » » » » t.Fatalf("Case %dB: got=%s expectedFirst B=%q", i, cycleDescription.String(), c.expectedFirstB)
488 } 488 }
489 if !strings.Contains(cycleDescription.String(), fmt.Sprintf("last:%s", c.expectedLastB)) { 489 if !strings.Contains(cycleDescription.String(), fmt.Sprintf("last:%s", c.expectedLastB)) {
490 » » » » » t.Fatalf("Case %dB: got=%s expectedLast= %q", i, cycleDescription.String(), c.expectedLastB) 490 » » » » » t.Fatalf("Case %dB: got=%s expectedLastB =%q", i, cycleDescription.String(), c.expectedLastB)
491 } 491 }
492 if !strings.Contains(cycleDescription.String(), fmt.Sprintf("{%s}", c.expectedPathB)) { 492 if !strings.Contains(cycleDescription.String(), fmt.Sprintf("{%s}", c.expectedPathB)) {
493 » » » » » t.Fatalf("Case %dB: got=%s expectedPath= %q", i, cycleDescription.String(), c.expectedPathB) 493 » » » » » t.Fatalf("Case %dB: got=%s expectedPathB =%q", i, cycleDescription.String(), c.expectedPathB)
494 } 494 }
495 } 495 }
496 } 496 }
497 } 497 }
498 } 498 }
499 499
500 // TestWellFoundedIsWellFounded tests the function |checkWellFounded| on graphs 500 // TestWellFoundedIsWellFounded tests the function |checkWellFounded| on graphs
501 // that contain both circles and squares and are well-founded. 501 // that contain both circles and squares and are well-founded.
502 func TestWellFoundedIsWellFounded(t *testing.T) { 502 func TestWellFoundedIsWellFounded(t *testing.T) {
503 cases := []WellFoundedGraphTestCase{ 503 cases := []WellFoundedGraphTestCase{
(...skipping 836 matching lines...) Expand 10 before | Expand all | Expand 10 after
1340 if !strings.Contains(cycleDescription.String(), fmt.Sprintf("last:%s", c.expectedLastB)) { 1340 if !strings.Contains(cycleDescription.String(), fmt.Sprintf("last:%s", c.expectedLastB)) {
1341 t.Fatalf("Case %dB: got=%s expectedLast= %q", i, cycleDescription.String(), c.expectedLastB) 1341 t.Fatalf("Case %dB: got=%s expectedLast= %q", i, cycleDescription.String(), c.expectedLastB)
1342 } 1342 }
1343 if !strings.Contains(cycleDescription.String(), fmt.Sprintf("{%s}", c.expectedPathB)) { 1343 if !strings.Contains(cycleDescription.String(), fmt.Sprintf("{%s}", c.expectedPathB)) {
1344 t.Fatalf("Case %dB: got=%s expectedPath= %q", i, cycleDescription.String(), c.expectedPathB) 1344 t.Fatalf("Case %dB: got=%s expectedPath= %q", i, cycleDescription.String(), c.expectedPathB)
1345 } 1345 }
1346 } 1346 }
1347 } 1347 }
1348 } 1348 }
1349 } 1349 }
OLDNEW
« no previous file with comments | « mojom/mojom_tool/utils/wellfounded_graphs.go ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698