Skip to content

Commit

Permalink
handle json stringification for arrays
Browse files Browse the repository at this point in the history
  • Loading branch information
n14little committed May 19, 2020
1 parent d734c44 commit 89b487d
Show file tree
Hide file tree
Showing 2 changed files with 68 additions and 10 deletions.
40 changes: 40 additions & 0 deletions boa/src/builtins/json/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -102,3 +102,43 @@ fn json_stringify_replacer_function() {
let expected = forward(&mut engine, r#"'{"bbb":2}'"#);
assert_eq!(actual, expected);
}

#[test]
fn json_stringify_arrays() {
let realm = Realm::create();
let mut engine = Executor::new(realm);
let actual = forward(&mut engine, r#"JSON.stringify(['a', 'b'])"#);
let expected = forward(&mut engine, r#"'["a","b"]'"#);

assert_eq!(actual, expected);
}

#[test]
fn json_stringify_object_array() {
let realm = Realm::create();
let mut engine = Executor::new(realm);
let actual = forward(&mut engine, r#"JSON.stringify([{a: 'b'}, {b: 'c'}])"#);
let expected = forward(&mut engine, r#"'[{"a":"b"},{"b":"c"}]'"#);

assert_eq!(actual, expected);
}

#[test]
fn json_stringify_array_converts_undefined_to_null() {
let realm = Realm::create();
let mut engine = Executor::new(realm);
let actual = forward(&mut engine, r#"JSON.stringify([undefined])"#);
let expected = forward(&mut engine, r#"'[null]'"#);

assert_eq!(actual, expected);
}

#[test]
fn json_stringify_array_converts_function_to_null() {
let realm = Realm::create();
let mut engine = Executor::new(realm);
let actual = forward(&mut engine, r#"JSON.stringify([() => {}])"#);
let expected = forward(&mut engine, r#"'[null]'"#);

assert_eq!(actual, expected);
}
38 changes: 28 additions & 10 deletions boa/src/builtins/value/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -682,24 +682,42 @@ impl ValueData {
/// Conversts the `Value` to `JSON`.
pub fn to_json(&self) -> JSONValue {
match *self {
Self::Null | Self::Symbol(_) | Self::Undefined => JSONValue::Null,
Self::Null => JSONValue::Null,
Self::Boolean(b) => JSONValue::Bool(b),
Self::Object(ref obj) => {
let mut new_obj = Map::new();
obj.borrow().properties.iter().for_each(|(k, _)| {
let key = k.clone();
let value = self.get_field_slice(k);
if !value.is_undefined() && !value.is_function() {
new_obj.insert(key, value.to_json());
}
});
JSONValue::Object(new_obj)
if obj.borrow().kind == ObjectKind::Array {
let mut arr: Vec<JSONValue> = Vec::new();
obj.borrow().properties.iter().for_each(|(k, _)| {
if k != "length" {
let value = self.get_field_slice(k);
if value.is_undefined() || value.is_function() {
arr.push(JSONValue::Null);
} else {
arr.push(self.get_field_slice(k).to_json());
}
}
});
JSONValue::Array(arr)
} else {
let mut new_obj = Map::new();
obj.borrow().properties.iter().for_each(|(k, _)| {
let key = k.clone();
let value = self.get_field_slice(k);
if !value.is_undefined() && !value.is_function() {
new_obj.insert(key, value.to_json());
}
});
JSONValue::Object(new_obj)
}
}
Self::String(ref str) => JSONValue::String(str.clone()),
Self::Rational(num) => JSONValue::Number(
JSONNumber::from_f64(num).expect("Could not convert to JSONNumber"),
),
Self::Integer(val) => JSONValue::Number(JSONNumber::from(val)),
Self::Symbol(_) | Self::Undefined => {
panic!("Symbols and Undefined depend on parent type");
}
}
}

Expand Down

0 comments on commit 89b487d

Please sign in to comment.