github.com/iaas-resource-provision/iaas-rpc@v1.0.7-0.20211021023331-ed21f798c408/internal/lang/funcs/conversion_test.go (about)

     1  package funcs
     2  
     3  import (
     4  	"fmt"
     5  	"testing"
     6  
     7  	"github.com/zclconf/go-cty/cty"
     8  )
     9  
    10  func TestTo(t *testing.T) {
    11  	tests := []struct {
    12  		Value    cty.Value
    13  		TargetTy cty.Type
    14  		Want     cty.Value
    15  		Err      string
    16  	}{
    17  		{
    18  			cty.StringVal("a"),
    19  			cty.String,
    20  			cty.StringVal("a"),
    21  			``,
    22  		},
    23  		{
    24  			cty.UnknownVal(cty.String),
    25  			cty.String,
    26  			cty.UnknownVal(cty.String),
    27  			``,
    28  		},
    29  		{
    30  			cty.NullVal(cty.String),
    31  			cty.String,
    32  			cty.NullVal(cty.String),
    33  			``,
    34  		},
    35  		{
    36  			cty.StringVal("a").Mark("boop"),
    37  			cty.String,
    38  			cty.StringVal("a").Mark("boop"),
    39  			``,
    40  		},
    41  		{
    42  			cty.NullVal(cty.String).Mark("boop"),
    43  			cty.String,
    44  			cty.NullVal(cty.String).Mark("boop"),
    45  			``,
    46  		},
    47  		{
    48  			cty.True,
    49  			cty.String,
    50  			cty.StringVal("true"),
    51  			``,
    52  		},
    53  		{
    54  			cty.StringVal("a"),
    55  			cty.Bool,
    56  			cty.DynamicVal,
    57  			`cannot convert "a" to bool; only the strings "true" or "false" are allowed`,
    58  		},
    59  		{
    60  			cty.StringVal("a").Mark("boop"),
    61  			cty.Bool,
    62  			cty.DynamicVal,
    63  			`cannot convert this sensitive string to bool`,
    64  		},
    65  		{
    66  			cty.StringVal("a"),
    67  			cty.Number,
    68  			cty.DynamicVal,
    69  			`cannot convert "a" to number; given string must be a decimal representation of a number`,
    70  		},
    71  		{
    72  			cty.StringVal("a").Mark("boop"),
    73  			cty.Number,
    74  			cty.DynamicVal,
    75  			`cannot convert this sensitive string to number`,
    76  		},
    77  		{
    78  			cty.NullVal(cty.String),
    79  			cty.Number,
    80  			cty.NullVal(cty.Number),
    81  			``,
    82  		},
    83  		{
    84  			cty.UnknownVal(cty.Bool),
    85  			cty.String,
    86  			cty.UnknownVal(cty.String),
    87  			``,
    88  		},
    89  		{
    90  			cty.UnknownVal(cty.String),
    91  			cty.Bool,
    92  			cty.UnknownVal(cty.Bool), // conversion is optimistic
    93  			``,
    94  		},
    95  		{
    96  			cty.TupleVal([]cty.Value{cty.StringVal("hello"), cty.True}),
    97  			cty.List(cty.String),
    98  			cty.ListVal([]cty.Value{cty.StringVal("hello"), cty.StringVal("true")}),
    99  			``,
   100  		},
   101  		{
   102  			cty.TupleVal([]cty.Value{cty.StringVal("hello"), cty.True}),
   103  			cty.Set(cty.String),
   104  			cty.SetVal([]cty.Value{cty.StringVal("hello"), cty.StringVal("true")}),
   105  			``,
   106  		},
   107  		{
   108  			cty.ObjectVal(map[string]cty.Value{"foo": cty.StringVal("hello"), "bar": cty.True}),
   109  			cty.Map(cty.String),
   110  			cty.MapVal(map[string]cty.Value{"foo": cty.StringVal("hello"), "bar": cty.StringVal("true")}),
   111  			``,
   112  		},
   113  		{
   114  			cty.ObjectVal(map[string]cty.Value{"foo": cty.StringVal("hello"), "bar": cty.StringVal("world").Mark("boop")}),
   115  			cty.Map(cty.String),
   116  			cty.MapVal(map[string]cty.Value{"foo": cty.StringVal("hello"), "bar": cty.StringVal("world").Mark("boop")}),
   117  			``,
   118  		},
   119  		{
   120  			cty.ObjectVal(map[string]cty.Value{"foo": cty.StringVal("hello"), "bar": cty.StringVal("world")}).Mark("boop"),
   121  			cty.Map(cty.String),
   122  			cty.MapVal(map[string]cty.Value{"foo": cty.StringVal("hello"), "bar": cty.StringVal("world")}).Mark("boop"),
   123  			``,
   124  		},
   125  		{
   126  			cty.TupleVal([]cty.Value{cty.StringVal("hello"), cty.StringVal("world").Mark("boop")}),
   127  			cty.List(cty.String),
   128  			cty.ListVal([]cty.Value{cty.StringVal("hello"), cty.StringVal("world").Mark("boop")}),
   129  			``,
   130  		},
   131  		{
   132  			cty.TupleVal([]cty.Value{cty.StringVal("hello"), cty.StringVal("world")}).Mark("boop"),
   133  			cty.List(cty.String),
   134  			cty.ListVal([]cty.Value{cty.StringVal("hello"), cty.StringVal("world")}).Mark("boop"),
   135  			``,
   136  		},
   137  		{
   138  			cty.EmptyTupleVal,
   139  			cty.String,
   140  			cty.DynamicVal,
   141  			`cannot convert tuple to string`,
   142  		},
   143  		{
   144  			cty.UnknownVal(cty.EmptyTuple),
   145  			cty.String,
   146  			cty.DynamicVal,
   147  			`cannot convert tuple to string`,
   148  		},
   149  		{
   150  			cty.EmptyObjectVal,
   151  			cty.Object(map[string]cty.Type{"foo": cty.String}),
   152  			cty.DynamicVal,
   153  			`incompatible object type for conversion: attribute "foo" is required`,
   154  		},
   155  	}
   156  
   157  	for _, test := range tests {
   158  		t.Run(fmt.Sprintf("to %s(%#v)", test.TargetTy.FriendlyNameForConstraint(), test.Value), func(t *testing.T) {
   159  			f := MakeToFunc(test.TargetTy)
   160  			got, err := f.Call([]cty.Value{test.Value})
   161  
   162  			if test.Err != "" {
   163  				if err == nil {
   164  					t.Fatal("succeeded; want error")
   165  				}
   166  				if got, want := err.Error(), test.Err; got != want {
   167  					t.Fatalf("wrong error\ngot:  %s\nwant: %s", got, want)
   168  				}
   169  				return
   170  			} else if err != nil {
   171  				t.Fatalf("unexpected error: %s", err)
   172  			}
   173  
   174  			if !got.RawEquals(test.Want) {
   175  				t.Errorf("wrong result\ngot:  %#v\nwant: %#v", got, test.Want)
   176  			}
   177  		})
   178  	}
   179  }