blob: ee7a9e340d68b216dbf9325ecf998c0df1fbac06 [file] [log] [blame]
Cole Faustc9508aa2023-02-07 11:38:27 -08001// Copyright 2023 Google Inc. All rights reserved.
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 starlark_import
16
17import (
18 "reflect"
19 "testing"
20
21 "go.starlark.net/starlark"
22)
23
24func createStarlarkValue(t *testing.T, code string) starlark.Value {
25 t.Helper()
26 result, err := starlark.ExecFile(&starlark.Thread{}, "main.bzl", "x = "+code, builtins)
27 if err != nil {
28 panic(err)
29 }
30 return result["x"]
31}
32
33func TestUnmarshallConcreteType(t *testing.T) {
34 x, err := Unmarshal[string](createStarlarkValue(t, `"foo"`))
35 if err != nil {
36 t.Error(err)
37 return
38 }
39 if x != "foo" {
40 t.Errorf(`Expected "foo", got %q`, x)
41 }
42}
43
44func TestUnmarshallConcreteTypeWithInterfaces(t *testing.T) {
45 x, err := Unmarshal[map[string]map[string]interface{}](createStarlarkValue(t,
46 `{"foo": {"foo2": "foo3"}, "bar": {"bar2": ["bar3"]}}`))
47 if err != nil {
48 t.Error(err)
49 return
50 }
51 expected := map[string]map[string]interface{}{
52 "foo": {"foo2": "foo3"},
53 "bar": {"bar2": []string{"bar3"}},
54 }
55 if !reflect.DeepEqual(x, expected) {
56 t.Errorf(`Expected %v, got %v`, expected, x)
57 }
58}
59
60func TestUnmarshall(t *testing.T) {
61 testCases := []struct {
62 input string
63 expected interface{}
64 }{
65 {
66 input: `"foo"`,
67 expected: "foo",
68 },
69 {
70 input: `5`,
71 expected: 5,
72 },
73 {
74 input: `["foo", "bar"]`,
75 expected: []string{"foo", "bar"},
76 },
77 {
78 input: `("foo", "bar")`,
79 expected: []string{"foo", "bar"},
80 },
81 {
82 input: `("foo",5)`,
83 expected: []interface{}{"foo", 5},
84 },
85 {
86 input: `{"foo": 5, "bar": 10}`,
87 expected: map[string]int{"foo": 5, "bar": 10},
88 },
89 {
90 input: `{"foo": ["qux"], "bar": []}`,
91 expected: map[string][]string{"foo": {"qux"}, "bar": nil},
92 },
93 {
94 input: `struct(Foo="foo", Bar=5)`,
95 expected: struct {
96 Foo string
97 Bar int
98 }{Foo: "foo", Bar: 5},
99 },
100 {
101 // Unexported fields version of the above
102 input: `struct(foo="foo", bar=5)`,
103 expected: struct {
104 foo string
105 bar int
106 }{foo: "foo", bar: 5},
107 },
108 {
109 input: `{"foo": "foo2", "bar": ["bar2"], "baz": 5, "qux": {"qux2": "qux3"}, "quux": {"quux2": "quux3", "quux4": 5}}`,
110 expected: map[string]interface{}{
111 "foo": "foo2",
112 "bar": []string{"bar2"},
113 "baz": 5,
114 "qux": map[string]string{"qux2": "qux3"},
115 "quux": map[string]interface{}{
116 "quux2": "quux3",
117 "quux4": 5,
118 },
119 },
120 },
121 }
122
123 for _, tc := range testCases {
124 x, err := UnmarshalReflect(createStarlarkValue(t, tc.input), reflect.TypeOf(tc.expected))
125 if err != nil {
126 t.Error(err)
127 continue
128 }
129 if !reflect.DeepEqual(x.Interface(), tc.expected) {
130 t.Errorf(`Expected %#v, got %#v`, tc.expected, x.Interface())
131 }
132 }
133}