1
0
Fork 0
mirror of https://github.com/denoland/deno.git synced 2024-11-01 09:24:20 -04:00
denoland-deno/serde_v8/tests/de.rs
2021-03-25 22:36:46 -04:00

169 lines
3.8 KiB
Rust

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);
assert!(rt.is_ok(), format!("from_v8(\"{}\"): {:?}", $src, rt.err()));
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()
)
);