github.com/hashicorp/hcl/v2@v2.20.0/gohcl/schema_test.go (about) 1 // Copyright (c) HashiCorp, Inc. 2 // SPDX-License-Identifier: MPL-2.0 3 4 package gohcl 5 6 import ( 7 "fmt" 8 "reflect" 9 "testing" 10 11 "github.com/davecgh/go-spew/spew" 12 "github.com/hashicorp/hcl/v2" 13 ) 14 15 func TestImpliedBodySchema(t *testing.T) { 16 tests := []struct { 17 val interface{} 18 wantSchema *hcl.BodySchema 19 wantPartial bool 20 }{ 21 { 22 struct{}{}, 23 &hcl.BodySchema{}, 24 false, 25 }, 26 { 27 struct { 28 Ignored bool 29 }{}, 30 &hcl.BodySchema{}, 31 false, 32 }, 33 { 34 struct { 35 Attr1 bool `hcl:"attr1"` 36 Attr2 bool `hcl:"attr2"` 37 }{}, 38 &hcl.BodySchema{ 39 Attributes: []hcl.AttributeSchema{ 40 { 41 Name: "attr1", 42 Required: true, 43 }, 44 { 45 Name: "attr2", 46 Required: true, 47 }, 48 }, 49 }, 50 false, 51 }, 52 { 53 struct { 54 Attr *bool `hcl:"attr,attr"` 55 }{}, 56 &hcl.BodySchema{ 57 Attributes: []hcl.AttributeSchema{ 58 { 59 Name: "attr", 60 Required: false, 61 }, 62 }, 63 }, 64 false, 65 }, 66 { 67 struct { 68 Thing struct{} `hcl:"thing,block"` 69 }{}, 70 &hcl.BodySchema{ 71 Blocks: []hcl.BlockHeaderSchema{ 72 { 73 Type: "thing", 74 }, 75 }, 76 }, 77 false, 78 }, 79 { 80 struct { 81 Thing struct { 82 Type string `hcl:"type,label"` 83 Name string `hcl:"name,label"` 84 } `hcl:"thing,block"` 85 }{}, 86 &hcl.BodySchema{ 87 Blocks: []hcl.BlockHeaderSchema{ 88 { 89 Type: "thing", 90 LabelNames: []string{"type", "name"}, 91 }, 92 }, 93 }, 94 false, 95 }, 96 { 97 struct { 98 Thing []struct { 99 Type string `hcl:"type,label"` 100 Name string `hcl:"name,label"` 101 } `hcl:"thing,block"` 102 }{}, 103 &hcl.BodySchema{ 104 Blocks: []hcl.BlockHeaderSchema{ 105 { 106 Type: "thing", 107 LabelNames: []string{"type", "name"}, 108 }, 109 }, 110 }, 111 false, 112 }, 113 { 114 struct { 115 Thing *struct { 116 Type string `hcl:"type,label"` 117 Name string `hcl:"name,label"` 118 } `hcl:"thing,block"` 119 }{}, 120 &hcl.BodySchema{ 121 Blocks: []hcl.BlockHeaderSchema{ 122 { 123 Type: "thing", 124 LabelNames: []string{"type", "name"}, 125 }, 126 }, 127 }, 128 false, 129 }, 130 { 131 struct { 132 Thing struct { 133 Name string `hcl:"name,label"` 134 Something string `hcl:"something"` 135 } `hcl:"thing,block"` 136 }{}, 137 &hcl.BodySchema{ 138 Blocks: []hcl.BlockHeaderSchema{ 139 { 140 Type: "thing", 141 LabelNames: []string{"name"}, 142 }, 143 }, 144 }, 145 false, 146 }, 147 { 148 struct { 149 Doodad string `hcl:"doodad"` 150 Thing struct { 151 Name string `hcl:"name,label"` 152 } `hcl:"thing,block"` 153 }{}, 154 &hcl.BodySchema{ 155 Attributes: []hcl.AttributeSchema{ 156 { 157 Name: "doodad", 158 Required: true, 159 }, 160 }, 161 Blocks: []hcl.BlockHeaderSchema{ 162 { 163 Type: "thing", 164 LabelNames: []string{"name"}, 165 }, 166 }, 167 }, 168 false, 169 }, 170 { 171 struct { 172 Doodad string `hcl:"doodad"` 173 Config string `hcl:",remain"` 174 }{}, 175 &hcl.BodySchema{ 176 Attributes: []hcl.AttributeSchema{ 177 { 178 Name: "doodad", 179 Required: true, 180 }, 181 }, 182 }, 183 true, 184 }, 185 { 186 struct { 187 Expr hcl.Expression `hcl:"expr"` 188 }{}, 189 &hcl.BodySchema{ 190 Attributes: []hcl.AttributeSchema{ 191 { 192 Name: "expr", 193 Required: false, 194 }, 195 }, 196 }, 197 false, 198 }, 199 { 200 struct { 201 Meh string `hcl:"meh,optional"` 202 }{}, 203 &hcl.BodySchema{ 204 Attributes: []hcl.AttributeSchema{ 205 { 206 Name: "meh", 207 Required: false, 208 }, 209 }, 210 }, 211 false, 212 }, 213 } 214 215 for _, test := range tests { 216 t.Run(fmt.Sprintf("%#v", test.val), func(t *testing.T) { 217 schema, partial := ImpliedBodySchema(test.val) 218 if !reflect.DeepEqual(schema, test.wantSchema) { 219 t.Errorf( 220 "wrong schema\ngot: %s\nwant: %s", 221 spew.Sdump(schema), spew.Sdump(test.wantSchema), 222 ) 223 } 224 225 if partial != test.wantPartial { 226 t.Errorf( 227 "wrong partial flag\ngot: %#v\nwant: %#v", 228 partial, test.wantPartial, 229 ) 230 } 231 }) 232 } 233 }