console.rs

  1use crate::{
  2    tests::{active_debug_session_panel, start_debug_session},
  3    *,
  4};
  5use dap::requests::StackTrace;
  6use gpui::{BackgroundExecutor, TestAppContext, VisualTestContext};
  7use project::{FakeFs, Project};
  8use serde_json::json;
  9use tests::{init_test, init_test_workspace};
 10
 11#[gpui::test]
 12async fn test_handle_output_event(executor: BackgroundExecutor, cx: &mut TestAppContext) {
 13    init_test(cx);
 14
 15    let fs = FakeFs::new(executor.clone());
 16
 17    fs.insert_tree(
 18        "/project",
 19        json!({
 20            "main.rs": "First line\nSecond line\nThird line\nFourth line",
 21        }),
 22    )
 23    .await;
 24
 25    let project = Project::test(fs, ["/project".as_ref()], cx).await;
 26    let workspace = init_test_workspace(&project, cx).await;
 27    let cx = &mut VisualTestContext::from_window(*workspace, cx);
 28    workspace
 29        .update(cx, |workspace, window, cx| {
 30            workspace.focus_panel::<DebugPanel>(window, cx);
 31        })
 32        .unwrap();
 33
 34    let session = start_debug_session(&workspace, cx, |_| {}).unwrap();
 35    let client = session.update(cx, |session, _| session.adapter_client().unwrap());
 36
 37    client.on_request::<StackTrace, _>(move |_, _| {
 38        Ok(dap::StackTraceResponse {
 39            stack_frames: Vec::default(),
 40            total_frames: None,
 41        })
 42    });
 43
 44    client
 45        .fake_event(dap::messages::Events::Output(dap::OutputEvent {
 46            category: None,
 47            output: "First console output line before thread stopped!".to_string(),
 48            data: None,
 49            variables_reference: None,
 50            source: None,
 51            line: None,
 52            column: None,
 53            group: None,
 54            location_reference: None,
 55        }))
 56        .await;
 57
 58    client
 59        .fake_event(dap::messages::Events::Output(dap::OutputEvent {
 60            category: Some(dap::OutputEventCategory::Stdout),
 61            output: "First output line before thread stopped!".to_string(),
 62            data: None,
 63            variables_reference: None,
 64            source: None,
 65            line: None,
 66            column: None,
 67            group: None,
 68            location_reference: None,
 69        }))
 70        .await;
 71
 72    client
 73        .fake_event(dap::messages::Events::Stopped(dap::StoppedEvent {
 74            reason: dap::StoppedEventReason::Pause,
 75            description: None,
 76            thread_id: Some(1),
 77            preserve_focus_hint: None,
 78            text: None,
 79            all_threads_stopped: None,
 80            hit_breakpoint_ids: None,
 81        }))
 82        .await;
 83
 84    cx.run_until_parked();
 85
 86    let running_state =
 87        active_debug_session_panel(workspace, cx).update_in(cx, |item, window, cx| {
 88            cx.focus_self(window);
 89            item.mode()
 90                .as_running()
 91                .expect("Session should be running by this point")
 92                .clone()
 93        });
 94
 95    cx.run_until_parked();
 96
 97    // assert we have output from before the thread stopped
 98    workspace
 99        .update(cx, |workspace, _window, cx| {
100            let debug_panel = workspace.panel::<DebugPanel>(cx).unwrap();
101            let active_debug_session_panel = debug_panel
102                .update(cx, |this, _| this.active_session())
103                .unwrap();
104
105            assert_eq!(
106                "First console output line before thread stopped!\nFirst output line before thread stopped!\n",
107                active_debug_session_panel.read(cx).mode().as_running().unwrap().read(cx).console().read(cx).editor().read(cx).text(cx).as_str()
108            );
109        })
110        .unwrap();
111
112    client
113        .fake_event(dap::messages::Events::Output(dap::OutputEvent {
114            category: Some(dap::OutputEventCategory::Stdout),
115            output: "Second output line after thread stopped!".to_string(),
116            data: None,
117            variables_reference: None,
118            source: None,
119            line: None,
120            column: None,
121            group: None,
122            location_reference: None,
123        }))
124        .await;
125
126    client
127        .fake_event(dap::messages::Events::Output(dap::OutputEvent {
128            category: Some(dap::OutputEventCategory::Console),
129            output: "Second console output line after thread stopped!".to_string(),
130            data: None,
131            variables_reference: None,
132            source: None,
133            line: None,
134            column: None,
135            group: None,
136            location_reference: None,
137        }))
138        .await;
139
140    cx.run_until_parked();
141    running_state.update(cx, |_, cx| {
142        cx.refresh_windows();
143    });
144    cx.run_until_parked();
145
146    // assert we have output from before and after the thread stopped
147    workspace
148        .update(cx, |workspace, _window, cx| {
149            let debug_panel = workspace.panel::<DebugPanel>(cx).unwrap();
150            let active_session_panel = debug_panel
151                .update(cx, |this, _| this.active_session())
152                .unwrap();
153
154            assert_eq!(
155                "First console output line before thread stopped!\nFirst output line before thread stopped!\nSecond output line after thread stopped!\nSecond console output line after thread stopped!\n",
156                active_session_panel.read(cx).mode().as_running().unwrap().read(cx).console().read(cx).editor().read(cx).text(cx).as_str()
157            );
158        })
159        .unwrap();
160}
161
162// #[gpui::test]
163// async fn test_grouped_output(executor: BackgroundExecutor, cx: &mut TestAppContext) {
164//     init_test(cx);
165
166//     let fs = FakeFs::new(executor.clone());
167
168//     fs.insert_tree(
169//         "/project",
170//         json!({
171//             "main.rs": "First line\nSecond line\nThird line\nFourth line",
172//         }),
173//     )
174//     .await;
175
176//     let project = Project::test(fs, ["/project".as_ref()], cx).await;
177//     let workspace = init_test_workspace(&project, cx).await;
178//     let cx = &mut VisualTestContext::from_window(*workspace, cx);
179
180//     let task = project.update(cx, |project, cx| {
181//         project.start_debug_session(
182//             dap::test_config(dap::DebugRequestType::Launch, None, None),
183//             cx,
184//         )
185//     });
186
187//     let session = task.await.unwrap();
188//     let client = session.update(cx, |session, _| session.adapter_client().unwrap());
189
190//     client
191//         .on_request::<StackTrace, _>(move |_, _| {
192//             Ok(dap::StackTraceResponse {
193//                 stack_frames: Vec::default(),
194//                 total_frames: None,
195//             })
196//         })
197//         .await;
198
199//     client
200//         .fake_event(dap::messages::Events::Stopped(dap::StoppedEvent {
201//             reason: dap::StoppedEventReason::Pause,
202//             description: None,
203//             thread_id: Some(1),
204//             preserve_focus_hint: None,
205//             text: None,
206//             all_threads_stopped: None,
207//             hit_breakpoint_ids: None,
208//         }))
209//         .await;
210
211//     client
212//         .fake_event(dap::messages::Events::Output(dap::OutputEvent {
213//             category: None,
214//             output: "First line".to_string(),
215//             data: None,
216//             variables_reference: None,
217//             source: None,
218//             line: None,
219//             column: None,
220//             group: None,
221//             location_reference: None,
222//         }))
223//         .await;
224
225//     client
226//         .fake_event(dap::messages::Events::Output(dap::OutputEvent {
227//             category: Some(dap::OutputEventCategory::Stdout),
228//             output: "First group".to_string(),
229//             data: None,
230//             variables_reference: None,
231//             source: None,
232//             line: None,
233//             column: None,
234//             group: Some(dap::OutputEventGroup::Start),
235//             location_reference: None,
236//         }))
237//         .await;
238
239//     client
240//         .fake_event(dap::messages::Events::Output(dap::OutputEvent {
241//             category: Some(dap::OutputEventCategory::Stdout),
242//             output: "First item in group 1".to_string(),
243//             data: None,
244//             variables_reference: None,
245//             source: None,
246//             line: None,
247//             column: None,
248//             group: None,
249//             location_reference: None,
250//         }))
251//         .await;
252
253//     client
254//         .fake_event(dap::messages::Events::Output(dap::OutputEvent {
255//             category: Some(dap::OutputEventCategory::Stdout),
256//             output: "Second item in group 1".to_string(),
257//             data: None,
258//             variables_reference: None,
259//             source: None,
260//             line: None,
261//             column: None,
262//             group: None,
263//             location_reference: None,
264//         }))
265//         .await;
266
267//     client
268//         .fake_event(dap::messages::Events::Output(dap::OutputEvent {
269//             category: Some(dap::OutputEventCategory::Stdout),
270//             output: "Second group".to_string(),
271//             data: None,
272//             variables_reference: None,
273//             source: None,
274//             line: None,
275//             column: None,
276//             group: Some(dap::OutputEventGroup::Start),
277//             location_reference: None,
278//         }))
279//         .await;
280
281//     client
282//         .fake_event(dap::messages::Events::Output(dap::OutputEvent {
283//             category: Some(dap::OutputEventCategory::Stdout),
284//             output: "First item in group 2".to_string(),
285//             data: None,
286//             variables_reference: None,
287//             source: None,
288//             line: None,
289//             column: None,
290//             group: None,
291//             location_reference: None,
292//         }))
293//         .await;
294
295//     client
296//         .fake_event(dap::messages::Events::Output(dap::OutputEvent {
297//             category: Some(dap::OutputEventCategory::Stdout),
298//             output: "Second item in group 2".to_string(),
299//             data: None,
300//             variables_reference: None,
301//             source: None,
302//             line: None,
303//             column: None,
304//             group: None,
305//             location_reference: None,
306//         }))
307//         .await;
308
309//     client
310//         .fake_event(dap::messages::Events::Output(dap::OutputEvent {
311//             category: Some(dap::OutputEventCategory::Stdout),
312//             output: "End group 2".to_string(),
313//             data: None,
314//             variables_reference: None,
315//             source: None,
316//             line: None,
317//             column: None,
318//             group: Some(dap::OutputEventGroup::End),
319//             location_reference: None,
320//         }))
321//         .await;
322
323//     client
324//         .fake_event(dap::messages::Events::Output(dap::OutputEvent {
325//             category: Some(dap::OutputEventCategory::Stdout),
326//             output: "Third group".to_string(),
327//             data: None,
328//             variables_reference: None,
329//             source: None,
330//             line: None,
331//             column: None,
332//             group: Some(dap::OutputEventGroup::StartCollapsed),
333//             location_reference: None,
334//         }))
335//         .await;
336
337//     client
338//         .fake_event(dap::messages::Events::Output(dap::OutputEvent {
339//             category: Some(dap::OutputEventCategory::Stdout),
340//             output: "First item in group 3".to_string(),
341//             data: None,
342//             variables_reference: None,
343//             source: None,
344//             line: None,
345//             column: None,
346//             group: None,
347//             location_reference: None,
348//         }))
349//         .await;
350
351//     client
352//         .fake_event(dap::messages::Events::Output(dap::OutputEvent {
353//             category: Some(dap::OutputEventCategory::Stdout),
354//             output: "Second item in group 3".to_string(),
355//             data: None,
356//             variables_reference: None,
357//             source: None,
358//             line: None,
359//             column: None,
360//             group: None,
361//             location_reference: None,
362//         }))
363//         .await;
364
365//     client
366//         .fake_event(dap::messages::Events::Output(dap::OutputEvent {
367//             category: Some(dap::OutputEventCategory::Stdout),
368//             output: "End group 3".to_string(),
369//             data: None,
370//             variables_reference: None,
371//             source: None,
372//             line: None,
373//             column: None,
374//             group: Some(dap::OutputEventGroup::End),
375//             location_reference: None,
376//         }))
377//         .await;
378
379//     client
380//         .fake_event(dap::messages::Events::Output(dap::OutputEvent {
381//             category: Some(dap::OutputEventCategory::Stdout),
382//             output: "Third item in group 1".to_string(),
383//             data: None,
384//             variables_reference: None,
385//             source: None,
386//             line: None,
387//             column: None,
388//             group: None,
389//             location_reference: None,
390//         }))
391//         .await;
392
393//     client
394//         .fake_event(dap::messages::Events::Output(dap::OutputEvent {
395//             category: Some(dap::OutputEventCategory::Stdout),
396//             output: "Second item".to_string(),
397//             data: None,
398//             variables_reference: None,
399//             source: None,
400//             line: None,
401//             column: None,
402//             group: Some(dap::OutputEventGroup::End),
403//             location_reference: None,
404//         }))
405//         .await;
406
407//     cx.run_until_parked();
408
409//     active_debug_session_panel(workspace, cx).update(cx, |debug_panel_item, cx| {
410//         debug_panel_item
411//             .mode()
412//             .as_running()
413//             .unwrap()
414//             .update(cx, |running_state, cx| {
415//                 running_state.console().update(cx, |console, cx| {
416//                     console.editor().update(cx, |editor, cx| {
417//                         pretty_assertions::assert_eq!(
418//                             "
419//                         First line
420//                         First group
421//                             First item in group 1
422//                             Second item in group 1
423//                             Second group
424//                                 First item in group 2
425//                                 Second item in group 2
426//                             End group 2
427//                         ⋯    End group 3
428//                             Third item in group 1
429//                         Second item
430//                     "
431//                             .unindent(),
432//                             editor.display_text(cx)
433//                         );
434//                     })
435//                 });
436//             });
437//     });
438
439//     let shutdown_session = project.update(cx, |project, cx| {
440//         project.dap_store().update(cx, |dap_store, cx| {
441//             dap_store.shutdown_session(session.read(cx).session_id(), cx)
442//         })
443//     });
444
445//     shutdown_session.await.unwrap();
446// }
447
448// todo(debugger): enable this again
449// #[gpui::test]
450// async fn test_evaluate_expression(executor: BackgroundExecutor, cx: &mut TestAppContext) {
451//     init_test(cx);
452
453//     const NEW_VALUE: &str = "{nested1: \"Nested 1 updated\", nested2: \"Nested 2 updated\"}";
454
455//     let called_evaluate = Arc::new(AtomicBool::new(false));
456
457//     let fs = FakeFs::new(executor.clone());
458
459//     let test_file_content = r#"
460//         const variable1 = {
461//             nested1: "Nested 1",
462//             nested2: "Nested 2",
463//         };
464//         const variable2 = "Value 2";
465//         const variable3 = "Value 3";
466//     "#
467//     .unindent();
468
469//     fs.insert_tree(
470//         "/project",
471//         json!({
472//            "src": {
473//                "test.js": test_file_content,
474//            }
475//         }),
476//     )
477//     .await;
478
479//     let project = Project::test(fs, ["/project".as_ref()], cx).await;
480//     let workspace = init_test_workspace(&project, cx).await;
481//     let cx = &mut VisualTestContext::from_window(*workspace, cx);
482
483//     let task = project.update(cx, |project, cx| {
484//         project.start_debug_session(dap::test_config(None), cx)
485//     });
486
487//     let session = task.await.unwrap();
488//     let client = session.update(cx, |session, _| session.adapter_client().unwrap());
489
490//     client
491//         .on_request::<Threads, _>(move |_, _| {
492//             Ok(dap::ThreadsResponse {
493//                 threads: vec![dap::Thread {
494//                     id: 1,
495//                     name: "Thread 1".into(),
496//                 }],
497//             })
498//         })
499//         .await;
500
501//     let stack_frames = vec![StackFrame {
502//         id: 1,
503//         name: "Stack Frame 1".into(),
504//         source: Some(dap::Source {
505//             name: Some("test.js".into()),
506//             path: Some("/project/src/test.js".into()),
507//             source_reference: None,
508//             presentation_hint: None,
509//             origin: None,
510//             sources: None,
511//             adapter_data: None,
512//             checksums: None,
513//         }),
514//         line: 3,
515//         column: 1,
516//         end_line: None,
517//         end_column: None,
518//         can_restart: None,
519//         instruction_pointer_reference: None,
520//         module_id: None,
521//         presentation_hint: None,
522//     }];
523
524//     client
525//         .on_request::<StackTrace, _>({
526//             let stack_frames = Arc::new(stack_frames.clone());
527//             move |_, args| {
528//                 assert_eq!(1, args.thread_id);
529
530//                 Ok(dap::StackTraceResponse {
531//                     stack_frames: (*stack_frames).clone(),
532//                     total_frames: None,
533//                 })
534//             }
535//         })
536//         .await;
537
538//     let scopes = vec![
539//         Scope {
540//             name: "Scope 1".into(),
541//             presentation_hint: None,
542//             variables_reference: 2,
543//             named_variables: None,
544//             indexed_variables: None,
545//             expensive: false,
546//             source: None,
547//             line: None,
548//             column: None,
549//             end_line: None,
550//             end_column: None,
551//         },
552//         Scope {
553//             name: "Scope 2".into(),
554//             presentation_hint: None,
555//             variables_reference: 4,
556//             named_variables: None,
557//             indexed_variables: None,
558//             expensive: false,
559//             source: None,
560//             line: None,
561//             column: None,
562//             end_line: None,
563//             end_column: None,
564//         },
565//     ];
566
567//     client
568//         .on_request::<Scopes, _>({
569//             let scopes = Arc::new(scopes.clone());
570//             move |_, args| {
571//                 assert_eq!(1, args.frame_id);
572
573//                 Ok(dap::ScopesResponse {
574//                     scopes: (*scopes).clone(),
575//                 })
576//             }
577//         })
578//         .await;
579
580//     let scope1_variables = Arc::new(Mutex::new(vec![
581//         Variable {
582//             name: "variable1".into(),
583//             value: "{nested1: \"Nested 1\", nested2: \"Nested 2\"}".into(),
584//             type_: None,
585//             presentation_hint: None,
586//             evaluate_name: None,
587//             variables_reference: 3,
588//             named_variables: None,
589//             indexed_variables: None,
590//             memory_reference: None,
591//             declaration_location_reference: None,
592//             value_location_reference: None,
593//         },
594//         Variable {
595//             name: "variable2".into(),
596//             value: "Value 2".into(),
597//             type_: None,
598//             presentation_hint: None,
599//             evaluate_name: None,
600//             variables_reference: 0,
601//             named_variables: None,
602//             indexed_variables: None,
603//             memory_reference: None,
604//             declaration_location_reference: None,
605//             value_location_reference: None,
606//         },
607//     ]));
608
609//     let nested_variables = vec![
610//         Variable {
611//             name: "nested1".into(),
612//             value: "Nested 1".into(),
613//             type_: None,
614//             presentation_hint: None,
615//             evaluate_name: None,
616//             variables_reference: 0,
617//             named_variables: None,
618//             indexed_variables: None,
619//             memory_reference: None,
620//             declaration_location_reference: None,
621//             value_location_reference: None,
622//         },
623//         Variable {
624//             name: "nested2".into(),
625//             value: "Nested 2".into(),
626//             type_: None,
627//             presentation_hint: None,
628//             evaluate_name: None,
629//             variables_reference: 0,
630//             named_variables: None,
631//             indexed_variables: None,
632//             memory_reference: None,
633//             declaration_location_reference: None,
634//             value_location_reference: None,
635//         },
636//     ];
637
638//     let scope2_variables = vec![Variable {
639//         name: "variable3".into(),
640//         value: "Value 3".into(),
641//         type_: None,
642//         presentation_hint: None,
643//         evaluate_name: None,
644//         variables_reference: 0,
645//         named_variables: None,
646//         indexed_variables: None,
647//         memory_reference: None,
648//         declaration_location_reference: None,
649//         value_location_reference: None,
650//     }];
651
652//     client
653//         .on_request::<Variables, _>({
654//             let scope1_variables = scope1_variables.clone();
655//             let nested_variables = Arc::new(nested_variables.clone());
656//             let scope2_variables = Arc::new(scope2_variables.clone());
657//             move |_, args| match args.variables_reference {
658//                 4 => Ok(dap::VariablesResponse {
659//                     variables: (*scope2_variables).clone(),
660//                 }),
661//                 3 => Ok(dap::VariablesResponse {
662//                     variables: (*nested_variables).clone(),
663//                 }),
664//                 2 => Ok(dap::VariablesResponse {
665//                     variables: scope1_variables.lock().unwrap().clone(),
666//                 }),
667//                 id => unreachable!("unexpected variables reference {id}"),
668//             }
669//         })
670//         .await;
671
672//     client
673//         .on_request::<Evaluate, _>({
674//             let called_evaluate = called_evaluate.clone();
675//             let scope1_variables = scope1_variables.clone();
676//             move |_, args| {
677//                 called_evaluate.store(true, Ordering::SeqCst);
678
679//                 assert_eq!(format!("$variable1 = {}", NEW_VALUE), args.expression);
680//                 assert_eq!(Some(1), args.frame_id);
681//                 assert_eq!(Some(dap::EvaluateArgumentsContext::Variables), args.context);
682
683//                 scope1_variables.lock().unwrap()[0].value = NEW_VALUE.to_string();
684
685//                 Ok(dap::EvaluateResponse {
686//                     result: NEW_VALUE.into(),
687//                     type_: None,
688//                     presentation_hint: None,
689//                     variables_reference: 0,
690//                     named_variables: None,
691//                     indexed_variables: None,
692//                     memory_reference: None,
693//                     value_location_reference: None,
694//                 })
695//             }
696//         })
697//         .await;
698
699//     client
700//         .fake_event(dap::messages::Events::Stopped(dap::StoppedEvent {
701//             reason: dap::StoppedEventReason::Pause,
702//             description: None,
703//             thread_id: Some(1),
704//             preserve_focus_hint: None,
705//             text: None,
706//             all_threads_stopped: None,
707//             hit_breakpoint_ids: None,
708//         }))
709//         .await;
710
711//     cx.run_until_parked();
712
713//     // toggle nested variables for scope 1
714//     active_debug_session_panel(workspace, cx).update(cx, |debug_panel_item, cx| {
715//         debug_panel_item
716//             .mode()
717//             .as_running()
718//             .unwrap()
719//             .update(cx, |running_state, cx| {
720//                 running_state
721//                     .variable_list()
722//                     .update(cx, |variable_list, cx| {
723//                         variable_list.toggle_variable(
724//                             &VariablePath {
725//                                 indices: Arc::from([scopes[0].variables_reference]),
726//                             },
727//                             cx,
728//                         );
729//                     });
730//             });
731//     });
732
733//     cx.run_until_parked();
734
735//     active_debug_session_panel(workspace, cx).update_in(cx, |debug_panel_item, window, cx| {
736//         debug_panel_item
737//             .mode()
738//             .as_running()
739//             .unwrap()
740//             .update(cx, |running_state, cx| {
741//                 running_state.console().update(cx, |console, item_cx| {
742//                     console
743//                         .query_bar()
744//                         .update(item_cx, |query_bar, console_cx| {
745//                             query_bar.set_text(
746//                                 format!("$variable1 = {}", NEW_VALUE),
747//                                 window,
748//                                 console_cx,
749//                             );
750//                         });
751
752//                     console.evaluate(&menu::Confirm, window, item_cx);
753//                 });
754//             });
755//     });
756
757//     cx.run_until_parked();
758
759//     active_debug_session_panel(workspace, cx).update(cx, |debug_panel_item, cx| {
760//         assert_eq!(
761//             "",
762//             debug_panel_item
763//                 .mode()
764//                 .as_running()
765//                 .unwrap()
766//                 .read(cx)
767//                 .console()
768//                 .read(cx)
769//                 .query_bar()
770//                 .read(cx)
771//                 .text(cx)
772//                 .as_str()
773//         );
774
775//         assert_eq!(
776//             format!("{}\n", NEW_VALUE),
777//             debug_panel_item
778//                 .mode()
779//                 .as_running()
780//                 .unwrap()
781//                 .read(cx)
782//                 .console()
783//                 .read(cx)
784//                 .editor()
785//                 .read(cx)
786//                 .text(cx)
787//                 .as_str()
788//         );
789
790//         debug_panel_item
791//             .mode()
792//             .as_running()
793//             .unwrap()
794//             .update(cx, |running_state, cx| {
795//                 running_state
796//                     .variable_list()
797//                     .update(cx, |variable_list, _| {
798//                         let scope1_variables = scope1_variables.lock().unwrap().clone();
799
800//                         // scope 1
801//                         // assert_eq!(
802//                         //     vec![
803//                         //         VariableContainer {
804//                         //             container_reference: scopes[0].variables_reference,
805//                         //             variable: scope1_variables[0].clone(),
806//                         //             depth: 1,
807//                         //         },
808//                         //         VariableContainer {
809//                         //             container_reference: scope1_variables[0].variables_reference,
810//                         //             variable: nested_variables[0].clone(),
811//                         //             depth: 2,
812//                         //         },
813//                         //         VariableContainer {
814//                         //             container_reference: scope1_variables[0].variables_reference,
815//                         //             variable: nested_variables[1].clone(),
816//                         //             depth: 2,
817//                         //         },
818//                         //         VariableContainer {
819//                         //             container_reference: scopes[0].variables_reference,
820//                         //             variable: scope1_variables[1].clone(),
821//                         //             depth: 1,
822//                         //         },
823//                         //     ],
824//                         //     variable_list.variables_by_scope(1, 2).unwrap().variables()
825//                         // );
826
827//                         // scope 2
828//                         // assert_eq!(
829//                         //     vec![VariableContainer {
830//                         //         container_reference: scopes[1].variables_reference,
831//                         //         variable: scope2_variables[0].clone(),
832//                         //         depth: 1,
833//                         //     }],
834//                         //     variable_list.variables_by_scope(1, 4).unwrap().variables()
835//                         // );
836
837//                         variable_list.assert_visual_entries(vec![
838//                             "v Scope 1",
839//                             "    v variable1",
840//                             "       > nested1",
841//                             "       > nested2",
842//                             "    > variable2",
843//                         ]);
844
845//                         // assert visual entries
846//                         // assert_eq!(
847//                         //     vec![
848//                         //         VariableListEntry::Scope(scopes[0].clone()),
849//                         //         VariableListEntry::Variable {
850//                         //             depth: 1,
851//                         //             scope: Arc::new(scopes[0].clone()),
852//                         //             has_children: true,
853//                         //             variable: Arc::new(scope1_variables[0].clone()),
854//                         //             container_reference: scopes[0].variables_reference,
855//                         //         },
856//                         //         VariableListEntry::Variable {
857//                         //             depth: 2,
858//                         //             scope: Arc::new(scopes[0].clone()),
859//                         //             has_children: false,
860//                         //             variable: Arc::new(nested_variables[0].clone()),
861//                         //             container_reference: scope1_variables[0].variables_reference,
862//                         //         },
863//                         //         VariableListEntry::Variable {
864//                         //             depth: 2,
865//                         //             scope: Arc::new(scopes[0].clone()),
866//                         //             has_children: false,
867//                         //             variable: Arc::new(nested_variables[1].clone()),
868//                         //             container_reference: scope1_variables[0].variables_reference,
869//                         //         },
870//                         //         VariableListEntry::Variable {
871//                         //             depth: 1,
872//                         //             scope: Arc::new(scopes[0].clone()),
873//                         //             has_children: false,
874//                         //             variable: Arc::new(scope1_variables[1].clone()),
875//                         //             container_reference: scopes[0].variables_reference,
876//                         //         },
877//                         //         VariableListEntry::Scope(scopes[1].clone()),
878//                         //     ],
879//                         //     variable_list.entries().get(&1).unwrap().clone()
880//                         // );
881//                     });
882//             });
883//     });
884
885//     assert!(
886//         called_evaluate.load(std::sync::atomic::Ordering::SeqCst),
887//         "Expected evaluate request to be called"
888//     );
889
890//     let shutdown_session = project.update(cx, |project, cx| {
891//         project.dap_store().update(cx, |dap_store, cx| {
892//             dap_store.shutdown_session(&session.read(cx).session_id(), cx)
893//         })
894//     });
895
896//     shutdown_session.await.unwrap();
897// }