From 6bda3ef174194688674e496f6c245d443e413aed Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fran=C3=A7ois=20Laignel?= Date: Sun, 29 Jul 2018 18:18:24 +0200 Subject: [PATCH] serde: add roundtrip tests This allows making sure serialization and deserialization are in sync for types with asymetrical implementations. --- gstreamer/src/buffer_serde.rs | 43 ++++++++ gstreamer/src/bufferlist_serde.rs | 50 +++++++++ gstreamer/src/clock_time_serde.rs | 22 +++- gstreamer/src/date_time_serde.rs | 22 +++- gstreamer/src/format_serde.rs | 55 +++++++--- gstreamer/src/sample_serde.rs | 76 ++++++++++++-- gstreamer/src/segment_serde.rs | 50 +++++++-- gstreamer/src/structure_serde.rs | 24 +++-- gstreamer/src/tags_serde.rs | 72 ++++++++++++- gstreamer/src/toc_serde.rs | 167 +++++++++++++++++++++++++++++- gstreamer/src/value_serde.rs | 130 +++++++++++++++++++---- 11 files changed, 637 insertions(+), 74 deletions(-) diff --git a/gstreamer/src/buffer_serde.rs b/gstreamer/src/buffer_serde.rs index 07966071d..5dbff9fa7 100644 --- a/gstreamer/src/buffer_serde.rs +++ b/gstreamer/src/buffer_serde.rs @@ -220,4 +220,47 @@ mod tests { assert_eq!(data.as_slice(), vec![1, 2, 3, 4].as_slice()); } } + + #[test] + fn test_serde_roundtrip() { + ::init().unwrap(); + + let mut buffer = Buffer::from_slice(vec![1, 2, 3, 4]).unwrap(); + { + let buffer = buffer.get_mut().unwrap(); + buffer.set_pts(1.into()); + buffer.set_offset(3); + buffer.set_offset_end(4); + buffer.set_duration(5.into()); + buffer.set_flags(BufferFlags::LIVE | BufferFlags::LAST); + } + + // Ron + let buffer_ser = ron::ser::to_string(&buffer).unwrap(); + let buffer_de: Buffer = ron::de::from_str(buffer_ser.as_str()).unwrap(); + assert_eq!(buffer_de.get_pts(), buffer.get_pts()); + assert_eq!(buffer_de.get_dts(), buffer.get_dts()); + assert_eq!(buffer_de.get_offset(), buffer.get_offset()); + assert_eq!(buffer_de.get_offset_end(), buffer.get_offset_end()); + assert_eq!(buffer_de.get_duration(), buffer.get_duration()); + assert_eq!(buffer_de.get_flags(), buffer.get_flags()); + { + let data = buffer_de.map_readable().unwrap(); + assert_eq!(data.as_slice(), vec![1, 2, 3, 4].as_slice()); + } + + // Pickle + let buffer_ser = serde_pickle::to_vec(&buffer, true).unwrap(); + let buffer_de: Buffer = serde_pickle::from_slice(buffer_ser.as_slice()).unwrap(); + assert_eq!(buffer_de.get_pts(), buffer.get_pts()); + assert_eq!(buffer_de.get_dts(), buffer.get_dts()); + assert_eq!(buffer_de.get_offset(), buffer.get_offset()); + assert_eq!(buffer_de.get_offset_end(), buffer.get_offset_end()); + assert_eq!(buffer_de.get_duration(), buffer.get_duration()); + assert_eq!(buffer_de.get_flags(), buffer.get_flags()); + { + let data = buffer_de.map_readable().unwrap(); + assert_eq!(data.as_slice(), vec![1, 2, 3, 4].as_slice()); + } + } } diff --git a/gstreamer/src/bufferlist_serde.rs b/gstreamer/src/bufferlist_serde.rs index baacfd9a9..2082cf21d 100644 --- a/gstreamer/src/bufferlist_serde.rs +++ b/gstreamer/src/bufferlist_serde.rs @@ -184,4 +184,54 @@ mod tests { assert_eq!(data.as_slice(), vec![5, 6].as_slice()); } } + + #[test] + fn test_serde_roundtrip() { + use Buffer; + + ::init().unwrap(); + + let mut buffer_list = BufferList::new(); + { + let buffer_list = buffer_list.get_mut().unwrap(); + + let mut buffer = Buffer::from_slice(vec![1, 2, 3, 4]).unwrap(); + { + let buffer = buffer.get_mut().unwrap(); + buffer.set_pts(1.into()); + buffer.set_offset(0); + buffer.set_offset_end(4); + buffer.set_duration(4.into()); + } + buffer_list.add(buffer); + + let mut buffer = Buffer::from_slice(vec![5, 6]).unwrap(); + { + let buffer = buffer.get_mut().unwrap(); + buffer.set_pts(5.into()); + buffer.set_offset(4); + buffer.set_offset_end(6); + buffer.set_duration(2.into()); + } + buffer_list.add(buffer); + } + let buffer_list_ser = ron::ser::to_string(&buffer_list).unwrap(); + + let buffer_list: BufferList = ron::de::from_str(buffer_list_ser.as_str()).unwrap(); + let mut iter = buffer_list.iter(); + let buffer = iter.next().unwrap(); + assert_eq!(buffer.get_pts(), 1.into()); + assert_eq!(buffer.get_dts(), None.into()); + { + let data = buffer.map_readable().unwrap(); + assert_eq!(data.as_slice(), vec![1, 2, 3, 4].as_slice()); + } + + let buffer = iter.next().unwrap(); + assert_eq!(buffer.get_pts(), 5.into()); + { + let data = buffer.map_readable().unwrap(); + assert_eq!(data.as_slice(), vec![5, 6].as_slice()); + } + } } diff --git a/gstreamer/src/clock_time_serde.rs b/gstreamer/src/clock_time_serde.rs index 5e4b4bedc..08471ede6 100644 --- a/gstreamer/src/clock_time_serde.rs +++ b/gstreamer/src/clock_time_serde.rs @@ -35,7 +35,7 @@ impl<'de> Visitor<'de> for ClockTimeVisitor { where D: Deserializer<'de>, { - u64::deserialize(deserializer).and_then(|value| Ok(ClockTime::from_nseconds(value))) + u64::deserialize(deserializer).map(|value| ClockTime::from_nseconds(value)) } fn visit_none(self) -> Result { @@ -110,4 +110,24 @@ mod tests { let clocktime: ClockTime = serde_json::from_str(clocktime_json).unwrap(); assert_eq!(clocktime.nseconds(), None); } + + #[test] + fn test_serde_roundtrip() { + ::init().unwrap(); + + // Some + let clocktime = ClockTime::from_nseconds(42_123_456_789); + let clocktime_ser = ron::ser::to_string(&clocktime).unwrap(); + let clocktime: ClockTime = ron::de::from_str(clocktime_ser.as_str()).unwrap(); + assert_eq!(clocktime.seconds(), Some(42)); + assert_eq!(clocktime.mseconds(), Some(42_123)); + assert_eq!(clocktime.useconds(), Some(42_123_456)); + assert_eq!(clocktime.nseconds(), Some(42_123_456_789)); + + // None + let clocktime = ClockTime(None); + let clocktime_ser = ron::ser::to_string(&clocktime).unwrap(); + let clocktime: ClockTime = ron::de::from_str(clocktime_ser.as_str()).unwrap(); + assert_eq!(clocktime.nseconds(), None); + } } diff --git a/gstreamer/src/date_time_serde.rs b/gstreamer/src/date_time_serde.rs index 5694067ff..4dd414a03 100644 --- a/gstreamer/src/date_time_serde.rs +++ b/gstreamer/src/date_time_serde.rs @@ -53,7 +53,7 @@ impl From for DateTime { impl<'de> Deserialize<'de> for DateTime { fn deserialize>(deserializer: D) -> Result { - DateTimeDe::deserialize(deserializer).and_then(|datetime_de| Ok(datetime_de.into())) + DateTimeDe::deserialize(deserializer).map(|datetime_de| datetime_de.into()) } } @@ -137,4 +137,24 @@ mod tests { assert_eq!(datetime.get_second(), 42); assert_eq!(datetime.get_microsecond(), 841_000); } + + #[test] + fn test_serde_roundtrip() { + ::init().unwrap(); + + let datetime = DateTime::new(2f32, 2018, 5, 28, 16, 6, 42.841f64); + let datetime_ser = ron::ser::to_string(&datetime).unwrap(); + let datetime_de: DateTime = ron::de::from_str(datetime_ser.as_str()).unwrap(); + assert_eq!( + datetime_de.get_time_zone_offset(), + datetime.get_time_zone_offset() + ); + assert_eq!(datetime_de.get_year(), datetime.get_year()); + assert_eq!(datetime_de.get_month(), datetime.get_month()); + assert_eq!(datetime_de.get_day(), datetime.get_day()); + assert_eq!(datetime_de.get_hour(), datetime.get_hour()); + assert_eq!(datetime_de.get_minute(), datetime.get_minute()); + assert_eq!(datetime_de.get_second(), datetime.get_second()); + assert_eq!(datetime_de.get_microsecond(), datetime.get_microsecond()); + } } diff --git a/gstreamer/src/format_serde.rs b/gstreamer/src/format_serde.rs index 9eef6df3c..14372e9fc 100644 --- a/gstreamer/src/format_serde.rs +++ b/gstreamer/src/format_serde.rs @@ -39,16 +39,13 @@ mod tests { extern crate ron; extern crate serde_json; - use format::Default; + use format::{Buffers, Bytes, Default}; + use ClockTime; use Format; use GenericFormattedValue; #[test] fn test_serialize() { - use format::Buffers; - use format::Bytes; - use ClockTime; - ::init().unwrap(); let mut pretty_config = ron::ser::PrettyConfig::default(); @@ -113,20 +110,44 @@ mod tests { fn test_deserialize() { ::init().unwrap(); - let format_ron = "Default(Some(42))"; - let format: GenericFormattedValue = ron::de::from_str(format_ron).unwrap(); - assert_eq!(format, GenericFormattedValue::Default(Default(Some(42)))); + let value_ron = "Default(Some(42))"; + let value_de: GenericFormattedValue = ron::de::from_str(value_ron).unwrap(); + assert_eq!(value_de, GenericFormattedValue::Default(Default(Some(42)))); - let format_json = "{\"Default\":42}"; - let format: GenericFormattedValue = serde_json::from_str(format_json).unwrap(); - assert_eq!(format, GenericFormattedValue::Default(Default(Some(42)))); + let value_json = "{\"Default\":42}"; + let value_de: GenericFormattedValue = serde_json::from_str(value_json).unwrap(); + assert_eq!(value_de, GenericFormattedValue::Default(Default(Some(42)))); - let format_ron = "Other(Percent, 42)"; - let format: GenericFormattedValue = ron::de::from_str(format_ron).unwrap(); - assert_eq!(format, GenericFormattedValue::Other(Format::Percent, 42)); + let value_ron = "Other(Percent, 42)"; + let value_de: GenericFormattedValue = ron::de::from_str(value_ron).unwrap(); + assert_eq!(value_de, GenericFormattedValue::Other(Format::Percent, 42)); - let format_json = "{\"Other\":[\"Percent\",42]}"; - let format: GenericFormattedValue = serde_json::from_str(format_json).unwrap(); - assert_eq!(format, GenericFormattedValue::Other(Format::Percent, 42)); + let value_json = "{\"Other\":[\"Percent\",42]}"; + let value_de: GenericFormattedValue = serde_json::from_str(value_json).unwrap(); + assert_eq!(value_de, GenericFormattedValue::Other(Format::Percent, 42)); + } + + #[test] + fn test_serde_roundtrip() { + ::init().unwrap(); + + macro_rules! test_roundrip( + ($value:expr) => { + let value_ser = ron::ser::to_string(&$value).unwrap(); + let value_de: GenericFormattedValue = ron::de::from_str(value_ser.as_str()).unwrap(); + assert_eq!(value_de, $value); + } + ); + + test_roundrip!(GenericFormattedValue::Undefined(42)); + test_roundrip!(GenericFormattedValue::Default(Default(Some(42)))); + test_roundrip!(GenericFormattedValue::Bytes(Bytes(Some(42)))); + test_roundrip!(GenericFormattedValue::Time(ClockTime::from_nseconds( + 42_123_456_789 + ))); + test_roundrip!(GenericFormattedValue::Buffers(Buffers(Some(42)))); + test_roundrip!(GenericFormattedValue::Percent(Some(42))); + test_roundrip!(GenericFormattedValue::Other(Format::Percent, 42)); + test_roundrip!(GenericFormattedValue::Other(Format::__Unknown(7), 42)); } } diff --git a/gstreamer/src/sample_serde.rs b/gstreamer/src/sample_serde.rs index 3da5ee6d6..5dd5e8d56 100644 --- a/gstreamer/src/sample_serde.rs +++ b/gstreamer/src/sample_serde.rs @@ -75,19 +75,18 @@ impl<'de> Deserialize<'de> for Sample { mod tests { extern crate ron; + use Buffer; + use Caps; + use ClockTime; + use Format; + use GenericFormattedValue; use Sample; + use Segment; + use SegmentFlags; + use Structure; #[test] fn test_serialize() { - use Buffer; - use Caps; - use ClockTime; - use Format; - use GenericFormattedValue; - use Segment; - use SegmentFlags; - use Structure; - ::init().unwrap(); let mut pretty_config = ron::ser::PrettyConfig::default(); @@ -315,4 +314,63 @@ mod tests { //assert!(sample.get_segment().is_none()); assert!(sample.get_info().is_none()); } + + #[test] + fn test_roundrip() { + ::init().unwrap(); + + // Segment present + let sample = { + let mut buffer = Buffer::from_slice(vec![1, 2, 3, 4]).unwrap(); + { + let buffer = buffer.get_mut().unwrap(); + buffer.set_pts(1.into()); + buffer.set_offset(0); + buffer.set_offset_end(4); + buffer.set_duration(4.into()); + } + + let caps = Caps::builder("sample/caps") + .field("int", &12) + .field("bool", &true) + .build(); + + let mut segment = Segment::new(); + segment.set_flags(SegmentFlags::RESET | SegmentFlags::SEGMENT); + segment.set_rate(1f64); + segment.set_applied_rate(0.9f64); + segment.set_format(Format::Time); + segment.set_base(GenericFormattedValue::Time(ClockTime::from_nseconds(123))); + segment.set_offset(GenericFormattedValue::Time(ClockTime::from_nseconds(42))); + segment.set_start(GenericFormattedValue::Time(ClockTime::from_nseconds(1024))); + segment.set_stop(GenericFormattedValue::Time(ClockTime::from_nseconds(2048))); + segment.set_time(GenericFormattedValue::Time(ClockTime::from_nseconds(1042))); + segment.set_position(GenericFormattedValue::Time(ClockTime::from_nseconds(256))); + segment.set_duration(GenericFormattedValue::Time(ClockTime::none())); + + let info = Structure::builder("sample.info") + .field("f3", &123i32) + .build(); + + Sample::new::( + Some(&buffer), + Some(&caps), + Some(&segment), + Some(info), + ) + }; + let sample_ser = ron::ser::to_string(&sample).unwrap(); + let sample_de: Sample = ron::de::from_str(sample_ser.as_str()).unwrap(); + let buffer_de = sample_de.get_buffer().unwrap(); + assert_eq!(buffer_de.get_pts(), 1.into()); + assert_eq!(buffer_de.get_offset_end(), 4); + { + let data = buffer_de.map_readable().unwrap(); + assert_eq!(data.as_slice(), vec![1, 2, 3, 4].as_slice()); + } + assert!(sample_de.get_buffer_list().is_none()); + assert!(sample_de.get_caps().is_some()); + assert!(sample_de.get_segment().is_some()); + assert!(sample_de.get_info().is_some()); + } } diff --git a/gstreamer/src/segment_serde.rs b/gstreamer/src/segment_serde.rs index 445b50c33..69acc3ed4 100644 --- a/gstreamer/src/segment_serde.rs +++ b/gstreamer/src/segment_serde.rs @@ -98,17 +98,15 @@ impl<'de> Deserialize<'de> for Segment { impl<'de, T: FormattedValue + SpecificFormattedValue> Deserialize<'de> for FormattedSegment { fn deserialize>(deserializer: D) -> Result { - Segment::deserialize(deserializer) - .and_then(|segment| { - segment.downcast::() - .map_err(|segment| { - de::Error::custom(format!( - "failed to convert segment with format {:?} to {:?}", - segment.get_format(), - T::get_default_format(), - )) - }) + Segment::deserialize(deserializer).and_then(|segment| { + segment.downcast::().map_err(|segment| { + de::Error::custom(format!( + "failed to convert segment with format {:?} to {:?}", + segment.get_format(), + T::get_default_format(), + )) }) + }) } } @@ -266,4 +264,36 @@ mod tests { assert_eq!(fmt_seg.get_position(), ClockTime::from_nseconds(256)); assert_eq!(fmt_seg.get_duration(), ClockTime::none()); } + + #[test] + fn test_serde_roundtrip() { + ::init().unwrap(); + + let mut segment = Segment::new(); + segment.set_flags(SegmentFlags::RESET | SegmentFlags::SEGMENT); + segment.set_rate(1f64); + segment.set_applied_rate(0.9f64); + segment.set_format(Format::Time); + segment.set_base(GenericFormattedValue::Time(ClockTime::from_nseconds(123))); + segment.set_offset(GenericFormattedValue::Time(ClockTime::from_nseconds(42))); + segment.set_start(GenericFormattedValue::Time(ClockTime::from_nseconds(1024))); + segment.set_stop(GenericFormattedValue::Time(ClockTime::from_nseconds(2048))); + segment.set_time(GenericFormattedValue::Time(ClockTime::from_nseconds(1042))); + segment.set_position(GenericFormattedValue::Time(ClockTime::from_nseconds(256))); + segment.set_duration(GenericFormattedValue::Time(ClockTime::none())); + let segment_se = ron::ser::to_string(&segment).unwrap(); + + let segment_de: Segment = ron::de::from_str(segment_se.as_str()).unwrap(); + assert_eq!(segment_de.get_flags(), segment.get_flags()); + assert_eq!(segment_de.get_rate(), segment.get_rate()); + assert_eq!(segment_de.get_applied_rate(), segment.get_applied_rate()); + assert_eq!(segment_de.get_format(), segment.get_format()); + assert_eq!(segment_de.get_base(), segment.get_base()); + assert_eq!(segment_de.get_offset(), segment.get_offset()); + assert_eq!(segment_de.get_start(), segment.get_start()); + assert_eq!(segment_de.get_stop(), segment.get_stop()); + assert_eq!(segment_de.get_time(), segment.get_time()); + assert_eq!(segment_de.get_position(), segment.get_position()); + assert_eq!(segment_de.get_duration(), segment.get_duration()); + } } diff --git a/gstreamer/src/structure_serde.rs b/gstreamer/src/structure_serde.rs index cae4e7e85..bde72ecfc 100644 --- a/gstreamer/src/structure_serde.rs +++ b/gstreamer/src/structure_serde.rs @@ -165,13 +165,12 @@ impl<'de> Deserialize<'de> for Structure { mod tests { extern crate ron; + use Array; + use Fraction; use Structure; #[test] fn test_serialize() { - use Array; - use Fraction; - ::init().unwrap(); let s = Structure::builder("test") @@ -205,9 +204,6 @@ mod tests { #[test] fn test_deserialize() { - use Array; - use Fraction; - ::init().unwrap(); let s_ron = r#" @@ -236,4 +232,20 @@ mod tests { ).as_ref() ); } + + #[test] + fn test_serde_roundtrip() { + ::init().unwrap(); + + let s = Structure::builder("test") + .field("f1", &"abc") + .field("f2", &String::from("bcd")) + .field("f3", &123i32) + .field("fraction", &Fraction::new(1, 2)) + .field("array", &Array::new(&[&1, &2])) + .build(); + let s_ser = ron::ser::to_string(&s).unwrap(); + let s_de: Structure = ron::de::from_str(s_ser.as_str()).unwrap(); + assert_eq!(s_de.as_ref(), s.as_ref()); + } } diff --git a/gstreamer/src/tags_serde.rs b/gstreamer/src/tags_serde.rs index 3477fab3c..b767affea 100644 --- a/gstreamer/src/tags_serde.rs +++ b/gstreamer/src/tags_serde.rs @@ -247,14 +247,13 @@ mod tests { extern crate ron; use tags::*; + use Buffer; + use GenericFormattedValue; + use Sample; + use TagMergeMode; #[test] fn test_serialize() { - use Buffer; - use GenericFormattedValue; - use Sample; - use TagMergeMode; - ::init().unwrap(); let mut tags = TagList::new(); @@ -452,4 +451,67 @@ mod tests { assert_eq!(data.as_slice(), vec![1, 2, 3, 4].as_slice()); } } + + #[test] + fn test_serde_roundtrip() { + ::init().unwrap(); + + let mut tags = TagList::new(); + assert_eq!(tags.to_string(), "taglist;"); + { + let tags = tags.get_mut().unwrap(); + tags.add::(&"a title", TagMergeMode::Append); // String + tags.add::<Title>(&"another title", TagMergeMode::Append); // String + tags.add::<Duration>(&(::SECOND * 120).into(), TagMergeMode::Append); // u64 + tags.add::<Bitrate>(&96_000, TagMergeMode::Append); // u32 + tags.add::<TrackGain>(&1f64, TagMergeMode::Append); // f64 + tags.add::<DateTime>( + &::DateTime::new(2f32, 2018, 5, 28, 16, 6, 42.841f64), + TagMergeMode::Append, + ); // DateTime + + let sample = { + let mut buffer = Buffer::from_slice(vec![1, 2, 3, 4]).unwrap(); + { + let buffer = buffer.get_mut().unwrap(); + buffer.set_offset(0); + buffer.set_offset_end(0); + } + Sample::new::<GenericFormattedValue>(Some(&buffer), None, None, None) + }; + tags.add::<Image>(&sample, TagMergeMode::Append); // Sample + } + let tags_ser = ron::ser::to_string(&tags).unwrap(); + + let tags_de: TagList = ron::de::from_str(tags_ser.as_str()).unwrap(); + assert_eq!( + tags_de.get_index::<Title>(0).unwrap().get(), + tags.get_index::<Title>(0).unwrap().get(), + ); + assert_eq!( + tags_de.get_index::<Title>(1).unwrap().get(), + tags.get_index::<Title>(1).unwrap().get(), + ); + assert_eq!( + tags_de.get_index::<Duration>(0).unwrap().get(), + tags.get_index::<Duration>(0).unwrap().get(), + ); + assert_eq!( + tags_de.get_index::<Bitrate>(0).unwrap().get(), + tags.get_index::<Bitrate>(0).unwrap().get(), + ); + assert_eq!( + tags_de.get_index::<TrackGain>(0).unwrap().get(), + tags.get_index::<TrackGain>(0).unwrap().get(), + ); + let datetime = tags.get_index::<DateTime>(0).unwrap().get().unwrap(); + assert_eq!(datetime.get_year(), 2018); + assert_eq!(datetime.get_microsecond(), 841_000); + let sample = tags.get_index::<Image>(0).unwrap().get().unwrap(); + let buffer = sample.get_buffer().unwrap(); + { + let data = buffer.map_readable().unwrap(); + assert_eq!(data.as_slice(), vec![1, 2, 3, 4].as_slice()); + } + } } diff --git a/gstreamer/src/toc_serde.rs b/gstreamer/src/toc_serde.rs index e0f122da1..f0597929a 100644 --- a/gstreamer/src/toc_serde.rs +++ b/gstreamer/src/toc_serde.rs @@ -125,16 +125,15 @@ impl<'de> Deserialize<'de> for TocEntry { mod tests { extern crate ron; + use tags::Title; use toc::*; + use TagList; + use TagMergeMode; use TocEntryType; use TocScope; #[test] fn test_serialize() { - use tags::Title; - use TagList; - use TagMergeMode; - ::init().unwrap(); let mut toc = Toc::new(TocScope::Global); @@ -395,4 +394,164 @@ mod tests { assert_eq!(Some((10, 15)), chapter2.get_start_stop_times()); assert_eq!(0, chapter2.get_sub_entries().len()); } + + #[test] + fn test_serde_roundtrip() { + ::init().unwrap(); + + let mut toc = Toc::new(TocScope::Global); + { + let toc = toc.get_mut().unwrap(); + let mut tags = TagList::new(); + tags.get_mut() + .unwrap() + .add::<Title>(&"toc", TagMergeMode::Append); + toc.set_tags(tags); + + let mut toc_edition = TocEntry::new(TocEntryType::Edition, "edition"); + { + let toc_edition = toc_edition.get_mut().unwrap(); + toc_edition.set_start_stop_times(0, 15); + + let mut toc_chap_1 = TocEntry::new(TocEntryType::Chapter, "chapter1"); + { + let toc_chap_1 = toc_chap_1.get_mut().unwrap(); + toc_chap_1.set_start_stop_times(0, 10); + let mut toc_chap_1_1 = TocEntry::new(TocEntryType::Chapter, "chapter1.1"); + { + let toc_chap_1_1 = toc_chap_1_1.get_mut().unwrap(); + toc_chap_1_1.set_start_stop_times(0, 4); + let mut tags = TagList::new(); + tags.get_mut() + .unwrap() + .add::<Title>(&"chapter 1.1", TagMergeMode::Append); + toc_chap_1_1.set_tags(tags); + } + toc_chap_1.append_sub_entry(toc_chap_1_1); + + let mut toc_chap_1_2 = TocEntry::new(TocEntryType::Chapter, "chapter1.2"); + { + let toc_chap_1_2 = toc_chap_1_2.get_mut().unwrap(); + toc_chap_1_2.set_start_stop_times(4, 10); + let mut tags = TagList::new(); + tags.get_mut() + .unwrap() + .add::<Title>(&"chapter 1.2", TagMergeMode::Append); + toc_chap_1_2.set_tags(tags); + } + toc_chap_1.append_sub_entry(toc_chap_1_2); + } + toc_edition.append_sub_entry(toc_chap_1); + + let mut toc_chap_2 = TocEntry::new(TocEntryType::Chapter, "chapter2"); + { + let toc_chap_2 = toc_chap_2.get_mut().unwrap(); + toc_chap_2.set_start_stop_times(10, 15); + let mut tags = TagList::new(); + tags.get_mut() + .unwrap() + .add::<Title>(&"chapter 2", TagMergeMode::Append); + toc_chap_2.set_tags(tags); + } + toc_edition.append_sub_entry(toc_chap_2); + } + toc.append_entry(toc_edition); + } + let toc_ser = ron::ser::to_string(&toc).unwrap(); + + let toc_de: Toc = ron::de::from_str(toc_ser.as_str()).unwrap(); + assert_eq!(toc_de.get_scope(), toc.get_scope()); + + let entries_de = toc_de.get_entries(); + let entries = toc.get_entries(); + assert_eq!(entries_de.len(), entries.len()); + + let edition_de = &entries_de[0]; + let edition = &entries[0]; + assert_eq!(edition_de.get_entry_type(), edition.get_entry_type()); + assert_eq!(edition_de.get_uid(), edition.get_uid()); + assert_eq!(edition_de.get_tags(), edition.get_tags()); + assert_eq!( + edition_de.get_start_stop_times(), + edition.get_start_stop_times() + ); + + let sub_entries_de = edition_de.get_sub_entries(); + let sub_entries = edition.get_sub_entries(); + assert_eq!(sub_entries_de.len(), sub_entries.len()); + + let chapter1_de = &sub_entries_de[0]; + let chapter1 = &sub_entries[0]; + assert_eq!(chapter1_de.get_entry_type(), chapter1.get_entry_type()); + assert_eq!(chapter1_de.get_uid(), chapter1.get_uid()); + assert_eq!( + chapter1_de.get_tags().is_none(), + chapter1.get_tags().is_none() + ); + assert_eq!( + chapter1_de.get_start_stop_times(), + chapter1.get_start_stop_times() + ); + + let chap1_sub_entries_de = chapter1_de.get_sub_entries(); + let chap1_sub_entries = chapter1.get_sub_entries(); + assert_eq!(sub_entries_de.len(), sub_entries.len()); + + let chapter1_1_de = &chap1_sub_entries_de[0]; + let chapter1_1 = &chap1_sub_entries[0]; + assert_eq!(chapter1_1_de.get_entry_type(), chapter1_1.get_entry_type()); + assert_eq!(chapter1_1_de.get_uid(), chapter1_1.get_uid()); + assert_eq!( + chapter1_1_de.get_start_stop_times(), + chapter1_1.get_start_stop_times() + ); + let tags_de = chapter1_1_de.get_tags().unwrap(); + let tags = chapter1_1.get_tags().unwrap(); + assert_eq!( + tags_de.get_index::<Title>(0).unwrap().get(), + tags.get_index::<Title>(0).unwrap().get() + ); + assert_eq!( + chapter1_1_de.get_sub_entries().len(), + chapter1_1.get_sub_entries().len() + ); + + let chapter1_2_de = &chap1_sub_entries_de[1]; + let chapter1_2 = &chap1_sub_entries[1]; + assert_eq!(chapter1_2_de.get_entry_type(), chapter1_2.get_entry_type()); + assert_eq!(chapter1_2_de.get_uid(), chapter1_2.get_uid()); + assert_eq!( + chapter1_2_de.get_start_stop_times(), + chapter1_2.get_start_stop_times() + ); + let tags_de = chapter1_2_de.get_tags().unwrap(); + let tags = chapter1_2.get_tags().unwrap(); + assert_eq!( + tags_de.get_index::<Title>(0).unwrap().get(), + tags.get_index::<Title>(0).unwrap().get() + ); + assert_eq!( + chapter1_2_de.get_sub_entries().len(), + chapter1_2.get_sub_entries().len() + ); + + let chapter2_de = &sub_entries_de[1]; + let chapter2 = &sub_entries[1]; + assert_eq!(chapter2_de.get_entry_type(), chapter2.get_entry_type()); + assert_eq!(chapter2_de.get_uid(), chapter2.get_uid()); + let tags_de = chapter2_de.get_tags().unwrap(); + let tags = chapter2.get_tags().unwrap(); + assert_eq!( + tags_de.get_index::<Title>(0).unwrap().get(), + tags.get_index::<Title>(0).unwrap().get() + ); + assert_eq!( + chapter2_de.get_start_stop_times(), + chapter2.get_start_stop_times() + ); + assert_eq!( + chapter2_de.get_sub_entries().len(), + chapter2.get_sub_entries().len() + ); + } } diff --git a/gstreamer/src/value_serde.rs b/gstreamer/src/value_serde.rs index 2bbfff272..25b90b9c0 100644 --- a/gstreamer/src/value_serde.rs +++ b/gstreamer/src/value_serde.rs @@ -269,13 +269,15 @@ mod tests { extern crate ron; extern crate serde_json; + use Array; + use Bitmask; + use Fraction; + use FractionRange; + use IntRange; + use List; + #[test] fn test_serialize_simple() { - use Bitmask; - use Fraction; - use FractionRange; - use IntRange; - ::init().unwrap(); let mut pretty_config = ron::ser::PrettyConfig::default(); @@ -321,7 +323,6 @@ mod tests { fn test_serialize_collections() { use glib::value::ToValue; - use Array; use Fraction; use List; @@ -384,14 +385,6 @@ mod tests { #[cfg(feature = "ser_de")] #[test] fn test_deserialize_simple() { - extern crate ron; - extern crate serde_json; - - use Bitmask; - use Fraction; - use FractionRange; - use IntRange; - ::init().unwrap(); // Fraction @@ -441,16 +434,50 @@ mod tests { assert_eq!(bitmask_ref, bitmask); } + #[cfg(feature = "ser_de")] + #[test] + fn test_serde_roundtrip_simple() { + ::init().unwrap(); + + // Fraction + let fraction = Fraction::new(1, 3); + let fraction_ser = ron::ser::to_string(&fraction).unwrap(); + let fraction_de: Fraction = ron::de::from_str(fraction_ser.as_str()).unwrap(); + assert_eq!(fraction_de.0.numer(), fraction.0.numer()); + assert_eq!(fraction_de.0.denom(), fraction.0.denom()); + + // FractionRange + let fraction_range = FractionRange::new(Fraction::new(1, 3), Fraction::new(1, 2)); + let fraction_range_ser = ron::ser::to_string(&fraction_range).unwrap(); + let fraction_range_de: FractionRange = + ron::de::from_str(fraction_range_ser.as_str()).unwrap(); + assert_eq!( + fraction_range_de.min().0.denom(), + fraction_range.min().0.denom() + ); + assert_eq!( + fraction_range_de.max().0.denom(), + fraction_range.max().0.denom() + ); + + // IntRange + let int_range = IntRange::<i32>::new_with_step(0, 42, 21); + let int_range_ser = ron::ser::to_string(&int_range).unwrap(); + let int_range_de: IntRange<i32> = ron::de::from_str(int_range_ser.as_str()).unwrap(); + assert_eq!(int_range_de.min(), int_range.min()); + assert_eq!(int_range_de.max(), int_range.max()); + assert_eq!(int_range_de.step(), int_range.step()); + + // Bitmask + let bitmask = Bitmask::new(1024 + 128 + 32); + let bitmask_ser = ron::ser::to_string(&bitmask).unwrap(); + let bitmask_de: Bitmask = ron::de::from_str(bitmask_ser.as_str()).unwrap(); + assert_eq!(bitmask_de, bitmask); + } + #[cfg(feature = "ser_de")] #[test] fn test_deserialize_collections() { - extern crate ron; - extern crate serde_json; - - use Array; - use Fraction; - use List; - ::init().unwrap(); // Array @@ -503,4 +530,65 @@ mod tests { assert_eq!("test str".to_owned(), slice[1].get::<String>().unwrap()); } + + #[cfg(feature = "ser_de")] + #[test] + fn test_serde_roundtrip_collection() { + use glib::value::ToValue; + + ::init().unwrap(); + + // Array + let value_13 = Fraction::new(1, 3).to_value(); + let send_value_13 = value_13.try_into_send_value::<Fraction>().unwrap(); + let value_12 = Fraction::new(1, 2).to_value(); + let send_value_12 = value_12.try_into_send_value::<Fraction>().unwrap(); + let value_str = "test str".to_value(); + let send_value_str = value_str.try_into_send_value::<String>().unwrap(); + let array = Array::new(&[&send_value_13, &send_value_12, &send_value_str]); + let array_ser = ron::ser::to_string(&array).unwrap(); + + let array_de: Array = ron::de::from_str(array_ser.as_str()).unwrap(); + let slice_de = array_de.as_slice(); + let slice = array.as_slice(); + assert_eq!(slice_de.len(), slice.len()); + + let fraction_de = slice_de[0].get::<Fraction>().unwrap(); + let fraction = slice[0].get::<Fraction>().unwrap(); + assert_eq!(fraction_de.0.numer(), fraction.0.numer()); + assert_eq!(fraction_de.0.denom(), fraction.0.denom()); + + let fraction_de = slice_de[1].get::<Fraction>().unwrap(); + let fraction = slice[1].get::<Fraction>().unwrap(); + assert_eq!(fraction_de.0.numer(), fraction.0.numer()); + assert_eq!(fraction.0.denom(), fraction.0.denom()); + + assert_eq!( + slice_de[2].get::<String>().unwrap(), + slice[2].get::<String>().unwrap() + ); + + // List + let value_12 = Fraction::new(1, 2).to_value(); + let send_value_12 = value_12.try_into_send_value::<Fraction>().unwrap(); + let value_str = "test str".to_value(); + let send_value_str = value_str.try_into_send_value::<String>().unwrap(); + let list = List::new(&[&send_value_12, &send_value_str]); + let list_ser = ron::ser::to_string(&list).unwrap(); + + let list_de: List = ron::de::from_str(list_ser.as_str()).unwrap(); + let slice_de = list_de.as_slice(); + let slice = list.as_slice(); + assert_eq!(slice_de.len(), slice.len()); + + let fraction_de = slice_de[0].get::<Fraction>().unwrap(); + let fraction = slice[0].get::<Fraction>().unwrap(); + assert_eq!(fraction_de.0.numer(), fraction.0.numer()); + assert_eq!(fraction_de.0.denom(), fraction.0.denom()); + + assert_eq!( + slice_de[1].get::<String>().unwrap(), + slice[1].get::<String>().unwrap() + ); + } }