diff options
Diffstat (limited to 'tvix/nix-compat-derive-tests/tests/write_derive.rs')
-rw-r--r-- | tvix/nix-compat-derive-tests/tests/write_derive.rs | 370 |
1 files changed, 370 insertions, 0 deletions
diff --git a/tvix/nix-compat-derive-tests/tests/write_derive.rs b/tvix/nix-compat-derive-tests/tests/write_derive.rs new file mode 100644 index 000000000000..1ed5dbf7e735 --- /dev/null +++ b/tvix/nix-compat-derive-tests/tests/write_derive.rs @@ -0,0 +1,370 @@ +use std::fmt; + +use nix_compat::nix_daemon::ser::{ + mock::{Builder, Error}, + NixWrite as _, +}; +use nix_compat_derive::NixSerialize; + +#[derive(Debug, PartialEq, Eq, NixSerialize)] +pub struct UnitTest; + +#[derive(Debug, PartialEq, Eq, NixSerialize)] +pub struct EmptyTupleTest(); + +#[derive(Debug, PartialEq, Eq, NixSerialize)] +pub struct StructTest { + first: u64, + second: String, +} + +#[derive(Debug, PartialEq, Eq, NixSerialize)] +pub struct TupleTest(u64, String); + +#[derive(Debug, PartialEq, Eq, NixSerialize)] +pub struct StructVersionTest { + test: u64, + #[nix(version = "20..")] + hello: String, +} + +fn default_test() -> StructVersionTest { + StructVersionTest { + test: 89, + hello: String::from("klomp"), + } +} + +#[derive(Debug, PartialEq, Eq, NixSerialize)] +pub struct TupleVersionTest(u64, #[nix(version = "25..")] String); + +#[derive(Debug, PartialEq, Eq, NixSerialize)] +pub struct TupleVersionDefaultTest(u64, #[nix(version = "..25")] StructVersionTest); + +#[tokio::test] +async fn write_unit() { + let mut mock = Builder::new().build(); + mock.write_value(&UnitTest).await.unwrap(); +} + +#[tokio::test] +async fn write_empty_tuple() { + let mut mock = Builder::new().build(); + mock.write_value(&EmptyTupleTest()).await.unwrap(); +} + +#[tokio::test] +async fn write_struct() { + let mut mock = Builder::new() + .write_number(89) + .write_slice(b"klomp") + .build(); + mock.write_value(&StructTest { + first: 89, + second: String::from("klomp"), + }) + .await + .unwrap(); +} + +#[tokio::test] +async fn write_tuple() { + let mut mock = Builder::new() + .write_number(89) + .write_slice(b"klomp") + .build(); + mock.write_value(&TupleTest(89, String::from("klomp"))) + .await + .unwrap(); +} + +#[tokio::test] +async fn write_struct_version() { + let mut mock = Builder::new() + .version((1, 20)) + .write_number(89) + .write_slice(b"klomp") + .build(); + mock.write_value(&default_test()).await.unwrap(); +} + +#[tokio::test] +async fn write_struct_without_version() { + let mut mock = Builder::new().version((1, 19)).write_number(89).build(); + mock.write_value(&StructVersionTest { + test: 89, + hello: String::new(), + }) + .await + .unwrap(); +} + +#[tokio::test] +async fn write_tuple_version() { + let mut mock = Builder::new() + .version((1, 26)) + .write_number(89) + .write_slice(b"klomp") + .build(); + mock.write_value(&TupleVersionTest(89, "klomp".into())) + .await + .unwrap(); +} + +#[tokio::test] +async fn write_tuple_without_version() { + let mut mock = Builder::new().version((1, 19)).write_number(89).build(); + mock.write_value(&TupleVersionTest(89, String::new())) + .await + .unwrap(); +} + +#[tokio::test] +async fn write_complex_1() { + let mut mock = Builder::new() + .version((1, 19)) + .write_number(999) + .write_number(666) + .build(); + mock.write_value(&TupleVersionDefaultTest( + 999, + StructVersionTest { + test: 666, + hello: String::new(), + }, + )) + .await + .unwrap(); +} + +#[tokio::test] +async fn write_complex_2() { + let mut mock = Builder::new() + .version((1, 20)) + .write_number(999) + .write_number(666) + .write_slice(b"The quick brown \xF0\x9F\xA6\x8A jumps over 13 lazy \xF0\x9F\x90\xB6.") + .build(); + mock.write_value(&TupleVersionDefaultTest( + 999, + StructVersionTest { + test: 666, + hello: String::from("The quick brown 🦊 jumps over 13 lazy 🐶."), + }, + )) + .await + .unwrap(); +} + +#[tokio::test] +async fn write_complex_3() { + let mut mock = Builder::new().version((1, 25)).write_number(999).build(); + mock.write_value(&TupleVersionDefaultTest( + 999, + StructVersionTest { + test: 89, + hello: String::from("klomp"), + }, + )) + .await + .unwrap(); +} + +#[tokio::test] +async fn write_complex_4() { + let mut mock = Builder::new().version((1, 26)).write_number(999).build(); + mock.write_value(&TupleVersionDefaultTest( + 999, + StructVersionTest { + test: 89, + hello: String::from("klomp"), + }, + )) + .await + .unwrap(); +} + +#[derive(Debug, PartialEq, Eq, NixSerialize)] +#[nix(display)] +struct TestFromStr; + +impl fmt::Display for TestFromStr { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + write!(f, "test") + } +} + +#[tokio::test] +async fn write_display() { + let mut mock = Builder::new().write_display("test").build(); + mock.write_value(&TestFromStr).await.unwrap(); +} + +#[derive(Debug, PartialEq, Eq, NixSerialize)] +#[nix(display = "TestFromStr2::display")] +struct TestFromStr2; +struct TestFromStrDisplay; + +impl fmt::Display for TestFromStrDisplay { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + write!(f, "test") + } +} +impl TestFromStr2 { + fn display(&self) -> TestFromStrDisplay { + TestFromStrDisplay + } +} + +#[tokio::test] +async fn write_display_path() { + let mut mock = Builder::new().write_display("test").build(); + mock.write_value(&TestFromStr2).await.unwrap(); +} + +#[derive(Clone, Debug, PartialEq, Eq, NixSerialize)] +#[nix(try_into = "u64")] +struct TestTryFromU64(u64); + +impl TryFrom<TestTryFromU64> for u64 { + type Error = u64; + + fn try_from(value: TestTryFromU64) -> Result<Self, Self::Error> { + if value.0 != 42 { + Ok(value.0) + } else { + Err(value.0) + } + } +} + +#[tokio::test] +async fn write_try_into_u64() { + let mut mock = Builder::new().write_number(666).build(); + mock.write_value(&TestTryFromU64(666)).await.unwrap(); +} + +#[tokio::test] +async fn write_try_into_u64_invalid_data() { + let mut mock = Builder::new().build(); + let err = mock.write_value(&TestTryFromU64(42)).await.unwrap_err(); + assert_eq!(Error::UnsupportedData("42".into()), err); +} + +#[derive(Clone, Debug, PartialEq, Eq, NixSerialize)] +#[nix(into = "u64")] +struct TestFromU64; + +impl From<TestFromU64> for u64 { + fn from(_value: TestFromU64) -> u64 { + 42 + } +} + +#[tokio::test] +async fn write_into_u64() { + let mut mock = Builder::new().write_number(42).build(); + mock.write_value(&TestFromU64).await.unwrap(); +} + +#[derive(Debug, PartialEq, Eq, NixSerialize)] +enum TestEnum { + #[nix(version = "..=19")] + Pre20(TestFromU64, #[nix(version = "10..")] u64), + #[nix(version = "20..=29")] + Post20(StructVersionTest), + #[nix(version = "30..=39")] + Post30, + #[nix(version = "40..")] + Post40 { + msg: String, + #[nix(version = "45..")] + level: u64, + }, +} + +#[tokio::test] +async fn write_enum_9() { + let mut mock = Builder::new().version((1, 9)).write_number(42).build(); + mock.write_value(&TestEnum::Pre20(TestFromU64, 666)) + .await + .unwrap(); +} + +#[tokio::test] +async fn write_enum_19() { + let mut mock = Builder::new() + .version((1, 19)) + .write_number(42) + .write_number(666) + .build(); + mock.write_value(&TestEnum::Pre20(TestFromU64, 666)) + .await + .unwrap(); +} + +#[tokio::test] +async fn write_enum_20() { + let mut mock = Builder::new() + .version((1, 20)) + .write_number(666) + .write_slice(b"klomp") + .build(); + mock.write_value(&TestEnum::Post20(StructVersionTest { + test: 666, + hello: "klomp".into(), + })) + .await + .unwrap(); +} + +#[tokio::test] +async fn write_enum_30() { + let mut mock = Builder::new().version((1, 30)).build(); + mock.write_value(&TestEnum::Post30).await.unwrap(); +} + +#[tokio::test] +async fn write_enum_40() { + let mut mock = Builder::new() + .version((1, 40)) + .write_slice(b"hello world") + .build(); + mock.write_value(&TestEnum::Post40 { + msg: "hello world".into(), + level: 9001, + }) + .await + .unwrap(); +} + +#[tokio::test] +async fn write_enum_45() { + let mut mock = Builder::new() + .version((1, 45)) + .write_slice(b"hello world") + .write_number(9001) + .build(); + mock.write_value(&TestEnum::Post40 { + msg: "hello world".into(), + level: 9001, + }) + .await + .unwrap(); +} + +#[tokio::test] +async fn write_wrong_enum() { + let mut mock = Builder::new().version((1, 30)).build(); + let err = mock + .write_value(&TestEnum::Post40 { + msg: "hello world".into(), + level: 9001, + }) + .await + .unwrap_err(); + assert_eq!( + err, + Error::InvalidEnum("Post40 is not valid for version 1.30".into()) + ) +} |