aboutsummaryrefslogtreecommitdiff
path: root/starlarkstruct/struct_test.go
diff options
context:
space:
mode:
Diffstat (limited to 'starlarkstruct/struct_test.go')
-rw-r--r--starlarkstruct/struct_test.go69
1 files changed, 69 insertions, 0 deletions
diff --git a/starlarkstruct/struct_test.go b/starlarkstruct/struct_test.go
new file mode 100644
index 0000000..4f103bd
--- /dev/null
+++ b/starlarkstruct/struct_test.go
@@ -0,0 +1,69 @@
+// Copyright 2018 The Bazel Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package starlarkstruct_test
+
+import (
+ "fmt"
+ "path/filepath"
+ "testing"
+
+ "go.starlark.net/starlark"
+ "go.starlark.net/starlarkstruct"
+ "go.starlark.net/starlarktest"
+)
+
+func Test(t *testing.T) {
+ testdata := starlarktest.DataFile("starlarkstruct", ".")
+ thread := &starlark.Thread{Load: load}
+ starlarktest.SetReporter(thread, t)
+ filename := filepath.Join(testdata, "testdata/struct.star")
+ predeclared := starlark.StringDict{
+ "struct": starlark.NewBuiltin("struct", starlarkstruct.Make),
+ "gensym": starlark.NewBuiltin("gensym", gensym),
+ }
+ if _, err := starlark.ExecFile(thread, filename, nil, predeclared); err != nil {
+ if err, ok := err.(*starlark.EvalError); ok {
+ t.Fatal(err.Backtrace())
+ }
+ t.Fatal(err)
+ }
+}
+
+// load implements the 'load' operation as used in the evaluator tests.
+func load(thread *starlark.Thread, module string) (starlark.StringDict, error) {
+ if module == "assert.star" {
+ return starlarktest.LoadAssertModule()
+ }
+ return nil, fmt.Errorf("load not implemented")
+}
+
+// gensym is a built-in function that generates a unique symbol.
+func gensym(thread *starlark.Thread, _ *starlark.Builtin, args starlark.Tuple, kwargs []starlark.Tuple) (starlark.Value, error) {
+ var name string
+ if err := starlark.UnpackArgs("gensym", args, kwargs, "name", &name); err != nil {
+ return nil, err
+ }
+ return &symbol{name: name}, nil
+}
+
+// A symbol is a distinct value that acts as a constructor of "branded"
+// struct instances, like a class symbol in Python or a "provider" in Bazel.
+type symbol struct{ name string }
+
+var _ starlark.Callable = (*symbol)(nil)
+
+func (sym *symbol) Name() string { return sym.name }
+func (sym *symbol) String() string { return sym.name }
+func (sym *symbol) Type() string { return "symbol" }
+func (sym *symbol) Freeze() {} // immutable
+func (sym *symbol) Truth() starlark.Bool { return starlark.True }
+func (sym *symbol) Hash() (uint32, error) { return 0, fmt.Errorf("unhashable: %s", sym.Type()) }
+
+func (sym *symbol) CallInternal(thread *starlark.Thread, args starlark.Tuple, kwargs []starlark.Tuple) (starlark.Value, error) {
+ if len(args) > 0 {
+ return nil, fmt.Errorf("%s: unexpected positional arguments", sym)
+ }
+ return starlarkstruct.FromKeywords(sym, kwargs), nil
+}