console.rs

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