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