1use call::ActiveCall;
2use dap::DebugRequestType;
3use dap::requests::{Initialize, Launch, StackTrace};
4use dap::{SourceBreakpoint, requests::SetBreakpoints};
5use debugger_ui::debugger_panel::DebugPanel;
6use debugger_ui::session::DebugSession;
7use editor::Editor;
8use gpui::{Entity, TestAppContext, VisualTestContext};
9use project::{Project, ProjectPath, WorktreeId};
10use serde_json::json;
11use std::sync::Arc;
12use std::{
13 path::Path,
14 sync::atomic::{AtomicBool, Ordering},
15};
16use workspace::{Workspace, dock::Panel};
17
18use super::{TestClient, TestServer};
19
20pub fn init_test(cx: &mut gpui::TestAppContext) {
21 zlog::init_test();
22
23 cx.update(|cx| {
24 theme::init(theme::LoadThemes::JustBase, cx);
25 command_palette_hooks::init(cx);
26 language::init(cx);
27 workspace::init_settings(cx);
28 project::Project::init_settings(cx);
29 debugger_ui::init(cx);
30 editor::init(cx);
31 });
32}
33
34async fn add_debugger_panel(workspace: &Entity<Workspace>, cx: &mut VisualTestContext) {
35 let debugger_panel = workspace
36 .update_in(cx, |_workspace, window, cx| {
37 cx.spawn_in(window, DebugPanel::load)
38 })
39 .await
40 .unwrap();
41
42 workspace.update_in(cx, |workspace, window, cx| {
43 workspace.add_panel(debugger_panel, window, cx);
44 });
45}
46
47pub fn _active_session(
48 workspace: Entity<Workspace>,
49 cx: &mut VisualTestContext,
50) -> Entity<DebugSession> {
51 workspace.update_in(cx, |workspace, _window, cx| {
52 let debug_panel = workspace.panel::<DebugPanel>(cx).unwrap();
53 debug_panel
54 .update(cx, |this, cx| this.active_session(cx))
55 .unwrap()
56 })
57}
58
59struct ZedInstance<'a> {
60 client: TestClient,
61 project: Option<Entity<Project>>,
62 active_call: Entity<ActiveCall>,
63 cx: &'a mut TestAppContext,
64}
65
66impl<'a> ZedInstance<'a> {
67 fn new(client: TestClient, cx: &'a mut TestAppContext) -> Self {
68 ZedInstance {
69 project: None,
70 client,
71 active_call: cx.read(ActiveCall::global),
72 cx,
73 }
74 }
75
76 async fn host_project(
77 &mut self,
78 project_files: Option<serde_json::Value>,
79 ) -> (u64, WorktreeId) {
80 let (project, worktree_id) = self.client.build_local_project("/project", self.cx).await;
81 self.active_call
82 .update(self.cx, |call, cx| call.set_location(Some(&project), cx))
83 .await
84 .unwrap();
85
86 if let Some(tree) = project_files {
87 self.client.fs().insert_tree("/project", tree).await;
88 }
89
90 self.project = Some(project.clone());
91
92 let project_id = self
93 .active_call
94 .update(self.cx, |call, cx| call.share_project(project, cx))
95 .await
96 .unwrap();
97
98 (project_id, worktree_id)
99 }
100
101 async fn join_project(&mut self, project_id: u64) {
102 let remote_project = self.client.join_remote_project(project_id, self.cx).await;
103 self.project = Some(remote_project);
104
105 self.active_call
106 .update(self.cx, |call, cx| {
107 call.set_location(self.project.as_ref(), cx)
108 })
109 .await
110 .unwrap();
111 }
112
113 async fn expand(
114 &'a mut self,
115 ) -> (
116 &'a TestClient,
117 Entity<Workspace>,
118 Entity<Project>,
119 &'a mut VisualTestContext,
120 ) {
121 let (workspace, cx) = self.client.build_workspace(
122 self.project
123 .as_ref()
124 .expect("Project should be hosted or built before expanding"),
125 self.cx,
126 );
127 add_debugger_panel(&workspace, cx).await;
128 (&self.client, workspace, self.project.clone().unwrap(), cx)
129 }
130}
131
132async fn _setup_three_member_test<'a, 'b, 'c>(
133 server: &mut TestServer,
134 host_cx: &'a mut TestAppContext,
135 first_remote_cx: &'b mut TestAppContext,
136 second_remote_cx: &'c mut TestAppContext,
137) -> (ZedInstance<'a>, ZedInstance<'b>, ZedInstance<'c>) {
138 let host_client = server.create_client(host_cx, "user_host").await;
139 let first_remote_client = server.create_client(first_remote_cx, "user_remote_1").await;
140 let second_remote_client = server
141 .create_client(second_remote_cx, "user_remote_2")
142 .await;
143
144 init_test(host_cx);
145 init_test(first_remote_cx);
146 init_test(second_remote_cx);
147
148 server
149 .create_room(&mut [
150 (&host_client, host_cx),
151 (&first_remote_client, first_remote_cx),
152 (&second_remote_client, second_remote_cx),
153 ])
154 .await;
155
156 let host_zed = ZedInstance::new(host_client, host_cx);
157 let first_remote_zed = ZedInstance::new(first_remote_client, first_remote_cx);
158 let second_remote_zed = ZedInstance::new(second_remote_client, second_remote_cx);
159
160 (host_zed, first_remote_zed, second_remote_zed)
161}
162
163async fn setup_two_member_test<'a, 'b>(
164 server: &mut TestServer,
165 host_cx: &'a mut TestAppContext,
166 remote_cx: &'b mut TestAppContext,
167) -> (ZedInstance<'a>, ZedInstance<'b>) {
168 let host_client = server.create_client(host_cx, "user_host").await;
169 let remote_client = server.create_client(remote_cx, "user_remote").await;
170
171 init_test(host_cx);
172 init_test(remote_cx);
173
174 server
175 .create_room(&mut [(&host_client, host_cx), (&remote_client, remote_cx)])
176 .await;
177
178 let host_zed = ZedInstance::new(host_client, host_cx);
179 let remote_zed = ZedInstance::new(remote_client, remote_cx);
180
181 (host_zed, remote_zed)
182}
183
184#[gpui::test]
185async fn test_debug_panel_item_opens_on_remote(
186 host_cx: &mut TestAppContext,
187 remote_cx: &mut TestAppContext,
188) {
189 let executor = host_cx.executor();
190 let mut server = TestServer::start(executor).await;
191
192 let (mut host_zed, mut remote_zed) =
193 setup_two_member_test(&mut server, host_cx, remote_cx).await;
194
195 let (host_project_id, _) = host_zed.host_project(None).await;
196 remote_zed.join_project(host_project_id).await;
197
198 let (_client_host, _host_workspace, host_project, host_cx) = host_zed.expand().await;
199 let (_client_remote, remote_workspace, _remote_project, remote_cx) = remote_zed.expand().await;
200
201 remote_cx.run_until_parked();
202
203 let task = host_project.update(host_cx, |project, cx| {
204 project.start_debug_session(dap::test_config(DebugRequestType::Launch, None, None), cx)
205 });
206
207 let session = task.await.unwrap();
208 let client = session.read_with(host_cx, |project, _| project.adapter_client().unwrap());
209
210 client
211 .on_request::<Initialize, _>(move |_, _| {
212 Ok(dap::Capabilities {
213 supports_step_back: Some(false),
214 ..Default::default()
215 })
216 })
217 .await;
218
219 client.on_request::<Launch, _>(move |_, _| Ok(())).await;
220
221 client
222 .on_request::<StackTrace, _>(move |_, _| {
223 Ok(dap::StackTraceResponse {
224 stack_frames: Vec::default(),
225 total_frames: None,
226 })
227 })
228 .await;
229
230 client
231 .fake_event(dap::messages::Events::Stopped(dap::StoppedEvent {
232 reason: dap::StoppedEventReason::Pause,
233 description: None,
234 thread_id: Some(1),
235 preserve_focus_hint: None,
236 text: None,
237 all_threads_stopped: None,
238 hit_breakpoint_ids: None,
239 }))
240 .await;
241
242 host_cx.run_until_parked();
243 remote_cx.run_until_parked();
244
245 remote_workspace.update(remote_cx, |workspace, cx| {
246 let debug_panel = workspace.panel::<DebugPanel>(cx).unwrap();
247 let _active_session = debug_panel
248 .update(cx, |this, cx| this.active_session(cx))
249 .unwrap();
250
251 assert_eq!(
252 1,
253 debug_panel.update(cx, |this, cx| this.pane().unwrap().read(cx).items_len())
254 );
255 // assert_eq!(client.id(), active_session.read(cx).());
256 // assert_eq!(1, active_session.read(cx).thread_id().0);
257 // todo(debugger) check selected thread id
258 });
259
260 let shutdown_client = host_project.update(host_cx, |project, cx| {
261 project.dap_store().update(cx, |dap_store, cx| {
262 dap_store.shutdown_session(session.read(cx).session_id(), cx)
263 })
264 });
265
266 shutdown_client.await.unwrap();
267}
268
269#[gpui::test]
270async fn test_active_debug_panel_item_set_on_join_project(
271 host_cx: &mut TestAppContext,
272 remote_cx: &mut TestAppContext,
273) {
274 let executor = host_cx.executor();
275 let mut server = TestServer::start(executor).await;
276
277 let (mut host_zed, mut remote_zed) =
278 setup_two_member_test(&mut server, host_cx, remote_cx).await;
279
280 let (host_project_id, _) = host_zed.host_project(None).await;
281
282 let (_client_host, _host_workspace, host_project, host_cx) = host_zed.expand().await;
283
284 host_cx.run_until_parked();
285
286 let task = host_project.update(host_cx, |project, cx| {
287 project.start_debug_session(dap::test_config(DebugRequestType::Launch, None, None), cx)
288 });
289
290 let session = task.await.unwrap();
291 let client = session.read_with(host_cx, |project, _| project.adapter_client().unwrap());
292
293 client
294 .on_request::<Initialize, _>(move |_, _| {
295 Ok(dap::Capabilities {
296 supports_step_back: Some(false),
297 ..Default::default()
298 })
299 })
300 .await;
301
302 client.on_request::<Launch, _>(move |_, _| Ok(())).await;
303
304 client
305 .on_request::<StackTrace, _>(move |_, _| {
306 Ok(dap::StackTraceResponse {
307 stack_frames: Vec::default(),
308 total_frames: None,
309 })
310 })
311 .await;
312
313 client
314 .fake_event(dap::messages::Events::Stopped(dap::StoppedEvent {
315 reason: dap::StoppedEventReason::Pause,
316 description: None,
317 thread_id: Some(1),
318 preserve_focus_hint: None,
319 text: None,
320 all_threads_stopped: None,
321 hit_breakpoint_ids: None,
322 }))
323 .await;
324
325 // Give host_client time to send a debug panel item to collab server
326 host_cx.run_until_parked();
327
328 remote_zed.join_project(host_project_id).await;
329 let (_client_remote, remote_workspace, _remote_project, remote_cx) = remote_zed.expand().await;
330
331 host_cx.run_until_parked();
332 remote_cx.run_until_parked();
333
334 remote_workspace.update(remote_cx, |workspace, cx| {
335 let debug_panel = workspace.panel::<DebugPanel>(cx).unwrap();
336 let _active_session = debug_panel
337 .update(cx, |this, cx| this.active_session(cx))
338 .unwrap();
339
340 assert_eq!(
341 1,
342 debug_panel.update(cx, |this, cx| this.pane().unwrap().read(cx).items_len())
343 );
344 // assert_eq!(cl, active_session.read(cx).client_id());
345 // assert_eq!(1, active_session.read(cx).thread_id().0);
346 // todo(debugger)
347 });
348
349 let shutdown_client = host_project.update(host_cx, |project, cx| {
350 project.dap_store().update(cx, |dap_store, cx| {
351 dap_store.shutdown_session(session.read(cx).session_id(), cx)
352 })
353 });
354
355 shutdown_client.await.unwrap();
356
357 remote_cx.run_until_parked();
358
359 // assert we don't have a debug panel item anymore because the client shutdown
360 remote_workspace.update(remote_cx, |workspace, cx| {
361 let debug_panel = workspace.panel::<DebugPanel>(cx).unwrap();
362
363 debug_panel.update(cx, |this, cx| {
364 assert!(this.active_session(cx).is_none());
365 assert_eq!(0, this.pane().unwrap().read(cx).items_len());
366 });
367 });
368}
369
370#[gpui::test]
371async fn test_debug_panel_remote_button_presses(
372 _host_cx: &mut TestAppContext,
373 _remote_cx: &mut TestAppContext,
374) {
375 unimplemented!("Collab is still being refactored");
376 // let executor = host_cx.executor();
377 // let mut server = TestServer::start(executor).await;
378
379 // let (mut host_zed, mut remote_zed) =
380 // setup_two_member_test(&mut server, host_cx, remote_cx).await;
381
382 // let (host_project_id, _) = host_zed.host_project(None).await;
383 // remote_zed.join_project(host_project_id).await;
384
385 // let (_client_host, host_workspace, host_project, host_cx) = host_zed.expand().await;
386 // let (_client_remote, remote_workspace, _remote_project, remote_cx) = remote_zed.expand().await;
387
388 // let task = host_project.update(host_cx, |project, cx| {
389 // project.start_debug_session(dap::test_config(None), cx)
390 // });
391
392 // let session = task.await.unwrap();
393 // let client = session.read_with(host_cx, |project, _| project.adapter_client().unwrap());
394
395 // client
396 // .on_request::<Initialize, _>(move |_, _| {
397 // Ok(dap::Capabilities {
398 // supports_step_back: Some(true),
399 // ..Default::default()
400 // })
401 // })
402 // .await;
403
404 // client.on_request::<Launch, _>(move |_, _| Ok(())).await;
405
406 // client
407 // .on_request::<StackTrace, _>(move |_, _| {
408 // Ok(dap::StackTraceResponse {
409 // stack_frames: Vec::default(),
410 // total_frames: None,
411 // })
412 // })
413 // .await;
414
415 // client
416 // .fake_event(dap::messages::Events::Stopped(dap::StoppedEvent {
417 // reason: dap::StoppedEventReason::Pause,
418 // description: None,
419 // thread_id: Some(1),
420 // preserve_focus_hint: None,
421 // text: None,
422 // all_threads_stopped: None,
423 // hit_breakpoint_ids: None,
424 // }))
425 // .await;
426
427 // client
428 // .on_request::<dap::requests::Continue, _>(move |_, _| {
429 // Ok(dap::ContinueResponse {
430 // all_threads_continued: Some(true),
431 // })
432 // })
433 // .await;
434
435 // host_cx.run_until_parked();
436 // remote_cx.run_until_parked();
437
438 // let remote_debug_item = remote_workspace.update(remote_cx, |workspace, cx| {
439 // let debug_panel = workspace.panel::<DebugPanel>(cx).unwrap();
440 // let active_session = debug_panel
441 // .update(cx, |this, cx| this.active_session(cx))
442 // .unwrap();
443
444 // assert_eq!(
445 // 1,
446 // debug_panel.update(cx, |this, cx| this.pane().unwrap().read(cx).items_len())
447 // );
448 // // assert_eq!(client.id(), active_session.read(cx).client_id());
449 // // assert_eq!(1, active_session.read(cx).thread_id().0);
450 // // todo(debugger)
451 // active_session
452 // });
453
454 // let local_debug_item = host_workspace.update(host_cx, |workspace, cx| {
455 // let debug_panel = workspace.panel::<DebugPanel>(cx).unwrap();
456 // let active_session = debug_panel
457 // .update(cx, |this, cx| this.active_session(cx))
458 // .unwrap();
459
460 // assert_eq!(
461 // 1,
462 // debug_panel.update(cx, |this, cx| this.pane().unwrap().read(cx).items_len())
463 // );
464 // // assert_eq!(client.id(), active_session.read(cx).client_id());
465 // // assert_eq!(1, active_session.read(cx).thread_id().0);
466 // // todo(debugger)
467 // active_session
468 // });
469
470 // remote_debug_item.update(remote_cx, |this, cx| {
471 // this.continue_thread(cx);
472 // });
473
474 // host_cx.run_until_parked();
475 // remote_cx.run_until_parked();
476
477 // local_debug_item.update(host_cx, |debug_panel_item, cx| {
478 // assert_eq!(
479 // debugger_ui::debugger_panel::ThreadStatus::Running,
480 // debug_panel_item.thread_state().read(cx).status,
481 // );
482 // });
483
484 // remote_debug_item.update(remote_cx, |debug_panel_item, cx| {
485 // assert_eq!(
486 // debugger_ui::debugger_panel::ThreadStatus::Running,
487 // debug_panel_item.thread_state().read(cx).status,
488 // );
489 // });
490
491 // client
492 // .fake_event(dap::messages::Events::Stopped(dap::StoppedEvent {
493 // reason: dap::StoppedEventReason::Pause,
494 // description: None,
495 // thread_id: Some(1),
496 // preserve_focus_hint: None,
497 // text: None,
498 // all_threads_stopped: None,
499 // hit_breakpoint_ids: None,
500 // }))
501 // .await;
502
503 // client
504 // .on_request::<StackTrace, _>(move |_, _| {
505 // Ok(dap::StackTraceResponse {
506 // stack_frames: Vec::default(),
507 // total_frames: None,
508 // })
509 // })
510 // .await;
511
512 // host_cx.run_until_parked();
513 // remote_cx.run_until_parked();
514
515 // local_debug_item.update(host_cx, |debug_panel_item, cx| {
516 // assert_eq!(
517 // debugger_ui::debugger_panel::ThreadStatus::Stopped,
518 // debug_panel_item.thread_state().read(cx).status,
519 // );
520 // });
521
522 // remote_debug_item.update(remote_cx, |debug_panel_item, cx| {
523 // assert_eq!(
524 // debugger_ui::debugger_panel::ThreadStatus::Stopped,
525 // debug_panel_item.thread_state().read(cx).status,
526 // );
527 // });
528
529 // client
530 // .on_request::<dap::requests::Continue, _>(move |_, _| {
531 // Ok(dap::ContinueResponse {
532 // all_threads_continued: Some(true),
533 // })
534 // })
535 // .await;
536
537 // local_debug_item.update(host_cx, |this, cx| {
538 // this.continue_thread(cx);
539 // });
540
541 // host_cx.run_until_parked();
542 // remote_cx.run_until_parked();
543
544 // local_debug_item.update(host_cx, |debug_panel_item, cx| {
545 // assert_eq!(
546 // debugger_ui::debugger_panel::ThreadStatus::Running,
547 // debug_panel_item.thread_state().read(cx).status,
548 // );
549 // });
550
551 // remote_debug_item.update(remote_cx, |debug_panel_item, cx| {
552 // assert_eq!(
553 // debugger_ui::debugger_panel::ThreadStatus::Running,
554 // debug_panel_item.thread_state().read(cx).status,
555 // );
556 // });
557
558 // client
559 // .on_request::<dap::requests::Pause, _>(move |_, _| Ok(()))
560 // .await;
561
562 // client
563 // .on_request::<StackTrace, _>(move |_, _| {
564 // Ok(dap::StackTraceResponse {
565 // stack_frames: Vec::default(),
566 // total_frames: None,
567 // })
568 // })
569 // .await;
570
571 // client
572 // .fake_event(dap::messages::Events::Stopped(dap::StoppedEvent {
573 // reason: dap::StoppedEventReason::Pause,
574 // description: None,
575 // thread_id: Some(1),
576 // preserve_focus_hint: None,
577 // text: None,
578 // all_threads_stopped: None,
579 // hit_breakpoint_ids: None,
580 // }))
581 // .await;
582
583 // remote_debug_item.update(remote_cx, |this, cx| {
584 // this.pause_thread(cx);
585 // });
586
587 // remote_cx.run_until_parked();
588 // host_cx.run_until_parked();
589
590 // client
591 // .on_request::<dap::requests::StepOut, _>(move |_, _| Ok(()))
592 // .await;
593
594 // remote_debug_item.update(remote_cx, |this, cx| {
595 // this.step_out(cx);
596 // });
597
598 // client
599 // .fake_event(dap::messages::Events::Stopped(dap::StoppedEvent {
600 // reason: dap::StoppedEventReason::Pause,
601 // description: None,
602 // thread_id: Some(1),
603 // preserve_focus_hint: None,
604 // text: None,
605 // all_threads_stopped: None,
606 // hit_breakpoint_ids: None,
607 // }))
608 // .await;
609
610 // remote_cx.run_until_parked();
611 // host_cx.run_until_parked();
612
613 // client
614 // .on_request::<dap::requests::Next, _>(move |_, _| Ok(()))
615 // .await;
616
617 // remote_debug_item.update(remote_cx, |this, cx| {
618 // this.step_over(cx);
619 // });
620
621 // client
622 // .fake_event(dap::messages::Events::Stopped(dap::StoppedEvent {
623 // reason: dap::StoppedEventReason::Pause,
624 // description: None,
625 // thread_id: Some(1),
626 // preserve_focus_hint: None,
627 // text: None,
628 // all_threads_stopped: None,
629 // hit_breakpoint_ids: None,
630 // }))
631 // .await;
632
633 // remote_cx.run_until_parked();
634 // host_cx.run_until_parked();
635
636 // client
637 // .on_request::<dap::requests::StepIn, _>(move |_, _| Ok(()))
638 // .await;
639
640 // remote_debug_item.update(remote_cx, |this, cx| {
641 // this.step_in(cx);
642 // });
643
644 // client
645 // .fake_event(dap::messages::Events::Stopped(dap::StoppedEvent {
646 // reason: dap::StoppedEventReason::Pause,
647 // description: None,
648 // thread_id: Some(1),
649 // preserve_focus_hint: None,
650 // text: None,
651 // all_threads_stopped: None,
652 // hit_breakpoint_ids: None,
653 // }))
654 // .await;
655
656 // remote_cx.run_until_parked();
657 // host_cx.run_until_parked();
658
659 // client
660 // .on_request::<dap::requests::StepBack, _>(move |_, _| Ok(()))
661 // .await;
662
663 // remote_debug_item.update(remote_cx, |this, cx| {
664 // this.step_back(cx);
665 // });
666
667 // client
668 // .fake_event(dap::messages::Events::Stopped(dap::StoppedEvent {
669 // reason: dap::StoppedEventReason::Pause,
670 // description: None,
671 // thread_id: Some(1),
672 // preserve_focus_hint: None,
673 // text: None,
674 // all_threads_stopped: None,
675 // hit_breakpoint_ids: None,
676 // }))
677 // .await;
678
679 // remote_cx.run_until_parked();
680 // host_cx.run_until_parked();
681
682 // remote_debug_item.update(remote_cx, |this, cx| {
683 // this.stop_thread(cx);
684 // });
685
686 // host_cx.run_until_parked();
687 // remote_cx.run_until_parked();
688
689 // // assert we don't have a debug panel item anymore because the client shutdown
690 // remote_workspace.update(remote_cx, |workspace, cx| {
691 // let debug_panel = workspace.panel::<DebugPanel>(cx).unwrap();
692
693 // debug_panel.update(cx, |this, cx| {
694 // assert!(this.active_session(cx).is_none());
695 // assert_eq!(0, this.pane().unwrap().read(cx).items_len());
696 // });
697 // });
698}
699
700#[gpui::test]
701async fn test_restart_stack_frame(_host_cx: &mut TestAppContext, _remote_cx: &mut TestAppContext) {
702 unimplemented!("Collab is still being refactored");
703 // let executor = host_cx.executor();
704 // let mut server = TestServer::start(executor).await;
705
706 // let (mut host_zed, mut remote_zed) =
707 // setup_two_member_test(&mut server, host_cx, remote_cx).await;
708
709 // let (host_project_id, _) = host_zed.host_project(None).await;
710 // remote_zed.join_project(host_project_id).await;
711
712 // let (_client_host, _host_workspace, host_project, host_cx) = host_zed.expand().await;
713 // let (_client_remote, remote_workspace, _remote_project, remote_cx) = remote_zed.expand().await;
714
715 // let called_restart_frame = Arc::new(AtomicBool::new(false));
716
717 // let task = host_project.update(host_cx, |project, cx| {
718 // project.start_debug_session(dap::test_config(None), cx)
719 // });
720
721 // let session = task.await.unwrap();
722 // let client = session.read(cx).adapter_client().unwrap();
723
724 // client
725 // .on_request::<Initialize, _>(move |_, _| {
726 // Ok(dap::Capabilities {
727 // supports_restart_frame: Some(true),
728 // ..Default::default()
729 // })
730 // })
731 // .await;
732
733 // client.on_request::<Launch, _>(move |_, _| Ok(())).await;
734
735 // let stack_frames = vec![StackFrame {
736 // id: 1,
737 // name: "Stack Frame 1".into(),
738 // source: Some(dap::Source {
739 // name: Some("test.js".into()),
740 // path: Some("/project/src/test.js".into()),
741 // source_reference: None,
742 // presentation_hint: None,
743 // origin: None,
744 // sources: None,
745 // adapter_data: None,
746 // checksums: None,
747 // }),
748 // line: 3,
749 // column: 1,
750 // end_line: None,
751 // end_column: None,
752 // can_restart: None,
753 // instruction_pointer_reference: None,
754 // module_id: None,
755 // presentation_hint: None,
756 // }];
757
758 // client
759 // .on_request::<StackTrace, _>({
760 // let stack_frames = Arc::new(stack_frames.clone());
761 // move |_, args| {
762 // assert_eq!(1, args.thread_id);
763
764 // Ok(dap::StackTraceResponse {
765 // stack_frames: (*stack_frames).clone(),
766 // total_frames: None,
767 // })
768 // }
769 // })
770 // .await;
771
772 // client
773 // .on_request::<RestartFrame, _>({
774 // let called_restart_frame = called_restart_frame.clone();
775 // move |_, args| {
776 // assert_eq!(1, args.frame_id);
777
778 // called_restart_frame.store(true, Ordering::SeqCst);
779
780 // Ok(())
781 // }
782 // })
783 // .await;
784
785 // client
786 // .fake_event(dap::messages::Events::Stopped(dap::StoppedEvent {
787 // reason: dap::StoppedEventReason::Pause,
788 // description: None,
789 // thread_id: Some(1),
790 // preserve_focus_hint: None,
791 // text: None,
792 // all_threads_stopped: None,
793 // hit_breakpoint_ids: None,
794 // }))
795 // .await;
796
797 // host_cx.run_until_parked();
798 // remote_cx.run_until_parked();
799
800 // // try to restart stack frame 1 from the guest side
801 // remote_workspace.update(remote_cx, |workspace, cx| {
802 // let debug_panel = workspace.panel::<DebugPanel>(cx).unwrap();
803 // let active_session = debug_panel
804 // .update(cx, |this, cx| this.active_session(cx))
805 // .unwrap();
806
807 // active_session.update(cx, |debug_panel_item, cx| {
808 // debug_panel_item
809 // .stack_frame_list()
810 // .update(cx, |stack_frame_list, cx| {
811 // stack_frame_list.restart_stack_frame(1, cx);
812 // });
813 // });
814 // });
815
816 // host_cx.run_until_parked();
817 // remote_cx.run_until_parked();
818
819 // assert!(
820 // called_restart_frame.load(std::sync::atomic::Ordering::SeqCst),
821 // "Restart stack frame was not called"
822 // );
823
824 // let shutdown_client = host_project.update(host_cx, |project, cx| {
825 // project.dap_store().update(cx, |dap_store, cx| {
826 // dap_store.shutdown_session(&session.read(cx).session_id(), cx)
827 // })
828 // });
829
830 // shutdown_client.await.unwrap();
831}
832
833#[gpui::test]
834async fn test_updated_breakpoints_send_to_dap(
835 host_cx: &mut TestAppContext,
836 remote_cx: &mut TestAppContext,
837) {
838 let executor = host_cx.executor();
839 let mut server = TestServer::start(executor).await;
840
841 let (mut host_zed, mut remote_zed) =
842 setup_two_member_test(&mut server, host_cx, remote_cx).await;
843
844 let (host_project_id, worktree_id) = host_zed
845 .host_project(Some(json!({"test.txt": "one\ntwo\nthree\nfour\nfive"})))
846 .await;
847
848 remote_zed.join_project(host_project_id).await;
849
850 let (_client_host, host_workspace, host_project, host_cx) = host_zed.expand().await;
851 let (_client_remote, remote_workspace, _remote_project, remote_cx) = remote_zed.expand().await;
852
853 let project_path = ProjectPath {
854 worktree_id,
855 path: Arc::from(Path::new(&"test.txt")),
856 };
857
858 let task = host_project.update(host_cx, |project, cx| {
859 project.start_debug_session(dap::test_config(DebugRequestType::Launch, None, None), cx)
860 });
861
862 let session = task.await.unwrap();
863 let client = session.read_with(host_cx, |project, _| project.adapter_client().unwrap());
864
865 client
866 .on_request::<Initialize, _>(move |_, _| {
867 Ok(dap::Capabilities {
868 supports_restart_frame: Some(true),
869 ..Default::default()
870 })
871 })
872 .await;
873
874 client.on_request::<Launch, _>(move |_, _| Ok(())).await;
875 client
876 .on_request::<StackTrace, _>(move |_, _| {
877 Ok(dap::StackTraceResponse {
878 stack_frames: Vec::default(),
879 total_frames: None,
880 })
881 })
882 .await;
883
884 let called_set_breakpoints = Arc::new(AtomicBool::new(false));
885 client
886 .on_request::<SetBreakpoints, _>({
887 let called_set_breakpoints = called_set_breakpoints.clone();
888 move |_, args| {
889 assert_eq!("/project/test.txt", args.source.path.unwrap());
890 assert_eq!(
891 vec![SourceBreakpoint {
892 line: 3,
893 column: None,
894 condition: None,
895 hit_condition: None,
896 log_message: None,
897 mode: None
898 }],
899 args.breakpoints.unwrap()
900 );
901 // assert!(!args.source_modified.unwrap());
902 // todo(debugger): Implement source_modified handling
903
904 called_set_breakpoints.store(true, Ordering::SeqCst);
905
906 Ok(dap::SetBreakpointsResponse {
907 breakpoints: Vec::default(),
908 })
909 }
910 })
911 .await;
912
913 client
914 .fake_event(dap::messages::Events::Stopped(dap::StoppedEvent {
915 reason: dap::StoppedEventReason::Pause,
916 description: None,
917 thread_id: Some(1),
918 preserve_focus_hint: None,
919 text: None,
920 all_threads_stopped: None,
921 hit_breakpoint_ids: None,
922 }))
923 .await;
924
925 host_cx.run_until_parked();
926 remote_cx.run_until_parked();
927
928 // Client B opens an editor.
929 let editor_b = remote_workspace
930 .update_in(remote_cx, |workspace, window, cx| {
931 workspace.open_path(project_path.clone(), None, true, window, cx)
932 })
933 .await
934 .unwrap()
935 .downcast::<Editor>()
936 .unwrap();
937
938 editor_b.update_in(remote_cx, |editor, window, cx| {
939 editor.move_down(&editor::actions::MoveDown, window, cx);
940 editor.move_down(&editor::actions::MoveDown, window, cx);
941 editor.toggle_breakpoint(&editor::actions::ToggleBreakpoint, window, cx);
942 });
943
944 // Client A opens an editor.
945 let editor_a = host_workspace
946 .update_in(host_cx, |workspace, window, cx| {
947 workspace.open_path(project_path.clone(), None, true, window, cx)
948 })
949 .await
950 .unwrap()
951 .downcast::<Editor>()
952 .unwrap();
953
954 host_cx.run_until_parked();
955 remote_cx.run_until_parked();
956
957 let called_set_breakpoints = Arc::new(AtomicBool::new(false));
958 client
959 .on_request::<SetBreakpoints, _>({
960 let called_set_breakpoints = called_set_breakpoints.clone();
961 move |_, args| {
962 assert_eq!("/project/test.txt", args.source.path.unwrap());
963 assert!(args.breakpoints.unwrap().is_empty());
964 // assert!(!args.source_modified.unwrap());
965 // todo(debugger) Implement source modified support
966
967 called_set_breakpoints.store(true, Ordering::SeqCst);
968
969 Ok(dap::SetBreakpointsResponse {
970 breakpoints: Vec::default(),
971 })
972 }
973 })
974 .await;
975
976 // remove the breakpoint that client B added
977 editor_a.update_in(host_cx, |editor, window, cx| {
978 editor.move_down(&editor::actions::MoveDown, window, cx);
979 editor.move_down(&editor::actions::MoveDown, window, cx);
980 editor.toggle_breakpoint(&editor::actions::ToggleBreakpoint, window, cx);
981 });
982
983 host_cx.run_until_parked();
984 remote_cx.run_until_parked();
985
986 assert!(
987 called_set_breakpoints.load(std::sync::atomic::Ordering::SeqCst),
988 "SetBreakpoint request must be called"
989 );
990
991 let called_set_breakpoints = Arc::new(AtomicBool::new(false));
992 client
993 .on_request::<SetBreakpoints, _>({
994 let called_set_breakpoints = called_set_breakpoints.clone();
995 move |_, args| {
996 assert_eq!("/project/test.txt", args.source.path.unwrap());
997 let mut breakpoints = args.breakpoints.unwrap();
998 breakpoints.sort_by_key(|b| b.line);
999 assert_eq!(
1000 vec![
1001 SourceBreakpoint {
1002 line: 2,
1003 column: None,
1004 condition: None,
1005 hit_condition: None,
1006 log_message: None,
1007 mode: None
1008 },
1009 SourceBreakpoint {
1010 line: 3,
1011 column: None,
1012 condition: None,
1013 hit_condition: None,
1014 log_message: None,
1015 mode: None
1016 }
1017 ],
1018 breakpoints
1019 );
1020 // assert!(!args.source_modified.unwrap());
1021 // todo(debugger) Implement source modified support
1022
1023 called_set_breakpoints.store(true, Ordering::SeqCst);
1024
1025 Ok(dap::SetBreakpointsResponse {
1026 breakpoints: Vec::default(),
1027 })
1028 }
1029 })
1030 .await;
1031
1032 // Add our own breakpoint now
1033 editor_a.update_in(host_cx, |editor, window, cx| {
1034 editor.toggle_breakpoint(&editor::actions::ToggleBreakpoint, window, cx);
1035 editor.move_up(&editor::actions::MoveUp, window, cx);
1036 editor.toggle_breakpoint(&editor::actions::ToggleBreakpoint, window, cx);
1037 });
1038
1039 host_cx.run_until_parked();
1040 remote_cx.run_until_parked();
1041
1042 assert!(
1043 called_set_breakpoints.load(std::sync::atomic::Ordering::SeqCst),
1044 "SetBreakpoint request must be called"
1045 );
1046
1047 let shutdown_client = host_project.update(host_cx, |project, cx| {
1048 project.dap_store().update(cx, |dap_store, cx| {
1049 dap_store.shutdown_session(session.read(cx).session_id(), cx)
1050 })
1051 });
1052
1053 shutdown_client.await.unwrap();
1054}
1055
1056#[gpui::test]
1057async fn test_module_list(
1058 _host_cx: &mut TestAppContext,
1059 _remote_cx: &mut TestAppContext,
1060 _late_join_cx: &mut TestAppContext,
1061) {
1062 unimplemented!("Collab is still being refactored");
1063 // let executor = host_cx.executor();
1064 // let mut server = TestServer::start(executor).await;
1065
1066 // let (mut host_zed, mut remote_zed, mut late_join_zed) =
1067 // setup_three_member_test(&mut server, host_cx, remote_cx, late_join_cx).await;
1068
1069 // let (host_project_id, _worktree_id) = host_zed.host_project(None).await;
1070
1071 // remote_zed.join_project(host_project_id).await;
1072
1073 // let (_client_host, host_workspace, host_project, host_cx) = host_zed.expand().await;
1074 // let (_client_remote, remote_workspace, _remote_project, remote_cx) = remote_zed.expand().await;
1075
1076 // let task = host_project.update(host_cx, |project, cx| {
1077 // project.start_debug_session(dap::test_config(None), cx)
1078 // });
1079
1080 // let session = task.await.unwrap();
1081 // let client = session.read_with(host_cx, |project, _| project.adapter_client().unwrap());
1082
1083 // let called_initialize = Arc::new(AtomicBool::new(false));
1084
1085 // client
1086 // .on_request::<Initialize, _>({
1087 // let called_initialize = called_initialize.clone();
1088 // move |_, _| {
1089 // called_initialize.store(true, Ordering::SeqCst);
1090 // Ok(dap::Capabilities {
1091 // supports_restart_frame: Some(true),
1092 // supports_modules_request: Some(true),
1093 // ..Default::default()
1094 // })
1095 // }
1096 // })
1097 // .await;
1098
1099 // client.on_request::<Launch, _>(move |_, _| Ok(())).await;
1100 // client
1101 // .on_request::<StackTrace, _>(move |_, _| {
1102 // Ok(dap::StackTraceResponse {
1103 // stack_frames: Vec::default(),
1104 // total_frames: None,
1105 // })
1106 // })
1107 // .await;
1108
1109 // let called_modules = Arc::new(AtomicBool::new(false));
1110 // let modules = vec![
1111 // dap::Module {
1112 // id: dap::ModuleId::Number(1),
1113 // name: "First Module".into(),
1114 // address_range: None,
1115 // date_time_stamp: None,
1116 // path: None,
1117 // symbol_file_path: None,
1118 // symbol_status: None,
1119 // version: None,
1120 // is_optimized: None,
1121 // is_user_code: None,
1122 // },
1123 // dap::Module {
1124 // id: dap::ModuleId::Number(2),
1125 // name: "Second Module".into(),
1126 // address_range: None,
1127 // date_time_stamp: None,
1128 // path: None,
1129 // symbol_file_path: None,
1130 // symbol_status: None,
1131 // version: None,
1132 // is_optimized: None,
1133 // is_user_code: None,
1134 // },
1135 // ];
1136
1137 // client
1138 // .on_request::<dap::requests::Modules, _>({
1139 // let called_modules = called_modules.clone();
1140 // let modules = modules.clone();
1141 // move |_, _| unsafe {
1142 // static mut REQUEST_COUNT: i32 = 1;
1143 // assert_eq!(
1144 // 1, REQUEST_COUNT,
1145 // "This request should only be called once from the host"
1146 // );
1147 // REQUEST_COUNT += 1;
1148 // called_modules.store(true, Ordering::SeqCst);
1149
1150 // Ok(dap::ModulesResponse {
1151 // modules: modules.clone(),
1152 // total_modules: Some(2u64),
1153 // })
1154 // }
1155 // })
1156 // .await;
1157
1158 // host_cx.run_until_parked();
1159 // remote_cx.run_until_parked();
1160
1161 // assert!(
1162 // called_initialize.load(std::sync::atomic::Ordering::SeqCst),
1163 // "Request Initialize must be called"
1164 // );
1165
1166 // client
1167 // .fake_event(dap::messages::Events::Stopped(dap::StoppedEvent {
1168 // reason: dap::StoppedEventReason::Pause,
1169 // description: None,
1170 // thread_id: Some(1),
1171 // preserve_focus_hint: None,
1172 // text: None,
1173 // all_threads_stopped: None,
1174 // hit_breakpoint_ids: None,
1175 // }))
1176 // .await;
1177
1178 // host_cx.run_until_parked();
1179 // remote_cx.run_until_parked();
1180
1181 // assert!(
1182 // called_modules.load(std::sync::atomic::Ordering::SeqCst),
1183 // "Request Modules must be called"
1184 // );
1185
1186 // host_workspace.update(host_cx, |workspace, cx| {
1187 // let debug_panel = workspace.panel::<DebugPanel>(cx).unwrap();
1188 // let debug_panel_item = debug_panel
1189 // .update(cx, |this, cx| this.active_session(cx))
1190 // .unwrap();
1191
1192 // debug_panel_item.update(cx, |item, cx| {
1193 // assert_eq!(
1194 // true,
1195 // item.capabilities(cx).supports_modules_request.unwrap(),
1196 // "Local supports modules request should be true"
1197 // );
1198
1199 // let local_module_list = item.module_list().update(cx, |list, cx| list.modules(cx));
1200
1201 // assert_eq!(
1202 // 2usize,
1203 // local_module_list.len(),
1204 // "Local module list should have two items in it"
1205 // );
1206 // assert_eq!(
1207 // modules.clone(),
1208 // local_module_list,
1209 // "Local module list should match module list from response"
1210 // );
1211 // })
1212 // });
1213
1214 // remote_workspace.update(remote_cx, |workspace, cx| {
1215 // let debug_panel = workspace.panel::<DebugPanel>(cx).unwrap();
1216 // let debug_panel_item = debug_panel
1217 // .update(cx, |this, cx| this.active_session(cx))
1218 // .unwrap();
1219
1220 // debug_panel_item.update(cx, |item, cx| {
1221 // assert_eq!(
1222 // true,
1223 // item.capabilities(cx).supports_modules_request.unwrap(),
1224 // "Remote capabilities supports modules request should be true"
1225 // );
1226 // let remote_module_list = item.module_list().update(cx, |list, cx| list.modules(cx));
1227
1228 // assert_eq!(
1229 // 2usize,
1230 // remote_module_list.len(),
1231 // "Remote module list should have two items in it"
1232 // );
1233 // assert_eq!(
1234 // modules.clone(),
1235 // remote_module_list,
1236 // "Remote module list should match module list from response"
1237 // );
1238 // })
1239 // });
1240
1241 // late_join_zed.join_project(host_project_id).await;
1242 // let (_late_join_client, late_join_workspace, _late_join_project, late_join_cx) =
1243 // late_join_zed.expand().await;
1244
1245 // late_join_workspace.update(late_join_cx, |workspace, cx| {
1246 // let debug_panel = workspace.panel::<DebugPanel>(cx).unwrap();
1247 // let debug_panel_item = debug_panel
1248 // .update(cx, |this, cx| this.active_session(cx))
1249 // .unwrap();
1250
1251 // debug_panel_item.update(cx, |item, cx| {
1252 // assert_eq!(
1253 // true,
1254 // item.capabilities(cx).supports_modules_request.unwrap(),
1255 // "Remote (mid session join) capabilities supports modules request should be true"
1256 // );
1257 // let remote_module_list = item.module_list().update(cx, |list, cx| list.modules(cx));
1258
1259 // assert_eq!(
1260 // 2usize,
1261 // remote_module_list.len(),
1262 // "Remote (mid session join) module list should have two items in it"
1263 // );
1264 // assert_eq!(
1265 // modules.clone(),
1266 // remote_module_list,
1267 // "Remote (mid session join) module list should match module list from response"
1268 // );
1269 // })
1270 // });
1271
1272 // let shutdown_client = host_project.update(host_cx, |project, cx| {
1273 // project.dap_store().update(cx, |dap_store, cx| {
1274 // dap_store.shutdown_session(&session.read(cx).id(), cx)
1275 // })
1276 // });
1277
1278 // shutdown_client.await.unwrap();
1279}
1280
1281// #[gpui::test]
1282// async fn test_variable_list(
1283// host_cx: &mut TestAppContext,
1284// remote_cx: &mut TestAppContext,
1285// late_join_cx: &mut TestAppContext,
1286// ) {
1287// let executor = host_cx.executor();
1288// let mut server = TestServer::start(executor).await;
1289
1290// let (mut host_zed, mut remote_zed, mut late_join_zed) =
1291// setup_three_member_test(&mut server, host_cx, remote_cx, late_join_cx).await;
1292
1293// let (host_project_id, _worktree_id) = host_zed
1294// .host_project(Some(json!({"test.txt": "one\ntwo\nthree\nfour\nfive"})))
1295// .await;
1296
1297// remote_zed.join_project(host_project_id).await;
1298
1299// let (_client_host, host_workspace, host_project, host_cx) = host_zed.expand().await;
1300// let (_client_remote, remote_workspace, _remote_project, remote_cx) = remote_zed.expand().await;
1301
1302// let task = host_project.update(host_cx, |project, cx| {
1303// project.start_debug_session(
1304// dap::DebugAdapterConfig {
1305// label: "test config".into(),
1306// kind: dap::DebugAdapterKind::Fake,
1307// request: dap::DebugRequestType::Launch,
1308// program: None,
1309// cwd: None,
1310// initialize_args: None,
1311// },
1312// cx,
1313// )
1314// });
1315
1316// let (session, client) = task.await.unwrap();
1317
1318// client
1319// .on_request::<Initialize, _>(move |_, _| {
1320// Ok(dap::Capabilities {
1321// supports_step_back: Some(true),
1322// ..Default::default()
1323// })
1324// })
1325// .await;
1326
1327// client.on_request::<Launch, _>(move |_, _| Ok(())).await;
1328
1329// let stack_frames = vec![dap::StackFrame {
1330// id: 1,
1331// name: "Stack Frame 1".into(),
1332// source: Some(dap::Source {
1333// name: Some("test.js".into()),
1334// path: Some("/project/src/test.js".into()),
1335// source_reference: None,
1336// presentation_hint: None,
1337// origin: None,
1338// sources: None,
1339// adapter_data: None,
1340// checksums: None,
1341// }),
1342// line: 1,
1343// column: 1,
1344// end_line: None,
1345// end_column: None,
1346// can_restart: None,
1347// instruction_pointer_reference: None,
1348// module_id: None,
1349// presentation_hint: None,
1350// }];
1351
1352// let scopes = vec![Scope {
1353// name: "Scope 1".into(),
1354// presentation_hint: None,
1355// variables_reference: 1,
1356// named_variables: None,
1357// indexed_variables: None,
1358// expensive: false,
1359// source: None,
1360// line: None,
1361// column: None,
1362// end_line: None,
1363// end_column: None,
1364// }];
1365
1366// let variable_1 = Variable {
1367// name: "variable 1".into(),
1368// value: "1".into(),
1369// type_: None,
1370// presentation_hint: None,
1371// evaluate_name: None,
1372// variables_reference: 2,
1373// named_variables: None,
1374// indexed_variables: None,
1375// memory_reference: None,
1376// };
1377
1378// let variable_2 = Variable {
1379// name: "variable 2".into(),
1380// value: "2".into(),
1381// type_: None,
1382// presentation_hint: None,
1383// evaluate_name: None,
1384// variables_reference: 3,
1385// named_variables: None,
1386// indexed_variables: None,
1387// memory_reference: None,
1388// };
1389
1390// let variable_3 = Variable {
1391// name: "variable 3".into(),
1392// value: "hello world".into(),
1393// type_: None,
1394// presentation_hint: None,
1395// evaluate_name: None,
1396// variables_reference: 4,
1397// named_variables: None,
1398// indexed_variables: None,
1399// memory_reference: None,
1400// };
1401
1402// let variable_4 = Variable {
1403// name: "variable 4".into(),
1404// value: "hello world this is the final variable".into(),
1405// type_: None,
1406// presentation_hint: None,
1407// evaluate_name: None,
1408// variables_reference: 0,
1409// named_variables: None,
1410// indexed_variables: None,
1411// memory_reference: None,
1412// };
1413
1414// client
1415// .on_request::<StackTrace, _>({
1416// let stack_frames = std::sync::Arc::new(stack_frames.clone());
1417// move |_, args| {
1418// assert_eq!(1, args.thread_id);
1419
1420// Ok(dap::StackTraceResponse {
1421// stack_frames: (*stack_frames).clone(),
1422// total_frames: None,
1423// })
1424// }
1425// })
1426// .await;
1427
1428// client
1429// .on_request::<Scopes, _>({
1430// let scopes = Arc::new(scopes.clone());
1431// move |_, args| {
1432// assert_eq!(1, args.frame_id);
1433
1434// Ok(dap::ScopesResponse {
1435// scopes: (*scopes).clone(),
1436// })
1437// }
1438// })
1439// .await;
1440
1441// let first_variable_request = vec![variable_1.clone(), variable_2.clone()];
1442
1443// client
1444// .on_request::<Variables, _>({
1445// move |_, args| {
1446// assert_eq!(1, args.variables_reference);
1447
1448// Ok(dap::VariablesResponse {
1449// variables: first_variable_request.clone(),
1450// })
1451// }
1452// })
1453// .await;
1454
1455// client
1456// .fake_event(dap::messages::Events::Stopped(dap::StoppedEvent {
1457// reason: dap::StoppedEventReason::Pause,
1458// description: None,
1459// thread_id: Some(1),
1460// preserve_focus_hint: None,
1461// text: None,
1462// all_threads_stopped: None,
1463// hit_breakpoint_ids: None,
1464// }))
1465// .await;
1466
1467// host_cx.run_until_parked();
1468// remote_cx.run_until_parked();
1469
1470// let local_debug_item = host_workspace.update(host_cx, |workspace, cx| {
1471// let debug_panel = workspace.panel::<DebugPanel>(cx).unwrap();
1472// let active_debug_panel_item = debug_panel
1473// .update(cx, |this, cx| this.active_debug_panel_item(cx))
1474// .unwrap();
1475
1476// assert_eq!(
1477// 1,
1478// debug_panel.update(cx, |this, cx| this.pane().unwrap().read(cx).items_len())
1479// );
1480// assert_eq!(client.id(), active_debug_panel_item.read(cx).client_id());
1481// assert_eq!(1, active_debug_panel_item.read(cx).thread_id());
1482// active_debug_panel_item
1483// });
1484
1485// let remote_debug_item = remote_workspace.update(remote_cx, |workspace, cx| {
1486// let debug_panel = workspace.panel::<DebugPanel>(cx).unwrap();
1487// let active_debug_panel_item = debug_panel
1488// .update(cx, |this, cx| this.active_debug_panel_item(cx))
1489// .unwrap();
1490
1491// assert_eq!(
1492// 1,
1493// debug_panel.update(cx, |this, cx| this.pane().unwrap().read(cx).items_len())
1494// );
1495// assert_eq!(client.id(), active_debug_panel_item.read(cx).client_id());
1496// assert_eq!(1, active_debug_panel_item.read(cx).thread_id());
1497// active_debug_panel_item
1498// });
1499
1500// let first_visual_entries = vec!["v Scope 1", " > variable 1", " > variable 2"];
1501// let first_variable_containers = vec![
1502// VariableContainer {
1503// container_reference: scopes[0].variables_reference,
1504// variable: variable_1.clone(),
1505// depth: 1,
1506// },
1507// VariableContainer {
1508// container_reference: scopes[0].variables_reference,
1509// variable: variable_2.clone(),
1510// depth: 1,
1511// },
1512// ];
1513
1514// local_debug_item
1515// .update(host_cx, |this, _| this.variable_list().clone())
1516// .update(host_cx, |variable_list, cx| {
1517// assert_eq!(1, variable_list.scopes().len());
1518// assert_eq!(scopes, variable_list.scopes().get(&1).unwrap().clone());
1519// assert_eq!(&first_variable_containers, &variable_list.variables());
1520
1521// variable_list.assert_visual_entries(first_visual_entries.clone(), cx);
1522// });
1523
1524// client
1525// .on_request::<Variables, _>({
1526// let variables = Arc::new(vec![variable_3.clone()]);
1527// move |_, args| {
1528// assert_eq!(2, args.variables_reference);
1529
1530// Ok(dap::VariablesResponse {
1531// variables: (*variables).clone(),
1532// })
1533// }
1534// })
1535// .await;
1536
1537// remote_debug_item
1538// .update(remote_cx, |this, _| this.variable_list().clone())
1539// .update(remote_cx, |variable_list, cx| {
1540// assert_eq!(1, variable_list.scopes().len());
1541// assert_eq!(scopes, variable_list.scopes().get(&1).unwrap().clone());
1542// assert_eq!(&first_variable_containers, &variable_list.variables());
1543
1544// variable_list.assert_visual_entries(first_visual_entries.clone(), cx);
1545
1546// variable_list.toggle_variable(&scopes[0], &variable_1, 1, cx);
1547// });
1548
1549// host_cx.run_until_parked();
1550// remote_cx.run_until_parked();
1551
1552// let second_req_variable_list = vec![
1553// VariableContainer {
1554// container_reference: scopes[0].variables_reference,
1555// variable: variable_1.clone(),
1556// depth: 1,
1557// },
1558// VariableContainer {
1559// container_reference: variable_1.variables_reference,
1560// variable: variable_3.clone(),
1561// depth: 2,
1562// },
1563// VariableContainer {
1564// container_reference: scopes[0].variables_reference,
1565// variable: variable_2.clone(),
1566// depth: 1,
1567// },
1568// ];
1569
1570// remote_debug_item
1571// .update(remote_cx, |this, _| this.variable_list().clone())
1572// .update(remote_cx, |variable_list, cx| {
1573// assert_eq!(1, variable_list.scopes().len());
1574// assert_eq!(3, variable_list.variables().len());
1575// assert_eq!(scopes, variable_list.scopes().get(&1).unwrap().clone());
1576// assert_eq!(&second_req_variable_list, &variable_list.variables());
1577
1578// variable_list.assert_visual_entries(
1579// vec![
1580// "v Scope 1",
1581// " v variable 1",
1582// " > variable 3",
1583// " > variable 2",
1584// ],
1585// cx,
1586// );
1587// });
1588
1589// client
1590// .on_request::<Variables, _>({
1591// let variables = Arc::new(vec![variable_4.clone()]);
1592// move |_, args| {
1593// assert_eq!(3, args.variables_reference);
1594
1595// Ok(dap::VariablesResponse {
1596// variables: (*variables).clone(),
1597// })
1598// }
1599// })
1600// .await;
1601
1602// local_debug_item
1603// .update(host_cx, |this, _| this.variable_list().clone())
1604// .update(host_cx, |variable_list, cx| {
1605// assert_eq!(1, variable_list.scopes().len());
1606// assert_eq!(3, variable_list.variables().len());
1607// assert_eq!(scopes, variable_list.scopes().get(&1).unwrap().clone());
1608// assert_eq!(&second_req_variable_list, &variable_list.variables());
1609
1610// variable_list.assert_visual_entries(first_visual_entries.clone(), cx);
1611
1612// variable_list.toggle_variable(&scopes[0], &variable_2.clone(), 1, cx);
1613// });
1614
1615// host_cx.run_until_parked();
1616// remote_cx.run_until_parked();
1617
1618// let final_variable_containers: Vec<VariableContainer> = vec![
1619// VariableContainer {
1620// container_reference: scopes[0].variables_reference,
1621// variable: variable_1.clone(),
1622// depth: 1,
1623// },
1624// VariableContainer {
1625// container_reference: variable_1.variables_reference,
1626// variable: variable_3.clone(),
1627// depth: 2,
1628// },
1629// VariableContainer {
1630// container_reference: scopes[0].variables_reference,
1631// variable: variable_2.clone(),
1632// depth: 1,
1633// },
1634// VariableContainer {
1635// container_reference: variable_2.variables_reference,
1636// variable: variable_4.clone(),
1637// depth: 2,
1638// },
1639// ];
1640
1641// remote_debug_item
1642// .update(remote_cx, |this, _| this.variable_list().clone())
1643// .update(remote_cx, |variable_list, cx| {
1644// assert_eq!(1, variable_list.scopes().len());
1645// assert_eq!(4, variable_list.variables().len());
1646// assert_eq!(scopes, variable_list.scopes().get(&1).unwrap().clone());
1647// assert_eq!(&final_variable_containers, &variable_list.variables());
1648
1649// variable_list.assert_visual_entries(
1650// vec![
1651// "v Scope 1",
1652// " v variable 1",
1653// " > variable 3",
1654// " > variable 2",
1655// ],
1656// cx,
1657// );
1658// });
1659
1660// local_debug_item
1661// .update(host_cx, |this, _| this.variable_list().clone())
1662// .update(host_cx, |variable_list, cx| {
1663// assert_eq!(1, variable_list.scopes().len());
1664// assert_eq!(4, variable_list.variables().len());
1665// assert_eq!(scopes, variable_list.scopes().get(&1).unwrap().clone());
1666// assert_eq!(&final_variable_containers, &variable_list.variables());
1667
1668// variable_list.assert_visual_entries(
1669// vec![
1670// "v Scope 1",
1671// " > variable 1",
1672// " v variable 2",
1673// " > variable 4",
1674// ],
1675// cx,
1676// );
1677// });
1678
1679// late_join_zed.join_project(host_project_id).await;
1680// let (_late_join_client, late_join_workspace, _late_join_project, late_join_cx) =
1681// late_join_zed.expand().await;
1682
1683// late_join_cx.run_until_parked();
1684
1685// let last_join_remote_item = late_join_workspace.update(late_join_cx, |workspace, cx| {
1686// let debug_panel = workspace.panel::<DebugPanel>(cx).unwrap();
1687// let active_debug_panel_item = debug_panel
1688// .update(cx, |this, cx| this.active_debug_panel_item(cx))
1689// .unwrap();
1690
1691// assert_eq!(
1692// 1,
1693// debug_panel.update(cx, |this, cx| this.pane().unwrap().read(cx).items_len())
1694// );
1695// assert_eq!(client.id(), active_debug_panel_item.read(cx).client_id());
1696// assert_eq!(1, active_debug_panel_item.read(cx).thread_id());
1697// active_debug_panel_item
1698// });
1699
1700// last_join_remote_item
1701// .update(late_join_cx, |this, _| this.variable_list().clone())
1702// .update(late_join_cx, |variable_list, cx| {
1703// assert_eq!(1, variable_list.scopes().len());
1704// assert_eq!(4, variable_list.variables().len());
1705// assert_eq!(scopes, variable_list.scopes().get(&1).unwrap().clone());
1706// assert_eq!(final_variable_containers, variable_list.variables());
1707
1708// variable_list.assert_visual_entries(first_visual_entries, cx);
1709// });
1710
1711// let shutdown_client = host_project.update(host_cx, |project, cx| {
1712// project.dap_store().update(cx, |dap_store, cx| {
1713// dap_store.shutdown_session(&session.read(cx).id(), cx)
1714// })
1715// });
1716
1717// shutdown_client.await.unwrap();
1718// }
1719
1720#[gpui::test]
1721async fn test_ignore_breakpoints(
1722 _host_cx: &mut TestAppContext,
1723 _remote_cx: &mut TestAppContext,
1724 _cx_c: &mut TestAppContext,
1725) {
1726 unimplemented!("Collab is still being refactored");
1727 // let executor = host_cx.executor();
1728 // let mut server = TestServer::start(executor).await;
1729
1730 // let (mut host_zed, mut remote_zed, mut late_join_zed) =
1731 // setup_three_member_test(&mut server, host_cx, remote_cx, cx_c).await;
1732
1733 // let (host_project_id, worktree_id) = host_zed
1734 // .host_project(Some(json!({"test.txt": "one\ntwo\nthree\nfour\nfive"})))
1735 // .await;
1736
1737 // remote_zed.join_project(host_project_id).await;
1738
1739 // let (_client_host, host_workspace, host_project, host_cx) = host_zed.expand().await;
1740 // let (_client_remote, remote_workspace, remote_project, remote_cx) = remote_zed.expand().await;
1741
1742 // let project_path = ProjectPath {
1743 // worktree_id,
1744 // path: Arc::from(Path::new(&"test.txt")),
1745 // };
1746
1747 // let local_editor = host_workspace
1748 // .update_in(host_cx, |workspace, window, cx| {
1749 // workspace.open_path(project_path.clone(), None, true, window, cx)
1750 // })
1751 // .await
1752 // .unwrap()
1753 // .downcast::<Editor>()
1754 // .unwrap();
1755
1756 // local_editor.update_in(host_cx, |editor, window, cx| {
1757 // editor.move_down(&editor::actions::MoveDown, window, cx);
1758 // editor.toggle_breakpoint(&editor::actions::ToggleBreakpoint, window, cx); // Line 2
1759 // editor.move_down(&editor::actions::MoveDown, window, cx);
1760 // editor.toggle_breakpoint(&editor::actions::ToggleBreakpoint, window, cx);
1761 // // Line 3
1762 // });
1763
1764 // host_cx.run_until_parked();
1765 // remote_cx.run_until_parked();
1766
1767 // let task = host_project.update(host_cx, |project, cx| {
1768 // project.start_debug_session(dap::test_config(None), cx)
1769 // });
1770
1771 // let session = task.await.unwrap();
1772 // let client = session.read_with(host_cx, |project, _| project.adapter_client().unwrap());
1773 // let client_id = client.id();
1774
1775 // client
1776 // .on_request::<Initialize, _>(move |_, _| {
1777 // Ok(dap::Capabilities {
1778 // supports_configuration_done_request: Some(true),
1779 // ..Default::default()
1780 // })
1781 // })
1782 // .await;
1783
1784 // let called_set_breakpoints = Arc::new(AtomicBool::new(false));
1785 // client
1786 // .on_request::<SetBreakpoints, _>({
1787 // let called_set_breakpoints = called_set_breakpoints.clone();
1788 // move |_, args| {
1789 // assert_eq!("/project/test.txt", args.source.path.unwrap());
1790
1791 // let mut actual_breakpoints = args.breakpoints.unwrap();
1792 // actual_breakpoints.sort_by_key(|b| b.line);
1793
1794 // let expected_breakpoints = vec![
1795 // SourceBreakpoint {
1796 // line: 2,
1797 // column: None,
1798 // condition: None,
1799 // hit_condition: None,
1800 // log_message: None,
1801 // mode: None,
1802 // },
1803 // SourceBreakpoint {
1804 // line: 3,
1805 // column: None,
1806 // condition: None,
1807 // hit_condition: None,
1808 // log_message: None,
1809 // mode: None,
1810 // },
1811 // ];
1812
1813 // assert_eq!(actual_breakpoints, expected_breakpoints);
1814
1815 // called_set_breakpoints.store(true, Ordering::SeqCst);
1816
1817 // Ok(dap::SetBreakpointsResponse {
1818 // breakpoints: Vec::default(),
1819 // })
1820 // }
1821 // })
1822 // .await;
1823
1824 // client.on_request::<Launch, _>(move |_, _| Ok(())).await;
1825 // client
1826 // .on_request::<StackTrace, _>(move |_, _| {
1827 // Ok(dap::StackTraceResponse {
1828 // stack_frames: Vec::default(),
1829 // total_frames: None,
1830 // })
1831 // })
1832 // .await;
1833
1834 // client
1835 // .fake_event(dap::messages::Events::Initialized(Some(
1836 // dap::Capabilities {
1837 // supports_configuration_done_request: Some(true),
1838 // ..Default::default()
1839 // },
1840 // )))
1841 // .await;
1842
1843 // host_cx.run_until_parked();
1844 // remote_cx.run_until_parked();
1845
1846 // assert!(
1847 // called_set_breakpoints.load(std::sync::atomic::Ordering::SeqCst),
1848 // "SetBreakpoint request must be called when starting debug session"
1849 // );
1850
1851 // client
1852 // .fake_event(dap::messages::Events::Stopped(dap::StoppedEvent {
1853 // reason: dap::StoppedEventReason::Pause,
1854 // description: None,
1855 // thread_id: Some(1),
1856 // preserve_focus_hint: None,
1857 // text: None,
1858 // all_threads_stopped: None,
1859 // hit_breakpoint_ids: None,
1860 // }))
1861 // .await;
1862
1863 // host_cx.run_until_parked();
1864 // remote_cx.run_until_parked();
1865
1866 // let remote_debug_item = remote_workspace.update(remote_cx, |workspace, cx| {
1867 // let debug_panel = workspace.panel::<DebugPanel>(cx).unwrap();
1868 // let active_session = debug_panel
1869 // .update(cx, |this, cx| this.active_session(cx))
1870 // .unwrap();
1871
1872 // assert_eq!(
1873 // 1,
1874 // debug_panel.update(cx, |this, cx| this.pane().unwrap().read(cx).items_len())
1875 // );
1876
1877 // let session_id = debug_panel.update(cx, |this, cx| {
1878 // this.dap_store()
1879 // .read(cx)
1880 // .session_by_client_id(client.id())
1881 // .unwrap()
1882 // .read(cx)
1883 // .id()
1884 // });
1885
1886 // let breakpoints_ignored = active_session.read(cx).are_breakpoints_ignored(cx);
1887
1888 // assert_eq!(session_id, active_session.read(cx).session().read(cx).id());
1889 // assert_eq!(false, breakpoints_ignored);
1890 // assert_eq!(client.id(), active_session.read(cx).client_id());
1891 // assert_eq!(1, active_session.read(cx).thread_id().0);
1892 // active_session
1893 // });
1894
1895 // called_set_breakpoints.store(false, Ordering::SeqCst);
1896
1897 // client
1898 // .on_request::<SetBreakpoints, _>({
1899 // let called_set_breakpoints = called_set_breakpoints.clone();
1900 // move |_, args| {
1901 // assert_eq!("/project/test.txt", args.source.path.unwrap());
1902 // assert_eq!(args.breakpoints, Some(vec![]));
1903
1904 // called_set_breakpoints.store(true, Ordering::SeqCst);
1905
1906 // Ok(dap::SetBreakpointsResponse {
1907 // breakpoints: Vec::default(),
1908 // })
1909 // }
1910 // })
1911 // .await;
1912
1913 // let local_debug_item = host_workspace.update(host_cx, |workspace, cx| {
1914 // let debug_panel = workspace.panel::<DebugPanel>(cx).unwrap();
1915 // let active_session = debug_panel
1916 // .update(cx, |this, cx| this.active_session(cx))
1917 // .unwrap();
1918
1919 // assert_eq!(
1920 // 1,
1921 // debug_panel.update(cx, |this, cx| this.pane().unwrap().read(cx).items_len())
1922 // );
1923
1924 // assert_eq!(false, active_session.read(cx).are_breakpoints_ignored(cx));
1925 // assert_eq!(client.id(), active_session.read(cx).client_id());
1926 // assert_eq!(1, active_session.read(cx).thread_id().0);
1927
1928 // active_session
1929 // });
1930
1931 // local_debug_item.update(host_cx, |item, cx| {
1932 // item.toggle_ignore_breakpoints(cx); // Set to true
1933 // assert_eq!(true, item.are_breakpoints_ignored(cx));
1934 // });
1935
1936 // host_cx.run_until_parked();
1937 // remote_cx.run_until_parked();
1938
1939 // assert!(
1940 // called_set_breakpoints.load(std::sync::atomic::Ordering::SeqCst),
1941 // "SetBreakpoint request must be called to ignore breakpoints"
1942 // );
1943
1944 // client
1945 // .on_request::<SetBreakpoints, _>({
1946 // let called_set_breakpoints = called_set_breakpoints.clone();
1947 // move |_, _args| {
1948 // called_set_breakpoints.store(true, Ordering::SeqCst);
1949
1950 // Ok(dap::SetBreakpointsResponse {
1951 // breakpoints: Vec::default(),
1952 // })
1953 // }
1954 // })
1955 // .await;
1956
1957 // let remote_editor = remote_workspace
1958 // .update_in(remote_cx, |workspace, window, cx| {
1959 // workspace.open_path(project_path.clone(), None, true, window, cx)
1960 // })
1961 // .await
1962 // .unwrap()
1963 // .downcast::<Editor>()
1964 // .unwrap();
1965
1966 // called_set_breakpoints.store(false, std::sync::atomic::Ordering::SeqCst);
1967
1968 // remote_editor.update_in(remote_cx, |editor, window, cx| {
1969 // // Line 1
1970 // editor.toggle_breakpoint(&editor::actions::ToggleBreakpoint, window, cx);
1971 // });
1972
1973 // host_cx.run_until_parked();
1974 // remote_cx.run_until_parked();
1975
1976 // assert!(
1977 // called_set_breakpoints.load(std::sync::atomic::Ordering::SeqCst),
1978 // "SetBreakpoint request be called whenever breakpoints are toggled but with not breakpoints"
1979 // );
1980
1981 // remote_debug_item.update(remote_cx, |debug_panel, cx| {
1982 // let breakpoints_ignored = debug_panel.are_breakpoints_ignored(cx);
1983
1984 // assert_eq!(true, breakpoints_ignored);
1985 // assert_eq!(client.id(), debug_panel.client_id());
1986 // assert_eq!(1, debug_panel.thread_id().0);
1987 // });
1988
1989 // client
1990 // .on_request::<SetBreakpoints, _>({
1991 // let called_set_breakpoints = called_set_breakpoints.clone();
1992 // move |_, args| {
1993 // assert_eq!("/project/test.txt", args.source.path.unwrap());
1994
1995 // let mut actual_breakpoints = args.breakpoints.unwrap();
1996 // actual_breakpoints.sort_by_key(|b| b.line);
1997
1998 // let expected_breakpoints = vec![
1999 // SourceBreakpoint {
2000 // line: 1,
2001 // column: None,
2002 // condition: None,
2003 // hit_condition: None,
2004 // log_message: None,
2005 // mode: None,
2006 // },
2007 // SourceBreakpoint {
2008 // line: 2,
2009 // column: None,
2010 // condition: None,
2011 // hit_condition: None,
2012 // log_message: None,
2013 // mode: None,
2014 // },
2015 // SourceBreakpoint {
2016 // line: 3,
2017 // column: None,
2018 // condition: None,
2019 // hit_condition: None,
2020 // log_message: None,
2021 // mode: None,
2022 // },
2023 // ];
2024
2025 // assert_eq!(actual_breakpoints, expected_breakpoints);
2026
2027 // called_set_breakpoints.store(true, Ordering::SeqCst);
2028
2029 // Ok(dap::SetBreakpointsResponse {
2030 // breakpoints: Vec::default(),
2031 // })
2032 // }
2033 // })
2034 // .await;
2035
2036 // late_join_zed.join_project(host_project_id).await;
2037 // let (_late_join_client, late_join_workspace, late_join_project, late_join_cx) =
2038 // late_join_zed.expand().await;
2039
2040 // late_join_cx.run_until_parked();
2041
2042 // let last_join_remote_item = late_join_workspace.update(late_join_cx, |workspace, cx| {
2043 // let debug_panel = workspace.panel::<DebugPanel>(cx).unwrap();
2044 // let active_session = debug_panel
2045 // .update(cx, |this, cx| this.active_session(cx))
2046 // .unwrap();
2047
2048 // let breakpoints_ignored = active_session.read(cx).are_breakpoints_ignored(cx);
2049
2050 // assert_eq!(true, breakpoints_ignored);
2051
2052 // assert_eq!(
2053 // 1,
2054 // debug_panel.update(cx, |this, cx| this.pane().unwrap().read(cx).items_len())
2055 // );
2056 // assert_eq!(client.id(), active_session.read(cx).client_id());
2057 // assert_eq!(1, active_session.read(cx).thread_id().0);
2058 // active_session
2059 // });
2060
2061 // remote_debug_item.update(remote_cx, |item, cx| {
2062 // item.toggle_ignore_breakpoints(cx);
2063 // });
2064
2065 // host_cx.run_until_parked();
2066 // remote_cx.run_until_parked();
2067 // late_join_cx.run_until_parked();
2068
2069 // assert!(
2070 // called_set_breakpoints.load(std::sync::atomic::Ordering::SeqCst),
2071 // "SetBreakpoint request should be called to update breakpoints"
2072 // );
2073
2074 // client
2075 // .on_request::<SetBreakpoints, _>({
2076 // let called_set_breakpoints = called_set_breakpoints.clone();
2077 // move |_, args| {
2078 // assert_eq!("/project/test.txt", args.source.path.unwrap());
2079 // assert_eq!(args.breakpoints, Some(vec![]));
2080
2081 // called_set_breakpoints.store(true, Ordering::SeqCst);
2082
2083 // Ok(dap::SetBreakpointsResponse {
2084 // breakpoints: Vec::default(),
2085 // })
2086 // }
2087 // })
2088 // .await;
2089
2090 // local_debug_item.update(host_cx, |debug_panel_item, cx| {
2091 // assert_eq!(
2092 // false,
2093 // debug_panel_item.are_breakpoints_ignored(cx),
2094 // "Remote client set this to false"
2095 // );
2096 // });
2097
2098 // remote_debug_item.update(remote_cx, |debug_panel_item, cx| {
2099 // assert_eq!(
2100 // false,
2101 // debug_panel_item.are_breakpoints_ignored(cx),
2102 // "Remote client set this to false"
2103 // );
2104 // });
2105
2106 // last_join_remote_item.update(late_join_cx, |debug_panel_item, cx| {
2107 // assert_eq!(
2108 // false,
2109 // debug_panel_item.are_breakpoints_ignored(cx),
2110 // "Remote client set this to false"
2111 // );
2112 // });
2113
2114 // let shutdown_client = host_project.update(host_cx, |project, cx| {
2115 // project.dap_store().update(cx, |dap_store, cx| {
2116 // dap_store.shutdown_session(&session.read(cx).id(), cx)
2117 // })
2118 // });
2119
2120 // shutdown_client.await.unwrap();
2121
2122 // host_cx.run_until_parked();
2123 // remote_cx.run_until_parked();
2124
2125 // remote_project.update(remote_cx, |project, cx| {
2126 // project.dap_store().update(cx, |dap_store, _cx| {
2127 // let sessions = dap_store.sessions().collect::<Vec<_>>();
2128
2129 // assert_eq!(
2130 // None,
2131 // dap_store.session_by_client_id(&client_id),
2132 // "No client_id to session mapping should exist after shutdown"
2133 // );
2134 // assert_eq!(
2135 // 0,
2136 // sessions.len(),
2137 // "No sessions should be left after shutdown"
2138 // );
2139 // })
2140 // });
2141
2142 // late_join_project.update(late_join_cx, |project, cx| {
2143 // project.dap_store().update(cx, |dap_store, _cx| {
2144 // let sessions = dap_store.sessions().collect::<Vec<_>>();
2145
2146 // assert_eq!(
2147 // None,
2148 // dap_store.session_by_client_id(&client_id),
2149 // "No client_id to session mapping should exist after shutdown"
2150 // );
2151 // assert_eq!(
2152 // 0,
2153 // sessions.len(),
2154 // "No sessions should be left after shutdown"
2155 // );
2156 // })
2157 // });
2158}
2159
2160#[gpui::test]
2161async fn test_debug_panel_console(_host_cx: &mut TestAppContext, _remote_cx: &mut TestAppContext) {
2162 unimplemented!("Collab is still being refactored");
2163 // let executor = host_cx.executor();
2164 // let mut server = TestServer::start(executor).await;
2165
2166 // let (mut host_zed, mut remote_zed) =
2167 // setup_two_member_test(&mut server, host_cx, remote_cx).await;
2168
2169 // let (host_project_id, _) = host_zed.host_project(None).await;
2170 // remote_zed.join_project(host_project_id).await;
2171
2172 // let (_client_host, _host_workspace, host_project, host_cx) = host_zed.expand().await;
2173 // let (_client_remote, remote_workspace, _remote_project, remote_cx) = remote_zed.expand().await;
2174
2175 // remote_cx.run_until_parked();
2176
2177 // let task = host_project.update(host_cx, |project, cx| {
2178 // project.start_debug_session(dap::test_config(None), cx)
2179 // });
2180
2181 // let session = task.await.unwrap();
2182 // let client = session.read_with(host_cx, |project, _| project.adapter_client().unwrap());
2183
2184 // client
2185 // .on_request::<Initialize, _>(move |_, _| {
2186 // Ok(dap::Capabilities {
2187 // supports_step_back: Some(false),
2188 // ..Default::default()
2189 // })
2190 // })
2191 // .await;
2192
2193 // client.on_request::<Launch, _>(move |_, _| Ok(())).await;
2194
2195 // client
2196 // .on_request::<StackTrace, _>(move |_, _| {
2197 // Ok(dap::StackTraceResponse {
2198 // stack_frames: Vec::default(),
2199 // total_frames: None,
2200 // })
2201 // })
2202 // .await;
2203
2204 // client
2205 // .fake_event(dap::messages::Events::Stopped(dap::StoppedEvent {
2206 // reason: dap::StoppedEventReason::Pause,
2207 // description: None,
2208 // thread_id: Some(1),
2209 // preserve_focus_hint: None,
2210 // text: None,
2211 // all_threads_stopped: None,
2212 // hit_breakpoint_ids: None,
2213 // }))
2214 // .await;
2215
2216 // client
2217 // .fake_event(dap::messages::Events::Output(dap::OutputEvent {
2218 // category: None,
2219 // output: "First line".to_string(),
2220 // data: None,
2221 // variables_reference: None,
2222 // source: None,
2223 // line: None,
2224 // column: None,
2225 // group: None,
2226 // location_reference: None,
2227 // }))
2228 // .await;
2229
2230 // client
2231 // .fake_event(dap::messages::Events::Output(dap::OutputEvent {
2232 // category: Some(dap::OutputEventCategory::Stdout),
2233 // output: "First group".to_string(),
2234 // data: None,
2235 // variables_reference: None,
2236 // source: None,
2237 // line: None,
2238 // column: None,
2239 // group: Some(dap::OutputEventGroup::Start),
2240 // location_reference: None,
2241 // }))
2242 // .await;
2243
2244 // client
2245 // .fake_event(dap::messages::Events::Output(dap::OutputEvent {
2246 // category: Some(dap::OutputEventCategory::Stdout),
2247 // output: "First item in group 1".to_string(),
2248 // data: None,
2249 // variables_reference: None,
2250 // source: None,
2251 // line: None,
2252 // column: None,
2253 // group: None,
2254 // location_reference: None,
2255 // }))
2256 // .await;
2257
2258 // client
2259 // .fake_event(dap::messages::Events::Output(dap::OutputEvent {
2260 // category: Some(dap::OutputEventCategory::Stdout),
2261 // output: "Second item in group 1".to_string(),
2262 // data: None,
2263 // variables_reference: None,
2264 // source: None,
2265 // line: None,
2266 // column: None,
2267 // group: None,
2268 // location_reference: None,
2269 // }))
2270 // .await;
2271
2272 // client
2273 // .fake_event(dap::messages::Events::Output(dap::OutputEvent {
2274 // category: Some(dap::OutputEventCategory::Stdout),
2275 // output: "Second group".to_string(),
2276 // data: None,
2277 // variables_reference: None,
2278 // source: None,
2279 // line: None,
2280 // column: None,
2281 // group: Some(dap::OutputEventGroup::Start),
2282 // location_reference: None,
2283 // }))
2284 // .await;
2285
2286 // client
2287 // .fake_event(dap::messages::Events::Output(dap::OutputEvent {
2288 // category: Some(dap::OutputEventCategory::Stdout),
2289 // output: "First item in group 2".to_string(),
2290 // data: None,
2291 // variables_reference: None,
2292 // source: None,
2293 // line: None,
2294 // column: None,
2295 // group: None,
2296 // location_reference: None,
2297 // }))
2298 // .await;
2299
2300 // client
2301 // .fake_event(dap::messages::Events::Output(dap::OutputEvent {
2302 // category: Some(dap::OutputEventCategory::Stdout),
2303 // output: "Second item in group 2".to_string(),
2304 // data: None,
2305 // variables_reference: None,
2306 // source: None,
2307 // line: None,
2308 // column: None,
2309 // group: None,
2310 // location_reference: None,
2311 // }))
2312 // .await;
2313
2314 // client
2315 // .fake_event(dap::messages::Events::Output(dap::OutputEvent {
2316 // category: Some(dap::OutputEventCategory::Stdout),
2317 // output: "End group 2".to_string(),
2318 // data: None,
2319 // variables_reference: None,
2320 // source: None,
2321 // line: None,
2322 // column: None,
2323 // group: Some(dap::OutputEventGroup::End),
2324 // location_reference: None,
2325 // }))
2326 // .await;
2327
2328 // client
2329 // .fake_event(dap::messages::Events::Output(dap::OutputEvent {
2330 // category: Some(dap::OutputEventCategory::Stdout),
2331 // output: "Third group".to_string(),
2332 // data: None,
2333 // variables_reference: None,
2334 // source: None,
2335 // line: None,
2336 // column: None,
2337 // group: Some(dap::OutputEventGroup::StartCollapsed),
2338 // location_reference: None,
2339 // }))
2340 // .await;
2341
2342 // client
2343 // .fake_event(dap::messages::Events::Output(dap::OutputEvent {
2344 // category: Some(dap::OutputEventCategory::Stdout),
2345 // output: "First item in group 3".to_string(),
2346 // data: None,
2347 // variables_reference: None,
2348 // source: None,
2349 // line: None,
2350 // column: None,
2351 // group: None,
2352 // location_reference: None,
2353 // }))
2354 // .await;
2355
2356 // client
2357 // .fake_event(dap::messages::Events::Output(dap::OutputEvent {
2358 // category: Some(dap::OutputEventCategory::Stdout),
2359 // output: "Second item in group 3".to_string(),
2360 // data: None,
2361 // variables_reference: None,
2362 // source: None,
2363 // line: None,
2364 // column: None,
2365 // group: None,
2366 // location_reference: None,
2367 // }))
2368 // .await;
2369
2370 // client
2371 // .fake_event(dap::messages::Events::Output(dap::OutputEvent {
2372 // category: Some(dap::OutputEventCategory::Stdout),
2373 // output: "End group 3".to_string(),
2374 // data: None,
2375 // variables_reference: None,
2376 // source: None,
2377 // line: None,
2378 // column: None,
2379 // group: Some(dap::OutputEventGroup::End),
2380 // location_reference: None,
2381 // }))
2382 // .await;
2383
2384 // client
2385 // .fake_event(dap::messages::Events::Output(dap::OutputEvent {
2386 // category: Some(dap::OutputEventCategory::Stdout),
2387 // output: "Third item in group 1".to_string(),
2388 // data: None,
2389 // variables_reference: None,
2390 // source: None,
2391 // line: None,
2392 // column: None,
2393 // group: None,
2394 // location_reference: None,
2395 // }))
2396 // .await;
2397
2398 // client
2399 // .fake_event(dap::messages::Events::Output(dap::OutputEvent {
2400 // category: Some(dap::OutputEventCategory::Stdout),
2401 // output: "Second item".to_string(),
2402 // data: None,
2403 // variables_reference: None,
2404 // source: None,
2405 // line: None,
2406 // column: None,
2407 // group: Some(dap::OutputEventGroup::End),
2408 // location_reference: None,
2409 // }))
2410 // .await;
2411
2412 // host_cx.run_until_parked();
2413 // remote_cx.run_until_parked();
2414
2415 // active_session(remote_workspace, remote_cx).update(remote_cx, |session_item, cx| {
2416 // session_item
2417 // .mode()
2418 // .as_running()
2419 // .unwrap()
2420 // .read(cx)
2421 // .console()
2422 // .update(cx, |console, cx| {
2423 // console.editor().update(cx, |editor, cx| {
2424 // pretty_assertions::assert_eq!(
2425 // "
2426 // <First line
2427 // First group
2428 // First item in group 1
2429 // Second item in group 1
2430 // Second group
2431 // First item in group 2
2432 // Second item in group 2
2433 // End group 2
2434 // ⋯ End group 3
2435 // Third item in group 1
2436 // Second item
2437 // "
2438 // .unindent(),
2439 // editor.display_text(cx)
2440 // );
2441 // })
2442 // });
2443 // });
2444
2445 // let shutdown_client = host_project.update(host_cx, |project, cx| {
2446 // project.dap_store().update(cx, |dap_store, cx| {
2447 // dap_store.shutdown_session(&session.read(cx).session_id(), cx)
2448 // })
2449 // });
2450
2451 // shutdown_client.await.unwrap();
2452}