github.com/hashicorp/terraform-plugin-sdk@v1.17.2/terraform/transform_reference_test.go (about) 1 package terraform 2 3 import ( 4 "reflect" 5 "sort" 6 "strings" 7 "testing" 8 9 "github.com/hashicorp/terraform-plugin-sdk/internal/addrs" 10 "github.com/hashicorp/terraform-plugin-sdk/internal/dag" 11 ) 12 13 func TestReferenceTransformer_simple(t *testing.T) { 14 g := Graph{Path: addrs.RootModuleInstance} 15 g.Add(&graphNodeRefParentTest{ 16 NameValue: "A", 17 Names: []string{"A"}, 18 }) 19 g.Add(&graphNodeRefChildTest{ 20 NameValue: "B", 21 Refs: []string{"A"}, 22 }) 23 24 tf := &ReferenceTransformer{} 25 if err := tf.Transform(&g); err != nil { 26 t.Fatalf("err: %s", err) 27 } 28 29 actual := strings.TrimSpace(g.String()) 30 expected := strings.TrimSpace(testTransformRefBasicStr) 31 if actual != expected { 32 t.Fatalf("wrong result\n\ngot:\n%s\n\nwant:\n%s", actual, expected) 33 } 34 } 35 36 func TestReferenceTransformer_self(t *testing.T) { 37 g := Graph{Path: addrs.RootModuleInstance} 38 g.Add(&graphNodeRefParentTest{ 39 NameValue: "A", 40 Names: []string{"A"}, 41 }) 42 g.Add(&graphNodeRefChildTest{ 43 NameValue: "B", 44 Refs: []string{"A", "B"}, 45 }) 46 47 tf := &ReferenceTransformer{} 48 if err := tf.Transform(&g); err != nil { 49 t.Fatalf("err: %s", err) 50 } 51 52 actual := strings.TrimSpace(g.String()) 53 expected := strings.TrimSpace(testTransformRefBasicStr) 54 if actual != expected { 55 t.Fatalf("wrong result\n\ngot:\n%s\n\nwant:\n%s", actual, expected) 56 } 57 } 58 59 func TestReferenceTransformer_path(t *testing.T) { 60 g := Graph{Path: addrs.RootModuleInstance} 61 g.Add(&graphNodeRefParentTest{ 62 NameValue: "A", 63 Names: []string{"A"}, 64 }) 65 g.Add(&graphNodeRefChildTest{ 66 NameValue: "B", 67 Refs: []string{"A"}, 68 }) 69 g.Add(&graphNodeRefParentTest{ 70 NameValue: "child.A", 71 PathValue: []string{"root", "child"}, 72 Names: []string{"A"}, 73 }) 74 g.Add(&graphNodeRefChildTest{ 75 NameValue: "child.B", 76 PathValue: []string{"root", "child"}, 77 Refs: []string{"A"}, 78 }) 79 80 tf := &ReferenceTransformer{} 81 if err := tf.Transform(&g); err != nil { 82 t.Fatalf("err: %s", err) 83 } 84 85 actual := strings.TrimSpace(g.String()) 86 expected := strings.TrimSpace(testTransformRefPathStr) 87 if actual != expected { 88 t.Fatalf("wrong result\n\ngot:\n%s\n\nwant:\n%s", actual, expected) 89 } 90 } 91 92 func TestReferenceMapReferences(t *testing.T) { 93 cases := map[string]struct { 94 Nodes []dag.Vertex 95 Check dag.Vertex 96 Result []string 97 }{ 98 "simple": { 99 Nodes: []dag.Vertex{ 100 &graphNodeRefParentTest{ 101 NameValue: "A", 102 Names: []string{"A"}, 103 }, 104 }, 105 Check: &graphNodeRefChildTest{ 106 NameValue: "foo", 107 Refs: []string{"A"}, 108 }, 109 Result: []string{"A"}, 110 }, 111 } 112 113 for tn, tc := range cases { 114 t.Run(tn, func(t *testing.T) { 115 rm := NewReferenceMap(tc.Nodes) 116 result, _ := rm.References(tc.Check) 117 118 var resultStr []string 119 for _, v := range result { 120 resultStr = append(resultStr, dag.VertexName(v)) 121 } 122 123 sort.Strings(resultStr) 124 sort.Strings(tc.Result) 125 if !reflect.DeepEqual(resultStr, tc.Result) { 126 t.Fatalf("bad: %#v", resultStr) 127 } 128 }) 129 } 130 } 131 132 func TestReferenceMapReferencedBy(t *testing.T) { 133 cases := map[string]struct { 134 Nodes []dag.Vertex 135 Check dag.Vertex 136 Result []string 137 }{ 138 "simple": { 139 Nodes: []dag.Vertex{ 140 &graphNodeRefChildTest{ 141 NameValue: "A", 142 Refs: []string{"A"}, 143 }, 144 &graphNodeRefChildTest{ 145 NameValue: "B", 146 Refs: []string{"A"}, 147 }, 148 &graphNodeRefChildTest{ 149 NameValue: "C", 150 Refs: []string{"B"}, 151 }, 152 }, 153 Check: &graphNodeRefParentTest{ 154 NameValue: "foo", 155 Names: []string{"A"}, 156 }, 157 Result: []string{"A", "B"}, 158 }, 159 } 160 161 for tn, tc := range cases { 162 t.Run(tn, func(t *testing.T) { 163 rm := NewReferenceMap(tc.Nodes) 164 result := rm.Referrers(tc.Check) 165 166 var resultStr []string 167 for _, v := range result { 168 resultStr = append(resultStr, dag.VertexName(v)) 169 } 170 171 sort.Strings(resultStr) 172 sort.Strings(tc.Result) 173 if !reflect.DeepEqual(resultStr, tc.Result) { 174 t.Fatalf("bad: %#v", resultStr) 175 } 176 }) 177 } 178 } 179 180 type graphNodeRefParentTest struct { 181 NameValue string 182 PathValue []string 183 Names []string 184 } 185 186 var _ GraphNodeReferenceable = (*graphNodeRefParentTest)(nil) 187 188 func (n *graphNodeRefParentTest) Name() string { 189 return n.NameValue 190 } 191 192 func (n *graphNodeRefParentTest) ReferenceableAddrs() []addrs.Referenceable { 193 ret := make([]addrs.Referenceable, len(n.Names)) 194 for i, name := range n.Names { 195 ret[i] = addrs.LocalValue{Name: name} 196 } 197 return ret 198 } 199 200 func (n *graphNodeRefParentTest) Path() addrs.ModuleInstance { 201 return normalizeModulePath(n.PathValue) 202 } 203 204 type graphNodeRefChildTest struct { 205 NameValue string 206 PathValue []string 207 Refs []string 208 } 209 210 var _ GraphNodeReferencer = (*graphNodeRefChildTest)(nil) 211 212 func (n *graphNodeRefChildTest) Name() string { 213 return n.NameValue 214 } 215 216 func (n *graphNodeRefChildTest) References() []*addrs.Reference { 217 ret := make([]*addrs.Reference, len(n.Refs)) 218 for i, name := range n.Refs { 219 ret[i] = &addrs.Reference{ 220 Subject: addrs.LocalValue{Name: name}, 221 } 222 } 223 return ret 224 } 225 226 func (n *graphNodeRefChildTest) Path() addrs.ModuleInstance { 227 return normalizeModulePath(n.PathValue) 228 } 229 230 const testTransformRefBasicStr = ` 231 A 232 B 233 A 234 ` 235 236 const testTransformRefPathStr = ` 237 A 238 B 239 A 240 child.A 241 child.B 242 child.A 243 `