Skip to content

Commit d553f94

Browse files
committed
macros: add tests for {Ser,De}Value macros integration
As those macros are complex and feature many switches and flavors, tests are added that verify that when a UDT struct is derived both SerializeValue and DeserializeValue: - attributes are parsed correctly and trait impls are generated without errors, - after serialization and deserialization, the result is what is expected.
1 parent 1269002 commit d553f94

File tree

5 files changed

+160
-5
lines changed

5 files changed

+160
-5
lines changed

scylla-cql/src/types/deserialize/value.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1950,7 +1950,7 @@ impl From<UdtDeserializationErrorKind> for BuiltinDeserializationErrorKind {
19501950

19511951
#[cfg(test)]
19521952
#[path = "value_tests.rs"]
1953-
pub(super) mod tests;
1953+
pub(crate) mod tests;
19541954

19551955
/// ```compile_fail
19561956
///

scylla-cql/src/types/deserialize/value_tests.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -585,7 +585,7 @@ fn test_tuples() {
585585
);
586586
}
587587

588-
fn udt_def_with_fields(
588+
pub(crate) fn udt_def_with_fields(
589589
fields: impl IntoIterator<Item = (impl Into<Cow<'static, str>>, ColumnType<'static>)>,
590590
) -> ColumnType<'static> {
591591
ColumnType::UserDefinedType {
@@ -1044,7 +1044,7 @@ fn test_custom_type_parser() {
10441044
assert_eq!(tup, SwappedPair("foo", 42));
10451045
}
10461046

1047-
fn deserialize<'frame, 'metadata, T>(
1047+
pub(crate) fn deserialize<'frame, 'metadata, T>(
10481048
typ: &'metadata ColumnType<'metadata>,
10491049
bytes: &'frame Bytes,
10501050
) -> Result<T, DeserializationError>

scylla-cql/src/types/mod.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,5 @@
11
pub mod deserialize;
22
pub mod serialize;
3+
4+
#[cfg(test)]
5+
mod types_tests;

scylla-cql/src/types/serialize/value.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1594,7 +1594,7 @@ mod doctests {
15941594
}
15951595

15961596
#[cfg(test)]
1597-
mod tests {
1597+
pub(crate) mod tests {
15981598
use std::collections::BTreeMap;
15991599

16001600
use crate::frame::response::result::{ColumnType, CqlValue};
@@ -1654,7 +1654,7 @@ mod tests {
16541654
t.serialize(typ, writer).map(|_| ()).map(|()| ret)
16551655
}
16561656

1657-
fn do_serialize<T: SerializeValue>(t: T, typ: &ColumnType) -> Vec<u8> {
1657+
pub(crate) fn do_serialize<T: SerializeValue>(t: T, typ: &ColumnType) -> Vec<u8> {
16581658
do_serialize_result(t, typ).unwrap()
16591659
}
16601660

Lines changed: 152 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,152 @@
1+
mod derive_macros_integration {
2+
mod value {
3+
use bytes::Bytes;
4+
5+
use crate::frame::response::result::ColumnType;
6+
use crate::types::deserialize::value::tests::{deserialize, udt_def_with_fields};
7+
use crate::types::serialize::value::tests::do_serialize;
8+
9+
#[test]
10+
fn derive_serialize_and_deserialize_value_loose_ordering() {
11+
#[derive(
12+
scylla_macros::DeserializeValue, scylla_macros::SerializeValue, PartialEq, Eq, Debug,
13+
)]
14+
#[scylla(crate = "crate")]
15+
struct Udt<'a> {
16+
a: &'a str,
17+
#[scylla(skip)]
18+
x: String,
19+
#[scylla(allow_missing)]
20+
b: Option<i32>,
21+
#[scylla(default_when_null)]
22+
c: i64,
23+
}
24+
25+
let original_udt = Udt {
26+
a: "The quick brown fox",
27+
x: String::from("THIS SHOULD NOT BE (DE)SERIALIZED"),
28+
b: Some(42),
29+
c: 2137,
30+
};
31+
32+
let tests = [
33+
// All fields present
34+
(
35+
udt_def_with_fields([
36+
("a", ColumnType::Text),
37+
("b", ColumnType::Int),
38+
("c", ColumnType::BigInt),
39+
]),
40+
Udt {
41+
x: String::new(),
42+
..original_udt
43+
},
44+
),
45+
//
46+
// One field missing:
47+
// - ignored during serialization,
48+
// - default-initialized during deserialization.
49+
(
50+
udt_def_with_fields([("a", ColumnType::Text), ("c", ColumnType::BigInt)]),
51+
Udt {
52+
x: String::new(),
53+
b: None,
54+
..original_udt
55+
},
56+
),
57+
//
58+
// UDT fields switched - should still work.
59+
(
60+
udt_def_with_fields([
61+
("b", ColumnType::Int),
62+
("a", ColumnType::Text),
63+
("c", ColumnType::BigInt),
64+
]),
65+
Udt {
66+
x: String::new(),
67+
..original_udt
68+
},
69+
),
70+
];
71+
for (typ, expected_udt) in tests {
72+
let serialized_udt = Bytes::from(do_serialize(&original_udt, &typ));
73+
let deserialized_udt = deserialize::<Udt<'_>>(&typ, &serialized_udt).unwrap();
74+
75+
assert_eq!(deserialized_udt, expected_udt);
76+
}
77+
}
78+
79+
#[test]
80+
fn derive_serialize_and_deserialize_value_strict_ordering() {
81+
#[derive(
82+
scylla_macros::DeserializeValue, scylla_macros::SerializeValue, PartialEq, Eq, Debug,
83+
)]
84+
#[scylla(crate = "crate", flavor = "enforce_order")]
85+
struct Udt<'a> {
86+
#[scylla(allow_missing)]
87+
#[scylla(default_when_null)]
88+
a: &'a str,
89+
#[scylla(skip)]
90+
x: String,
91+
#[scylla(allow_missing)]
92+
b: Option<i32>,
93+
}
94+
95+
let original_udt = Udt {
96+
a: "The quick brown fox",
97+
x: String::from("THIS SHOULD NOT BE (DE)SERIALIZED"),
98+
b: Some(42),
99+
};
100+
101+
let tests = [
102+
// All fields present
103+
(
104+
udt_def_with_fields([("a", ColumnType::Text), ("b", ColumnType::Int)]),
105+
Udt {
106+
x: String::new(),
107+
..original_udt
108+
},
109+
),
110+
//
111+
// An excess field at the end of UDT
112+
(
113+
udt_def_with_fields([
114+
("a", ColumnType::Text),
115+
("b", ColumnType::Int),
116+
("d", ColumnType::Boolean),
117+
]),
118+
Udt {
119+
x: String::new(),
120+
..original_udt
121+
},
122+
),
123+
//
124+
// Missing non-required fields
125+
(
126+
udt_def_with_fields([("a", ColumnType::Text)]),
127+
Udt {
128+
x: String::new(),
129+
b: None,
130+
..original_udt
131+
},
132+
),
133+
//
134+
// An excess field at the end of UDT instead of non-required fields
135+
(
136+
udt_def_with_fields([("d", ColumnType::Boolean)]),
137+
Udt {
138+
x: String::new(),
139+
a: "",
140+
b: None,
141+
},
142+
),
143+
];
144+
for (typ, expected_udt) in tests {
145+
let serialized_udt = Bytes::from(do_serialize(&original_udt, &typ));
146+
let deserialized_udt = deserialize::<Udt<'_>>(&typ, &serialized_udt).unwrap();
147+
148+
assert_eq!(deserialized_udt, expected_udt);
149+
}
150+
}
151+
}
152+
}

0 commit comments

Comments
 (0)