diff --git a/nih_plug_derive/tests/persist.rs b/nih_plug_derive/tests/persist.rs new file mode 100644 index 00000000..b5a595c2 --- /dev/null +++ b/nih_plug_derive/tests/persist.rs @@ -0,0 +1,138 @@ +use std::collections::BTreeMap; +use std::sync::Mutex; + +use nih_plug::prelude::*; + +#[derive(Params, Default)] +struct WrapperParams { + #[nested(id_prefix = "foo")] + pub inner: InnerParams, +} + +#[derive(Params, Default)] +struct ArrayWrapperParams { + #[nested(array)] + pub inners: [InnerParams; 3], +} + +#[derive(Default)] +struct InnerParams { + /// The value `deserialize()` has been called with so we can check that the prefix has been + /// stripped correctly. + pub deserialize_called_with: Mutex>>, +} + +unsafe impl Params for InnerParams { + fn param_map(&self) -> Vec<(String, ParamPtr, String)> { + Vec::new() + } + + fn serialize_fields(&self) -> BTreeMap { + // When nested in another struct, the ID prefix will be added to `bar` + let mut data = BTreeMap::new(); + data.insert(String::from("bar"), String::from("baz")); + + data + } + + fn deserialize_fields(&self, serialized: &BTreeMap) { + *self.deserialize_called_with.lock().unwrap() = Some(serialized.clone()); + } +} + +mod persist { + mod nested_prefix { + + use super::super::*; + + #[test] + fn serialize() { + let params = WrapperParams::default(); + + // This should have had a prefix added to the serialized value + let serialized = params.serialize_fields(); + assert_eq!(serialized.len(), 1); + assert_eq!(serialized["foo_bar"], "baz"); + } + + #[test] + fn deserialize() { + let mut serialized = BTreeMap::new(); + serialized.insert(String::from("foo_bar"), String::from("aaa")); + + let params = WrapperParams::default(); + params.deserialize_fields(&serialized); + + // This contains the values passed to the inner struct's deserialize function + let deserialized = params + .inner + .deserialize_called_with + .lock() + .unwrap() + .take() + .unwrap(); + assert_eq!(deserialized.len(), 1); + assert_eq!(deserialized["bar"], "aaa"); + } + + #[test] + fn deserialize_mismatching_prefix() { + let mut serialized = BTreeMap::new(); + serialized.insert(String::from("foo_bar"), String::from("aaa")); + serialized.insert( + String::from("something"), + String::from("this should not be there"), + ); + + let params = WrapperParams::default(); + params.deserialize_fields(&serialized); + + // The `something` key should not be passed to the child struct + let deserialized = params + .inner + .deserialize_called_with + .lock() + .unwrap() + .take() + .unwrap(); + assert_eq!(deserialized.len(), 1); + assert_eq!(deserialized["bar"], "aaa"); + } + } + + mod array_suffix { + use super::super::*; + + #[test] + fn serialize() { + let params = ArrayWrapperParams::default(); + + let serialized = params.serialize_fields(); + assert_eq!(serialized.len(), 3); + assert_eq!(serialized["bar_1"], "baz"); + assert_eq!(serialized["bar_2"], "baz"); + assert_eq!(serialized["bar_2"], "baz"); + } + + #[test] + fn deserialize() { + let mut serialized = BTreeMap::new(); + serialized.insert(String::from("bar_1"), String::from("aaa")); + serialized.insert(String::from("bar_2"), String::from("bbb")); + serialized.insert(String::from("bar_3"), String::from("ccc")); + + let params = ArrayWrapperParams::default(); + params.deserialize_fields(&serialized); + for (inner, expected_value) in params.inners.into_iter().zip(["aaa", "bbb", "ccc"]) { + let deserialized = inner + .deserialize_called_with + .lock() + .unwrap() + .take() + .unwrap(); + assert_eq!(deserialized.len(), 1); + assert_eq!(deserialized["bar"], expected_value); + } + } + } +}