2021-03-26 20:26:27 -04:00
|
|
|
// Copyright 2018-2021 the Deno authors. All rights reserved. MIT license.
|
2021-03-25 22:36:46 -04:00
|
|
|
use rusty_v8 as v8;
|
|
|
|
|
|
|
|
use serde::Deserialize;
|
|
|
|
|
|
|
|
use serde_v8::utils::{js_exec, v8_do};
|
|
|
|
|
|
|
|
#[derive(Debug, Deserialize, PartialEq)]
|
|
|
|
struct MathOp {
|
|
|
|
pub a: u64,
|
|
|
|
pub b: u64,
|
|
|
|
pub operator: Option<String>,
|
|
|
|
}
|
|
|
|
|
|
|
|
fn dedo(
|
|
|
|
code: &str,
|
|
|
|
f: impl FnOnce(&mut v8::HandleScope, v8::Local<v8::Value>),
|
|
|
|
) {
|
|
|
|
v8_do(|| {
|
|
|
|
let isolate = &mut v8::Isolate::new(v8::CreateParams::default());
|
|
|
|
let handle_scope = &mut v8::HandleScope::new(isolate);
|
|
|
|
let context = v8::Context::new(handle_scope);
|
|
|
|
let scope = &mut v8::ContextScope::new(handle_scope, context);
|
|
|
|
let v = js_exec(scope, code);
|
|
|
|
|
|
|
|
f(scope, v);
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
|
|
|
macro_rules! detest {
|
|
|
|
($fn_name:ident, $t:ty, $src:expr, $rust:expr) => {
|
|
|
|
#[test]
|
|
|
|
fn $fn_name() {
|
|
|
|
dedo($src, |scope, v| {
|
|
|
|
let rt = serde_v8::from_v8(scope, v);
|
2021-03-28 11:09:46 -04:00
|
|
|
assert!(rt.is_ok(), "from_v8(\"{}\"): {:?}", $src, rt.err());
|
2021-03-25 22:36:46 -04:00
|
|
|
let t: $t = rt.unwrap();
|
|
|
|
assert_eq!(t, $rust);
|
|
|
|
});
|
|
|
|
}
|
|
|
|
};
|
|
|
|
}
|
|
|
|
|
|
|
|
detest!(de_option_some, Option<bool>, "true", Some(true));
|
|
|
|
detest!(de_option_null, Option<bool>, "null", None);
|
|
|
|
detest!(de_option_undefined, Option<bool>, "undefined", None);
|
|
|
|
detest!(de_unit_null, (), "null", ());
|
|
|
|
detest!(de_unit_undefined, (), "undefined", ());
|
|
|
|
detest!(de_bool, bool, "true", true);
|
|
|
|
detest!(de_u64, u64, "32", 32);
|
|
|
|
detest!(de_string, String, "'Hello'", "Hello".to_owned());
|
|
|
|
detest!(de_vec_u64, Vec<u64>, "[1,2,3,4,5]", vec![1, 2, 3, 4, 5]);
|
|
|
|
detest!(
|
|
|
|
de_vec_str,
|
|
|
|
Vec<String>,
|
|
|
|
"['hello', 'world']",
|
|
|
|
vec!["hello".to_owned(), "world".to_owned()]
|
|
|
|
);
|
|
|
|
detest!(
|
|
|
|
de_tuple,
|
|
|
|
(u64, bool, ()),
|
|
|
|
"[123, true, null]",
|
|
|
|
(123, true, ())
|
|
|
|
);
|
|
|
|
detest!(
|
|
|
|
de_mathop,
|
|
|
|
MathOp,
|
|
|
|
"({a: 1, b: 3, c: 'ignored'})",
|
|
|
|
MathOp {
|
|
|
|
a: 1,
|
|
|
|
b: 3,
|
|
|
|
operator: None
|
|
|
|
}
|
|
|
|
);
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn de_f64() {
|
|
|
|
dedo("12345.0", |scope, v| {
|
|
|
|
let x: f64 = serde_v8::from_v8(scope, v).unwrap();
|
|
|
|
assert!((x - 12345.0).abs() < f64::EPSILON);
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn de_map() {
|
|
|
|
use std::collections::HashMap;
|
|
|
|
|
|
|
|
dedo("({a: 1, b: 2, c: 3})", |scope, v| {
|
|
|
|
let map: HashMap<String, u64> = serde_v8::from_v8(scope, v).unwrap();
|
|
|
|
assert_eq!(map.get("a").cloned(), Some(1));
|
|
|
|
assert_eq!(map.get("b").cloned(), Some(2));
|
|
|
|
assert_eq!(map.get("c").cloned(), Some(3));
|
|
|
|
assert_eq!(map.get("nada"), None);
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
|
|
|
////
|
|
|
|
// JSON tests: serde_json::Value compatibility
|
|
|
|
////
|
|
|
|
|
|
|
|
detest!(
|
|
|
|
de_json_null,
|
|
|
|
serde_json::Value,
|
|
|
|
"null",
|
|
|
|
serde_json::Value::Null
|
|
|
|
);
|
|
|
|
detest!(
|
|
|
|
de_json_bool,
|
|
|
|
serde_json::Value,
|
|
|
|
"true",
|
|
|
|
serde_json::Value::Bool(true)
|
|
|
|
);
|
|
|
|
detest!(
|
|
|
|
de_json_int,
|
|
|
|
serde_json::Value,
|
|
|
|
"123",
|
|
|
|
serde_json::Value::Number(serde_json::Number::from_f64(123.0).unwrap())
|
|
|
|
);
|
|
|
|
detest!(
|
|
|
|
de_json_float,
|
|
|
|
serde_json::Value,
|
|
|
|
"123.45",
|
|
|
|
serde_json::Value::Number(serde_json::Number::from_f64(123.45).unwrap())
|
|
|
|
);
|
|
|
|
detest!(
|
|
|
|
de_json_string,
|
|
|
|
serde_json::Value,
|
|
|
|
"'Hello'",
|
|
|
|
serde_json::Value::String("Hello".to_string())
|
|
|
|
);
|
|
|
|
detest!(
|
|
|
|
de_json_vec_string,
|
|
|
|
serde_json::Value,
|
|
|
|
"['Hello', 'World']",
|
|
|
|
serde_json::Value::Array(vec![
|
|
|
|
serde_json::Value::String("Hello".to_string()),
|
|
|
|
serde_json::Value::String("World".to_string())
|
|
|
|
])
|
|
|
|
);
|
|
|
|
detest!(
|
|
|
|
de_json_tuple,
|
|
|
|
serde_json::Value,
|
|
|
|
"[true, 'World', 123.45, null]",
|
|
|
|
serde_json::Value::Array(vec![
|
|
|
|
serde_json::Value::Bool(true),
|
|
|
|
serde_json::Value::String("World".to_string()),
|
|
|
|
serde_json::Value::Number(serde_json::Number::from_f64(123.45).unwrap()),
|
|
|
|
serde_json::Value::Null,
|
|
|
|
])
|
|
|
|
);
|
|
|
|
detest!(
|
|
|
|
de_json_object,
|
|
|
|
serde_json::Value,
|
|
|
|
"({a: 1, b: 'hello', c: true})",
|
|
|
|
serde_json::Value::Object(
|
|
|
|
vec![
|
|
|
|
(
|
|
|
|
"a".to_string(),
|
|
|
|
serde_json::Value::Number(serde_json::Number::from_f64(1.0).unwrap()),
|
|
|
|
),
|
|
|
|
(
|
|
|
|
"b".to_string(),
|
|
|
|
serde_json::Value::String("hello".to_string()),
|
|
|
|
),
|
|
|
|
("c".to_string(), serde_json::Value::Bool(true),),
|
|
|
|
]
|
|
|
|
.drain(..)
|
|
|
|
.collect()
|
|
|
|
)
|
|
|
|
);
|