1use std::{path::Path, sync::Arc};
2
3use dap::client::DebugAdapterClient;
4use gpui::{App, AppContext, Subscription};
5
6use super::session::{Session, SessionStateEvent};
7
8pub fn intercept_debug_sessions<T: Fn(&Arc<DebugAdapterClient>) + 'static>(
9 cx: &mut gpui::TestAppContext,
10 configure: T,
11) -> Subscription {
12 cx.update(|cx| {
13 let configure = Arc::new(configure);
14 cx.observe_new::<Session>(move |_, _, cx| {
15 let configure = configure.clone();
16 cx.subscribe_self(move |session, event, cx| {
17 let configure = configure.clone();
18 if matches!(event, SessionStateEvent::Running) {
19 let client = session.adapter_client().unwrap();
20 register_default_handlers(session, &client, cx);
21 configure(&client);
22 cx.background_spawn(async move {
23 client
24 .fake_event(dap::messages::Events::Initialized(
25 Some(Default::default()),
26 ))
27 .await
28 })
29 .detach();
30 }
31 })
32 .detach();
33 })
34 })
35}
36
37fn register_default_handlers(session: &Session, client: &Arc<DebugAdapterClient>, cx: &mut App) {
38 client.on_request::<dap::requests::Initialize, _>(move |_, _| Ok(Default::default()));
39 let paths = session
40 .as_local()
41 .unwrap()
42 .breakpoint_store
43 .read(cx)
44 .breakpoint_paths();
45
46 client.on_request::<dap::requests::SetBreakpoints, _>(move |_, args| {
47 let p = Arc::from(Path::new(&args.source.path.unwrap()));
48 if !paths.contains(&p) {
49 panic!("Sent breakpoints for path without any")
50 }
51
52 Ok(dap::SetBreakpointsResponse {
53 breakpoints: Vec::default(),
54 })
55 });
56
57 client.on_request::<dap::requests::Launch, _>(move |_, _| Ok(()));
58
59 client.on_request::<dap::requests::SetExceptionBreakpoints, _>(move |_, _| {
60 Ok(dap::SetExceptionBreakpointsResponse { breakpoints: None })
61 });
62
63 client.on_request::<dap::requests::Disconnect, _>(move |_, _| Ok(()));
64
65 client.on_request::<dap::requests::Threads, _>(move |_, _| {
66 Ok(dap::ThreadsResponse { threads: vec![] })
67 });
68}