Browse Source

Merge pull request #737 from RageKnify/fix/729_obj_toString

Fix output of Object.toString()
pull/754/head
João Borges 4 years ago committed by GitHub
parent
commit
cd2ea032f6
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 30
      boa/src/builtins/object/mod.rs
  2. 44
      boa/src/builtins/object/tests.rs

30
boa/src/builtins/object/mod.rs

@ -115,9 +115,33 @@ impl Object {
/// [spec]: https://tc39.es/ecma262/#sec-object.prototype.tostring
/// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/toString
#[allow(clippy::wrong_self_convention)]
pub fn to_string(this: &Value, _: &[Value], _: &mut Context) -> Result<Value> {
// FIXME: it should not display the object.
Ok(this.display().to_string().into())
pub fn to_string(this: &Value, _: &[Value], ctx: &mut Context) -> Result<Value> {
if this.is_undefined() {
Ok("[object Undefined]".into())
} else if this.is_null() {
Ok("[object Null]".into())
} else {
let gc_o = this.to_object(ctx)?;
let o = gc_o.borrow();
let builtin_tag = match &o.data {
ObjectData::Array => "Array",
// TODO: Arguments Exotic Objects are currently not supported
ObjectData::Function(_) => "Function",
ObjectData::Error => "Error",
ObjectData::Boolean(_) => "Boolean",
ObjectData::Number(_) => "Number",
ObjectData::String(_) => "String",
ObjectData::Date(_) => "Date",
ObjectData::RegExp(_) => "RegExp",
_ => "Object",
};
let tag = o.get(&ctx.well_known_symbols().to_string_tag_symbol().into());
let tag_str = tag.as_string().map(|s| s.as_str()).unwrap_or(builtin_tag);
Ok(format!("[object {}]", tag_str).into())
}
}
/// `Object.prototype.hasOwnPrototype( property )`

44
boa/src/builtins/object/tests.rs

@ -55,7 +55,7 @@ fn object_create_with_number() {
#[test]
#[ignore]
// to test on __proto__ somehow. __proto__ getter is not working as expected currently
// TODO: to test on __proto__ somehow. __proto__ getter is not working as expected currently
fn object_create_with_function() {
let mut engine = Context::new();
@ -135,3 +135,45 @@ fn object_property_is_enumerable() {
);
assert_eq!(forward(&mut engine, r#"x.propertyIsEnumerable()"#), "false",)
}
#[test]
fn object_to_string() {
let mut ctx = Context::new();
let init = r#"
let u = undefined;
let n = null;
let a = [];
Array.prototype.toString = Object.prototype.toString;
let f = () => {};
Function.prototype.toString = Object.prototype.toString;
let b = Boolean();
Boolean.prototype.toString = Object.prototype.toString;
let i = Number(42);
Number.prototype.toString = Object.prototype.toString;
let s = String('boa');
String.prototype.toString = Object.prototype.toString;
let d = new Date(Date.now());
Date.prototype.toString = Object.prototype.toString;
let re = /boa/;
RegExp.prototype.toString = Object.prototype.toString;
let o = Object();
"#;
eprintln!("{}", forward(&mut ctx, init));
// TODO: need Function.prototype.call to be implemented
// assert_eq!(
// forward(&mut ctx, "Object.prototype.toString.call(u)"),
// "\"[object Undefined]\""
// );
// assert_eq!(
// forward(&mut ctx, "Object.prototype.toString.call(n)"),
// "\"[object Null]\""
// );
assert_eq!(forward(&mut ctx, "a.toString()"), "\"[object Array]\"");
assert_eq!(forward(&mut ctx, "f.toString()"), "\"[object Function]\"");
assert_eq!(forward(&mut ctx, "b.toString()"), "\"[object Boolean]\"");
assert_eq!(forward(&mut ctx, "i.toString()"), "\"[object Number]\"");
assert_eq!(forward(&mut ctx, "s.toString()"), "\"[object String]\"");
assert_eq!(forward(&mut ctx, "d.toString()"), "\"[object Date]\"");
assert_eq!(forward(&mut ctx, "re.toString()"), "\"[object RegExp]\"");
assert_eq!(forward(&mut ctx, "o.toString()"), "\"[object Object]\"");
}

Loading…
Cancel
Save