research: evaluate moejs extension compatibility and performance

This commit is contained in:
Levi committed 2026-11-14 13:28:06 +08:00
1 parent be0a395447
commit 941fda7d13
29 files changed
+1688

No files matched your search

+107
View File
@@ -0,0 +1,107 @@
package evaluation
import (
"fmt"
"testing"
"github.com/MoeForge/moejs"
"github.com/dop251/goja"
)
type request struct {
URL string `json:"url"`
}
type context struct {
Req *request `json:"req"`
Res map[string]any `json:"res"`
}
func (r *request) SetURL(s string) { r.URL = s }
// These are migration probes, asserting the observed difference, not claiming
// the existing Gopeed Go bridge has been ported.
func TestHostInterop(t *testing.T) {
for _, name := range []string{"goja", "moejs"} {
t.Run(name, func(t *testing.T) {
c := &context{Req: &request{URL: "before"}}
code := `ctx.req.url = "after"; ctx.res = {files:[{name:"video.mp4"}]}; typeof ctx.req.setURL`
var v any
var e error
if name == "goja" {
rt := goja.New()
rt.SetFieldNameMapper(goja.TagFieldNameMapper("json", true))
if e = rt.Set("ctx", c); e != nil {
t.Fatal(e)
}
value, err := rt.RunString(code)
e = err
if e == nil {
v = value.Export()
}
if c.Req.URL != "after" || c.Res == nil {
t.Fatal("goja write through failed")
}
} else {
rt := moejs.NewRuntime(moejs.Options{MutableIntrinsics: true})
if e = rt.SetGlobal("ctx", c); e != nil {
t.Fatal(e)
}
s, err := moejs.CompileScript("interop", code)
if err != nil {
t.Fatal(err)
}
value, err := rt.RunScript(s)
e = err
if e == nil {
v, e = rt.ToGo(value)
}
if c.Req.URL != "before" || c.Res != nil {
t.Fatal("expected snapshot semantics")
}
}
if e != nil {
t.Fatal(e)
}
t.Logf("Go URL=%s, Go res=%v, JS method=%v", c.Req.URL, c.Res, v)
})
}
}
func TestFrozenCompatibility(t *testing.T) {
r, e := New("moejs-frozen")
if e != nil {
t.Logf("shared frozen builtins reject host polyfill: %v", e)
return
}
defer r.Close()
b, e := r.Eval(`Object.defineProperty(Array.prototype,"__probe",{value:1}); true`)
if e == nil {
t.Fatalf("expected frozen builtins to reject mutation, got %v", b)
}
t.Log(e)
}
func BenchmarkBareRuntime(b *testing.B) {
for _, name := range []string{"goja", "moejs-mutable", "moejs-shared"} {
b.Run(name, func(b *testing.B) {
b.ReportAllocs()
for i := 0; i < b.N; i++ {
if name == "goja" {
r := goja.New()
v, e := r.RunString("1+1")
if e != nil || v.ToInteger() != 2 {
b.Fatal(e)
}
} else {
r := moejs.NewRuntime(moejs.Options{MutableIntrinsics: name == "moejs-mutable"})
s, e := moejs.CompileScript("small", "1+1")
if e != nil {
b.Fatal(e)
}
v, e := r.RunScript(s)
if e != nil || v.String() != "2" {
b.Fatal(fmt.Sprint(v), e)
}
}
}
})
}
}