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}