refactor(common): 重构 Conn 实体并优化地图进入逻辑
- 优化 Conn 实体的 SendPack 方法,提高代码复用性 - 添加 goja 模块到 go.work 文件 - 重构地图进入逻辑,增加玩家广播和刷怪功能 - 调整 OutInfo 结构中的 Vip 和 Viped 字段类型 - 简化 MonsterRefresh 结构体定义
This commit is contained in:
328
common/utils/goja/object_gomap_test.go
Normal file
328
common/utils/goja/object_gomap_test.go
Normal file
@@ -0,0 +1,328 @@
|
||||
package goja
|
||||
|
||||
import "testing"
|
||||
|
||||
func TestGomapProp(t *testing.T) {
|
||||
const SCRIPT = `
|
||||
o.a + o.b;
|
||||
`
|
||||
r := New()
|
||||
r.Set("o", map[string]interface{}{
|
||||
"a": 40,
|
||||
"b": 2,
|
||||
})
|
||||
v, err := r.RunString(SCRIPT)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if i := v.ToInteger(); i != 42 {
|
||||
t.Fatalf("Expected 42, got: %d", i)
|
||||
}
|
||||
}
|
||||
|
||||
func TestGomapEnumerate(t *testing.T) {
|
||||
const SCRIPT = `
|
||||
var hasX = false;
|
||||
var hasY = false;
|
||||
for (var key in o) {
|
||||
switch (key) {
|
||||
case "x":
|
||||
if (hasX) {
|
||||
throw "Already have x";
|
||||
}
|
||||
hasX = true;
|
||||
break;
|
||||
case "y":
|
||||
if (hasY) {
|
||||
throw "Already have y";
|
||||
}
|
||||
hasY = true;
|
||||
break;
|
||||
default:
|
||||
throw "Unexpected property: " + key;
|
||||
}
|
||||
}
|
||||
hasX && hasY;
|
||||
`
|
||||
r := New()
|
||||
r.Set("o", map[string]interface{}{
|
||||
"x": 40,
|
||||
"y": 2,
|
||||
})
|
||||
v, err := r.RunString(SCRIPT)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
if !v.StrictEquals(valueTrue) {
|
||||
t.Fatalf("Expected true, got %v", v)
|
||||
}
|
||||
}
|
||||
|
||||
func TestGomapDeleteWhileEnumerate(t *testing.T) {
|
||||
const SCRIPT = `
|
||||
var hasX = false;
|
||||
var hasY = false;
|
||||
for (var key in o) {
|
||||
switch (key) {
|
||||
case "x":
|
||||
if (hasX) {
|
||||
throw "Already have x";
|
||||
}
|
||||
hasX = true;
|
||||
delete o.y;
|
||||
break;
|
||||
case "y":
|
||||
if (hasY) {
|
||||
throw "Already have y";
|
||||
}
|
||||
hasY = true;
|
||||
delete o.x;
|
||||
break;
|
||||
default:
|
||||
throw "Unexpected property: " + key;
|
||||
}
|
||||
}
|
||||
hasX && !hasY || hasY && !hasX;
|
||||
`
|
||||
r := New()
|
||||
r.Set("o", map[string]interface{}{
|
||||
"x": 40,
|
||||
"y": 2,
|
||||
})
|
||||
v, err := r.RunString(SCRIPT)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
if !v.StrictEquals(valueTrue) {
|
||||
t.Fatalf("Expected true, got %v", v)
|
||||
}
|
||||
}
|
||||
|
||||
func TestGomapInstanceOf(t *testing.T) {
|
||||
const SCRIPT = `
|
||||
(o instanceof Object) && !(o instanceof Error);
|
||||
`
|
||||
r := New()
|
||||
r.Set("o", map[string]interface{}{})
|
||||
v, err := r.RunString(SCRIPT)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
if !v.StrictEquals(valueTrue) {
|
||||
t.Fatalf("Expected true, got %v", v)
|
||||
}
|
||||
}
|
||||
|
||||
func TestGomapTypeOf(t *testing.T) {
|
||||
const SCRIPT = `
|
||||
typeof o;
|
||||
`
|
||||
r := New()
|
||||
r.Set("o", map[string]interface{}{})
|
||||
v, err := r.RunString(SCRIPT)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
if !v.StrictEquals(asciiString("object")) {
|
||||
t.Fatalf("Expected object, got %v", v)
|
||||
}
|
||||
}
|
||||
|
||||
func TestGomapProto(t *testing.T) {
|
||||
const SCRIPT = `
|
||||
o.hasOwnProperty("test");
|
||||
`
|
||||
r := New()
|
||||
r.Set("o", map[string]interface{}{
|
||||
"test": 42,
|
||||
})
|
||||
v, err := r.RunString(SCRIPT)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
if !v.StrictEquals(valueTrue) {
|
||||
t.Fatalf("Expected true, got %v", v)
|
||||
}
|
||||
}
|
||||
|
||||
func TestGoMapExtensibility(t *testing.T) {
|
||||
const SCRIPT = `
|
||||
"use strict";
|
||||
o.test = 42;
|
||||
Object.preventExtensions(o);
|
||||
o.test = 43;
|
||||
try {
|
||||
o.test1 = 42;
|
||||
} catch (e) {
|
||||
if (!(e instanceof TypeError)) {
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
o.test === 43 && o.test1 === undefined;
|
||||
`
|
||||
|
||||
r := New()
|
||||
r.Set("o", map[string]interface{}{})
|
||||
v, err := r.RunString(SCRIPT)
|
||||
if err != nil {
|
||||
if ex, ok := err.(*Exception); ok {
|
||||
t.Fatal(ex.String())
|
||||
} else {
|
||||
t.Fatal(err)
|
||||
}
|
||||
}
|
||||
|
||||
if !v.StrictEquals(valueTrue) {
|
||||
t.Fatalf("Expected true, got %v", v)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
func TestGoMapWithProto(t *testing.T) {
|
||||
vm := New()
|
||||
m := map[string]interface{}{
|
||||
"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);
|
||||
assert.sameValue(tHolder, true);
|
||||
Object.preventExtensions(m);
|
||||
assert.throws(TypeError, function() {
|
||||
m.t2 = 1;
|
||||
});
|
||||
m.t1 = "test2";
|
||||
assert.sameValue(m.t1, "test2");
|
||||
})();
|
||||
`, _undefined, t)
|
||||
}
|
||||
|
||||
func TestGoMapProtoProp(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]interface{}{})
|
||||
r.testScriptWithTestLib(SCRIPT, _undefined, t)
|
||||
}
|
||||
|
||||
func TestGoMapProtoPropChain(t *testing.T) {
|
||||
const SCRIPT = `
|
||||
(function() {
|
||||
"use strict";
|
||||
var p1 = Object.create(null);
|
||||
m.__proto__ = p1;
|
||||
|
||||
Object.defineProperty(p1, "test", {
|
||||
value: 42
|
||||
});
|
||||
|
||||
Object.defineProperty(m, "test", {
|
||||
value: 43,
|
||||
writable: true,
|
||||
});
|
||||
var o = Object.create(m);
|
||||
o.test = 44;
|
||||
assert.sameValue(o.test, 44);
|
||||
|
||||
var sym = Symbol(true);
|
||||
Object.defineProperty(p1, sym, {
|
||||
value: 42
|
||||
});
|
||||
|
||||
Object.defineProperty(m, sym, {
|
||||
value: 43,
|
||||
writable: true,
|
||||
});
|
||||
o[sym] = 44;
|
||||
assert.sameValue(o[sym], 44);
|
||||
})();
|
||||
`
|
||||
|
||||
r := New()
|
||||
r.Set("m", map[string]interface{}{})
|
||||
r.testScriptWithTestLib(SCRIPT, _undefined, t)
|
||||
}
|
||||
|
||||
func TestGoMapUnicode(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]interface{}{
|
||||
"é": 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)
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user