mirror of
https://github.com/pjh456/OxideJS.git
synced 2026-10-25 11:11:11 +08:00
fix: 不可扩展对象设置原型返回失败
This commit is contained in:
@@ -330,6 +330,39 @@ fn object_set_prototype_of_sets_prototype_and_validates() {
|
||||
assert!(err.contains("TypeError"), "unexpected error: {err}");
|
||||
}
|
||||
|
||||
// Object.setPrototypeOf 负向分路:不可扩展目标、原型环、原始值目标。
|
||||
#[test]
|
||||
fn object_set_prototype_of_negative_paths() {
|
||||
// 不可扩展且新旧原型不同抛 TypeError。
|
||||
let err = match eval("var o = {}; Object.preventExtensions(o); Object.setPrototypeOf(o, null);") {
|
||||
Ok(_) => panic!("non-extensible target with a different prototype should fail"),
|
||||
Err(err) => err,
|
||||
};
|
||||
assert!(err.contains("TypeError"), "unexpected error: {err}");
|
||||
|
||||
// 不可扩展但新旧原型相同仍成功,符合规范「SameValue 先于可扩展判定」。
|
||||
let (_vm, result) = eval(
|
||||
"var o = {}; var p = Object.getPrototypeOf(o); Object.preventExtensions(o); \
|
||||
Object.setPrototypeOf(o, p) === o",
|
||||
)
|
||||
.unwrap();
|
||||
assert!(
|
||||
result.is_bool() && result.as_bool(),
|
||||
"same prototype on non-extensible target should succeed"
|
||||
);
|
||||
|
||||
// 原型环抛 TypeError。
|
||||
let err = match eval("var a = {}; var b = {}; Object.setPrototypeOf(a, b); Object.setPrototypeOf(b, a);") {
|
||||
Ok(_) => panic!("cyclic prototype should fail"),
|
||||
Err(err) => err,
|
||||
};
|
||||
assert!(err.contains("TypeError"), "unexpected error: {err}");
|
||||
|
||||
// 原始值目标原样返回,不抛错。
|
||||
let (_vm, result) = eval("Object.setPrototypeOf(1, null)").unwrap();
|
||||
assert!(result.is_int() && result.as_int() == 1, "primitive target should be returned unchanged");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn entries_values_with_interleaved_symbol_key() {
|
||||
let (_vm, result) = eval(
|
||||
|
||||
@@ -82,6 +82,22 @@ fn reflect_prototype_and_extensible_methods() {
|
||||
assert!(result.as_bool());
|
||||
}
|
||||
|
||||
// 不可扩展目标:新旧不同返回 false,新旧相同返回 true,且原值不被改写。
|
||||
#[test]
|
||||
fn reflect_set_prototype_of_non_extensible_returns_false() {
|
||||
let mut vm = Vm::new();
|
||||
let result = eval(
|
||||
&mut vm,
|
||||
"var a = {}; Object.preventExtensions(a); \
|
||||
var diff = Reflect.setPrototypeOf(a, null); \
|
||||
var kept = Object.getPrototypeOf(a) === Object.prototype; \
|
||||
var same = Reflect.setPrototypeOf(a, Object.prototype); \
|
||||
diff === false && kept && same === true",
|
||||
)
|
||||
.unwrap();
|
||||
assert!(result.as_bool());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn reflect_apply_calls_function() {
|
||||
let mut vm = Vm::new();
|
||||
|
||||
Reference in New Issue
Block a user