console.rs

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