1use std::sync::Arc;
2
3use anyhow::{Context as _, Result};
4use dap::adapters::DebugTaskDefinition;
5use dap::client::DebugAdapterClient;
6use gpui::{Entity, TestAppContext, WindowHandle};
7use project::{Project, debugger::session::Session};
8use settings::SettingsStore;
9use task::SharedTaskContext;
10use terminal_view::terminal_panel::TerminalPanel;
11use workspace::MultiWorkspace;
12
13use crate::{debugger_panel::DebugPanel, session::DebugSession};
14
15#[cfg(test)]
16mod attach_modal;
17#[cfg(test)]
18mod console;
19#[cfg(test)]
20mod dap_logger;
21#[cfg(test)]
22mod debugger_panel;
23#[cfg(test)]
24mod inline_values;
25#[cfg(test)]
26mod module_list;
27#[cfg(test)]
28mod new_process_modal;
29#[cfg(test)]
30mod persistence;
31#[cfg(test)]
32mod stack_frame_list;
33#[cfg(test)]
34mod variable_list;
35
36pub fn init_test(cx: &mut gpui::TestAppContext) {
37 #[cfg(test)]
38 zlog::init_test();
39
40 cx.update(|cx| {
41 let settings = SettingsStore::test(cx);
42 cx.set_global(settings);
43 terminal_view::init(cx);
44 theme::init(theme::LoadThemes::JustBase, cx);
45 command_palette_hooks::init(cx);
46 editor::init(cx);
47 crate::init(cx);
48 dap_adapters::init(cx);
49 });
50}
51
52pub async fn init_test_workspace(
53 project: &Entity<Project>,
54 cx: &mut TestAppContext,
55) -> WindowHandle<MultiWorkspace> {
56 let workspace_handle =
57 cx.add_window(|window, cx| MultiWorkspace::test_new(project.clone(), window, cx));
58
59 let debugger_panel = workspace_handle
60 .update(cx, |multi, window, cx| {
61 multi.workspace().update(cx, |_workspace, cx| {
62 cx.spawn_in(window, async move |this, cx| {
63 DebugPanel::load(this, cx).await
64 })
65 })
66 })
67 .unwrap()
68 .await
69 .expect("Failed to load debug panel");
70
71 let terminal_panel = workspace_handle
72 .update(cx, |multi, window, cx| {
73 let weak_workspace = multi.workspace().downgrade();
74 cx.spawn_in(window, async move |_, cx| {
75 TerminalPanel::load(weak_workspace, cx.clone()).await
76 })
77 })
78 .unwrap()
79 .await
80 .expect("Failed to load terminal panel");
81
82 workspace_handle
83 .update(cx, |multi, window, cx| {
84 multi.workspace().update(cx, |workspace, cx| {
85 workspace.add_panel(debugger_panel, window, cx);
86 workspace.add_panel(terminal_panel, window, cx);
87 });
88 })
89 .unwrap();
90 workspace_handle
91}
92
93#[track_caller]
94pub fn active_debug_session_panel(
95 workspace: WindowHandle<MultiWorkspace>,
96 cx: &mut TestAppContext,
97) -> Entity<DebugSession> {
98 workspace
99 .update(cx, |multi, _window, cx| {
100 multi.workspace().update(cx, |workspace, cx| {
101 let debug_panel = workspace.panel::<DebugPanel>(cx).unwrap();
102 debug_panel
103 .update(cx, |this, _| this.active_session())
104 .unwrap()
105 })
106 })
107 .unwrap()
108}
109
110pub fn start_debug_session_with<T: Fn(&Arc<DebugAdapterClient>) + 'static>(
111 workspace: &WindowHandle<MultiWorkspace>,
112 cx: &mut gpui::TestAppContext,
113 config: DebugTaskDefinition,
114 configure: T,
115) -> Result<Entity<Session>> {
116 let _subscription = project::debugger::test::intercept_debug_sessions(cx, configure);
117 workspace.update(cx, |multi, window, cx| {
118 multi.workspace().update(cx, |workspace, cx| {
119 workspace.start_debug_session(
120 config.to_scenario(),
121 SharedTaskContext::default(),
122 None,
123 None,
124 window,
125 cx,
126 )
127 })
128 })?;
129 cx.run_until_parked();
130 let session = workspace.read_with(cx, |workspace, cx| {
131 workspace
132 .workspace()
133 .read(cx)
134 .panel::<DebugPanel>(cx)
135 .and_then(|panel| panel.read(cx).active_session())
136 .map(|session| session.read(cx).running_state().read(cx).session())
137 .cloned()
138 .context("Failed to get active session")
139 })??;
140
141 Ok(session)
142}
143
144pub fn start_debug_session<T: Fn(&Arc<DebugAdapterClient>) + 'static>(
145 workspace: &WindowHandle<MultiWorkspace>,
146 cx: &mut gpui::TestAppContext,
147 configure: T,
148) -> Result<Entity<Session>> {
149 use serde_json::json;
150
151 start_debug_session_with(
152 workspace,
153 cx,
154 DebugTaskDefinition {
155 adapter: "fake-adapter".into(),
156 label: "test".into(),
157 config: json!({
158 "request": "launch"
159 }),
160 tcp_connection: None,
161 },
162 configure,
163 )
164}