test.rs

 1use std::{path::Path, sync::Arc};
 2
 3use anyhow::Result;
 4use dap::{DebugRequest, client::DebugAdapterClient};
 5use gpui::{App, AppContext, Entity, Subscription, Task};
 6use task::DebugTaskDefinition;
 7
 8use crate::Project;
 9
10use super::session::Session;
11
12pub fn intercept_debug_sessions<T: Fn(&Arc<DebugAdapterClient>) + 'static>(
13    cx: &mut gpui::TestAppContext,
14    configure: T,
15) -> Subscription {
16    cx.update(|cx| {
17        cx.observe_new::<Session>(move |session, _, cx| {
18            let client = session.adapter_client().unwrap();
19            register_default_handlers(session, &client, cx);
20            configure(&client);
21            cx.background_spawn(async move {
22                client
23                    .fake_event(dap::messages::Events::Initialized(Some(Default::default())))
24                    .await
25            })
26            .detach();
27        })
28    })
29}
30
31pub fn start_debug_session_with<T: Fn(&Arc<DebugAdapterClient>) + 'static>(
32    project: &Entity<Project>,
33    cx: &mut gpui::TestAppContext,
34    config: DebugTaskDefinition,
35    configure: T,
36) -> Task<Result<Entity<Session>>> {
37    let subscription = intercept_debug_sessions(cx, configure);
38    let task = project.update(cx, |project, cx| project.start_debug_session(config, cx));
39    cx.spawn(async move |_| {
40        let result = task.await;
41        drop(subscription);
42        result
43    })
44}
45
46pub fn start_debug_session<T: Fn(&Arc<DebugAdapterClient>) + 'static>(
47    project: &Entity<Project>,
48    cx: &mut gpui::TestAppContext,
49    configure: T,
50) -> Task<Result<Entity<Session>>> {
51    start_debug_session_with(
52        project,
53        cx,
54        DebugTaskDefinition {
55            adapter: "fake-adapter".to_string(),
56            request: DebugRequest::Launch(Default::default()),
57            label: "test".to_string(),
58            initialize_args: None,
59            tcp_connection: None,
60            stop_on_entry: None,
61        },
62        configure,
63    )
64}
65
66fn register_default_handlers(session: &Session, client: &Arc<DebugAdapterClient>, cx: &mut App) {
67    client.on_request::<dap::requests::Initialize, _>(move |_, _| Ok(Default::default()));
68    let paths = session
69        .as_local()
70        .unwrap()
71        .breakpoint_store
72        .read(cx)
73        .breakpoint_paths();
74
75    client.on_request::<dap::requests::SetBreakpoints, _>(move |_, args| {
76        let p = Arc::from(Path::new(&args.source.path.unwrap()));
77        if !paths.contains(&p) {
78            panic!("Sent breakpoints for path without any")
79        }
80
81        Ok(dap::SetBreakpointsResponse {
82            breakpoints: Vec::default(),
83        })
84    });
85
86    client.on_request::<dap::requests::Launch, _>(move |_, _| Ok(()));
87
88    client.on_request::<dap::requests::SetExceptionBreakpoints, _>(move |_, _| {
89        Ok(dap::SetExceptionBreakpointsResponse { breakpoints: None })
90    });
91
92    client.on_request::<dap::requests::Disconnect, _>(move |_, _| Ok(()));
93
94    client.on_request::<dap::requests::Threads, _>(move |_, _| {
95        Ok(dap::ThreadsResponse { threads: vec![] })
96    });
97}