blob: bc0ea4c498b42b87e71962da76917c04d4196d90 [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
Cole Faustf8231dd2023-04-21 17:37:11 -070033func TestUnmarshalConcreteType(t *testing.T) {
Cole Faustc9508aa2023-02-07 11:38:27 -080034 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
Cole Faustf8231dd2023-04-21 17:37:11 -070044func TestUnmarshalConcreteTypeWithInterfaces(t *testing.T) {
Cole Faustc9508aa2023-02-07 11:38:27 -080045 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
Cole Faustf8231dd2023-04-21 17:37:11 -070060func TestUnmarshalToStarlarkValue(t *testing.T) {
61 x, err := Unmarshal[map[string]starlark.Value](createStarlarkValue(t,
62 `{"foo": "Hi", "bar": None}`))
63 if err != nil {
64 t.Error(err)
65 return
66 }
67 if x["foo"].(starlark.String).GoString() != "Hi" {
68 t.Errorf("Expected \"Hi\", got: %q", x["foo"].(starlark.String).GoString())
69 }
70 if x["bar"].Type() != "NoneType" {
71 t.Errorf("Expected \"NoneType\", got: %q", x["bar"].Type())
72 }
73}
74
75func TestUnmarshal(t *testing.T) {
Cole Faustc9508aa2023-02-07 11:38:27 -080076 testCases := []struct {
77 input string
78 expected interface{}
79 }{
80 {
81 input: `"foo"`,
82 expected: "foo",
83 },
84 {
85 input: `5`,
86 expected: 5,
87 },
88 {
89 input: `["foo", "bar"]`,
90 expected: []string{"foo", "bar"},
91 },
92 {
93 input: `("foo", "bar")`,
94 expected: []string{"foo", "bar"},
95 },
96 {
97 input: `("foo",5)`,
98 expected: []interface{}{"foo", 5},
99 },
100 {
101 input: `{"foo": 5, "bar": 10}`,
102 expected: map[string]int{"foo": 5, "bar": 10},
103 },
104 {
105 input: `{"foo": ["qux"], "bar": []}`,
106 expected: map[string][]string{"foo": {"qux"}, "bar": nil},
107 },
108 {
109 input: `struct(Foo="foo", Bar=5)`,
110 expected: struct {
111 Foo string
112 Bar int
113 }{Foo: "foo", Bar: 5},
114 },
115 {
116 // Unexported fields version of the above
117 input: `struct(foo="foo", bar=5)`,
118 expected: struct {
119 foo string
120 bar int
121 }{foo: "foo", bar: 5},
122 },
123 {
124 input: `{"foo": "foo2", "bar": ["bar2"], "baz": 5, "qux": {"qux2": "qux3"}, "quux": {"quux2": "quux3", "quux4": 5}}`,
125 expected: map[string]interface{}{
126 "foo": "foo2",
127 "bar": []string{"bar2"},
128 "baz": 5,
129 "qux": map[string]string{"qux2": "qux3"},
130 "quux": map[string]interface{}{
131 "quux2": "quux3",
132 "quux4": 5,
133 },
134 },
135 },
136 }
137
138 for _, tc := range testCases {
139 x, err := UnmarshalReflect(createStarlarkValue(t, tc.input), reflect.TypeOf(tc.expected))
140 if err != nil {
141 t.Error(err)
142 continue
143 }
144 if !reflect.DeepEqual(x.Interface(), tc.expected) {
145 t.Errorf(`Expected %#v, got %#v`, tc.expected, x.Interface())
146 }
147 }
148}