From cb20192c8349afa86a38cfbcddef9213051a4ee2 Mon Sep 17 00:00:00 2001 From: Ivan Enderlin Date: Wed, 13 Sep 2023 21:29:03 +0200 Subject: [PATCH] !fixup --- eyeball-im-util/src/vector/limit.rs | 17 ++- eyeball-im-util/tests/it/limit.rs | 175 ++++++++++++++++++++++++++++ 2 files changed, 188 insertions(+), 4 deletions(-) diff --git a/eyeball-im-util/src/vector/limit.rs b/eyeball-im-util/src/vector/limit.rs index 34fc074..3476746 100644 --- a/eyeball-im-util/src/vector/limit.rs +++ b/eyeball-im-util/src/vector/limit.rs @@ -65,8 +65,8 @@ where impl Stream for DynamicLimit where S: Stream, - S::Item: VectorDiffContainer + std::fmt::Debug, - VectorDiffContainerStreamElement: Clone + Send + Sync + 'static + std::fmt::Debug, + S::Item: VectorDiffContainer, + VectorDiffContainerStreamElement: Clone + Send + Sync + 'static, VectorDiffContainerStreamFamily: VectorDiffContainerFamily> = S::Item>, L: Stream, @@ -82,8 +82,8 @@ where impl DynamicLimitProj<'_, S, L> where S: Stream, - S::Item: VectorDiffContainer + std::fmt::Debug, - VectorDiffContainerStreamElement: Clone + Send + Sync + 'static + std::fmt::Debug, + S::Item: VectorDiffContainer, + VectorDiffContainerStreamElement: Clone + Send + Sync + 'static, VectorDiffContainerStreamFamily: VectorDiffContainerFamily> = S::Item>, L: Stream, @@ -173,6 +173,15 @@ where } VectorDiff::PopFront => { self.push_ready_value(VectorDiff::PopFront); + + if length > limit { + // Push back a new item. + self.push_ready_value(VectorDiff::PushBack { + // SAFETY: It's safe to `unwrap` here as we are sure a value exists at index + // `limit - 1`. We are also sure that `limit > 1`. + value: self.buffered_vector.get(limit - 1).unwrap().clone(), + }) + } } VectorDiff::PopBack => { if is_full { diff --git a/eyeball-im-util/tests/it/limit.rs b/eyeball-im-util/tests/it/limit.rs index 3956281..e7a26b6 100644 --- a/eyeball-im-util/tests/it/limit.rs +++ b/eyeball-im-util/tests/it/limit.rs @@ -215,6 +215,18 @@ fn append() { // Observe nothing. assert_pending!(sub); + // Check the content of the vector. + { + let expected = vector![10, 11, 12, 13, 14, 15, 16, 17, 18, 19]; + assert_eq!(*ob, expected); + + Observable::set(&mut limit, 0); + assert_next_eq!(sub, VectorDiff::Truncate { length: 0 }); + + Observable::set(&mut limit, 42); + assert_next_eq!(sub, VectorDiff::Append { values: expected }); + } + drop(ob); assert_closed!(sub); } @@ -239,6 +251,169 @@ fn clear() { assert_next_eq!(sub, VectorDiff::PushBack { value: 10 }); assert_next_eq!(sub, VectorDiff::Clear); + // Check the content of the vector. + { + let expected = vector![]; + assert_eq!(*ob, expected); + } + + drop(ob); + assert_closed!(sub); +} + +#[test] +fn push_front() { + let mut ob = ObservableVector::::new(); + let mut limit = Observable::new(0); + let mut sub = + DynamicLimit::new(ob.clone(), ob.subscribe().into_stream(), Observable::subscribe(&limit)); + + // Set limit to 2. + Observable::set(&mut limit, 2); + + // Add 1 value. + ob.push_front(10); + + // Observe 1 value. + assert_next_eq!(sub, VectorDiff::PushFront { value: 10 }); + + // Add 1 value. + ob.push_front(11); + + // Observe 1 value. + assert_next_eq!(sub, VectorDiff::PushFront { value: 11 }); + + // Add 1 value. + ob.push_front(12); + + // Observe 1 value being removed, and 1 new value. + assert_next_eq!(sub, VectorDiff::PopBack); + assert_next_eq!(sub, VectorDiff::PushFront { value: 12 }); + assert_pending!(sub); + + // Add 1 value. + ob.push_front(13); + + // Observe 1 value being removed, and 1 new value. + assert_next_eq!(sub, VectorDiff::PopBack); + assert_next_eq!(sub, VectorDiff::PushFront { value: 13 }); + assert_pending!(sub); + + // Check the content of the vector. + { + let expected = vector![13, 12, 11, 10]; + assert_eq!(*ob, expected); + + Observable::set(&mut limit, 0); + assert_next_eq!(sub, VectorDiff::Truncate { length: 0 }); + + Observable::set(&mut limit, 42); + assert_next_eq!(sub, VectorDiff::Append { values: expected }); + } + + drop(ob); + assert_closed!(sub); +} + +#[test] +fn push_back() { + let mut ob = ObservableVector::::new(); + let mut limit = Observable::new(0); + let mut sub = + DynamicLimit::new(ob.clone(), ob.subscribe().into_stream(), Observable::subscribe(&limit)); + + // Set limit to 2. + Observable::set(&mut limit, 2); + + // Add 1 value. + ob.push_back(10); + + // Observe 1 value. + assert_next_eq!(sub, VectorDiff::PushBack { value: 10 }); + + // Add 1 value. + ob.push_back(11); + + // Observe 1 value. + assert_next_eq!(sub, VectorDiff::PushBack { value: 11 }); + + // Add 1 value. + ob.push_back(12); + + // Observe nothing. + assert_pending!(sub); + + // Add 1 value. + ob.push_back(13); + + // Observe nothing. + assert_pending!(sub); + + // Check the content of the vector. + { + let expected = vector![10, 11, 12, 13]; + assert_eq!(*ob, expected); + + Observable::set(&mut limit, 0); + assert_next_eq!(sub, VectorDiff::Truncate { length: 0 }); + + Observable::set(&mut limit, 42); + assert_next_eq!(sub, VectorDiff::Append { values: expected }); + } + + drop(ob); + assert_closed!(sub); +} + +#[test] +fn pop_front() { + let mut ob = ObservableVector::::new(); + let mut limit = Observable::new(0); + let mut sub = + DynamicLimit::new(ob.clone(), ob.subscribe().into_stream(), Observable::subscribe(&limit)); + + // Add 4 values. + ob.append(vector![10, 11, 12, 13]); + + // Set limit to 2. + Observable::set(&mut limit, 2); + + // Observe 2 values. + assert_next_eq!(sub, VectorDiff::Append { values: vector![10, 11] }); + + // Remove 1 value. + ob.pop_front(); + + // Observe 1 value being removed, and 1 new value being inserted at the back. + assert_next_eq!(sub, VectorDiff::PopFront); + assert_next_eq!(sub, VectorDiff::PushBack { value: 12 }); + + // Remove 1 value. + ob.pop_front(); + + // Observe 1 value being removed, and 1 new value being inserted at the back. + assert_next_eq!(sub, VectorDiff::PopFront); + assert_next_eq!(sub, VectorDiff::PushBack { value: 13 }); + + // Remove 1 value. + ob.pop_front(); + + // Observe only 1 value being removed. + assert_next_eq!(sub, VectorDiff::PopFront); + assert_pending!(sub); + + // Check the content of the vector. + { + let expected = vector![13]; + assert_eq!(*ob, expected); + + Observable::set(&mut limit, 0); + assert_next_eq!(sub, VectorDiff::Truncate { length: 0 }); + + Observable::set(&mut limit, 42); + assert_next_eq!(sub, VectorDiff::Append { values: expected }); + } + drop(ob); assert_closed!(sub); }