xref: /aosp_15_r20/external/starlark-go/internal/compile/compile_test.go (revision 4947cdc739c985f6d86941e22894f5cefe7c9e9a)
1*4947cdc7SCole Faustpackage compile_test
2*4947cdc7SCole Faust
3*4947cdc7SCole Faustimport (
4*4947cdc7SCole Faust	"bytes"
5*4947cdc7SCole Faust	"strings"
6*4947cdc7SCole Faust	"testing"
7*4947cdc7SCole Faust
8*4947cdc7SCole Faust	"go.starlark.net/starlark"
9*4947cdc7SCole Faust)
10*4947cdc7SCole Faust
11*4947cdc7SCole Faust// TestSerialization verifies that a serialized program can be loaded,
12*4947cdc7SCole Faust// deserialized, and executed.
13*4947cdc7SCole Faustfunc TestSerialization(t *testing.T) {
14*4947cdc7SCole Faust	predeclared := starlark.StringDict{
15*4947cdc7SCole Faust		"x": starlark.String("mur"),
16*4947cdc7SCole Faust		"n": starlark.MakeInt(2),
17*4947cdc7SCole Faust	}
18*4947cdc7SCole Faust	const src = `
19*4947cdc7SCole Faustdef mul(a, b):
20*4947cdc7SCole Faust    return a * b
21*4947cdc7SCole Faust
22*4947cdc7SCole Fausty = mul(x, n)
23*4947cdc7SCole Faust`
24*4947cdc7SCole Faust	_, oldProg, err := starlark.SourceProgram("mul.star", src, predeclared.Has)
25*4947cdc7SCole Faust	if err != nil {
26*4947cdc7SCole Faust		t.Fatal(err)
27*4947cdc7SCole Faust	}
28*4947cdc7SCole Faust
29*4947cdc7SCole Faust	buf := new(bytes.Buffer)
30*4947cdc7SCole Faust	if err := oldProg.Write(buf); err != nil {
31*4947cdc7SCole Faust		t.Fatalf("oldProg.WriteTo: %v", err)
32*4947cdc7SCole Faust	}
33*4947cdc7SCole Faust
34*4947cdc7SCole Faust	newProg, err := starlark.CompiledProgram(buf)
35*4947cdc7SCole Faust	if err != nil {
36*4947cdc7SCole Faust		t.Fatalf("CompiledProgram: %v", err)
37*4947cdc7SCole Faust	}
38*4947cdc7SCole Faust
39*4947cdc7SCole Faust	thread := new(starlark.Thread)
40*4947cdc7SCole Faust	globals, err := newProg.Init(thread, predeclared)
41*4947cdc7SCole Faust	if err != nil {
42*4947cdc7SCole Faust		t.Fatalf("newProg.Init: %v", err)
43*4947cdc7SCole Faust	}
44*4947cdc7SCole Faust	if got, want := globals["y"], starlark.String("murmur"); got != want {
45*4947cdc7SCole Faust		t.Errorf("Value of global was %s, want %s", got, want)
46*4947cdc7SCole Faust		t.Logf("globals: %v", globals)
47*4947cdc7SCole Faust	}
48*4947cdc7SCole Faust
49*4947cdc7SCole Faust	// Verify stack frame.
50*4947cdc7SCole Faust	predeclared["n"] = starlark.None
51*4947cdc7SCole Faust	_, err = newProg.Init(thread, predeclared)
52*4947cdc7SCole Faust	evalErr, ok := err.(*starlark.EvalError)
53*4947cdc7SCole Faust	if !ok {
54*4947cdc7SCole Faust		t.Fatalf("newProg.Init call returned err %v, want *EvalError", err)
55*4947cdc7SCole Faust	}
56*4947cdc7SCole Faust	const want = `Traceback (most recent call last):
57*4947cdc7SCole Faust  mul.star:5:8: in <toplevel>
58*4947cdc7SCole Faust  mul.star:3:14: in mul
59*4947cdc7SCole FaustError: unknown binary op: string * NoneType`
60*4947cdc7SCole Faust	if got := evalErr.Backtrace(); got != want {
61*4947cdc7SCole Faust		t.Fatalf("got <<%s>>, want <<%s>>", got, want)
62*4947cdc7SCole Faust	}
63*4947cdc7SCole Faust}
64*4947cdc7SCole Faust
65*4947cdc7SCole Faustfunc TestGarbage(t *testing.T) {
66*4947cdc7SCole Faust	const garbage = "This is not a compiled Starlark program."
67*4947cdc7SCole Faust	_, err := starlark.CompiledProgram(strings.NewReader(garbage))
68*4947cdc7SCole Faust	if err == nil {
69*4947cdc7SCole Faust		t.Fatalf("CompiledProgram did not report an error when decoding garbage")
70*4947cdc7SCole Faust	}
71*4947cdc7SCole Faust	if !strings.Contains(err.Error(), "not a compiled module") {
72*4947cdc7SCole Faust		t.Fatalf("CompiledProgram reported the wrong error when decoding garbage: %v", err)
73*4947cdc7SCole Faust	}
74*4947cdc7SCole Faust}
75