@@ -3,50 +3,175 @@ package autogeneration_test
3
3
import (
4
4
"testing"
5
5
6
+ "github.com/hashicorp/terraform-plugin-framework/attr"
6
7
"github.com/hashicorp/terraform-plugin-framework/types"
7
8
"github.com/mongodb/terraform-provider-mongodbatlas/internal/common/autogeneration"
8
9
"github.com/stretchr/testify/assert"
9
10
"github.com/stretchr/testify/require"
10
11
)
11
12
13
+ func TestMarshalBasic (t * testing.T ) {
14
+ model := struct {
15
+ AttrFloat types.Float64 `tfsdk:"attr_float"`
16
+ AttrString types.String `tfsdk:"attr_string"`
17
+ // values with tag `omitjson` are not marshaled, and they don't need to be Terraform types
18
+ AttrOmit types.String `tfsdk:"attr_omit" autogeneration:"omitjson"`
19
+ AttrOmitNoTerraform string `autogeneration:"omitjson"`
20
+ AttrUnkown types.String `tfsdk:"attr_unknown"`
21
+ AttrNull types.String `tfsdk:"attr_null"`
22
+ AttrInt types.Int64 `tfsdk:"attr_int"`
23
+ }{
24
+ AttrFloat : types .Float64Value (1.234 ),
25
+ AttrString : types .StringValue ("hello" ),
26
+ AttrOmit : types .StringValue ("omit" ),
27
+ AttrOmitNoTerraform : "omit" ,
28
+ AttrUnkown : types .StringUnknown (), // unknown values are not marshaled
29
+ AttrNull : types .StringNull (), // null values are not marshaled
30
+ AttrInt : types .Int64Value (1 ),
31
+ }
32
+ const expectedJSON = `{ "attr_string": "hello", "attr_int": 1, "attr_float": 1.234 }`
33
+ raw , err := autogeneration .Marshal (& model , false )
34
+ require .NoError (t , err )
35
+ assert .JSONEq (t , expectedJSON , string (raw ))
36
+ }
37
+
38
+ func TestMarshalOmitJSONUpdate (t * testing.T ) {
39
+ const (
40
+ expectedCreate = `{ "attr": "val1", "attr_omit_update": "val2" }`
41
+ expectedUpdate = `{ "attr": "val1" }`
42
+ )
43
+ model := struct {
44
+ Attr types.String `tfsdk:"attr"`
45
+ AttrOmitUpdate types.String `tfsdk:"attr_omit_update" autogeneration:"omitjsonupdate"`
46
+ AttrOmit types.String `tfsdk:"attr_omit" autogeneration:"omitjson"`
47
+ }{
48
+ Attr : types .StringValue ("val1" ),
49
+ AttrOmitUpdate : types .StringValue ("val2" ),
50
+ AttrOmit : types .StringValue ("omit" ),
51
+ }
52
+ create , errCreate := autogeneration .Marshal (& model , false )
53
+ require .NoError (t , errCreate )
54
+ assert .JSONEq (t , expectedCreate , string (create ))
55
+
56
+ update , errUpdate := autogeneration .Marshal (& model , true )
57
+ require .NoError (t , errUpdate )
58
+ assert .JSONEq (t , expectedUpdate , string (update ))
59
+ }
60
+
61
+ func TestMarshalUnsupported (t * testing.T ) {
62
+ testCases := map [string ]any {
63
+ "Object not supported yet, only no-nested types" : & struct {
64
+ Attr types.Object
65
+ }{
66
+ Attr : types .ObjectValueMust (map [string ]attr.Type {
67
+ "key" : types .StringType ,
68
+ }, map [string ]attr.Value {
69
+ "key" : types .StringValue ("value" ),
70
+ }),
71
+ },
72
+ "List not supported yet, only no-nested types" : & struct {
73
+ Attr types.List
74
+ }{
75
+ Attr : types .ListValueMust (types .StringType , []attr.Value {
76
+ types .StringValue ("value" ),
77
+ }),
78
+ },
79
+ "Map not supported yet, only no-nested types" : & struct {
80
+ Attr types.Map
81
+ }{
82
+ Attr : types .MapValueMust (types .StringType , map [string ]attr.Value {
83
+ "key" : types .StringValue ("value" ),
84
+ }),
85
+ },
86
+ "Set not supported yet, only no-nested types" : & struct {
87
+ Attr types.Set
88
+ }{
89
+ Attr : types .SetValueMust (types .StringType , []attr.Value {
90
+ types .StringValue ("value" ),
91
+ }),
92
+ },
93
+ "Int32 not supported yet as it's not being used in any model" : & struct {
94
+ Attr types.Int32
95
+ }{
96
+ Attr : types .Int32Value (1 ),
97
+ },
98
+ "Float32 not supported yet as it's not being used in any model" : & struct {
99
+ Attr types.Float32
100
+ }{
101
+ Attr : types .Float32Value (1.0 ),
102
+ },
103
+ }
104
+ for name , model := range testCases {
105
+ t .Run (name , func (t * testing.T ) {
106
+ raw , err := autogeneration .Marshal (model , false )
107
+ require .Error (t , err )
108
+ assert .Nil (t , raw )
109
+ })
110
+ }
111
+ }
112
+
113
+ func TestMarshalPanic (t * testing.T ) {
114
+ str := "string"
115
+ testCases := map [string ]any {
116
+ "no Terraform types" : & struct {
117
+ Attr string
118
+ }{
119
+ Attr : "a" ,
120
+ },
121
+ "no pointer" : struct {
122
+ Attr types.String
123
+ }{
124
+ Attr : types .StringValue ("a" ),
125
+ },
126
+ "no struct" : & str ,
127
+ }
128
+ for name , model := range testCases {
129
+ t .Run (name , func (t * testing.T ) {
130
+ assert .Panics (t , func () {
131
+ _ , _ = autogeneration .Marshal (model , false )
132
+ })
133
+ })
134
+ }
135
+ }
136
+
12
137
func TestUnmarshalBasic (t * testing.T ) {
13
138
var model struct {
14
- AttributeFloat types.Float64 `tfsdk:"attribute_float "`
15
- AttributeFloatWithInt types.Float64 `tfsdk:"attribute_float_with_int "`
16
- AttributeString types.String `tfsdk:"attribute_string "`
17
- AttributeNotInJSON types.String `tfsdk:"attribute_not_in_json "`
18
- AttributeInt types.Int64 `tfsdk:"attribute_int "`
19
- AttributeIntWithFloat types.Int64 `tfsdk:"attribute_int_with_float "`
20
- AttributeTrue types.Bool `tfsdk:"attribute_true "`
21
- AttributeFalse types.Bool `tfsdk:"attribute_false "`
139
+ AttrFloat types.Float64 `tfsdk:"attr_float "`
140
+ AttrFloatWithInt types.Float64 `tfsdk:"attr_float_with_int "`
141
+ AttrString types.String `tfsdk:"attr_string "`
142
+ AttrNotInJSON types.String `tfsdk:"attr_not_in_json "`
143
+ AttrInt types.Int64 `tfsdk:"attr_int "`
144
+ AttrIntWithFloat types.Int64 `tfsdk:"attr_int_with_float "`
145
+ AttrTrue types.Bool `tfsdk:"attr_true "`
146
+ AttrFalse types.Bool `tfsdk:"attr_false "`
22
147
}
23
148
const (
24
149
epsilon = 10e-15 // float tolerance
25
150
// attribute_not_in_model is ignored because it is not in the model, no error is thrown.
26
151
// attribute_null is ignored because it is null, no error is thrown even if it is not in the model.
27
152
tfResponseJSON = `
28
153
{
29
- "attribute_string ": "value_string",
30
- "attribute_true ": true,
31
- "attribute_false ": false,
32
- "attribute_int ": 123,
33
- "attribute_int_with_float ": 10.6,
34
- "attribute_float ": 456.1,
35
- "attribute_float_with_int ": 13,
36
- "attribute_not_in_model ": "val",
37
- "attribute_null ": null
154
+ "attr_string ": "value_string",
155
+ "attr_true ": true,
156
+ "attr_false ": false,
157
+ "attr_int ": 123,
158
+ "attr_int_with_float ": 10.6,
159
+ "attr_float ": 456.1,
160
+ "attr_float_with_int ": 13,
161
+ "attr_not_in_model ": "val",
162
+ "attr_null ": null
38
163
}
39
164
`
40
165
)
41
166
require .NoError (t , autogeneration .Unmarshal ([]byte (tfResponseJSON ), & model ))
42
- assert .Equal (t , "value_string" , model .AttributeString .ValueString ())
43
- assert .True (t , model .AttributeTrue .ValueBool ())
44
- assert .False (t , model .AttributeFalse .ValueBool ())
45
- assert .Equal (t , int64 (123 ), model .AttributeInt .ValueInt64 ())
46
- assert .Equal (t , int64 (10 ), model .AttributeIntWithFloat .ValueInt64 ()) // response floats stored in model ints have their decimals stripped.
47
- assert .InEpsilon (t , float64 (456.1 ), model .AttributeFloat .ValueFloat64 (), epsilon )
48
- assert .InEpsilon (t , float64 (13 ), model .AttributeFloatWithInt .ValueFloat64 (), epsilon )
49
- assert .True (t , model .AttributeNotInJSON .IsNull ()) // attributes not in JSON response are not changed, so null is kept.
167
+ assert .Equal (t , "value_string" , model .AttrString .ValueString ())
168
+ assert .True (t , model .AttrTrue .ValueBool ())
169
+ assert .False (t , model .AttrFalse .ValueBool ())
170
+ assert .Equal (t , int64 (123 ), model .AttrInt .ValueInt64 ())
171
+ assert .Equal (t , int64 (10 ), model .AttrIntWithFloat .ValueInt64 ()) // response floats stored in model ints have their decimals stripped.
172
+ assert .InEpsilon (t , float64 (456.1 ), model .AttrFloat .ValueFloat64 (), epsilon )
173
+ assert .InEpsilon (t , float64 (13 ), model .AttrFloatWithInt .ValueFloat64 (), epsilon )
174
+ assert .True (t , model .AttrNotInJSON .IsNull ()) // attributes not in JSON response are not changed, so null is kept.
50
175
}
51
176
52
177
func TestUnmarshalErrors (t * testing.T ) {
@@ -132,11 +257,11 @@ func TestUnmarshalUnsupportedResponse(t *testing.T) {
132
257
}{
133
258
"JSON objects not support yet" : {
134
259
responseJSON : `{"attr": {"key": "value"}}` ,
135
- errorStr : "not supported yet type map[string]interface {} for field attr" ,
260
+ errorStr : "unmarshal not supported yet for type map[string]interface {} for field attr" ,
136
261
},
137
262
"JSON arrays not supported yet" : {
138
263
responseJSON : `{"attr": [{"key": "value"}]}` ,
139
- errorStr : "not supported yet type []interface {} for field attr" ,
264
+ errorStr : "unmarshal not supported yet for type []interface {} for field attr" ,
140
265
},
141
266
}
142
267
for name , tc := range testCases {
0 commit comments