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