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