go.starlark.net@v0.0.0-20231101134539-556fd59b42f6/starlarkstruct/struct_test.go (about) 1 // Copyright 2018 The Bazel Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in the LICENSE file. 4 5 package starlarkstruct_test 6 7 import ( 8 "fmt" 9 "path/filepath" 10 "testing" 11 12 "go.starlark.net/starlark" 13 "go.starlark.net/starlarkstruct" 14 "go.starlark.net/starlarktest" 15 ) 16 17 func Test(t *testing.T) { 18 testdata := starlarktest.DataFile("starlarkstruct", ".") 19 thread := &starlark.Thread{Load: load} 20 starlarktest.SetReporter(thread, t) 21 filename := filepath.Join(testdata, "testdata/struct.star") 22 predeclared := starlark.StringDict{ 23 "struct": starlark.NewBuiltin("struct", starlarkstruct.Make), 24 "gensym": starlark.NewBuiltin("gensym", gensym), 25 } 26 if _, err := starlark.ExecFile(thread, filename, nil, predeclared); err != nil { 27 if err, ok := err.(*starlark.EvalError); ok { 28 t.Fatal(err.Backtrace()) 29 } 30 t.Fatal(err) 31 } 32 } 33 34 // load implements the 'load' operation as used in the evaluator tests. 35 func load(thread *starlark.Thread, module string) (starlark.StringDict, error) { 36 if module == "assert.star" { 37 return starlarktest.LoadAssertModule() 38 } 39 return nil, fmt.Errorf("load not implemented") 40 } 41 42 // gensym is a built-in function that generates a unique symbol. 43 func gensym(thread *starlark.Thread, _ *starlark.Builtin, args starlark.Tuple, kwargs []starlark.Tuple) (starlark.Value, error) { 44 var name string 45 if err := starlark.UnpackArgs("gensym", args, kwargs, "name", &name); err != nil { 46 return nil, err 47 } 48 return &symbol{name: name}, nil 49 } 50 51 // A symbol is a distinct value that acts as a constructor of "branded" 52 // struct instances, like a class symbol in Python or a "provider" in Bazel. 53 type symbol struct{ name string } 54 55 var _ starlark.Callable = (*symbol)(nil) 56 57 func (sym *symbol) Name() string { return sym.name } 58 func (sym *symbol) String() string { return sym.name } 59 func (sym *symbol) Type() string { return "symbol" } 60 func (sym *symbol) Freeze() {} // immutable 61 func (sym *symbol) Truth() starlark.Bool { return starlark.True } 62 func (sym *symbol) Hash() (uint32, error) { return 0, fmt.Errorf("unhashable: %s", sym.Type()) } 63 64 func (sym *symbol) CallInternal(thread *starlark.Thread, args starlark.Tuple, kwargs []starlark.Tuple) (starlark.Value, error) { 65 if len(args) > 0 { 66 return nil, fmt.Errorf("%s: unexpected positional arguments", sym) 67 } 68 return starlarkstruct.FromKeywords(sym, kwargs), nil 69 }