1
2
3
4
5
6
7
8
9
10
11
12
13
14
15 package wasm_test
16
17 import (
18 "fmt"
19 "io/fs"
20 "os"
21 "path/filepath"
22 stdruntime "runtime"
23 "strings"
24 "testing"
25
26 "cuelang.org/go/cmd/cue/cmd"
27 "cuelang.org/go/cue"
28 "cuelang.org/go/cue/ast"
29 "cuelang.org/go/cue/ast/astutil"
30 "cuelang.org/go/cue/build"
31 "cuelang.org/go/cue/cuecontext"
32 "cuelang.org/go/cue/errors"
33 "cuelang.org/go/cue/format"
34 "cuelang.org/go/cue/interpreter/wasm"
35 "cuelang.org/go/cue/parser"
36 "cuelang.org/go/internal/cuetest"
37 "cuelang.org/go/internal/cuetxtar"
38
39 "github.com/rogpeppe/go-internal/gotooltest"
40 "github.com/rogpeppe/go-internal/testscript"
41 )
42
43
44
45 func TestMain(m *testing.M) {
46 os.Exit(testscript.RunMain(m, map[string]func() int{
47 "cue": cmd.MainTest,
48 }))
49 }
50
51
52 func TestExe(t *testing.T) {
53 root := must(filepath.Abs("testdata"))(t)
54 wasmFiles := filepath.Join(root, "cue")
55 p := testscript.Params{
56 Dir: "testdata/cue",
57 UpdateScripts: cuetest.UpdateGoldenFiles,
58 RequireExplicitExec: true,
59 Setup: func(e *testscript.Env) error {
60 copyWasmFiles(t, e.WorkDir, wasmFiles)
61 return nil
62 },
63 Condition: cuetest.Condition,
64 }
65 if err := gotooltest.Setup(&p); err != nil {
66 t.Fatal(err)
67 }
68 testscript.Run(t, p)
69 }
70
71
72 func TestWasm(t *testing.T) {
73 test := cuetxtar.TxTarTest{
74 Root: "./testdata/cue",
75 Name: "wasm",
76 }
77
78 test.Run(t, func(t *cuetxtar.Test) {
79 ctx := cuecontext.New(cuecontext.Interpreter(wasm.New()))
80
81 if t.HasTag("cuecmd") {
82
83
84 return
85 }
86
87 bi := t.Instance()
88
89
90
91 for _, f := range t.Archive.Files {
92 if strings.HasSuffix(f.Name, ".wasm") {
93 bf := &build.File{
94 Filename: f.Name,
95 }
96 bi.UnknownFiles = append(bi.UnknownFiles, bf)
97 }
98 }
99
100 v := ctx.BuildInstance(bi)
101 err := v.Validate()
102
103 if t.HasTag("error") {
104
105
106 for _, err := range errors.Errors(err) {
107 t.WriteErrors(err)
108 }
109 return
110 }
111
112
113
114 if err != nil {
115 fmt.Fprintln(t, "Errors:")
116 for _, err := range errors.Errors(err) {
117 t.WriteErrors(err)
118 }
119 fmt.Fprintln(t, "")
120 fmt.Fprintln(t, "Result:")
121 }
122
123 syntax := v.Syntax(
124 cue.Attributes(false), cue.Final(), cue.Definitions(true), cue.ErrorsAsValues(true),
125 )
126 file, err := astutil.ToFile(syntax.(ast.Expr))
127 if err != nil {
128 t.Fatal(err)
129 }
130
131 got, err := format.Node(file, format.UseSpaces(4), format.TabIndent(false))
132 if err != nil {
133 t.Fatal(err)
134 }
135 fmt.Fprint(t, string(got))
136 })
137 }
138
139 func copyWasmFiles(t *testing.T, dstDir, srcDir string) {
140 filepath.WalkDir(dstDir, func(path string, d fs.DirEntry, err error) error {
141 if filepath.Ext(path) != ".wasm" {
142 return nil
143 }
144 relPath := must(filepath.Rel(dstDir, path))(t)
145 from := filepath.Join(srcDir, relPath)
146 copyFile(t, path, from)
147 return nil
148 })
149 }
150
151 func copyFile(t *testing.T, dst, src string) {
152 buf := must(os.ReadFile(src))(t)
153 err := os.WriteFile(dst, buf, 0664)
154 if err != nil {
155 t.Fatal(err)
156 }
157 }
158
159 func check(t *testing.T, dir string, got string) {
160 golden := filepath.Join("testdata", dir) + ".golden"
161
162 if cuetest.UpdateGoldenFiles {
163 os.WriteFile(golden, []byte(got), 0644)
164 }
165
166 want := string(must(os.ReadFile(golden))(t))
167 if got != want {
168 t.Errorf("want %v, got %v", want, got)
169 }
170 }
171
172 func loadDir(t *testing.T, name string) cue.Value {
173 ctx := cuecontext.New(cuecontext.Interpreter(wasm.New()))
174 bi := dirInstance(t, name)
175 return ctx.BuildInstance(bi)
176 }
177
178 func dirInstance(t *testing.T, name string) *build.Instance {
179 ctx := build.NewContext(build.ParseFile(loadFile))
180 inst := ctx.NewInstance(name, nil)
181
182 files := must(os.ReadDir(name))(t)
183 for _, f := range files {
184 if strings.HasSuffix(f.Name(), "cue") {
185 inst.AddFile(filepath.Join(name, f.Name()), nil)
186 }
187 if strings.HasSuffix(f.Name(), "wasm") {
188 f := &build.File{
189 Filename: f.Name(),
190 }
191 inst.UnknownFiles = append(inst.UnknownFiles, f)
192 }
193 }
194 inst.Complete()
195 return inst
196 }
197
198 func loadFile(filename string, src any) (*ast.File, error) {
199 return parser.ParseFile(filename, src, parser.ParseFuncs)
200 }
201
202 func must[T any](v T, err error) func(t *testing.T) T {
203 fail := false
204 if err != nil {
205 fail = true
206 }
207 return func(t *testing.T) T {
208 if fail {
209 _, file, line, _ := stdruntime.Caller(1)
210 file = filepath.Base(file)
211 t.Fatalf("unexpected error at %v:%v: %v", file, line, err)
212 }
213 return v
214 }
215 }
216
View as plain text