blob: 50f9248659559b8019d885a8c8d93fff1318a18d [file] [log] [blame]
Marcel van Lohuizenb46a7ce2019-04-02 16:00:08 +02001// Copyright 2019 CUE Authors
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7// http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15package cue
16
17import (
Marcel van Lohuizenb46a7ce2019-04-02 16:00:08 +020018 "math/big"
19 "reflect"
20 "testing"
21 "time"
22
Marcel van Lohuizen46e73ec2019-04-03 12:19:18 +020023 "cuelang.org/go/cue/ast"
Marcel van Lohuizenb46a7ce2019-04-02 16:00:08 +020024 "cuelang.org/go/cue/errors"
25)
26
27func TestConvert(t *testing.T) {
28 i34 := big.NewInt(34)
29 d34 := mkBigInt(34)
Marcel van Lohuizen46e73ec2019-04-03 12:19:18 +020030 n34 := mkBigInt(-34)
Marcel van Lohuizenb46a7ce2019-04-02 16:00:08 +020031 f34 := big.NewFloat(34.0000)
32 testCases := []struct {
33 goVal interface{}
34 want string
35 }{{
Marcel van Lohuizen46e73ec2019-04-03 12:19:18 +020036 nil, "(*null | _)",
Marcel van Lohuizenb46a7ce2019-04-02 16:00:08 +020037 }, {
38 true, "true",
39 }, {
40 false, "false",
41 }, {
42 errors.New("oh noes"), "_|_(oh noes)",
43 }, {
44 "foo", `"foo"`,
45 }, {
46 3, "3",
47 }, {
48 uint(3), "3",
49 }, {
50 uint8(3), "3",
51 }, {
52 uint16(3), "3",
53 }, {
54 uint32(3), "3",
55 }, {
56 uint64(3), "3",
57 }, {
58 int8(-3), "-3",
59 }, {
60 int16(-3), "-3",
61 }, {
62 int32(-3), "-3",
63 }, {
64 int64(-3), "-3",
65 }, {
66 float64(3.1), "3.1",
67 }, {
68 &i34, "34",
69 }, {
70 &f34, "34",
71 }, {
72 &d34, "34",
73 }, {
Marcel van Lohuizen46e73ec2019-04-03 12:19:18 +020074 &n34, "-34",
75 }, {
Marcel van Lohuizenb46a7ce2019-04-02 16:00:08 +020076 []int{1, 2, 3, 4}, "[1,2,3,4]",
77 }, {
78 []interface{}{}, "[]",
79 }, {
80 map[string][]int{
81 "a": []int{1},
82 "b": []int{3, 4},
83 }, "<0>{a: [1], b: [3,4]}",
84 }, {
85 map[int]int{}, "_|_(builtin map key not a string, but unsupported type int)",
86 }, {
87 map[int]int{1: 2}, "_|_(builtin map key not a string, but unsupported type int)",
88 }, {
89 struct {
90 a int
91 b int
92 }{3, 4},
93 "<0>{}",
94 }, {
95 struct {
96 A int
97 B int
98 }{3, 4},
99 "<0>{A: 3, B: 4}",
100 }, {
101 struct {
102 A int `json:"a"`
103 B int `yaml:"b"`
104 }{3, 4},
105 "<0>{a: 3, b: 4}",
106 }, {
107 struct {
108 A int `json:",bb" yaml:"" protobuf:"aa"`
109 B int `yaml:"cc" json:"bb" protobuf:"aa"`
110 }{3, 4},
111 "<0>{aa: 3, bb: 4}",
112 }, {
113 &struct{ A int }{3}, "<0>{A: 3}",
114 }, {
Marcel van Lohuizen46e73ec2019-04-03 12:19:18 +0200115 (*struct{ A int })(nil), "(*null | _)",
Marcel van Lohuizenb46a7ce2019-04-02 16:00:08 +0200116 }, {
117 reflect.ValueOf(3), "3",
118 }, {
119 time.Date(2019, 4, 1, 0, 0, 0, 0, time.UTC), `"2019-04-01T00:00:00Z"`,
120 }}
121 inst := getInstance(t, "foo")
122 b := ast.NewIdent("dummy")
123 for _, tc := range testCases {
124 ctx := inst.newContext()
125 t.Run("", func(t *testing.T) {
126 v := convert(ctx, newNode(b), tc.goVal)
127 got := debugStr(ctx, v)
128 if got != tc.want {
129 t.Errorf("got %q; want %q", got, tc.want)
130 }
131 })
132 }
133}
Marcel van Lohuizen46e73ec2019-04-03 12:19:18 +0200134
135func TestConvertType(t *testing.T) {
136 testCases := []struct {
137 goTyp interface{}
138 want string
139 }{{
140 struct {
141 A int `cue:">=0&<100"`
142 B *big.Int `cue:">=0"`
143 C *big.Int
144 D big.Int
145 F *big.Float
146 }{},
147 // TODO: indicate that B is explicitly an int only.
Marcel van Lohuizen4a360992019-05-11 18:18:31 +0200148 `<0>{A: ((int & >=-9223372036854775808 & int & <=9223372036854775807) & (>=0 & <100)), ` +
Marcel van Lohuizen46e73ec2019-04-03 12:19:18 +0200149 `B: >=0, ` +
150 `C?: _, ` +
151 `D: int, ` +
152 `F?: _}`,
153 }, {
154 &struct {
155 A int16 `cue:">=0&<100"`
156 B error `json:"b"`
157 C string
158 D bool
159 F float64
160 L []byte
161 T time.Time
162 }{},
Marcel van Lohuizen4a360992019-05-11 18:18:31 +0200163 `(*null | <0>{A: ((int & >=-32768 & int & <=32767) & (>=0 & <100)), ` +
Marcel van Lohuizen46e73ec2019-04-03 12:19:18 +0200164 `C: string, ` +
165 `D: bool, ` +
166 `F: float, ` +
167 `b: null, ` +
168 `L?: (*null | bytes), ` +
169 `T: _})`,
170 }, {
171 struct {
172 A int8 `cue:"C-B"`
173 B int8 `cue:"C-A,opt"`
174 C int8 `cue:"A+B"`
175 }{},
176 // TODO: should B be marked as optional?
Marcel van Lohuizen4a360992019-05-11 18:18:31 +0200177 `<0>{A: ((int & >=-128 & int & <=127) & (<0>.C - <0>.B)), ` +
178 `B?: ((int & >=-128 & int & <=127) & (<0>.C - <0>.A)), ` +
179 `C: ((int & >=-128 & int & <=127) & (<0>.A + <0>.B))}`,
Marcel van Lohuizen46e73ec2019-04-03 12:19:18 +0200180 }, {
181 []string{},
182 `(*null | [, ...string])`,
183 }, {
184 [4]string{},
185 `4*[string]`,
186 }, {
187 map[string]struct{ A map[string]uint }{},
188 `(*null | ` +
189 `<0>{<>: <1>(_: string)-><2>{` +
190 `A?: (*null | ` +
Marcel van Lohuizen4a360992019-05-11 18:18:31 +0200191 `<3>{<>: <4>(_: string)->(int & >=0 & int & <=18446744073709551615), })}, })`,
Marcel van Lohuizen46e73ec2019-04-03 12:19:18 +0200192 }, {
193 map[float32]int{},
194 `_|_(type float32 not supported as key type)`,
195 }}
196 inst := getInstance(t, "foo")
197
198 for _, tc := range testCases {
199 ctx := inst.newContext()
200 t.Run("", func(t *testing.T) {
Marcel van Lohuizen94d845d2019-05-10 00:28:03 +0200201 v := goTypeToValue(ctx, true, reflect.TypeOf(tc.goTyp))
Marcel van Lohuizen46e73ec2019-04-03 12:19:18 +0200202 got := debugStr(ctx, v)
203 if got != tc.want {
204 t.Errorf("\n got %q;\nwant %q", got, tc.want)
205 }
206 })
207 }
208}