unmarshal_test.go 3.1 KB

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