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