1
2
3
4
5
6
7
8
9
10
11
12
13 package starlarktest
14
15 import (
16 _ "embed"
17 "fmt"
18 "os"
19 "path/filepath"
20 "regexp"
21 "strings"
22 "sync"
23
24 "go.starlark.net/starlark"
25 "go.starlark.net/starlarkstruct"
26 )
27
28 const localKey = "Reporter"
29
30
31
32 type Reporter interface {
33 Error(args ...interface{})
34 }
35
36
37
38
39 func SetReporter(thread *starlark.Thread, r Reporter) {
40 thread.SetLocal(localKey, r)
41 }
42
43
44
45 func GetReporter(thread *starlark.Thread) Reporter {
46 r, ok := thread.Local(localKey).(Reporter)
47 if !ok {
48 panic("internal error: starlarktest.SetReporter was not called")
49 }
50 return r
51 }
52
53 var (
54 once sync.Once
55 assert starlark.StringDict
56
57 assertFileSrc string
58 assertErr error
59 )
60
61
62
63 func LoadAssertModule() (starlark.StringDict, error) {
64 once.Do(func() {
65 predeclared := starlark.StringDict{
66 "error": starlark.NewBuiltin("error", error_),
67 "catch": starlark.NewBuiltin("catch", catch),
68 "matches": starlark.NewBuiltin("matches", matches),
69 "module": starlark.NewBuiltin("module", starlarkstruct.MakeModule),
70 "_freeze": starlark.NewBuiltin("freeze", freeze),
71 }
72 thread := new(starlark.Thread)
73 assert, assertErr = starlark.ExecFile(thread, "assert.star", assertFileSrc, predeclared)
74 })
75 return assert, assertErr
76 }
77
78
79
80 func catch(thread *starlark.Thread, _ *starlark.Builtin, args starlark.Tuple, kwargs []starlark.Tuple) (starlark.Value, error) {
81 var fn starlark.Callable
82 if err := starlark.UnpackArgs("catch", args, kwargs, "fn", &fn); err != nil {
83 return nil, err
84 }
85 if _, err := starlark.Call(thread, fn, nil, nil); err != nil {
86 return starlark.String(err.Error()), nil
87 }
88 return starlark.None, nil
89 }
90
91
92 func matches(thread *starlark.Thread, _ *starlark.Builtin, args starlark.Tuple, kwargs []starlark.Tuple) (starlark.Value, error) {
93 var pattern, str string
94 if err := starlark.UnpackArgs("matches", args, kwargs, "pattern", &pattern, "str", &str); err != nil {
95 return nil, err
96 }
97 ok, err := regexp.MatchString(pattern, str)
98 if err != nil {
99 return nil, fmt.Errorf("matches: %s", err)
100 }
101 return starlark.Bool(ok), nil
102 }
103
104
105 func error_(thread *starlark.Thread, _ *starlark.Builtin, args starlark.Tuple, kwargs []starlark.Tuple) (starlark.Value, error) {
106 if len(args) != 1 {
107 return nil, fmt.Errorf("error: got %d arguments, want 1", len(args))
108 }
109 buf := new(strings.Builder)
110 stk := thread.CallStack()
111 stk.Pop()
112 fmt.Fprintf(buf, "%sError: ", stk)
113 if s, ok := starlark.AsString(args[0]); ok {
114 buf.WriteString(s)
115 } else {
116 buf.WriteString(args[0].String())
117 }
118 GetReporter(thread).Error(buf.String())
119 return starlark.None, nil
120 }
121
122
123 func freeze(thread *starlark.Thread, _ *starlark.Builtin, args starlark.Tuple, kwargs []starlark.Tuple) (starlark.Value, error) {
124 if len(kwargs) > 0 {
125 return nil, fmt.Errorf("freeze does not accept keyword arguments")
126 }
127 if len(args) != 1 {
128 return nil, fmt.Errorf("freeze got %d arguments, wants 1", len(args))
129 }
130 args[0].Freeze()
131 return args[0], nil
132 }
133
134
135
136
137
138 var DataFile = func(pkgdir, filename string) string {
139
140
141 testSrcdir := os.Getenv("TEST_SRCDIR")
142 testWorkspace := os.Getenv("TEST_WORKSPACE")
143 if testSrcdir != "" && testWorkspace != "" {
144 return filepath.Join(testSrcdir, "net_starlark_go", pkgdir, filename)
145 }
146
147
148
149 return filename
150 }
151
View as plain text