From dd229aa5ffe8328631f4450ca7ff1da6b3c50a3a Mon Sep 17 00:00:00 2001 From: Nick Little Date: Thu, 14 May 2020 23:16:39 -0500 Subject: [PATCH] WIP: to_json returns undefined to null --- boa/src/builtins/json/mod.rs | 27 ++++++++++++++++++++------- boa/src/builtins/json/tests.rs | 18 ++++++++++++++++++ 2 files changed, 38 insertions(+), 7 deletions(-) diff --git a/boa/src/builtins/json/mod.rs b/boa/src/builtins/json/mod.rs index 122cd8b3a8a..2786475e4b0 100644 --- a/boa/src/builtins/json/mod.rs +++ b/boa/src/builtins/json/mod.rs @@ -15,6 +15,7 @@ use crate::builtins::{ object::ObjectKind, + property::Property, value::{ResultValue, Value, ValueData}, }; use crate::exec::Interpreter; @@ -66,7 +67,7 @@ pub fn parse(_: &mut Value, args: &[Value], _: &mut Interpreter) -> ResultValue /// /// [spec]: https://tc39.es/ecma262/#sec-json.stringify /// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON/stringify -pub fn stringify(_: &mut Value, args: &[Value], _: &mut Interpreter) -> ResultValue { +pub fn stringify(_: &mut Value, args: &[Value], interpreter: &mut Interpreter) -> ResultValue { let object = args.get(0).expect("cannot get argument for JSON.stringify"); if args.len() == 1 { let json = object.to_json().to_string(); @@ -77,9 +78,9 @@ pub fn stringify(_: &mut Value, args: &[Value], _: &mut Interpreter) -> ResultVa if let Some(arg) = args.get(1) { if let ValueData::Object(ref obj) = arg.data() { let derefed_obj = (*obj).deref(); - let borrowed_derefed_obj = derefed_obj.borrow(); - if borrowed_derefed_obj.kind == ObjectKind::Array { - for (key, value) in borrowed_derefed_obj.properties.iter() { + let borrowed_derefed_replacer = derefed_obj.borrow(); + if borrowed_derefed_replacer.kind == ObjectKind::Array { + for (key, value) in borrowed_derefed_replacer.properties.iter() { if let Some(Value(x)) = &value.value { if key != "length" { object_to_return.set_property( @@ -89,10 +90,22 @@ pub fn stringify(_: &mut Value, args: &[Value], _: &mut Interpreter) -> ResultVa } } } - return Ok(Value::from(object_to_return.to_json().to_string())); - } else { - unimplemented!("replacer only supports arrays at this time"); + } else if borrowed_derefed_replacer.kind == ObjectKind::Function { + if let ValueData::Object(ref obj) = object.data() { + let derefed_obj = (*obj).deref(); + let borrowed_deref_obj = derefed_obj.borrow(); + for (key, val) in borrowed_deref_obj.properties.iter() { + if let Some(value) = &val.value { + let mut this_arg = object.clone(); + object_to_return.set_property( + String::from(key), + Property::default().value(interpreter.call(arg, &mut this_arg, &[Value::string(key), Value::from(value)]).unwrap()), + ); + } + } + } } + return Ok(Value::from(object_to_return.to_json().to_string())); } } panic!("cannot get replacer for JSON.stringify"); diff --git a/boa/src/builtins/json/tests.rs b/boa/src/builtins/json/tests.rs index f852f84f3b6..cec9ceb090c 100644 --- a/boa/src/builtins/json/tests.rs +++ b/boa/src/builtins/json/tests.rs @@ -40,3 +40,21 @@ fn json_stringify_replacer_array_numbers() { let expected = forward(&mut engine, r#"'{"1":"bbb","2":"ccc"}'"#); assert_eq!(actual, expected); } + +#[test] +fn json_stringify_replacer_function() { + let realm = Realm::create(); + let mut engine = Executor::new(realm); + let actual = forward( + &mut engine, + r#"JSON.stringify({ aaa: 1, bbb: 2}, (key, value) => { + if (key === 'aaa') { + return undefined; + } + + return value; + })"#, + ); + let expected = forward(&mut engine, r#"'{"bbb":2}'"#); + assert_eq!(actual, expected); +}