Skip to content

Commit 7182c0f

Browse files
authored
Add BSON deserialize tests (#85)
* Add BSON deserialize tests. * Fix linter issues.
1 parent 6b750b8 commit 7182c0f

File tree

2 files changed

+613
-0
lines changed

2 files changed

+613
-0
lines changed

crates/core/src/bson/mod.rs

Lines changed: 314 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ pub fn from_bytes<'de, T: Deserialize<'de>>(bytes: &'de [u8]) -> Result<T, BsonE
1515

1616
#[cfg(test)]
1717
mod test {
18+
use alloc::{vec, vec::Vec};
1819
use core::assert_matches::assert_matches;
1920

2021
use crate::sync::line::{SyncLine, TokenExpiresIn};
@@ -54,4 +55,317 @@ mod test {
5455
let expected: SyncLine = from_bytes(bson.as_slice()).expect("should deserialize");
5556
assert_matches!(expected, SyncLine::KeepAlive(TokenExpiresIn(60)));
5657
}
58+
59+
#[test]
60+
fn test_int64_positive_max() {
61+
// {"value": 9223372036854775807} (i64::MAX)
62+
let bson = b"\x14\x00\x00\x00\x12value\x00\xff\xff\xff\xff\xff\xff\xff\x7f\x00";
63+
64+
#[derive(Deserialize)]
65+
struct TestDoc {
66+
value: i64,
67+
}
68+
69+
let doc: TestDoc = from_bytes(bson).expect("should deserialize");
70+
assert_eq!(doc.value, i64::MAX);
71+
}
72+
73+
#[test]
74+
fn test_int64_negative_max() {
75+
// {"value": -9223372036854775808} (i64::MIN)
76+
let bson = b"\x14\x00\x00\x00\x12value\x00\x00\x00\x00\x00\x00\x00\x00\x80\x00";
77+
78+
#[derive(Deserialize)]
79+
struct TestDoc {
80+
value: i64,
81+
}
82+
83+
let doc: TestDoc = from_bytes(bson).expect("should deserialize");
84+
assert_eq!(doc.value, i64::MIN);
85+
}
86+
87+
#[test]
88+
fn test_int64_negative_one() {
89+
// {"value": -1}
90+
let bson = b"\x14\x00\x00\x00\x12value\x00\xff\xff\xff\xff\xff\xff\xff\xff\x00";
91+
92+
#[derive(Deserialize)]
93+
struct TestDoc {
94+
value: i64,
95+
}
96+
97+
let doc: TestDoc = from_bytes(bson).expect("should deserialize");
98+
assert_eq!(doc.value, -1);
99+
}
100+
101+
#[test]
102+
fn test_int64_negative_small() {
103+
// {"value": -42}
104+
let bson = b"\x14\x00\x00\x00\x12value\x00\xd6\xff\xff\xff\xff\xff\xff\xff\x00";
105+
106+
#[derive(Deserialize)]
107+
struct TestDoc {
108+
value: i64,
109+
}
110+
111+
let doc: TestDoc = from_bytes(bson).expect("should deserialize");
112+
assert_eq!(doc.value, -42);
113+
}
114+
115+
#[test]
116+
fn test_int32_negative_values() {
117+
// {"small": -1, "large": -2147483648} (i32::MIN)
118+
let bson =
119+
b"\x1b\x00\x00\x00\x10small\x00\xff\xff\xff\xff\x10large\x00\x00\x00\x00\x80\x00";
120+
121+
#[derive(Deserialize)]
122+
struct TestDoc {
123+
small: i32,
124+
large: i32,
125+
}
126+
127+
let doc: TestDoc = from_bytes(bson).expect("should deserialize");
128+
assert_eq!(doc.small, -1);
129+
assert_eq!(doc.large, i32::MIN);
130+
}
131+
132+
#[test]
133+
fn test_double_negative_values() {
134+
// {"neg": -3.14159}
135+
let bson = b"\x12\x00\x00\x00\x01neg\x00\x6e\x86\x1b\xf0\xf9\x21\x09\xc0\x00";
136+
137+
#[derive(Deserialize)]
138+
struct TestDoc {
139+
neg: f64,
140+
}
141+
142+
let doc: TestDoc = from_bytes(bson).expect("should deserialize");
143+
assert!((doc.neg - (-3.14159)).abs() < 0.00001);
144+
}
145+
146+
#[test]
147+
fn test_double_special_values() {
148+
// Test infinity, negative infinity, and NaN representations
149+
// {"inf": Infinity, "ninf": -Infinity, "nan": NaN}
150+
let bson = b"\x2d\x00\x00\x00\x01\x69\x6e\x66\x00\x00\x00\x00\x00\x00\x00\xf0\x7f\x01\x6e\x69\x6e\x66\x00\x00\x00\x00\x00\x00\x00\xf0\xff\x01\x6e\x61\x6e\x00\x00\x00\x00\x00\x00\x00\xf8\x7f\x00";
151+
152+
#[derive(Deserialize)]
153+
struct TestDoc {
154+
inf: f64,
155+
ninf: f64,
156+
nan: f64,
157+
}
158+
159+
let doc: TestDoc = from_bytes(bson).expect("should deserialize");
160+
assert_eq!(doc.inf, f64::INFINITY);
161+
assert_eq!(doc.ninf, f64::NEG_INFINITY);
162+
assert!(doc.nan.is_nan());
163+
}
164+
165+
#[test]
166+
fn test_empty_string() {
167+
// {"empty": ""}
168+
let bson = b"\x11\x00\x00\x00\x02empty\x00\x01\x00\x00\x00\x00\x00";
169+
170+
#[derive(Deserialize)]
171+
struct TestDoc<'a> {
172+
empty: &'a str,
173+
}
174+
175+
let doc: TestDoc = from_bytes(bson).expect("should deserialize");
176+
assert_eq!(doc.empty, "");
177+
}
178+
179+
#[test]
180+
fn test_unicode_string() {
181+
// {"unicode": "🦀💖"}
182+
let bson = b"\x1b\x00\x00\x00\x02unicode\x00\x09\x00\x00\x00\xf0\x9f\xa6\x80\xf0\x9f\x92\x96\x00\x00";
183+
184+
#[derive(Deserialize)]
185+
struct TestDoc<'a> {
186+
unicode: &'a str,
187+
}
188+
189+
let doc: TestDoc = from_bytes(bson).expect("should deserialize");
190+
assert_eq!(doc.unicode, "🦀💖");
191+
}
192+
193+
#[test]
194+
fn test_boolean_values() {
195+
// {"true_val": true, "false_val": false}
196+
let bson = b"\x1c\x00\x00\x00\x08true_val\x00\x01\x08false_val\x00\x00\x00";
197+
198+
#[derive(Deserialize)]
199+
struct TestDoc {
200+
true_val: bool,
201+
false_val: bool,
202+
}
203+
204+
let doc: TestDoc = from_bytes(bson).expect("should deserialize");
205+
assert_eq!(doc.true_val, true);
206+
assert_eq!(doc.false_val, false);
207+
}
208+
209+
#[test]
210+
fn test_null_value() {
211+
// {"null_val": null}
212+
let bson = b"\x0f\x00\x00\x00\x0anull_val\x00\x00";
213+
214+
#[derive(Deserialize)]
215+
struct TestDoc {
216+
null_val: Option<i32>,
217+
}
218+
219+
let doc: TestDoc = from_bytes(bson).expect("should deserialize");
220+
assert_eq!(doc.null_val, None);
221+
}
222+
223+
#[test]
224+
fn test_empty_document() {
225+
// {}
226+
let bson = b"\x05\x00\x00\x00\x00";
227+
228+
#[derive(Deserialize)]
229+
struct TestDoc {}
230+
231+
let _doc: TestDoc = from_bytes(bson).expect("should deserialize");
232+
}
233+
234+
#[test]
235+
fn test_nested_document() {
236+
// {"nested": {"inner": 42}}
237+
let bson =
238+
b"\x1d\x00\x00\x00\x03nested\x00\x10\x00\x00\x00\x10inner\x00*\x00\x00\x00\x00\x00";
239+
240+
#[derive(Deserialize)]
241+
struct Inner {
242+
inner: i32,
243+
}
244+
245+
#[derive(Deserialize)]
246+
struct TestDoc {
247+
nested: Inner,
248+
}
249+
250+
let doc: TestDoc = from_bytes(bson).expect("should deserialize");
251+
assert_eq!(doc.nested.inner, 42);
252+
}
253+
254+
#[test]
255+
fn test_array_with_integers() {
256+
// {"array": [1, 2]} - simplified array test
257+
// Array format: {"0": 1, "1": 2}
258+
let bson = b"\x1f\x00\x00\x00\x04array\x00\x13\x00\x00\x00\x100\x00\x01\x00\x00\x00\x101\x00\x02\x00\x00\x00\x00\x00";
259+
260+
#[derive(Deserialize)]
261+
struct TestDoc {
262+
array: Vec<i32>,
263+
}
264+
265+
let doc: TestDoc = from_bytes(bson).expect("should deserialize");
266+
assert_eq!(doc.array, vec![1, 2]);
267+
}
268+
269+
#[test]
270+
fn test_binary_data() {
271+
// {"binary": <binary data>}
272+
let bson = b"\x16\x00\x00\x00\x05binary\x00\x04\x00\x00\x00\x00\x01\x02\x03\x04\x00";
273+
274+
#[derive(Deserialize)]
275+
struct TestDoc<'a> {
276+
binary: &'a [u8],
277+
}
278+
279+
let doc: TestDoc = from_bytes(bson).expect("should deserialize");
280+
assert_eq!(doc.binary, &[1, 2, 3, 4]);
281+
}
282+
283+
// Error case tests
284+
285+
#[test]
286+
fn test_invalid_element_type() {
287+
// Document with invalid element type (99)
288+
let bson = b"\x10\x00\x00\x00\x63test\x00\x01\x00\x00\x00\x00";
289+
290+
#[derive(Deserialize)]
291+
#[allow(dead_code)]
292+
struct TestDoc {
293+
test: i32,
294+
}
295+
296+
let result: Result<TestDoc, _> = from_bytes(bson);
297+
assert!(result.is_err());
298+
}
299+
300+
#[test]
301+
fn test_truncated_document() {
302+
// Document claims to be longer than actual data
303+
let bson = b"\xff\x00\x00\x00\x10test\x00";
304+
305+
#[derive(Deserialize)]
306+
#[allow(dead_code)]
307+
struct TestDoc {
308+
test: i32,
309+
}
310+
311+
let result: Result<TestDoc, _> = from_bytes(bson);
312+
assert!(result.is_err());
313+
}
314+
315+
#[test]
316+
fn test_invalid_string_length() {
317+
// String with invalid length
318+
let bson = b"\x15\x00\x00\x00\x02test\x00\xff\xff\xff\xff\x00";
319+
320+
#[derive(Deserialize)]
321+
#[allow(dead_code)]
322+
struct TestDoc<'a> {
323+
test: &'a str,
324+
}
325+
326+
let result: Result<TestDoc, _> = from_bytes(bson);
327+
assert!(result.is_err());
328+
}
329+
330+
#[test]
331+
fn test_unterminated_cstring() {
332+
// Document with field name that doesn't have null terminator
333+
let bson = b"\x10\x00\x00\x00\x10test\x01\x00\x00\x00\x00\x00";
334+
335+
#[derive(Deserialize)]
336+
#[allow(dead_code)]
337+
struct TestDoc {
338+
test: i32,
339+
}
340+
341+
let result: Result<TestDoc, _> = from_bytes(bson);
342+
assert!(result.is_err());
343+
}
344+
345+
#[test]
346+
fn test_document_without_terminator() {
347+
// Document missing the final null byte
348+
let bson = b"\x0d\x00\x00\x00\x10test\x00*\x00\x00\x00";
349+
350+
#[derive(Deserialize)]
351+
#[allow(dead_code)]
352+
struct TestDoc {
353+
test: i32,
354+
}
355+
356+
let result: Result<TestDoc, _> = from_bytes(bson);
357+
assert!(result.is_err());
358+
}
359+
360+
#[test]
361+
fn test_invalid_document_size() {
362+
// Document with size less than minimum (5 bytes)
363+
let bson = b"\x04\x00\x00\x00\x00";
364+
365+
#[derive(Deserialize)]
366+
struct TestDoc {}
367+
368+
let result: Result<TestDoc, _> = from_bytes(bson);
369+
assert!(result.is_err());
370+
}
57371
}

0 commit comments

Comments
 (0)