summaryrefslogtreecommitdiff
path: root/serde_v8/tests
diff options
context:
space:
mode:
Diffstat (limited to 'serde_v8/tests')
-rw-r--r--serde_v8/tests/de.rs613
-rw-r--r--serde_v8/tests/magic.rs192
-rw-r--r--serde_v8/tests/ser.rs270
3 files changed, 0 insertions, 1075 deletions
diff --git a/serde_v8/tests/de.rs b/serde_v8/tests/de.rs
deleted file mode 100644
index 2edfe1bc6..000000000
--- a/serde_v8/tests/de.rs
+++ /dev/null
@@ -1,613 +0,0 @@
-// Copyright 2018-2023 the Deno authors. All rights reserved. MIT license.
-use serde::Deserialize;
-use serde::Deserializer;
-
-use serde_v8::utils::js_exec;
-use serde_v8::utils::v8_do;
-use serde_v8::BigInt;
-use serde_v8::ByteString;
-use serde_v8::Error;
-use serde_v8::JsBuffer;
-use serde_v8::U16String;
-
-#[derive(Debug, Deserialize, PartialEq)]
-struct MathOp {
- pub a: u64,
- pub b: u64,
- pub operator: Option<String>,
-}
-
-#[derive(Debug, PartialEq, Deserialize)]
-enum EnumUnit {
- A,
- B,
- C,
-}
-
-#[derive(Debug, PartialEq, Deserialize)]
-enum EnumPayloads {
- UInt(u64),
- Int(i64),
- Float(f64),
- Point { x: i64, y: i64 },
- Tuple(bool, i64, ()),
-}
-
-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! decheck {
- ($fn_name:ident, $t:ty, $src:expr, $x:ident, $check:expr) => {
- #[test]
- fn $fn_name() {
- #[allow(clippy::bool_assert_comparison)]
- dedo($src, |scope, v| {
- let rt = serde_v8::from_v8(scope, v);
- assert!(rt.is_ok(), "from_v8(\"{}\"): {:?}", $src, rt.err());
- let $x: $t = rt.unwrap();
- $check
- });
- }
- };
-}
-
-macro_rules! detest {
- ($fn_name:ident, $t:ty, $src:expr, $rust:expr) => {
- decheck!($fn_name, $t, $src, t, assert_eq!(t, $rust));
- };
-}
-
-macro_rules! defail {
- ($fn_name:ident, $t:ty, $src:expr, $failcase:expr) => {
- #[test]
- fn $fn_name() {
- #[allow(clippy::bool_assert_comparison)]
- dedo($src, |scope, v| {
- let rt: serde_v8::Result<$t> = serde_v8::from_v8(scope, v);
- let rtstr = format!("{:?}", rt);
- let failed_as_expected = $failcase(rt);
- assert!(
- failed_as_expected,
- "expected failure on deserialize(\"{}\"), got: {}",
- $src, rtstr
- );
- });
- }
- };
-}
-
-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_char, char, "'é'", 'é');
-detest!(de_u64, u64, "32", 32);
-detest!(de_string, String, "'Hello'", "Hello".to_owned());
-detest!(de_vec_empty, Vec<u64>, "[]", vec![0; 0]);
-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, ())
-);
-defail!(
- de_tuple_wrong_len_short,
- (u64, bool, ()),
- "[123, true]",
- |e| e == Err(Error::LengthMismatch(2, 3))
-);
-defail!(
- de_tuple_wrong_len_long,
- (u64, bool, ()),
- "[123, true, null, 'extra']",
- |e| e == Err(Error::LengthMismatch(4, 3))
-);
-detest!(
- de_mathop,
- MathOp,
- "({a: 1, b: 3, c: 'ignored'})",
- MathOp {
- a: 1,
- b: 3,
- operator: None
- }
-);
-
-// Unit enums
-detest!(de_enum_unit_a, EnumUnit, "'A'", EnumUnit::A);
-detest!(de_enum_unit_so_a, EnumUnit, "new String('A')", EnumUnit::A);
-detest!(de_enum_unit_b, EnumUnit, "'B'", EnumUnit::B);
-detest!(de_enum_unit_so_b, EnumUnit, "new String('B')", EnumUnit::B);
-detest!(de_enum_unit_c, EnumUnit, "'C'", EnumUnit::C);
-detest!(de_enum_unit_so_c, EnumUnit, "new String('C')", EnumUnit::C);
-
-// Enums with payloads (tuples & struct)
-detest!(
- de_enum_payload_int,
- EnumPayloads,
- "({ Int: -123 })",
- EnumPayloads::Int(-123)
-);
-detest!(
- de_enum_payload_uint,
- EnumPayloads,
- "({ UInt: 123 })",
- EnumPayloads::UInt(123)
-);
-detest!(
- de_enum_payload_float,
- EnumPayloads,
- "({ Float: 1.23 })",
- EnumPayloads::Float(1.23)
-);
-detest!(
- de_enum_payload_point,
- EnumPayloads,
- "({ Point: { x: 1, y: 2 } })",
- EnumPayloads::Point { x: 1, y: 2 }
-);
-detest!(
- de_enum_payload_tuple,
- EnumPayloads,
- "({ Tuple: [true, 123, null ] })",
- EnumPayloads::Tuple(true, 123, ())
-);
-
-#[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);
- })
-}
-
-#[test]
-fn de_obj_with_numeric_keys() {
- dedo(
- r#"({
- lines: {
- 100: {
- unit: "m"
- },
- 200: {
- unit: "cm"
- }
- }
-})"#,
- |scope, v| {
- let json: serde_json::Value = serde_v8::from_v8(scope, v).unwrap();
- assert_eq!(
- json.to_string(),
- r#"{"lines":{"100":{"unit":"m"},"200":{"unit":"cm"}}}"#
- );
- },
- )
-}
-
-#[test]
-fn de_string_or_buffer() {
- dedo("'hello'", |scope, v| {
- let sob: serde_v8::StringOrBuffer = serde_v8::from_v8(scope, v).unwrap();
- assert_eq!(sob.as_ref(), &[0x68, 0x65, 0x6C, 0x6C, 0x6F]);
- });
-
- dedo("new Uint8Array([97])", |scope, v| {
- let sob: serde_v8::StringOrBuffer = serde_v8::from_v8(scope, v).unwrap();
- assert_eq!(sob.as_ref(), &[97]);
- });
-
- dedo("new Uint8Array([128])", |scope, v| {
- let sob: serde_v8::StringOrBuffer = serde_v8::from_v8(scope, v).unwrap();
- assert_eq!(sob.as_ref(), &[128]);
- });
-
- dedo(
- "(Uint8Array.from([0x68, 0x65, 0x6C, 0x6C, 0x6F]))",
- |scope, v| {
- let sob: serde_v8::StringOrBuffer = serde_v8::from_v8(scope, v).unwrap();
- assert_eq!(sob.as_ref(), &[0x68, 0x65, 0x6C, 0x6C, 0x6F]);
- },
- );
-}
-
-#[test]
-fn de_buffers() {
- // ArrayBufferView
- dedo("new Uint8Array([97])", |scope, v| {
- let buf: JsBuffer = serde_v8::from_v8(scope, v).unwrap();
- assert_eq!(&*buf, &[97]);
- });
-
- // ArrayBuffer
- dedo("(new Uint8Array([97])).buffer", |scope, v| {
- let buf: JsBuffer = serde_v8::from_v8(scope, v).unwrap();
- assert_eq!(&*buf, &[97]);
- });
-
- dedo(
- "(Uint8Array.from([0x68, 0x65, 0x6C, 0x6C, 0x6F]))",
- |scope, v| {
- let buf: JsBuffer = serde_v8::from_v8(scope, v).unwrap();
- assert_eq!(&*buf, &[0x68, 0x65, 0x6C, 0x6C, 0x6F]);
- },
- );
-
- dedo("(new ArrayBuffer(4))", |scope, v| {
- let buf: JsBuffer = serde_v8::from_v8(scope, v).unwrap();
- assert_eq!(&*buf, &[0x0, 0x0, 0x0, 0x0]);
- });
-
- dedo("(new ArrayBuffer(8, { maxByteLength: 16}))", |scope, v| {
- let result: Result<JsBuffer, Error> = serde_v8::from_v8(scope, v);
- matches!(result, Err(Error::ResizableBackingStoreNotSupported));
- });
-}
-
-// Structs
-#[derive(Debug, PartialEq, Deserialize)]
-struct StructUnit;
-
-#[derive(Debug, PartialEq)]
-struct StructPayload {
- a: u64,
- b: u64,
-}
-
-struct StructVisitor;
-
-impl<'de> serde::de::Visitor<'de> for StructVisitor {
- type Value = StructPayload;
- fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result {
- formatter.write_str("struct StructPayload")
- }
- fn visit_map<A>(self, mut map: A) -> Result<Self::Value, A::Error>
- where
- A: serde::de::MapAccess<'de>,
- {
- let mut payload = StructPayload { a: 0, b: 0 };
- while let Some(key) = map.next_key::<String>()? {
- match key.as_ref() {
- "a" => payload.a = map.next_value()?,
- "b" => payload.b = map.next_value()?,
- f => panic!("Unknown field {f}"),
- }
- }
- Ok(payload)
- }
-}
-
-detest!(de_unit_struct, StructUnit, "'StructUnit'", StructUnit);
-
-#[test]
-fn de_struct() {
- dedo("({ a: 1, b: 2 })", |scope, v| {
- let mut de = serde_v8::Deserializer::new(scope, v, None);
- let payload = de
- .deserialize_struct("StructPayload", &[], StructVisitor)
- .unwrap();
- assert_eq!(payload, StructPayload { a: 1, b: 2 })
- })
-}
-
-#[test]
-fn de_struct_hint() {
- dedo("({ a: 1, b: 2 })", |scope, v| {
- let mut de = serde_v8::Deserializer::new(scope, v, None);
- let payload = de
- .deserialize_struct("StructPayload", &["a", "b"], StructVisitor)
- .unwrap();
- assert_eq!(payload, StructPayload { a: 1, b: 2 })
- })
-}
-
-////
-// 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(123))
-);
-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::json!({
- "a": 1,
- "b": "hello",
- "c": true,
- })
-);
-detest!(
- de_json_object_from_map,
- serde_json::Value,
- "(new Map([['a', 1], ['b', 'hello'], ['c', true]]))",
- serde_json::json!({
- "a": 1,
- "b": "hello",
- "c": true,
- })
-);
-// TODO: this is not optimal, ideally we'd get an array of [1,2,3] instead.
-// Fixing that will require exposing Set::AsArray in the v8 bindings.
-detest!(
- de_json_object_from_set,
- serde_json::Value,
- "(new Set([1, 2, 3]))",
- serde_json::json!({})
-);
-
-defail!(defail_struct, MathOp, "123", |e| e
- == Err(Error::ExpectedObject("Number")));
-
-#[derive(Eq, PartialEq, Debug, Deserialize)]
-pub struct SomeThing {
- pub a: String,
- #[serde(default)]
- pub b: String,
-}
-detest!(
- de_struct_defaults,
- SomeThing,
- "({ a: 'hello' })",
- SomeThing {
- a: "hello".into(),
- b: "".into()
- }
-);
-
-detest!(de_bstr, ByteString, "'hello'", "hello".into());
-defail!(defail_bstr, ByteString, "'👋bye'", |e| e
- == Err(Error::ExpectedLatin1));
-
-#[derive(Eq, PartialEq, Debug, Deserialize)]
-pub struct StructWithBytes {
- #[serde(with = "serde_bytes")]
- a: Vec<u8>,
- #[serde(with = "serde_bytes")]
- b: Vec<u8>,
- #[serde(with = "serde_bytes")]
- c: Vec<u8>,
-}
-detest!(
- de_struct_with_bytes,
- StructWithBytes,
- "({ a: new Uint8Array([1, 2]), b: (new Uint8Array([3 , 4])).buffer, c: (new Uint32Array([0])).buffer})",
- StructWithBytes {
- a: vec![1, 2],
- b: vec![3, 4],
- c: vec![0, 0, 0, 0],
- }
-);
-detest!(
- de_u16str,
- U16String,
- "'hello'",
- "hello".encode_utf16().collect::<Vec<_>>().into()
-);
-detest!(
- de_u16str_non_latin1,
- U16String,
- "'👋bye'",
- "👋bye".encode_utf16().collect::<Vec<_>>().into()
-);
-
-// NaN
-detest!(de_nan_u8, u8, "NaN", 0);
-detest!(de_nan_u16, u16, "NaN", 0);
-detest!(de_nan_u32, u32, "NaN", 0);
-detest!(de_nan_u64, u64, "NaN", 0);
-detest!(de_nan_i8, i8, "NaN", 0);
-detest!(de_nan_i16, i16, "NaN", 0);
-detest!(de_nan_i32, i32, "NaN", 0);
-detest!(de_nan_i64, i64, "NaN", 0);
-decheck!(de_nan_f32, f32, "NaN", t, assert!(t.is_nan()));
-decheck!(de_nan_f64, f64, "NaN", t, assert!(t.is_nan()));
-
-// Infinity
-detest!(de_inf_u8, u8, "Infinity", u8::MAX);
-detest!(de_inf_u16, u16, "Infinity", u16::MAX);
-detest!(de_inf_u32, u32, "Infinity", u32::MAX);
-detest!(de_inf_u64, u64, "Infinity", u64::MAX);
-detest!(de_inf_i8, i8, "Infinity", i8::MAX);
-detest!(de_inf_i16, i16, "Infinity", i16::MAX);
-detest!(de_inf_i32, i32, "Infinity", i32::MAX);
-detest!(de_inf_i64, i64, "Infinity", i64::MAX);
-detest!(de_inf_f32, f32, "Infinity", f32::INFINITY);
-detest!(de_inf_f64, f64, "Infinity", f64::INFINITY);
-
-// -Infinity
-detest!(de_neg_inf_u8, u8, "-Infinity", u8::MIN);
-detest!(de_neg_inf_u16, u16, "-Infinity", u16::MIN);
-detest!(de_neg_inf_u32, u32, "-Infinity", u32::MIN);
-detest!(de_neg_inf_u64, u64, "-Infinity", u64::MIN);
-detest!(de_neg_inf_i8, i8, "-Infinity", i8::MIN);
-detest!(de_neg_inf_i16, i16, "-Infinity", i16::MIN);
-detest!(de_neg_inf_i32, i32, "-Infinity", i32::MIN);
-detest!(de_neg_inf_i64, i64, "-Infinity", i64::MIN);
-detest!(de_neg_inf_f32, f32, "-Infinity", f32::NEG_INFINITY);
-detest!(de_neg_inf_f64, f64, "-Infinity", f64::NEG_INFINITY);
-
-// BigInt to f32/f64 max/min
-detest!(
- de_bigint_f64_max,
- f64,
- "BigInt(1.7976931348623157e+308)",
- f64::MAX
-);
-detest!(
- de_bigint_f64_min,
- f64,
- "BigInt(-1.7976931348623157e+308)",
- f64::MIN
-);
-detest!(de_bigint_f32_max, f32, "BigInt(3.40282347e38)", f32::MAX);
-detest!(de_bigint_f32_min, f32, "BigInt(-3.40282347e38)", f32::MIN);
-// BigInt to f32/f64 saturating to inf
-detest!(
- de_bigint_f64_inf,
- f64,
- "(BigInt(1.7976931348623157e+308)*BigInt(100))",
- f64::INFINITY
-);
-detest!(
- de_bigint_f64_neg_inf,
- f64,
- "(BigInt(-1.7976931348623157e+308)*BigInt(100))",
- f64::NEG_INFINITY
-);
-
-detest!(
- de_bigint_f32_inf,
- f32,
- "BigInt(1.7976931348623157e+308)",
- f32::INFINITY
-);
-detest!(
- de_bigint_f32_neg_inf,
- f32,
- "BigInt(-1.7976931348623157e+308)",
- f32::NEG_INFINITY
-);
-
-// BigInt to BigInt
-detest!(
- de_bigint_var_u8,
- BigInt,
- "255n",
- num_bigint::BigInt::from(255u8).into()
-);
-detest!(
- de_bigint_var_i8,
- BigInt,
- "-128n",
- num_bigint::BigInt::from(-128i8).into()
-);
-detest!(
- de_bigint_var_u16,
- BigInt,
- "65535n",
- num_bigint::BigInt::from(65535u16).into()
-);
-detest!(
- de_bigint_var_i16,
- BigInt,
- "-32768n",
- num_bigint::BigInt::from(-32768i16).into()
-);
-detest!(
- de_bigint_var_u32,
- BigInt,
- "4294967295n",
- num_bigint::BigInt::from(4294967295u32).into()
-);
-detest!(
- de_bigint_var_i32,
- BigInt,
- "-2147483648n",
- num_bigint::BigInt::from(-2147483648i32).into()
-);
-detest!(
- de_bigint_var_u64,
- BigInt,
- "18446744073709551615n",
- num_bigint::BigInt::from(18446744073709551615u64).into()
-);
-detest!(
- de_bigint_var_i64,
- BigInt,
- "-9223372036854775808n",
- num_bigint::BigInt::from(-9223372036854775808i64).into()
-);
-detest!(
- de_bigint_var_u128,
- BigInt,
- "340282366920938463463374607431768211455n",
- num_bigint::BigInt::from(340282366920938463463374607431768211455u128).into()
-);
-detest!(
- de_bigint_var_i128,
- BigInt,
- "-170141183460469231731687303715884105728n",
- num_bigint::BigInt::from(-170141183460469231731687303715884105728i128).into()
-);
diff --git a/serde_v8/tests/magic.rs b/serde_v8/tests/magic.rs
deleted file mode 100644
index e3ed1d330..000000000
--- a/serde_v8/tests/magic.rs
+++ /dev/null
@@ -1,192 +0,0 @@
-// Copyright 2018-2023 the Deno authors. All rights reserved. MIT license.
-use serde::Deserialize;
-use serde::Serialize;
-
-use serde_v8::utils::js_exec;
-use serde_v8::utils::v8_do;
-use serde_v8::Result;
-
-#[derive(Deserialize)]
-struct MagicOp<'s> {
- #[allow(unused)]
- pub a: u64,
- #[allow(unused)]
- pub b: u64,
- pub c: serde_v8::Value<'s>,
- #[allow(unused)]
- pub operator: Option<String>,
-}
-
-#[derive(Serialize)]
-struct MagicContainer<'s> {
- pub magic: bool,
- pub contains: serde_v8::Value<'s>,
-}
-
-#[test]
-fn magic_basic() {
- 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);
-
- // Decode
- let v = js_exec(scope, "({a: 1, b: 3, c: 'abracadabra'})");
- let mop: MagicOp = serde_v8::from_v8(scope, v).unwrap();
- // Check string
- let v8_value: v8::Local<v8::Value> = mop.c.into();
- let vs = v8::Local::<v8::String>::try_from(v8_value).unwrap();
- let s = vs.to_rust_string_lossy(scope);
- assert_eq!(s, "abracadabra");
-
- // Encode
- let container = MagicContainer {
- magic: true,
- contains: v.into(),
- };
- let vc = serde_v8::to_v8(scope, container).unwrap();
- // JSON stringify & check
- let json = v8::json::stringify(scope, vc).unwrap();
- let s2 = json.to_rust_string_lossy(scope);
- assert_eq!(
- s2,
- r#"{"magic":true,"contains":{"a":1,"b":3,"c":"abracadabra"}}"#
- );
- })
-}
-
-#[test]
-fn magic_buffer() {
- v8_do(|| {
- // Init isolate
- 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 global = context.global(scope);
-
- // Simple buffer
- let v8_array = js_exec(scope, "new Uint8Array([1,2,3,4,5])");
- let zbuf: serde_v8::JsBuffer = serde_v8::from_v8(scope, v8_array).unwrap();
- assert_eq!(&*zbuf, &[1, 2, 3, 4, 5]);
-
- // Multi buffers
- let v8_arrays =
- js_exec(scope, "[new Uint8Array([1,2]), new Uint8Array([3,4,5])]");
- let (z1, z2): (serde_v8::JsBuffer, serde_v8::JsBuffer) =
- serde_v8::from_v8(scope, v8_arrays).unwrap();
- assert_eq!(&*z1, &[1, 2]);
- assert_eq!(&*z2, &[3, 4, 5]);
-
- // Wrapped in option, like our current op-ABI
- let v8_array = js_exec(scope, "new Uint8Array([1,2,3,4,5])");
- let zbuf: Option<serde_v8::JsBuffer> =
- serde_v8::from_v8(scope, v8_array).unwrap();
- assert_eq!(&*zbuf.unwrap(), &[1, 2, 3, 4, 5]);
-
- // Observe mutation in JS
- let v8_array = js_exec(scope, "new Uint8Array([1,2,3,4,5])");
- let mut zbuf: serde_v8::JsBuffer =
- serde_v8::from_v8(scope, v8_array).unwrap();
- let key = serde_v8::to_v8(scope, "t1").unwrap();
- global.set(scope, key, v8_array);
- (&mut *zbuf)[2] = 42;
- let eq = js_exec(scope, "t1[2] === 42");
- assert!(eq.is_true());
-
- // Shared buffers
- let v8_array =
- js_exec(scope, "new Uint8Array(new SharedArrayBuffer([1,2,3,4,5]))");
- let zbuf: Result<serde_v8::JsBuffer> = serde_v8::from_v8(scope, v8_array);
- assert!(zbuf.is_err());
-
- // Serialization
- let buf: Vec<u8> = vec![1, 2, 3, 99, 5];
- let zbuf: serde_v8::ToJsBuffer = buf.into();
- let v8_value = serde_v8::to_v8(scope, zbuf).unwrap();
- let key = serde_v8::to_v8(scope, "t2").unwrap();
- global.set(scope, key, v8_value);
- let eq = js_exec(scope, "t2[3] === 99");
- assert!(eq.is_true());
-
- // Composite Serialization
- #[derive(serde::Serialize)]
- struct Wrapper {
- a: serde_v8::ToJsBuffer,
- b: serde_v8::ToJsBuffer,
- }
- let buf1: Vec<u8> = vec![1, 2, 33, 4, 5];
- let buf2: Vec<u8> = vec![5, 4, 3, 2, 11];
- let wrapped = Wrapper {
- a: buf1.into(),
- b: buf2.into(),
- };
- let v8_value = serde_v8::to_v8(scope, wrapped).unwrap();
- let key = serde_v8::to_v8(scope, "t3").unwrap();
- global.set(scope, key, v8_value);
- let eq = js_exec(scope, "t3.a[2] === 33");
- assert!(eq.is_true());
- let eq = js_exec(scope, "t3.b[4] === 11");
- assert!(eq.is_true());
-
- // JsBuffer as bytes::Bytes
- let v8_array = js_exec(scope, "new Uint8Array([1,2,3,4,5])");
- let zbuf: serde_v8::JsBuffer = serde_v8::from_v8(scope, v8_array).unwrap();
- let buf: bytes::Bytes = zbuf.into();
- assert_eq!(buf, bytes::Bytes::from_static(&[1, 2, 3, 4, 5]));
- assert_eq!(buf, bytes::Bytes::from_static(&[1, 2, 3, 4, 5]));
- assert_eq!(buf.slice(0..2), bytes::Bytes::from_static(&[1, 2]));
- assert_eq!(buf.slice(2..), bytes::Bytes::from_static(&[3, 4, 5]));
- // We're specifically testing that slices are preserved post-clone
- #[allow(clippy::redundant_clone)]
- let buf2 = buf.slice(2..).clone();
- assert_eq!(buf2, bytes::Bytes::from_static(&[3, 4, 5]));
- })
-}
-
-#[test]
-fn magic_byte_string() {
- v8_do(|| {
- // Init isolate
- 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 global = context.global(scope);
-
- // JS string to ByteString
- let v8_string = js_exec(scope, "'test \\0\\t\\n\\r\\x7F\\x80áþÆñ'");
- let rust_reflex: serde_v8::ByteString =
- serde_v8::from_v8(scope, v8_string).unwrap();
- assert_eq!(
- rust_reflex.as_slice(),
- b"test \0\t\n\r\x7F\x80\xE1\xFE\xC6\xF1"
- );
-
- // Non-Latin-1 characters
- let v8_string = js_exec(scope, "'日本語'");
- let rust_reflex: Result<serde_v8::ByteString> =
- serde_v8::from_v8(scope, v8_string);
- assert!(rust_reflex.is_err());
-
- // Windows-1252 characters that aren't Latin-1
- let v8_string = js_exec(scope, "'œ'");
- let rust_reflex: Result<serde_v8::ByteString> =
- serde_v8::from_v8(scope, v8_string);
- assert!(rust_reflex.is_err());
-
- // ByteString to JS string
- let expected = "a\x00sf:~\x7Fá\u{009C}þ\u{008A}";
- let buf: Vec<u8> = b"a\x00sf:~\x7F\xE1\x9C\xFE\x8A".as_ref().into();
- let zbuf = serde_v8::ByteString::from(buf);
- let v8_value = serde_v8::to_v8(scope, zbuf).unwrap();
- let key = serde_v8::to_v8(scope, "actual").unwrap();
- global.set(scope, key, v8_value);
- let v8_value_expected = serde_v8::to_v8(scope, expected).unwrap();
- let key_expected = serde_v8::to_v8(scope, "expected").unwrap();
- global.set(scope, key_expected, v8_value_expected);
- let eq = js_exec(scope, "actual === expected");
- assert!(eq.is_true());
- })
-}
diff --git a/serde_v8/tests/ser.rs b/serde_v8/tests/ser.rs
deleted file mode 100644
index b61a758f9..000000000
--- a/serde_v8/tests/ser.rs
+++ /dev/null
@@ -1,270 +0,0 @@
-// Copyright 2018-2023 the Deno authors. All rights reserved. MIT license.
-use serde::Serialize;
-use serde_json::json;
-use serde_v8::utils::js_exec;
-use serde_v8::utils::v8_do;
-use serde_v8::BigInt;
-
-#[derive(Debug, Serialize, PartialEq)]
-struct MathOp {
- pub a: u64,
- pub b: u64,
- pub operator: Option<String>,
-}
-
-// Utility JS code (obj equality, etc...)
-const JS_UTILS: &str = r#"
-// Shallow obj equality (don't use deep objs for now)
-function objEqual(a, b) {
- const ka = Object.keys(a);
- const kb = Object.keys(b);
- return ka.length === kb.length && ka.every(k => a[k] === b[k]);
-}
-
-function arrEqual(a, b) {
- return a.length === b.length && a.every((v, i) => v === b[i]);
-}
-"#;
-const JS_POLLUTE: &str = r#"
-Object.defineProperty(Array.prototype, "0", {
- set: function (v) {
- throw new Error("Polluted Array 0 set");
- },
-});
-
-Object.defineProperty(Object.prototype, "a", {
- set: (v) => {
- throw new Error("Polluted Object 'a' set");
- }
-});
-"#;
-
-fn sercheck<T: Serialize>(val: T, code: &str, pollute: bool) -> bool {
- let mut equal = false;
-
- v8_do(|| {
- // Setup isolate
- 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);
-
- // Load util functions
- js_exec(scope, JS_UTILS);
- if pollute {
- js_exec(scope, JS_POLLUTE);
- }
- // TryCatch scope (to catch pollution exceptions)
- let scope = &mut v8::TryCatch::new(scope);
-
- // Set value as "x" in global scope
- let global = context.global(scope);
- let v8_key = serde_v8::to_v8(scope, "x").unwrap();
- let v8_val = serde_v8::to_v8(scope, val).unwrap();
- global.set(scope, v8_key, v8_val);
-
- // Pollution check
- if let Some(message) = scope.message() {
- let msg = message.get(scope).to_rust_string_lossy(scope);
- panic!("JS Exception: {msg}");
- }
-
- // Execute equality check in JS (e.g: x == ...)
- let v = js_exec(scope, code);
- // Cast to bool
- equal = serde_v8::from_v8(scope, v).unwrap();
- });
-
- equal
-}
-
-macro_rules! sertest {
- ($fn_name:ident, $rust:expr, $src:expr) => {
- #[test]
- fn $fn_name() {
- assert!(
- sercheck($rust, $src, false),
- "Expected: {} where x={:?}",
- $src,
- $rust,
- );
- }
- };
-}
-
-macro_rules! sertest_polluted {
- ($fn_name:ident, $rust:expr, $src:expr) => {
- #[test]
- fn $fn_name() {
- assert!(
- sercheck($rust, $src, true),
- "Expected: {} where x={:?}",
- $src,
- $rust,
- );
- }
- };
-}
-
-sertest!(ser_char, 'é', "x === 'é'");
-sertest!(ser_option_some, Some(true), "x === true");
-sertest!(ser_option_null, None as Option<bool>, "x === null");
-sertest!(ser_unit_null, (), "x === null");
-sertest!(ser_bool, true, "x === true");
-sertest!(ser_u64, 9007199254740991_u64, "x === 9007199254740991");
-sertest!(ser_big_int, 9007199254740992_i64, "x === 9007199254740992n");
-sertest!(
- ser_neg_big_int,
- -9007199254740992_i64,
- "x === -9007199254740992n"
-);
-sertest!(ser_f64, 12345.0, "x === 12345.0");
-sertest!(ser_string, "Hello", "x === 'Hello'");
-sertest!(ser_bytes, b"\x01\x02\x03", "arrEqual(x, [1, 2, 3])");
-sertest!(ser_vec_u64, vec![1, 2, 3, 4, 5], "arrEqual(x, [1,2,3,4,5])");
-sertest!(
- ser_vec_string,
- vec!["hello", "world"],
- "arrEqual(x, ['hello', 'world'])"
-);
-sertest!(ser_tuple, (123, true, ()), "arrEqual(x, [123, true, null])");
-sertest!(
- ser_mathop,
- MathOp {
- a: 1,
- b: 3,
- operator: None
- },
- "objEqual(x, {a: 1, b: 3, operator: null})"
-);
-
-sertest!(
- ser_bigint_u8,
- BigInt::from(num_bigint::BigInt::from(255_u8)),
- "x === 255n"
-);
-sertest!(
- ser_bigint_i8,
- BigInt::from(num_bigint::BigInt::from(-128_i8)),
- "x === -128n"
-);
-sertest!(
- ser_bigint_u16,
- BigInt::from(num_bigint::BigInt::from(65535_u16)),
- "x === 65535n"
-);
-sertest!(
- ser_bigint_i16,
- BigInt::from(num_bigint::BigInt::from(-32768_i16)),
- "x === -32768n"
-);
-sertest!(
- ser_bigint_u32,
- BigInt::from(num_bigint::BigInt::from(4294967295_u32)),
- "x === 4294967295n"
-);
-sertest!(
- ser_bigint_i32,
- BigInt::from(num_bigint::BigInt::from(-2147483648_i32)),
- "x === -2147483648n"
-);
-sertest!(
- ser_bigint_u64,
- BigInt::from(num_bigint::BigInt::from(9007199254740991_u64)),
- "x === 9007199254740991n"
-);
-sertest!(
- ser_bigint_i64,
- BigInt::from(num_bigint::BigInt::from(-9007199254740991_i64)),
- "x === -9007199254740991n"
-);
-sertest!(
- ser_bigint_u128,
- BigInt::from(num_bigint::BigInt::from(
- 340282366920938463463374607431768211455_u128
- )),
- "x === 340282366920938463463374607431768211455n"
-);
-sertest!(
- ser_bigint_i128,
- BigInt::from(num_bigint::BigInt::from(
- -170141183460469231731687303715884105728_i128
- )),
- "x === -170141183460469231731687303715884105728n"
-);
-
-sertest!(
- ser_map,
- {
- let map: std::collections::BTreeMap<&str, u32> =
- vec![("a", 1), ("b", 2), ("c", 3)].drain(..).collect();
- map
- },
- "objEqual(x, {a: 1, b: 2, c: 3})"
-);
-
-////
-// JSON tests: json!() compatibility
-////
-sertest!(ser_json_bool, json!(true), "x === true");
-sertest!(ser_json_null, json!(null), "x === null");
-sertest!(
- ser_json_int,
- json!(9007199254740991_u64),
- "x === 9007199254740991"
-);
-sertest!(
- ser_json_big_int,
- json!(9007199254740992_i64),
- "x === 9007199254740992n"
-);
-sertest!(
- ser_json_neg_big_int,
- json!(-9007199254740992_i64),
- "x === -9007199254740992n"
-);
-sertest!(ser_json_f64, json!(123.45), "x === 123.45");
-sertest!(ser_json_string, json!("Hello World"), "x === 'Hello World'");
-sertest!(ser_json_obj_empty, json!({}), "objEqual(x, {})");
-sertest!(
- ser_json_obj,
- json!({"a": 1, "b": 2, "c": true}),
- "objEqual(x, {a: 1, b: 2, c: true})"
-);
-sertest!(
- ser_json_vec_int,
- json!([1, 2, 3, 4, 5]),
- "arrEqual(x, [1,2,3,4,5])"
-);
-sertest!(
- ser_json_vec_string,
- json!(["Goodbye", "Dinosaurs 👋☄️"]),
- "arrEqual(x, ['Goodbye', 'Dinosaurs 👋☄️'])"
-);
-sertest!(
- ser_json_tuple,
- json!([true, 42, "nabla"]),
- "arrEqual(x, [true, 42, 'nabla'])"
-);
-
-////
-// Pollution tests
-////
-
-sertest_polluted!(
- ser_polluted_obj,
- MathOp {
- a: 1,
- b: 2,
- operator: None
- },
- "objEqual(x, { a: 1, b: 2, operator: null })"
-);
-
-sertest_polluted!(
- ser_polluted_tuple,
- (true, 123, false),
- "arrEqual(x, [true, 123, false])"
-);
-
-sertest_polluted!(ser_polluted_vec, vec![1, 2, 3], "arrEqual(x, [1, 2, 3])");