test.rs

  1use crate::{
  2    assets::Assets,
  3    channel::ChannelList,
  4    http::{HttpClient, Request, Response, ServerResponse},
  5    language,
  6    settings::{self, ThemeRegistry},
  7    user::UserStore,
  8    AppState,
  9};
 10use anyhow::Result;
 11use buffer::LanguageRegistry;
 12use futures::{future::BoxFuture, Future};
 13use gpui::{Entity, ModelHandle, MutableAppContext};
 14use parking_lot::Mutex;
 15use rpc_client as rpc;
 16use smol::channel;
 17use std::{fmt, marker::PhantomData, sync::Arc};
 18use worktree::fs::FakeFs;
 19
 20#[cfg(test)]
 21#[ctor::ctor]
 22fn init_logger() {
 23    env_logger::init();
 24}
 25
 26pub fn sample_text(rows: usize, cols: usize) -> String {
 27    let mut text = String::new();
 28    for row in 0..rows {
 29        let c: char = ('a' as u32 + row as u32) as u8 as char;
 30        let mut line = c.to_string().repeat(cols);
 31        if row < rows - 1 {
 32            line.push('\n');
 33        }
 34        text += &line;
 35    }
 36    text
 37}
 38
 39pub fn test_app_state(cx: &mut MutableAppContext) -> Arc<AppState> {
 40    let (settings_tx, settings) = settings::test(cx);
 41    let mut languages = LanguageRegistry::new();
 42    languages.add(Arc::new(language::rust()));
 43    let themes = ThemeRegistry::new(Assets, cx.font_cache().clone());
 44    let rpc = rpc::Client::new();
 45    let http = FakeHttpClient::new(|_| async move { Ok(ServerResponse::new(404)) });
 46    let user_store = cx.add_model(|cx| UserStore::new(rpc.clone(), http, cx));
 47    Arc::new(AppState {
 48        settings_tx: Arc::new(Mutex::new(settings_tx)),
 49        settings,
 50        themes,
 51        languages: Arc::new(languages),
 52        channel_list: cx.add_model(|cx| ChannelList::new(user_store.clone(), rpc.clone(), cx)),
 53        rpc,
 54        user_store,
 55        fs: Arc::new(FakeFs::new()),
 56    })
 57}
 58
 59pub struct Observer<T>(PhantomData<T>);
 60
 61impl<T: 'static> Entity for Observer<T> {
 62    type Event = ();
 63}
 64
 65impl<T: Entity> Observer<T> {
 66    pub fn new(
 67        handle: &ModelHandle<T>,
 68        cx: &mut gpui::TestAppContext,
 69    ) -> (ModelHandle<Self>, channel::Receiver<()>) {
 70        let (notify_tx, notify_rx) = channel::unbounded();
 71        let observer = cx.add_model(|cx| {
 72            cx.observe(handle, move |_, _, _| {
 73                let _ = notify_tx.try_send(());
 74            })
 75            .detach();
 76            Observer(PhantomData)
 77        });
 78        (observer, notify_rx)
 79    }
 80}
 81
 82pub struct FakeHttpClient {
 83    handler:
 84        Box<dyn 'static + Send + Sync + Fn(Request) -> BoxFuture<'static, Result<ServerResponse>>>,
 85}
 86
 87impl FakeHttpClient {
 88    pub fn new<Fut, F>(handler: F) -> Arc<dyn HttpClient>
 89    where
 90        Fut: 'static + Send + Future<Output = Result<ServerResponse>>,
 91        F: 'static + Send + Sync + Fn(Request) -> Fut,
 92    {
 93        Arc::new(Self {
 94            handler: Box::new(move |req| Box::pin(handler(req))),
 95        })
 96    }
 97}
 98
 99impl fmt::Debug for FakeHttpClient {
100    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
101        f.debug_struct("FakeHttpClient").finish()
102    }
103}
104
105impl HttpClient for FakeHttpClient {
106    fn send<'a>(&'a self, req: Request) -> BoxFuture<'a, Result<Response>> {
107        let future = (self.handler)(req);
108        Box::pin(async move { future.await.map(Into::into) })
109    }
110}