fix: symbol 作属性键独立编码,不再塌缩为空串

This commit is contained in:
爱特每羊队
2026-08-09 16:09:49 +08:00
parent c65d7e0373
commit 7c2e9ec1ff
14 changed files with 453 additions and 57 deletions
@@ -205,3 +205,81 @@ fn has_instance_preserves_ordinary_has_instance() {
let result = eval(&mut vm, "[] instanceof Array").unwrap();
assert!(result.as_bool());
}
// --- Symbol 作属性键 ---
#[test]
fn symbol_keys_stay_distinct() {
let mut vm = Vm::new();
let result = eval(&mut vm, "var s1=Symbol('a'), s2=Symbol('b'); var o={}; o[s1]=1; o[s2]=2; [o[s1],o[s2]]").unwrap();
let arr = unsafe { &*result.as_js_object_ptr() };
assert_eq!(arr.get_prop_at(0).as_int(), 1);
assert_eq!(arr.get_prop_at(1).as_int(), 2);
}
#[test]
fn symbol_keys_excluded_from_object_keys() {
let mut vm = Vm::new();
let result = eval(&mut vm, "var s=Symbol('x'); var o={a:1}; o[s]=2; Object.keys(o).length").unwrap();
assert_eq!(result.as_int(), 1);
}
#[test]
fn symbol_keys_excluded_from_own_property_names() {
let mut vm = Vm::new();
let result = eval(&mut vm, "var s=Symbol('x'); var o={}; o[s]=1; Object.getOwnPropertyNames(o).length").unwrap();
assert_eq!(result.as_int(), 0);
}
#[test]
fn symbol_keys_excluded_from_json_stringify() {
let mut vm = Vm::new();
let result = eval(&mut vm, "var s=Symbol('x'); var o={a:1}; o[s]=2; JSON.stringify(o)").unwrap();
assert_eq!(to_str(&vm, result), "{\"a\":1}");
}
#[test]
fn symbol_keys_excluded_from_for_in() {
let mut vm = Vm::new();
let result = eval(&mut vm, "var s=Symbol('x'); var o={}; o[s]=1; var n=0; for (var k in o) n++; n").unwrap();
assert_eq!(result.as_int(), 0);
}
#[test]
fn get_own_property_symbols_roundtrip() {
let mut vm = Vm::new();
let result = eval(&mut vm, "var s=Symbol('x'); var o={}; o[s]=7; var k=Object.getOwnPropertySymbols(o)[0]; o[k]").unwrap();
assert_eq!(result.as_int(), 7);
}
#[test]
fn get_own_property_symbols_length() {
let mut vm = Vm::new();
let result = eval(&mut vm, "var s=Symbol('x'); var o={}; o[s]=1; Object.getOwnPropertySymbols(o).length").unwrap();
assert_eq!(result.as_int(), 1);
}
#[test]
fn computed_symbol_key_object_literal() {
let mut vm = Vm::new();
let result = eval(&mut vm, "var o={[Symbol('k')]: 5, a: 1}; Object.keys(o).length").unwrap();
assert_eq!(result.as_int(), 1);
}
#[test]
fn well_known_symbol_key_excluded_from_keys() {
let mut vm = Vm::new();
let result = eval(&mut vm, "var o={}; o[Symbol.iterator]=1; Object.keys(o).length").unwrap();
assert_eq!(result.as_int(), 0);
}
#[test]
fn symbol_key_read_via_get_own_property_symbols_index() {
let mut vm = Vm::new();
let result = eval(
&mut vm,
"var s1=Symbol('a'), s2=Symbol('b'); var o={}; o[s1]=1; o[s2]=2; var ks=Object.getOwnPropertySymbols(o); var t=0; for (var i=0;i<ks.length;i++) t+=o[ks[i]]; t === 3",
)
.unwrap();
assert!(result.as_bool());
}
@@ -115,7 +115,9 @@ fn length_and_name_descriptors_are_non_writable_non_enumerable_configurable() {
#[test]
fn length_comes_before_name_in_property_order() {
assert_eq!(
eval_str("function f(a,b,c){}; var p=Object.getOwnPropertyNames(f); p[p.indexOf('length')] < p[p.indexOf('name')]"),
eval_str(
"function f(a,b,c){}; var p=Object.getOwnPropertyNames(f); p[p.indexOf('length')] < p[p.indexOf('name')]"
),
"true"
);
}