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