Files
opentf/internal/command/jsonprovider/function_test.go
Nathan Baulch ea558d9d4b Fix typos (#1905)
Signed-off-by: Nathan Baulch <nathan.baulch@gmail.com>
Signed-off-by: Christian Mesh <christianmesh1@gmail.com>
Co-authored-by: Christian Mesh <christianmesh1@gmail.com>
2024-08-29 13:20:33 -04:00

251 lines
5.9 KiB
Go

// Copyright (c) The OpenTofu Authors
// SPDX-License-Identifier: MPL-2.0
// Copyright (c) 2023 HashiCorp, Inc.
// SPDX-License-Identifier: MPL-2.0
package jsonprovider
import (
"encoding/json"
"testing"
"github.com/google/go-cmp/cmp"
"github.com/opentofu/opentofu/internal/providers"
"github.com/zclconf/go-cty/cty"
)
func TestMarshalReturnType(t *testing.T) {
type testcase struct {
Arg cty.Type
Expected any
}
tests := map[string]testcase{
"string": {
Arg: cty.String,
Expected: "string",
},
"number": {
Arg: cty.Number,
Expected: "number",
},
"bool": {
Arg: cty.Bool,
Expected: "bool",
},
"object": {
Arg: cty.Object(map[string]cty.Type{"number_type": cty.Number}),
Expected: []any{
string("object"),
map[string]cty.Type{"number_type": cty.Number},
},
},
"map": {
Arg: cty.Map(cty.String),
Expected: []any{
string("map"),
cty.String,
},
},
"list": {
Arg: cty.List(cty.Bool),
Expected: []any{
string("list"),
cty.Bool,
},
},
"set": {
Arg: cty.Set(cty.Number),
Expected: []any{
string("set"),
cty.Number,
},
},
"tuple": {
Arg: cty.Tuple([]cty.Type{cty.String}),
Expected: []any{
string("tuple"),
[]any{cty.String},
},
},
}
for tn, tc := range tests {
t.Run(tn, func(t *testing.T) {
actual := marshalReturnType(tc.Arg)
// to avoid the nightmare of comparing cty primitive types we can marshal them to json and compare that
actualJSON, _ := json.Marshal(actual)
expectedJSON, _ := json.Marshal(tc.Expected)
if !cmp.Equal(actualJSON, expectedJSON) {
t.Fatalf("values don't match:\n %v\n", cmp.Diff(string(actualJSON), string(expectedJSON)))
}
})
}
}
func TestMarshalParameter(t *testing.T) {
// used so can make a pointer to it
trueBoolVal := true
type testcase struct {
Arg providers.FunctionParameterSpec
Expected FunctionParam
}
tests := map[string]testcase{
"basic": {
Arg: providers.FunctionParameterSpec{
Description: "basic string func",
Type: cty.String,
},
Expected: FunctionParam{
Description: "basic string func",
Type: cty.String,
},
},
"nullable": {
Arg: providers.FunctionParameterSpec{
Description: "nullable number func",
Type: cty.Number,
AllowNullValue: trueBoolVal,
},
Expected: FunctionParam{
Description: "nullable number func",
Type: cty.Number,
IsNullable: &trueBoolVal,
},
},
}
for tn, tc := range tests {
t.Run(tn, func(t *testing.T) {
actual := marshalParameter(tc.Arg)
// to avoid the nightmare of comparing cty primitive types we can marshal them to json and compare that
actualJSON, _ := json.Marshal(actual)
expectedJSON, _ := json.Marshal(tc.Expected)
if !cmp.Equal(actualJSON, expectedJSON) {
t.Fatalf("values don't match:\n %v\n", cmp.Diff(string(actualJSON), string(expectedJSON)))
}
})
}
}
func TestMarshalParameters(t *testing.T) {
type testcase struct {
Arg []providers.FunctionParameterSpec
Expected []FunctionParam
}
tests := map[string]testcase{
"basic": {
Arg: []providers.FunctionParameterSpec{{
Description: "basic string func",
Type: cty.String,
}},
Expected: []FunctionParam{{
Description: "basic string func",
Type: cty.String,
}},
},
}
for tn, tc := range tests {
t.Run(tn, func(t *testing.T) {
actual := marshalParameters(tc.Arg)
// to avoid the nightmare of comparing cty primitive types we can marshal them to json and compare that
actualJSON, _ := json.Marshal(actual)
expectedJSON, _ := json.Marshal(tc.Expected)
if !cmp.Equal(actualJSON, expectedJSON) {
t.Fatalf("values don't match:\n %v\n", cmp.Diff(string(actualJSON), string(expectedJSON)))
}
})
}
}
func TestMarshalFunction(t *testing.T) {
type testcase struct {
Arg providers.FunctionSpec
Expected Function
}
tests := map[string]testcase{
"basic": {
Arg: providers.FunctionSpec{
Description: "basic string func",
Return: cty.String,
},
Expected: Function{
Description: "basic string func",
ReturnType: cty.String,
},
},
"variadic": {
Arg: providers.FunctionSpec{
Description: "basic string func",
Return: cty.String,
VariadicParameter: &providers.FunctionParameterSpec{
Description: "basic string func",
Type: cty.String,
},
},
Expected: Function{
Description: "basic string func",
ReturnType: cty.String,
VariadicParameter: &FunctionParam{
Description: "basic string func",
Type: cty.String,
},
},
},
}
for tn, tc := range tests {
t.Run(tn, func(t *testing.T) {
actual := marshalFunction(tc.Arg)
// to avoid the nightmare of comparing cty primitive types we can marshal them to json and compare that
actualJSON, _ := json.Marshal(actual)
expectedJSON, _ := json.Marshal(tc.Expected)
if !cmp.Equal(actualJSON, expectedJSON) {
t.Fatalf("values don't match:\n %v\n", cmp.Diff(string(actualJSON), string(expectedJSON)))
}
})
}
}
func TestMarshalFunctions(t *testing.T) {
type testcase struct {
Arg map[string]providers.FunctionSpec
Expected map[string]Function
}
tests := map[string]testcase{
"basic": {
Arg: map[string]providers.FunctionSpec{"basic_func": {
Description: "basic string func",
Return: cty.String,
}},
Expected: map[string]Function{"basic_func": {
Description: "basic string func",
ReturnType: cty.String,
}},
},
}
for tn, tc := range tests {
t.Run(tn, func(t *testing.T) {
actual := marshalFunctions(tc.Arg)
// to avoid the nightmare of comparing cty primitive types we can marshal them to json and compare that
actualJSON, _ := json.Marshal(actual)
expectedJSON, _ := json.Marshal(tc.Expected)
if !cmp.Equal(actualJSON, expectedJSON) {
t.Fatalf("values don't match:\n %v\n", cmp.Diff(string(actualJSON), string(expectedJSON)))
}
})
}
}