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