refactor(common): 重构 Conn 实体并优化地图进入逻辑
- 优化 Conn 实体的 SendPack 方法,提高代码复用性 - 添加 goja 模块到 go.work 文件 - 重构地图进入逻辑,增加玩家广播和刷怪功能 - 调整 OutInfo 结构中的 Vip 和 Viped 字段类型 - 简化 MonsterRefresh 结构体定义
This commit is contained in:
309
common/utils/goja/object_gomap_reflect_test.go
Normal file
309
common/utils/goja/object_gomap_reflect_test.go
Normal file
@@ -0,0 +1,309 @@
|
||||
package goja
|
||||
|
||||
import (
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestGoMapReflectGetSet(t *testing.T) {
|
||||
const SCRIPT = `
|
||||
m.c = m.a + m.b;
|
||||
`
|
||||
|
||||
vm := New()
|
||||
m := map[string]string{
|
||||
"a": "4",
|
||||
"b": "2",
|
||||
}
|
||||
vm.Set("m", m)
|
||||
|
||||
_, err := vm.RunString(SCRIPT)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
if c := m["c"]; c != "42" {
|
||||
t.Fatalf("Unexpected value: '%s'", c)
|
||||
}
|
||||
}
|
||||
|
||||
func TestGoMapReflectIntKey(t *testing.T) {
|
||||
const SCRIPT = `
|
||||
m[2] = m[0] + m[1];
|
||||
`
|
||||
|
||||
vm := New()
|
||||
m := map[int]int{
|
||||
0: 40,
|
||||
1: 2,
|
||||
}
|
||||
vm.Set("m", m)
|
||||
|
||||
_, err := vm.RunString(SCRIPT)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
if c := m[2]; c != 42 {
|
||||
t.Fatalf("Unexpected value: '%d'", c)
|
||||
}
|
||||
}
|
||||
|
||||
func TestGoMapReflectDelete(t *testing.T) {
|
||||
const SCRIPT = `
|
||||
delete m.a;
|
||||
`
|
||||
|
||||
vm := New()
|
||||
m := map[string]string{
|
||||
"a": "4",
|
||||
"b": "2",
|
||||
}
|
||||
vm.Set("m", m)
|
||||
|
||||
_, err := vm.RunString(SCRIPT)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
if _, exists := m["a"]; exists {
|
||||
t.Fatal("a still exists")
|
||||
}
|
||||
|
||||
if b := m["b"]; b != "2" {
|
||||
t.Fatalf("Unexpected b: '%s'", b)
|
||||
}
|
||||
}
|
||||
|
||||
func TestGoMapReflectJSON(t *testing.T) {
|
||||
const SCRIPT = `
|
||||
function f(m) {
|
||||
return JSON.stringify(m);
|
||||
}
|
||||
`
|
||||
|
||||
vm := New()
|
||||
m := map[string]string{
|
||||
"t": "42",
|
||||
}
|
||||
_, err := vm.RunString(SCRIPT)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
f := vm.Get("f")
|
||||
if call, ok := AssertFunction(f); ok {
|
||||
v, err := call(nil, ([]Value{vm.ToValue(m)})...)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if !v.StrictEquals(asciiString(`{"t":"42"}`)) {
|
||||
t.Fatalf("Unexpected value: %v", v)
|
||||
}
|
||||
} else {
|
||||
t.Fatalf("Not a function: %v", f)
|
||||
}
|
||||
}
|
||||
|
||||
func TestGoMapReflectProto(t *testing.T) {
|
||||
const SCRIPT = `
|
||||
m.hasOwnProperty("t");
|
||||
`
|
||||
|
||||
vm := New()
|
||||
m := map[string]string{
|
||||
"t": "42",
|
||||
}
|
||||
vm.Set("m", m)
|
||||
v, err := vm.RunString(SCRIPT)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if !v.StrictEquals(valueTrue) {
|
||||
t.Fatalf("Expected true, got %v", v)
|
||||
}
|
||||
}
|
||||
|
||||
type gomapReflect_noMethods map[string]interface{}
|
||||
type gomapReflect_withMethods map[string]interface{}
|
||||
|
||||
func (m gomapReflect_withMethods) Method() bool {
|
||||
return true
|
||||
}
|
||||
|
||||
func TestGoMapReflectNoMethods(t *testing.T) {
|
||||
const SCRIPT = `
|
||||
typeof m === "object" && m.hasOwnProperty("t") && m.t === 42;
|
||||
`
|
||||
|
||||
vm := New()
|
||||
m := make(gomapReflect_noMethods)
|
||||
m["t"] = 42
|
||||
vm.Set("m", m)
|
||||
v, err := vm.RunString(SCRIPT)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if !v.StrictEquals(valueTrue) {
|
||||
t.Fatalf("Expected true, got %v", v)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
func TestGoMapReflectWithMethods(t *testing.T) {
|
||||
const SCRIPT = `
|
||||
typeof m === "object" && !m.hasOwnProperty("t") && m.hasOwnProperty("Method") && m.Method();
|
||||
`
|
||||
|
||||
vm := New()
|
||||
m := make(gomapReflect_withMethods)
|
||||
m["t"] = 42
|
||||
vm.Set("m", m)
|
||||
v, err := vm.RunString(SCRIPT)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if !v.StrictEquals(valueTrue) {
|
||||
t.Fatalf("Expected true, got %v", v)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
func TestGoMapReflectWithProto(t *testing.T) {
|
||||
vm := New()
|
||||
m := map[string]string{
|
||||
"t": "42",
|
||||
}
|
||||
vm.Set("m", m)
|
||||
vm.testScriptWithTestLib(`
|
||||
(function() {
|
||||
'use strict';
|
||||
var proto = {};
|
||||
var getterAllowed = false;
|
||||
var setterAllowed = false;
|
||||
var tHolder = "proto t";
|
||||
Object.defineProperty(proto, "t", {
|
||||
get: function() {
|
||||
if (!getterAllowed) throw new Error("getter is called");
|
||||
return tHolder;
|
||||
},
|
||||
set: function(v) {
|
||||
if (!setterAllowed) throw new Error("setter is called");
|
||||
tHolder = v;
|
||||
}
|
||||
});
|
||||
var t1Holder;
|
||||
Object.defineProperty(proto, "t1", {
|
||||
get: function() {
|
||||
return t1Holder;
|
||||
},
|
||||
set: function(v) {
|
||||
t1Holder = v;
|
||||
}
|
||||
});
|
||||
Object.setPrototypeOf(m, proto);
|
||||
assert.sameValue(m.t, "42");
|
||||
m.t = 43;
|
||||
assert.sameValue(m.t, "43");
|
||||
t1Holder = "test";
|
||||
assert.sameValue(m.t1, "test");
|
||||
m.t1 = "test1";
|
||||
assert.sameValue(m.t1, "test1");
|
||||
delete m.t;
|
||||
getterAllowed = true;
|
||||
assert.sameValue(m.t, "proto t", "after delete");
|
||||
setterAllowed = true;
|
||||
m.t = true;
|
||||
assert.sameValue(m.t, true, "m.t === true");
|
||||
assert.sameValue(tHolder, true, "tHolder === true");
|
||||
Object.preventExtensions(m);
|
||||
assert.throws(TypeError, function() {
|
||||
m.t2 = 1;
|
||||
});
|
||||
m.t1 = "test2";
|
||||
assert.sameValue(m.t1, "test2");
|
||||
})();
|
||||
`, _undefined, t)
|
||||
}
|
||||
|
||||
func TestGoMapReflectProtoProp(t *testing.T) {
|
||||
const SCRIPT = `
|
||||
(function() {
|
||||
"use strict";
|
||||
var proto = {};
|
||||
Object.defineProperty(proto, "ro", {value: 42});
|
||||
Object.setPrototypeOf(m, proto);
|
||||
assert.throws(TypeError, function() {
|
||||
m.ro = 43;
|
||||
});
|
||||
Object.defineProperty(m, "ro", {value: 43});
|
||||
assert.sameValue(m.ro, "43");
|
||||
})();
|
||||
`
|
||||
|
||||
r := New()
|
||||
r.Set("m", map[string]string{})
|
||||
r.testScriptWithTestLib(SCRIPT, _undefined, t)
|
||||
}
|
||||
|
||||
func TestGoMapReflectUnicode(t *testing.T) {
|
||||
const SCRIPT = `
|
||||
Object.setPrototypeOf(m, s);
|
||||
if (m.Тест !== "passed") {
|
||||
throw new Error("m.Тест: " + m.Тест);
|
||||
}
|
||||
m["é"];
|
||||
`
|
||||
type S struct {
|
||||
Тест string
|
||||
}
|
||||
vm := New()
|
||||
m := map[string]int{
|
||||
"é": 42,
|
||||
}
|
||||
s := S{
|
||||
Тест: "passed",
|
||||
}
|
||||
vm.Set("m", m)
|
||||
vm.Set("s", &s)
|
||||
res, err := vm.RunString(SCRIPT)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if res == nil || !res.StrictEquals(valueInt(42)) {
|
||||
t.Fatalf("Unexpected value: %v", res)
|
||||
}
|
||||
}
|
||||
|
||||
func TestGoMapReflectStruct(t *testing.T) {
|
||||
type S struct {
|
||||
Test int
|
||||
}
|
||||
|
||||
m := map[string]S{
|
||||
"1": {Test: 1},
|
||||
}
|
||||
|
||||
vm := New()
|
||||
vm.Set("m", m)
|
||||
res, err := vm.RunString("m[1].Test = 2; m[1].Test")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if res.Export() != int64(1) {
|
||||
t.Fatal(res)
|
||||
}
|
||||
}
|
||||
|
||||
func TestGoMapReflectElt(t *testing.T) {
|
||||
type mapping map[string]interface{}
|
||||
|
||||
const SCRIPT = `a.s() && a.t === null && a.t1 === undefined;`
|
||||
|
||||
r := New()
|
||||
|
||||
r.Set("a", mapping{
|
||||
"s": func() bool { return true },
|
||||
"t": nil,
|
||||
})
|
||||
|
||||
r.testScript(SCRIPT, valueTrue, t)
|
||||
}
|
||||
Reference in New Issue
Block a user