Move Network test helper from util crate into text crate

Max Brunsfeld and Nathan Sobo created

This way, `util` does not depend on `clock`.

Co-Authored-By: Nathan Sobo <nathan@zed.dev>

Change summary

crates/language/src/tests.rs |  3 +
crates/text/src/network.rs   | 69 ++++++++++++++++++++++++++++++++++++++
crates/text/src/tests.rs     |  3 -
crates/text/src/text.rs      |  2 +
crates/util/Cargo.toml       |  3 -
crates/util/src/test.rs      | 69 --------------------------------------
6 files changed, 75 insertions(+), 74 deletions(-)

Detailed changes

crates/language/src/tests.rs 🔗

@@ -11,8 +11,9 @@ use std::{
     rc::Rc,
     time::{Duration, Instant},
 };
+use text::network::Network;
 use unindent::Unindent as _;
-use util::{post_inc, test::Network};
+use util::post_inc;
 
 #[cfg(test)]
 #[ctor::ctor]

crates/text/src/network.rs 🔗

@@ -0,0 +1,69 @@
+use clock::ReplicaId;
+
+pub struct Network<T: Clone, R: rand::Rng> {
+    inboxes: std::collections::BTreeMap<ReplicaId, Vec<Envelope<T>>>,
+    all_messages: Vec<T>,
+    rng: R,
+}
+
+#[derive(Clone)]
+struct Envelope<T: Clone> {
+    message: T,
+}
+
+impl<T: Clone, R: rand::Rng> Network<T, R> {
+    pub fn new(rng: R) -> Self {
+        Network {
+            inboxes: Default::default(),
+            all_messages: Vec::new(),
+            rng,
+        }
+    }
+
+    pub fn add_peer(&mut self, id: ReplicaId) {
+        self.inboxes.insert(id, Vec::new());
+    }
+
+    pub fn replicate(&mut self, old_replica_id: ReplicaId, new_replica_id: ReplicaId) {
+        self.inboxes
+            .insert(new_replica_id, self.inboxes[&old_replica_id].clone());
+    }
+
+    pub fn is_idle(&self) -> bool {
+        self.inboxes.values().all(|i| i.is_empty())
+    }
+
+    pub fn broadcast(&mut self, sender: ReplicaId, messages: Vec<T>) {
+        for (replica, inbox) in self.inboxes.iter_mut() {
+            if *replica != sender {
+                for message in &messages {
+                    // Insert one or more duplicates of this message, potentially *before* the previous
+                    // message sent by this peer to simulate out-of-order delivery.
+                    for _ in 0..self.rng.gen_range(1..4) {
+                        let insertion_index = self.rng.gen_range(0..inbox.len() + 1);
+                        inbox.insert(
+                            insertion_index,
+                            Envelope {
+                                message: message.clone(),
+                            },
+                        );
+                    }
+                }
+            }
+        }
+        self.all_messages.extend(messages);
+    }
+
+    pub fn has_unreceived(&self, receiver: ReplicaId) -> bool {
+        !self.inboxes[&receiver].is_empty()
+    }
+
+    pub fn receive(&mut self, receiver: ReplicaId) -> Vec<T> {
+        let inbox = self.inboxes.get_mut(&receiver).unwrap();
+        let count = self.rng.gen_range(0..inbox.len() + 1);
+        inbox
+            .drain(0..count)
+            .map(|envelope| envelope.message)
+            .collect()
+    }
+}

crates/text/src/tests.rs 🔗

@@ -1,4 +1,4 @@
-use super::*;
+use super::{network::Network, *};
 use clock::ReplicaId;
 use rand::prelude::*;
 use std::{
@@ -7,7 +7,6 @@ use std::{
     iter::Iterator,
     time::{Duration, Instant},
 };
-use util::test::Network;
 
 #[cfg(test)]
 #[ctor::ctor]

crates/text/src/text.rs 🔗

@@ -1,5 +1,7 @@
 mod anchor;
 pub mod locator;
+#[cfg(any(test, feature = "test-support"))]
+pub mod network;
 pub mod operation_queue;
 mod patch;
 mod point;

crates/util/Cargo.toml 🔗

@@ -7,10 +7,9 @@ edition = "2021"
 doctest = false
 
 [features]
-test-support = ["clock", "rand", "serde_json", "tempdir"]
+test-support = ["rand", "serde_json", "tempdir"]
 
 [dependencies]
-clock = { path = "../clock", optional = true }
 anyhow = "1.0.38"
 futures = "0.3"
 log = "0.4"

crates/util/src/test.rs 🔗

@@ -1,75 +1,6 @@
-use clock::ReplicaId;
 use std::path::{Path, PathBuf};
 use tempdir::TempDir;
 
-#[derive(Clone)]
-struct Envelope<T: Clone> {
-    message: T,
-}
-
-pub struct Network<T: Clone, R: rand::Rng> {
-    inboxes: std::collections::BTreeMap<ReplicaId, Vec<Envelope<T>>>,
-    all_messages: Vec<T>,
-    rng: R,
-}
-
-impl<T: Clone, R: rand::Rng> Network<T, R> {
-    pub fn new(rng: R) -> Self {
-        Network {
-            inboxes: Default::default(),
-            all_messages: Vec::new(),
-            rng,
-        }
-    }
-
-    pub fn add_peer(&mut self, id: ReplicaId) {
-        self.inboxes.insert(id, Vec::new());
-    }
-
-    pub fn replicate(&mut self, old_replica_id: ReplicaId, new_replica_id: ReplicaId) {
-        self.inboxes
-            .insert(new_replica_id, self.inboxes[&old_replica_id].clone());
-    }
-
-    pub fn is_idle(&self) -> bool {
-        self.inboxes.values().all(|i| i.is_empty())
-    }
-
-    pub fn broadcast(&mut self, sender: ReplicaId, messages: Vec<T>) {
-        for (replica, inbox) in self.inboxes.iter_mut() {
-            if *replica != sender {
-                for message in &messages {
-                    // Insert one or more duplicates of this message, potentially *before* the previous
-                    // message sent by this peer to simulate out-of-order delivery.
-                    for _ in 0..self.rng.gen_range(1..4) {
-                        let insertion_index = self.rng.gen_range(0..inbox.len() + 1);
-                        inbox.insert(
-                            insertion_index,
-                            Envelope {
-                                message: message.clone(),
-                            },
-                        );
-                    }
-                }
-            }
-        }
-        self.all_messages.extend(messages);
-    }
-
-    pub fn has_unreceived(&self, receiver: ReplicaId) -> bool {
-        !self.inboxes[&receiver].is_empty()
-    }
-
-    pub fn receive(&mut self, receiver: ReplicaId) -> Vec<T> {
-        let inbox = self.inboxes.get_mut(&receiver).unwrap();
-        let count = self.rng.gen_range(0..inbox.len() + 1);
-        inbox
-            .drain(0..count)
-            .map(|envelope| envelope.message)
-            .collect()
-    }
-}
-
 pub fn temp_tree(tree: serde_json::Value) -> TempDir {
     let dir = TempDir::new("").unwrap();
     write_tree(dir.path(), tree);