1package stdlib
2
3import (
4	"fmt"
5	"testing"
6
7	"github.com/zclconf/go-cty/cty"
8)
9
10func TestJSONEncode(t *testing.T) {
11	tests := []struct {
12		Input cty.Value
13		Want  cty.Value
14	}{
15		// This does not comprehensively test all possible inputs because
16		// the underlying functions in package json already have tests of
17		// their own. Here we are mainly concerned with seeing that the
18		// function's definition accepts all reasonable values.
19		{
20			cty.NumberIntVal(15),
21			cty.StringVal(`15`),
22		},
23		{
24			cty.StringVal("hello"),
25			cty.StringVal(`"hello"`),
26		},
27		{
28			cty.True,
29			cty.StringVal(`true`),
30		},
31		{
32			cty.ListValEmpty(cty.Number),
33			cty.StringVal(`[]`),
34		},
35		{
36			cty.ListVal([]cty.Value{cty.True, cty.False}),
37			cty.StringVal(`[true,false]`),
38		},
39		{
40			cty.ObjectVal(map[string]cty.Value{"true": cty.True, "false": cty.False}),
41			cty.StringVal(`{"false":false,"true":true}`),
42		},
43		{
44			cty.UnknownVal(cty.Number),
45			cty.UnknownVal(cty.String),
46		},
47		{
48			cty.ObjectVal(map[string]cty.Value{"dunno": cty.UnknownVal(cty.Bool), "false": cty.False}),
49			cty.UnknownVal(cty.String),
50		},
51		{
52			cty.DynamicVal,
53			cty.UnknownVal(cty.String),
54		},
55		{
56			cty.NullVal(cty.String),
57			cty.StringVal("null"),
58		},
59	}
60
61	for _, test := range tests {
62		t.Run(fmt.Sprintf("JSONEncode(%#v)", test.Input), func(t *testing.T) {
63			got, err := JSONEncode(test.Input)
64
65			if err != nil {
66				t.Fatalf("unexpected error: %s", err)
67			}
68
69			if !got.RawEquals(test.Want) {
70				t.Errorf("wrong result\ngot:  %#v\nwant: %#v", got, test.Want)
71			}
72		})
73	}
74}
75
76func TestJSONDecode(t *testing.T) {
77	tests := []struct {
78		Input cty.Value
79		Want  cty.Value
80	}{
81		{
82			cty.StringVal(`15`),
83			cty.NumberIntVal(15),
84		},
85		{
86			cty.StringVal(`"hello"`),
87			cty.StringVal("hello"),
88		},
89		{
90			cty.StringVal(`true`),
91			cty.True,
92		},
93		{
94			cty.StringVal(`[]`),
95			cty.EmptyTupleVal,
96		},
97		{
98			cty.StringVal(`[true,false]`),
99			cty.TupleVal([]cty.Value{cty.True, cty.False}),
100		},
101		{
102			cty.StringVal(`{"false":false,"true":true}`),
103			cty.ObjectVal(map[string]cty.Value{"true": cty.True, "false": cty.False}),
104		},
105		{
106			cty.UnknownVal(cty.String),
107			cty.DynamicVal, // need to know the value to determine the type
108		},
109		{
110			cty.DynamicVal,
111			cty.DynamicVal,
112		},
113		{
114			cty.StringVal(`true`).Mark(1),
115			cty.True.Mark(1),
116		},
117	}
118
119	for _, test := range tests {
120		t.Run(fmt.Sprintf("JSONDecode(%#v)", test.Input), func(t *testing.T) {
121			got, err := JSONDecode(test.Input)
122
123			if err != nil {
124				t.Fatalf("unexpected error: %s", err)
125			}
126
127			if !got.RawEquals(test.Want) {
128				t.Errorf("wrong result\ngot:  %#v\nwant: %#v", got, test.Want)
129			}
130		})
131	}
132}
133