vitess.io/vitess@v0.16.2/go/tools/asthelpergen/integration/integration_visit_test.go (about) 1 /* 2 Copyright 2021 The Vitess Authors. 3 4 Licensed under the Apache License, Version 2.0 (the "License"); 5 you may not use this file except in compliance with the License. 6 You may obtain a copy of the License at 7 8 http://www.apache.org/licenses/LICENSE-2.0 9 10 Unless required by applicable law or agreed to in writing, software 11 distributed under the License is distributed on an "AS IS" BASIS, 12 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 See the License for the specific language governing permissions and 14 limitations under the License. 15 */ 16 17 package integration 18 19 import ( 20 "fmt" 21 "reflect" 22 "testing" 23 24 "github.com/stretchr/testify/require" 25 ) 26 27 type testVisitor struct { 28 seen []AST 29 } 30 31 func (tv *testVisitor) visit(node AST) (bool, error) { 32 tv.seen = append(tv.seen, node) 33 return true, nil 34 } 35 36 func TestVisitRefContainer(t *testing.T) { 37 leaf1 := &Leaf{1} 38 leaf2 := &Leaf{2} 39 container := &RefContainer{ASTType: leaf1, ASTImplementationType: leaf2} 40 containerContainer := &RefContainer{ASTType: container} 41 42 tv := &testVisitor{} 43 44 require.NoError(t, 45 VisitAST(containerContainer, tv.visit)) 46 47 tv.assertVisitOrder(t, []AST{ 48 containerContainer, 49 container, 50 leaf1, 51 leaf2, 52 }) 53 } 54 55 func TestVisitValueContainer(t *testing.T) { 56 leaf1 := &Leaf{1} 57 leaf2 := &Leaf{2} 58 container := ValueContainer{ASTType: leaf1, ASTImplementationType: leaf2} 59 containerContainer := ValueContainer{ASTType: container} 60 61 tv := &testVisitor{} 62 63 require.NoError(t, 64 VisitAST(containerContainer, tv.visit)) 65 66 expected := []AST{ 67 containerContainer, 68 container, 69 leaf1, 70 leaf2, 71 } 72 tv.assertVisitOrder(t, expected) 73 } 74 75 func TestVisitRefSliceContainer(t *testing.T) { 76 leaf1 := &Leaf{1} 77 leaf2 := &Leaf{2} 78 leaf3 := &Leaf{3} 79 leaf4 := &Leaf{4} 80 container := &RefSliceContainer{ASTElements: []AST{leaf1, leaf2}, ASTImplementationElements: []*Leaf{leaf3, leaf4}} 81 containerContainer := &RefSliceContainer{ASTElements: []AST{container}} 82 83 tv := &testVisitor{} 84 85 require.NoError(t, 86 VisitAST(containerContainer, tv.visit)) 87 88 tv.assertVisitOrder(t, []AST{ 89 containerContainer, 90 container, 91 leaf1, 92 leaf2, 93 leaf3, 94 leaf4, 95 }) 96 } 97 98 func TestVisitValueSliceContainer(t *testing.T) { 99 leaf1 := &Leaf{1} 100 leaf2 := &Leaf{2} 101 leaf3 := &Leaf{3} 102 leaf4 := &Leaf{4} 103 container := ValueSliceContainer{ASTElements: []AST{leaf1, leaf2}, ASTImplementationElements: []*Leaf{leaf3, leaf4}} 104 containerContainer := ValueSliceContainer{ASTElements: []AST{container}} 105 106 tv := &testVisitor{} 107 108 require.NoError(t, 109 VisitAST(containerContainer, tv.visit)) 110 111 tv.assertVisitOrder(t, []AST{ 112 containerContainer, 113 container, 114 leaf1, 115 leaf2, 116 leaf3, 117 leaf4, 118 }) 119 } 120 121 func TestVisitInterfaceSlice(t *testing.T) { 122 leaf1 := &Leaf{2} 123 astType := &RefContainer{NotASTType: 12} 124 implementationType := &Leaf{2} 125 126 leaf2 := &Leaf{3} 127 refContainer := &RefContainer{ 128 ASTType: astType, 129 ASTImplementationType: implementationType, 130 } 131 ast := InterfaceSlice{ 132 refContainer, 133 leaf1, 134 leaf2, 135 } 136 137 tv := &testVisitor{} 138 139 require.NoError(t, 140 VisitAST(ast, tv.visit)) 141 142 tv.assertVisitOrder(t, []AST{ 143 ast, 144 refContainer, 145 astType, 146 implementationType, 147 leaf1, 148 leaf2, 149 }) 150 } 151 152 func (tv *testVisitor) assertVisitOrder(t *testing.T, expected []AST) { 153 t.Helper() 154 var lines []string 155 failed := false 156 expectedSize := len(expected) 157 for i, step := range tv.seen { 158 if expectedSize <= i { 159 t.Errorf("❌️ - Expected less elements %v", tv.seen[i:]) 160 break 161 } else { 162 e := expected[i] 163 if reflect.DeepEqual(e, step) { 164 a := "✔️ - " + e.String() 165 if failed { 166 fmt.Println(a) 167 } else { 168 lines = append(lines, a) 169 } 170 } else { 171 if !failed { 172 // first error we see. 173 failed = true 174 for _, line := range lines { 175 fmt.Println(line) 176 } 177 } 178 t.Errorf("❌️ - Expected: %s Got: %s\n", e.String(), step.String()) 179 } 180 } 181 } 182 walkSize := len(tv.seen) 183 if expectedSize > walkSize { 184 t.Errorf("❌️ - Expected more elements %v", expected[walkSize:]) 185 } 186 }