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