github.com/terramate-io/tf@v0.0.0-20230830114523-fce866b4dfcd/legacy/helper/schema/backend_test.go (about) 1 // Copyright (c) HashiCorp, Inc. 2 // SPDX-License-Identifier: MPL-2.0 3 4 package schema 5 6 import ( 7 "context" 8 "fmt" 9 "testing" 10 11 "github.com/zclconf/go-cty/cty" 12 ) 13 14 func TestBackendPrepare(t *testing.T) { 15 cases := []struct { 16 Name string 17 B *Backend 18 Config map[string]cty.Value 19 Expect map[string]cty.Value 20 Err bool 21 }{ 22 { 23 "Basic required field", 24 &Backend{ 25 Schema: map[string]*Schema{ 26 "foo": &Schema{ 27 Required: true, 28 Type: TypeString, 29 }, 30 }, 31 }, 32 map[string]cty.Value{}, 33 map[string]cty.Value{}, 34 true, 35 }, 36 37 { 38 "Null config", 39 &Backend{ 40 Schema: map[string]*Schema{ 41 "foo": &Schema{ 42 Required: true, 43 Type: TypeString, 44 }, 45 }, 46 }, 47 nil, 48 map[string]cty.Value{}, 49 true, 50 }, 51 52 { 53 "Basic required field set", 54 &Backend{ 55 Schema: map[string]*Schema{ 56 "foo": &Schema{ 57 Required: true, 58 Type: TypeString, 59 }, 60 }, 61 }, 62 map[string]cty.Value{ 63 "foo": cty.StringVal("bar"), 64 }, 65 map[string]cty.Value{ 66 "foo": cty.StringVal("bar"), 67 }, 68 false, 69 }, 70 71 { 72 "unused default", 73 &Backend{ 74 Schema: map[string]*Schema{ 75 "foo": &Schema{ 76 Optional: true, 77 Type: TypeString, 78 Default: "baz", 79 }, 80 }, 81 }, 82 map[string]cty.Value{ 83 "foo": cty.StringVal("bar"), 84 }, 85 map[string]cty.Value{ 86 "foo": cty.StringVal("bar"), 87 }, 88 false, 89 }, 90 91 { 92 "default", 93 &Backend{ 94 Schema: map[string]*Schema{ 95 "foo": &Schema{ 96 Type: TypeString, 97 Optional: true, 98 Default: "baz", 99 }, 100 }, 101 }, 102 map[string]cty.Value{}, 103 map[string]cty.Value{ 104 "foo": cty.StringVal("baz"), 105 }, 106 false, 107 }, 108 109 { 110 "default func", 111 &Backend{ 112 Schema: map[string]*Schema{ 113 "foo": &Schema{ 114 Type: TypeString, 115 Optional: true, 116 DefaultFunc: func() (interface{}, error) { 117 return "baz", nil 118 }, 119 }, 120 }, 121 }, 122 map[string]cty.Value{}, 123 map[string]cty.Value{ 124 "foo": cty.StringVal("baz"), 125 }, 126 false, 127 }, 128 } 129 130 for i, tc := range cases { 131 t.Run(fmt.Sprintf("%d-%s", i, tc.Name), func(t *testing.T) { 132 cfgVal := cty.NullVal(cty.Object(map[string]cty.Type{})) 133 if tc.Config != nil { 134 cfgVal = cty.ObjectVal(tc.Config) 135 } 136 configVal, diags := tc.B.PrepareConfig(cfgVal) 137 if diags.HasErrors() != tc.Err { 138 for _, d := range diags { 139 t.Error(d.Description()) 140 } 141 } 142 143 if tc.Err { 144 return 145 } 146 147 expect := cty.ObjectVal(tc.Expect) 148 if !expect.RawEquals(configVal) { 149 t.Fatalf("\nexpected: %#v\ngot: %#v\n", expect, configVal) 150 } 151 }) 152 } 153 } 154 155 func TestBackendConfigure(t *testing.T) { 156 cases := []struct { 157 Name string 158 B *Backend 159 Config map[string]cty.Value 160 Err bool 161 }{ 162 { 163 "Basic config", 164 &Backend{ 165 Schema: map[string]*Schema{ 166 "foo": &Schema{ 167 Type: TypeInt, 168 Optional: true, 169 }, 170 }, 171 172 ConfigureFunc: func(ctx context.Context) error { 173 d := FromContextBackendConfig(ctx) 174 if d.Get("foo").(int) != 42 { 175 return fmt.Errorf("bad config data") 176 } 177 178 return nil 179 }, 180 }, 181 map[string]cty.Value{ 182 "foo": cty.NumberIntVal(42), 183 }, 184 false, 185 }, 186 } 187 188 for i, tc := range cases { 189 t.Run(fmt.Sprintf("%d-%s", i, tc.Name), func(t *testing.T) { 190 diags := tc.B.Configure(cty.ObjectVal(tc.Config)) 191 if diags.HasErrors() != tc.Err { 192 t.Errorf("wrong number of diagnostics") 193 } 194 }) 195 } 196 }