diff --git a/eyeball-im/src/vector.rs b/eyeball-im/src/vector.rs index aa36809..86490a2 100644 --- a/eyeball-im/src/vector.rs +++ b/eyeball-im/src/vector.rs @@ -80,11 +80,19 @@ impl ObservableVector { /// Clear out all of the elements in this `Vector` and notify subscribers. pub fn clear(&mut self) { - #[cfg(feature = "tracing")] - tracing::debug!(target: "eyeball_im::vector::update", "clear"); + let already_empty = self.values.is_empty(); - self.values.clear(); - self.broadcast_diff(VectorDiff::Clear); + #[cfg(feature = "tracing")] + tracing::debug!( + target: "eyeball_im::vector::update", + nop = already_empty.then_some(true), + "clear" + ); + + if !already_empty { + self.values.clear(); + self.broadcast_diff(VectorDiff::Clear); + } } /// Add an element at the front of the list and notify subscribers. diff --git a/eyeball-im/tests/it/main.rs b/eyeball-im/tests/it/main.rs index 96ce620..5c60888 100644 --- a/eyeball-im/tests/it/main.rs +++ b/eyeball-im/tests/it/main.rs @@ -1,5 +1,5 @@ use imbl::{vector, Vector}; -use stream_assert::{assert_next_eq, assert_pending}; +use stream_assert::{assert_closed, assert_next_eq, assert_pending}; use eyeball_im::{ObservableVector, ObservableVectorEntry, VectorDiff}; @@ -58,6 +58,25 @@ fn truncate() { assert!(ob.is_empty()); } +#[test] +fn clear() { + let mut ob: ObservableVector = ObservableVector::from(vector![1, 2]); + let mut sub = ob.subscribe().into_stream(); + assert_pending!(sub); + + ob.clear(); + assert_next_eq!(sub, VectorDiff::Clear); + assert!(ob.is_empty()); + + // Clearing again. The vector is empty now. We don't expect a + // `VectorDiff::Clear`. + ob.clear(); + assert_pending!(sub); + + drop(ob); + assert_closed!(sub); +} + #[test] fn for_each() { let mut ob: ObservableVector = ObservableVector::from(vector![0, 10, 1, 2, 4, 33, 5]);