Würdest du noch Tests einfügen? Es gibt jetzt für fast jede Datei einen Test, oder?
tests/collections.rs:
```rust
mod shared;
use data_stream::default_settings::{NativeSettings, PortableSettings};
use shared::assert_streamed_eq;
use std::collections::{BTreeMap, BTreeSet, HashMap, HashSet, LinkedList, VecDeque};
macro_rules! impl_test {
($name: ident, $t: ty, $settings: ty) => {
#[test]
fn $name() {
assert_streamed_eq::<$settings, $t>(&vec![1, 2, 3, 4, 5].into_iter().collect());
}
};
}
macro_rules! impl_map_test {
($name: ident, $t: ty, $settings: ty) => {
#[test]
fn $name() {
assert_streamed_eq::<$settings, $t>(
&vec![(1, 1.0), (2, 2.0), (3, 3.0), (4, 4.0), (5, 5.0)]
.into_iter()
.collect(),
);
}
};
}
impl_test!(check_vec_native, Vec<u32>, NativeSettings);
impl_test!(check_vec_portable, Vec<u32>, PortableSettings);
impl_test!(check_vec_deque_native, VecDeque<u32>, NativeSettings);
impl_test!(check_vec_deque_portable, VecDeque<u32>, PortableSettings);
impl_test!(check_linked_list_native, LinkedList<u32>, NativeSettings);
impl_test!(
check_linked_list_portable,
LinkedList<u32>,
PortableSettings
);
impl_test!(check_hash_set_native, HashSet<u32>, NativeSettings);
impl_test!(check_hash_set_portable, HashSet<u32>, PortableSettings);
impl_test!(check_binary_tree_set_native, BTreeSet<u32>, NativeSettings);
impl_test!(
check_binary_tree_set_portable,
BTreeSet<u32>,
PortableSettings
);
impl_map_test!(check_hash_map_native, HashMap<u32, f64>, NativeSettings);
impl_map_test!(check_hash_map_portable, HashMap<u32, f64>, PortableSettings);
impl_map_test!(check_binary_tree_map_native, BTreeMap<u32, f64>, NativeSettings);
impl_map_test!(
check_binary_tree_map_portable,
BTreeMap<u32, f64>,
PortableSettings
);
```
tests/derive.rs:
```rust
mod shared;
use data_stream::default_settings::PortableSettings;
use data_stream::{FromStream, ToStream};
use shared::assert_streamed_eq;
#[derive(Debug, PartialEq, ToStream, FromStream)]
struct UnitStruct;
#[derive(Debug, PartialEq, ToStream, FromStream)]
#[stream(bounds = "data_stream::numbers::EndianSettings")]
struct NewtypeStruct(u32);
#[derive(Debug, PartialEq, ToStream, FromStream)]
#[stream(bounds = "data_stream::numbers::EndianSettings")]
struct TupleStruct(u32, u64, bool);
#[derive(Debug, PartialEq, ToStream, FromStream)]
#[stream(bounds = "data_stream::numbers::EndianSettings")]
struct BasicStruct {
x: u32,
y: u64,
z: bool,
}
#[derive(Debug, PartialEq, ToStream, FromStream)]
#[stream(bounds = "data_stream::numbers::EndianSettings")]
struct NestedStruct {
inner: BasicStruct,
value: u16,
}
#[derive(Debug, PartialEq, ToStream, FromStream)]
#[stream(bounds = "data_stream::numbers::EndianSettings")]
struct OrderedStruct {
#[field(order = 2)]
second: u32,
#[field(order = 0)]
first: u64,
#[field(order = 1)]
middle: bool,
}
#[derive(Debug, PartialEq, ToStream, FromStream)]
#[stream(bounds = "data_stream::numbers::EndianSettings")]
struct IgnoredFieldStruct {
kept: u32,
#[field(ignore)]
skipped: u64,
also_kept: bool,
}
#[derive(Debug, PartialEq, ToStream, FromStream)]
#[stream(bounds = "data_stream::numbers::EndianSettings")]
struct IgnoredTupleStruct(u32, #[field(ignore)] u64, bool);
#[derive(Debug, PartialEq, ToStream, FromStream)]
#[stream(bounds = "data_stream::collections::SizeSettings")]
struct WithString {
name: String,
value: u32,
}
#[derive(Debug, PartialEq, ToStream, FromStream)]
#[stream(bounds = "data_stream::collections::SizeSettings")]
struct WithVec {
items: Vec<u32>,
label: String,
}
#[derive(Debug, PartialEq, ToStream, FromStream)]
#[stream(bounds = "data_stream::numbers::EndianSettings")]
enum SimpleEnum {
A,
B,
C,
}
#[derive(Debug, PartialEq, ToStream, FromStream)]
#[stream(bounds = "data_stream::numbers::EndianSettings")]
enum DataEnum {
Empty,
Single(u32),
Pair(u32, u64),
Named { x: u32, y: bool },
}
#[derive(Debug, PartialEq, ToStream, FromStream)]
#[stream(bounds = "data_stream::numbers::EndianSettings")]
enum CustomIndexEnum {
#[variant(index = 10)]
First,
Second,
#[variant(index = 50)]
Jump,
After,
}
#[derive(Debug, PartialEq, ToStream, FromStream)]
#[stream(bounds = "data_stream::numbers::EndianSettings")]
enum EnumWithIgnoredField {
Normal(u32),
WithIgnore {
kept: u32,
#[field(ignore)]
_skipped: bool,
},
}
#[derive(Debug, PartialEq, ToStream, FromStream)]
#[stream(bounds = "data_stream::collections::SizeSettings")]
enum ComplexEnum {
Empty,
WithVec(Vec<u32>),
WithString { name: String, id: u64 },
}
#[derive(Debug, PartialEq, ToStream, FromStream)]
#[stream(bounds = "data_stream::numbers::EndianSettings")]
struct GenericStruct<T: PartialEq + std::fmt::Debug> {
value: T,
flag: bool,
}
#[test]
fn unit_struct() {
assert_streamed_eq::<PortableSettings, _>(&UnitStruct);
}
#[test]
fn newtype_struct() {
assert_streamed_eq::<PortableSettings, _>(&NewtypeStruct(42));
}
#[test]
fn tuple_struct() {
assert_streamed_eq::<PortableSettings, _>(&TupleStruct(1, 2, true));
}
#[test]
fn basic_struct() {
assert_streamed_eq::<PortableSettings, _>(&BasicStruct {
x: 100,
y: 200,
z: false,
});
}
#[test]
fn nested_struct() {
assert_streamed_eq::<PortableSettings, _>(&NestedStruct {
inner: BasicStruct {
x: 1,
y: 2,
z: true,
},
value: 999,
});
}
#[test]
fn ordered_struct() {
assert_streamed_eq::<PortableSettings, _>(&OrderedStruct {
second: 2,
first: 1,
middle: true,
});
}
#[test]
fn ordered_struct_binary_layout() {
use data_stream::to_stream;
let value = OrderedStruct {
second: 2,
first: 1,
middle: true,
};
let mut bytes = Vec::new();
to_stream::<PortableSettings, _, _>(&value, &mut bytes).unwrap();
let mut expected = Vec::new();
to_stream::<PortableSettings, _, _>(&1u64, &mut expected).unwrap();
to_stream::<PortableSettings, _, _>(&true, &mut expected).unwrap();
to_stream::<PortableSettings, _, _>(&2u32, &mut expected).unwrap();
assert_eq!(bytes, expected);
}
#[test]
fn ignored_field_roundtrip() {
let original = IgnoredFieldStruct {
kept: 42,
skipped: 999,
also_kept: true,
};
let mut bytes = Vec::new();
data_stream::to_stream::<PortableSettings, _, _>(&original, &mut bytes).unwrap();
let restored: IgnoredFieldStruct =
data_stream::from_stream::<PortableSettings, _, _>(&mut &bytes[..]).unwrap();
assert_eq!(restored.kept, 42);
assert_eq!(restored.skipped, 0);
assert!(restored.also_kept);
}
#[test]
fn ignored_field_smaller_bytes() {
let with_ignore = IgnoredFieldStruct {
kept: 1,
skipped: 0,
also_kept: true,
};
let without_ignore = BasicStruct {
x: 1,
y: 0,
z: true,
};
let mut bytes_ignore = Vec::new();
data_stream::to_stream::<PortableSettings, _, _>(&with_ignore, &mut bytes_ignore).unwrap();
let mut bytes_full = Vec::new();
data_stream::to_stream::<PortableSettings, _, _>(&without_ignore, &mut bytes_full).unwrap();
assert!(bytes_ignore.len() < bytes_full.len());
}
#[test]
fn ignored_tuple_field() {
let original = IgnoredTupleStruct(42, 999, true);
let mut bytes = Vec::new();
data_stream::to_stream::<PortableSettings, _, _>(&original, &mut bytes).unwrap();
let restored: IgnoredTupleStruct =
data_stream::from_stream::<PortableSettings, _, _>(&mut &bytes[..]).unwrap();
assert_eq!(restored.0, 42);
assert_eq!(restored.1, 0);
assert!(restored.2);
}
#[test]
fn struct_with_string() {
assert_streamed_eq::<PortableSettings, _>(&WithString {
name: "hello".into(),
value: 7,
});
}
#[test]
fn struct_with_vec() {
assert_streamed_eq::<PortableSettings, _>(&WithVec {
items: vec![1, 2, 3],
label: "test".into(),
});
}
#[test]
fn struct_with_empty_collections() {
assert_streamed_eq::<PortableSettings, _>(&WithVec {
items: vec![],
label: String::new(),
});
}
#[test]
fn simple_enum_a() {
assert_streamed_eq::<PortableSettings, _>(&SimpleEnum::A);
}
#[test]
fn simple_enum_b() {
assert_streamed_eq::<PortableSettings, _>(&SimpleEnum::B);
}
#[test]
fn simple_enum_c() {
assert_streamed_eq::<PortableSettings, _>(&SimpleEnum::C);
}
#[test]
fn data_enum_empty() {
assert_streamed_eq::<PortableSettings, _>(&DataEnum::Empty);
}
#[test]
fn data_enum_single() {
assert_streamed_eq::<PortableSettings, _>(&DataEnum::Single(42));
}
#[test]
fn data_enum_pair() {
assert_streamed_eq::<PortableSettings, _>(&DataEnum::Pair(1, 2));
}
#[test]
fn data_enum_named() {
assert_streamed_eq::<PortableSettings, _>(&DataEnum::Named { x: 10, y: true });
}
#[test]
fn custom_index_first() {
assert_streamed_eq::<PortableSettings, _>(&CustomIndexEnum::First);
}
#[test]
fn custom_index_second() {
assert_streamed_eq::<PortableSettings, _>(&CustomIndexEnum::Second);
}
#[test]
fn custom_index_jump() {
assert_streamed_eq::<PortableSettings, _>(&CustomIndexEnum::Jump);
}
#[test]
fn custom_index_after() {
assert_streamed_eq::<PortableSettings, _>(&CustomIndexEnum::After);
}
#[test]
fn custom_index_binary_values() {
use data_stream::to_stream;
let mut bytes_first = Vec::new();
to_stream::<PortableSettings, _, _>(&CustomIndexEnum::First, &mut bytes_first).unwrap();
let mut bytes_second = Vec::new();
to_stream::<PortableSettings, _, _>(&CustomIndexEnum::Second, &mut bytes_second).unwrap();
let mut bytes_jump = Vec::new();
to_stream::<PortableSettings, _, _>(&CustomIndexEnum::Jump, &mut bytes_jump).unwrap();
let mut bytes_after = Vec::new();
to_stream::<PortableSettings, _, _>(&CustomIndexEnum::After, &mut bytes_after).unwrap();
let read_disc = |bytes: &[u8]| -> u32 {
data_stream::from_stream::<PortableSettings, u32, _>(&mut &bytes[..]).unwrap()
};
assert_eq!(read_disc(&bytes_first), 10);
assert_eq!(read_disc(&bytes_second), 11);
assert_eq!(read_disc(&bytes_jump), 50);
assert_eq!(read_disc(&bytes_after), 51);
}
#[test]
fn enum_ignored_field() {
let original = EnumWithIgnoredField::WithIgnore {
kept: 42,
_skipped: true,
};
let mut bytes = Vec::new();
data_stream::to_stream::<PortableSettings, _, _>(&original, &mut bytes).unwrap();
let restored: EnumWithIgnoredField =
data_stream::from_stream::<PortableSettings, _, _>(&mut &bytes[..]).unwrap();
match restored {
EnumWithIgnoredField::WithIgnore {
kept,
_skipped: skipped,
} => {
assert_eq!(kept, 42);
assert!(!skipped);
}
EnumWithIgnoredField::Normal(_) => panic!("wrong variant"),
}
}
#[test]
fn complex_enum_empty() {
assert_streamed_eq::<PortableSettings, _>(&ComplexEnum::Empty);
}
#[test]
fn complex_enum_with_vec() {
assert_streamed_eq::<PortableSettings, _>(&ComplexEnum::WithVec(vec![1, 2, 3]));
}
#[test]
fn complex_enum_with_string() {
assert_streamed_eq::<PortableSettings, _>(&ComplexEnum::WithString {
name: "test".into(),
id: 42,
});
}
#[test]
fn generic_struct_u32() {
assert_streamed_eq::<PortableSettings, _>(&GenericStruct {
value: 42u32,
flag: true,
});
}
#[test]
fn generic_struct_bool() {
assert_streamed_eq::<PortableSettings, _>(&GenericStruct {
value: false,
flag: true,
});
}
#[test]
fn invalid_enum_discriminant() {
let mut bytes = Vec::new();
data_stream::to_stream::<PortableSettings, _, _>(&999u32, &mut bytes).unwrap();
let result = data_stream::from_stream::<PortableSettings, SimpleEnum, _>(&mut &bytes[..]);
assert!(result.is_err());
}
#[test]
fn read_from_empty_stream() {
let bytes: &[u8] = &[];
let result = data_stream::from_stream::<PortableSettings, BasicStruct, _>(&mut &bytes[..]);
assert!(result.is_err());
}
#[test]
fn read_enum_from_empty_stream() {
let bytes: &[u8] = &[];
let result = data_stream::from_stream::<PortableSettings, SimpleEnum, _>(&mut &bytes[..]);
assert!(result.is_err());
}
```
tests/numbers.rs:
```rust
mod shared;
use data_stream::numbers::{BigEndian, LittleEndian, NativeEndian};
use shared::assert_streamed_eq;
macro_rules! impl_test {
($name: ident, $t: ty, $endian: ty) => {
#[test]
fn $name() {
assert_streamed_eq::<$endian, _>(&(123 as $t));
}
};
}
impl_test!(check_u8_be, u8, BigEndian);
impl_test!(check_u16_be, u16, BigEndian);
impl_test!(check_u32_be, u32, BigEndian);
impl_test!(check_u64_be, u64, BigEndian);
impl_test!(check_u128_be, u128, BigEndian);
impl_test!(check_u8_le, u8, LittleEndian);
impl_test!(check_u16_le, u16, LittleEndian);
impl_test!(check_u32_le, u32, LittleEndian);
impl_test!(check_u64_le, u64, LittleEndian);
impl_test!(check_u128_le, u128, LittleEndian);
impl_test!(check_u8_ne, u8, NativeEndian);
impl_test!(check_u16_ne, u16, NativeEndian);
impl_test!(check_u32_ne, u32, NativeEndian);
impl_test!(check_u64_ne, u64, NativeEndian);
impl_test!(check_u128_ne, u128, NativeEndian);
impl_test!(check_i8_be, i8, BigEndian);
impl_test!(check_i16_be, i16, BigEndian);
impl_test!(check_i32_be, i32, BigEndian);
impl_test!(check_i64_be, i64, BigEndian);
impl_test!(check_i128_be, i128, BigEndian);
impl_test!(check_i8_le, i8, LittleEndian);
impl_test!(check_i16_le, i16, LittleEndian);
impl_test!(check_i32_le, i32, LittleEndian);
impl_test!(check_i64_le, i64, LittleEndian);
impl_test!(check_i128_le, i128, LittleEndian);
impl_test!(check_i8_ne, i8, NativeEndian);
impl_test!(check_i16_ne, i16, NativeEndian);
impl_test!(check_i32_ne, i32, NativeEndian);
impl_test!(check_i64_ne, i64, NativeEndian);
impl_test!(check_i128_ne, i128, NativeEndian);
impl_test!(check_f32_be, f32, BigEndian);
impl_test!(check_f64_be, f64, BigEndian);
impl_test!(check_f32_le, f32, LittleEndian);
impl_test!(check_f64_le, f64, LittleEndian);
impl_test!(check_f32_ne, f32, NativeEndian);
impl_test!(check_f64_ne, f64, NativeEndian);
impl_test!(check_usize_be, usize, BigEndian);
impl_test!(check_usize_le, usize, LittleEndian);
impl_test!(check_usize_ne, usize, NativeEndian);
```
tests/shared.rs:
```rust
use data_stream::{FromStream, ToStream, from_stream, to_stream};
use std::{fmt::Debug, io::Result};
pub fn try_streaming<S, V: ToStream<S> + FromStream<S>>(value: &V) -> Result<V> {
let mut bytes = Vec::new();
to_stream(value, &mut &mut bytes)?;
from_stream(&mut &bytes[..])
}
pub fn assert_streamed_eq<S, V: ToStream<S> + FromStream<S> + PartialEq + Debug>(value: &V) {
let copy = try_streaming(value).unwrap();
assert_eq!(value, ©);
}
```