test.rs

  1use crate::{language::LanguageRegistry, settings, time::ReplicaId, AppState};
  2use ctor::ctor;
  3use gpui::AppContext;
  4use rand::Rng;
  5use std::{
  6    collections::BTreeMap,
  7    path::{Path, PathBuf},
  8    sync::Arc,
  9};
 10use tempdir::TempDir;
 11
 12#[ctor]
 13fn init_logger() {
 14    env_logger::init();
 15}
 16
 17#[derive(Clone)]
 18struct Envelope<T: Clone> {
 19    message: T,
 20    sender: ReplicaId,
 21}
 22
 23pub(crate) struct Network<T: Clone> {
 24    inboxes: BTreeMap<ReplicaId, Vec<Envelope<T>>>,
 25    all_messages: Vec<T>,
 26}
 27
 28impl<T: Clone> Network<T> {
 29    pub fn new() -> Self {
 30        Network {
 31            inboxes: BTreeMap::new(),
 32            all_messages: Vec::new(),
 33        }
 34    }
 35
 36    pub fn add_peer(&mut self, id: ReplicaId) {
 37        self.inboxes.insert(id, Vec::new());
 38    }
 39
 40    pub fn is_idle(&self) -> bool {
 41        self.inboxes.values().all(|i| i.is_empty())
 42    }
 43
 44    pub fn broadcast<R>(&mut self, sender: ReplicaId, messages: Vec<T>, rng: &mut R)
 45    where
 46        R: Rng,
 47    {
 48        for (replica, inbox) in self.inboxes.iter_mut() {
 49            if *replica != sender {
 50                for message in &messages {
 51                    let min_index = inbox
 52                        .iter()
 53                        .enumerate()
 54                        .rev()
 55                        .find_map(|(index, envelope)| {
 56                            if sender == envelope.sender {
 57                                Some(index + 1)
 58                            } else {
 59                                None
 60                            }
 61                        })
 62                        .unwrap_or(0);
 63
 64                    // Insert one or more duplicates of this message *after* the previous
 65                    // message delivered by this replica.
 66                    for _ in 0..rng.gen_range(1..4) {
 67                        let insertion_index = rng.gen_range(min_index..inbox.len() + 1);
 68                        inbox.insert(
 69                            insertion_index,
 70                            Envelope {
 71                                message: message.clone(),
 72                                sender,
 73                            },
 74                        );
 75                    }
 76                }
 77            }
 78        }
 79        self.all_messages.extend(messages);
 80    }
 81
 82    pub fn has_unreceived(&self, receiver: ReplicaId) -> bool {
 83        !self.inboxes[&receiver].is_empty()
 84    }
 85
 86    pub fn receive<R>(&mut self, receiver: ReplicaId, rng: &mut R) -> Vec<T>
 87    where
 88        R: Rng,
 89    {
 90        let inbox = self.inboxes.get_mut(&receiver).unwrap();
 91        let count = rng.gen_range(0..inbox.len() + 1);
 92        inbox
 93            .drain(0..count)
 94            .map(|envelope| envelope.message)
 95            .collect()
 96    }
 97}
 98
 99pub fn sample_text(rows: usize, cols: usize) -> String {
100    let mut text = String::new();
101    for row in 0..rows {
102        let c: char = ('a' as u32 + row as u32) as u8 as char;
103        let mut line = c.to_string().repeat(cols);
104        if row < rows - 1 {
105            line.push('\n');
106        }
107        text += &line;
108    }
109    text
110}
111
112pub fn temp_tree(tree: serde_json::Value) -> TempDir {
113    let dir = TempDir::new("").unwrap();
114    write_tree(dir.path(), tree);
115    dir
116}
117
118fn write_tree(path: &Path, tree: serde_json::Value) {
119    use serde_json::Value;
120    use std::fs;
121
122    if let Value::Object(map) = tree {
123        for (name, contents) in map {
124            let mut path = PathBuf::from(path);
125            path.push(name);
126            match contents {
127                Value::Object(_) => {
128                    fs::create_dir(&path).unwrap();
129                    write_tree(&path, contents);
130                }
131                Value::Null => {
132                    fs::create_dir(&path).unwrap();
133                }
134                Value::String(contents) => {
135                    fs::write(&path, contents).unwrap();
136                }
137                _ => {
138                    panic!("JSON object must contain only objects, strings, or null");
139                }
140            }
141        }
142    } else {
143        panic!("You must pass a JSON object to this helper")
144    }
145}
146
147pub fn build_app_state(cx: &AppContext) -> AppState {
148    let settings = settings::channel(&cx.font_cache()).unwrap().1;
149    let language_registry = Arc::new(LanguageRegistry::new());
150    AppState {
151        settings,
152        language_registry,
153        rpc: zed_rpc::Peer::new(),
154    }
155}