inline_values.rs

   1use std::{path::Path, sync::Arc};
   2
   3use dap::{Scope, StackFrame, Variable, requests::Variables};
   4use editor::{Editor, EditorMode, MultiBuffer, actions::ToggleInlineValues};
   5use gpui::{BackgroundExecutor, TestAppContext, VisualTestContext};
   6use language::{Language, LanguageConfig, LanguageMatcher, tree_sitter_python, tree_sitter_rust};
   7use project::{FakeFs, Project};
   8use serde_json::json;
   9use unindent::Unindent as _;
  10use util::path;
  11
  12use crate::{
  13    debugger_panel::DebugPanel,
  14    tests::{active_debug_session_panel, init_test, init_test_workspace, start_debug_session},
  15};
  16
  17#[gpui::test]
  18async fn test_rust_inline_values(executor: BackgroundExecutor, cx: &mut TestAppContext) {
  19    init_test(cx);
  20
  21    fn stack_frame_for_line(line: u64) -> dap::StackFrame {
  22        StackFrame {
  23            id: 1,
  24            name: "Stack Frame 1".into(),
  25            source: Some(dap::Source {
  26                name: Some("main.rs".into()),
  27                path: Some(path!("/project/main.rs").into()),
  28                source_reference: None,
  29                presentation_hint: None,
  30                origin: None,
  31                sources: None,
  32                adapter_data: None,
  33                checksums: None,
  34            }),
  35            line,
  36            column: 1,
  37            end_line: None,
  38            end_column: None,
  39            can_restart: None,
  40            instruction_pointer_reference: None,
  41            module_id: None,
  42            presentation_hint: None,
  43        }
  44    }
  45
  46    let fs = FakeFs::new(executor.clone());
  47    let source_code = r#"
  48static mut GLOBAL: usize = 1;
  49
  50fn main() {
  51    let x = 10;
  52    let value = 42;
  53    let y = 4;
  54    let tester = {
  55        let y = 10;
  56        let y = 5;
  57        let b = 3;
  58        vec![y, 20, 30]
  59    };
  60
  61    let caller = || {
  62        let x = 3;
  63        println!("x={}", x);
  64    };
  65
  66    caller();
  67
  68    unsafe {
  69        GLOBAL = 2;
  70    }
  71
  72    let result = value * 2 * x;
  73    println!("Simple test executed: value={}, result={}", value, result);
  74    assert!(true);
  75}
  76"#
  77    .unindent();
  78    fs.insert_tree(path!("/project"), json!({ "main.rs": source_code }))
  79        .await;
  80
  81    let project = Project::test(fs.clone(), [path!("/project").as_ref()], cx).await;
  82    let workspace = init_test_workspace(&project, cx).await;
  83    workspace
  84        .update(cx, |workspace, window, cx| {
  85            workspace.focus_panel::<DebugPanel>(window, cx);
  86        })
  87        .unwrap();
  88    let cx = &mut VisualTestContext::from_window(*workspace, cx);
  89
  90    let session = start_debug_session(&workspace, cx, |_| {}).unwrap();
  91    let client = session.update(cx, |session, _| session.adapter_client().unwrap());
  92
  93    client.on_request::<dap::requests::Threads, _>(move |_, _| {
  94        Ok(dap::ThreadsResponse {
  95            threads: vec![dap::Thread {
  96                id: 1,
  97                name: "Thread 1".into(),
  98            }],
  99        })
 100    });
 101
 102    client.on_request::<dap::requests::StackTrace, _>(move |_, _| {
 103        Ok(dap::StackTraceResponse {
 104            stack_frames: vec![stack_frame_for_line(4)],
 105            total_frames: None,
 106        })
 107    });
 108
 109    client.on_request::<dap::requests::Evaluate, _>(move |_, args| {
 110        assert_eq!("GLOBAL", args.expression);
 111        Ok(dap::EvaluateResponse {
 112            result: "1".into(),
 113            type_: None,
 114            presentation_hint: None,
 115            variables_reference: 0,
 116            named_variables: None,
 117            indexed_variables: None,
 118            memory_reference: None,
 119            value_location_reference: None,
 120        })
 121    });
 122
 123    let local_variables = vec![
 124        Variable {
 125            name: "x".into(),
 126            value: "10".into(),
 127            type_: None,
 128            presentation_hint: None,
 129            evaluate_name: None,
 130            variables_reference: 0,
 131            named_variables: None,
 132            indexed_variables: None,
 133            memory_reference: None,
 134            declaration_location_reference: None,
 135            value_location_reference: None,
 136        },
 137        Variable {
 138            name: "y".into(),
 139            value: "4".into(),
 140            type_: None,
 141            presentation_hint: None,
 142            evaluate_name: None,
 143            variables_reference: 0,
 144            named_variables: None,
 145            indexed_variables: None,
 146            memory_reference: None,
 147            declaration_location_reference: None,
 148            value_location_reference: None,
 149        },
 150        Variable {
 151            name: "value".into(),
 152            value: "42".into(),
 153            type_: None,
 154            presentation_hint: None,
 155            evaluate_name: None,
 156            variables_reference: 0,
 157            named_variables: None,
 158            indexed_variables: None,
 159            memory_reference: None,
 160            declaration_location_reference: None,
 161            value_location_reference: None,
 162        },
 163    ];
 164
 165    client.on_request::<Variables, _>({
 166        let local_variables = Arc::new(local_variables.clone());
 167        move |_, _| {
 168            Ok(dap::VariablesResponse {
 169                variables: (*local_variables).clone(),
 170            })
 171        }
 172    });
 173
 174    client.on_request::<dap::requests::Scopes, _>(move |_, _| {
 175        Ok(dap::ScopesResponse {
 176            scopes: vec![Scope {
 177                name: "Locale".into(),
 178                presentation_hint: None,
 179                variables_reference: 2,
 180                named_variables: None,
 181                indexed_variables: None,
 182                expensive: false,
 183                source: None,
 184                line: None,
 185                column: None,
 186                end_line: None,
 187                end_column: None,
 188            }],
 189        })
 190    });
 191
 192    client
 193        .fake_event(dap::messages::Events::Stopped(dap::StoppedEvent {
 194            reason: dap::StoppedEventReason::Pause,
 195            description: None,
 196            thread_id: Some(1),
 197            preserve_focus_hint: None,
 198            text: None,
 199            all_threads_stopped: None,
 200            hit_breakpoint_ids: None,
 201        }))
 202        .await;
 203
 204    cx.run_until_parked();
 205
 206    let project_path = Path::new(path!("/project"));
 207    let worktree = project
 208        .update(cx, |project, cx| project.find_worktree(project_path, cx))
 209        .expect("This worktree should exist in project")
 210        .0;
 211
 212    let worktree_id = workspace
 213        .update(cx, |_, _, cx| worktree.read(cx).id())
 214        .unwrap();
 215
 216    let buffer = project
 217        .update(cx, |project, cx| {
 218            project.open_buffer((worktree_id, "main.rs"), cx)
 219        })
 220        .await
 221        .unwrap();
 222
 223    buffer.update(cx, |buffer, cx| {
 224        buffer.set_language(Some(Arc::new(rust_lang())), cx);
 225    });
 226
 227    let (editor, cx) = cx.add_window_view(|window, cx| {
 228        Editor::new(
 229            EditorMode::full(),
 230            MultiBuffer::build_from_buffer(buffer, cx),
 231            Some(project),
 232            window,
 233            cx,
 234        )
 235    });
 236
 237    active_debug_session_panel(workspace, cx).update_in(cx, |_, window, cx| {
 238        cx.focus_self(window);
 239    });
 240    cx.run_until_parked();
 241
 242    editor.update_in(cx, |editor, window, cx| {
 243        if !editor.inline_values_enabled() {
 244            editor.toggle_inline_values(&ToggleInlineValues, window, cx);
 245        }
 246    });
 247
 248    cx.run_until_parked();
 249
 250    editor.update_in(cx, |editor, window, cx| {
 251        pretty_assertions::assert_eq!(
 252            r#"
 253    static mut GLOBAL: 1: usize = 1;
 254
 255    fn main() {
 256        let x = 10;
 257        let value = 42;
 258        let y = 4;
 259        let tester = {
 260            let y = 10;
 261            let y = 5;
 262            let b = 3;
 263            vec![y, 20, 30]
 264        };
 265
 266        let caller = || {
 267            let x = 3;
 268            println!("x={}", x);
 269        };
 270
 271        caller();
 272
 273        unsafe {
 274            GLOBAL = 2;
 275        }
 276
 277        let result = value * 2 * x;
 278        println!("Simple test executed: value={}, result={}", value, result);
 279        assert!(true);
 280    }
 281    "#
 282            .unindent(),
 283            editor.snapshot(window, cx).text()
 284        );
 285    });
 286
 287    client.on_request::<dap::requests::StackTrace, _>(move |_, _| {
 288        Ok(dap::StackTraceResponse {
 289            stack_frames: vec![stack_frame_for_line(5)],
 290            total_frames: None,
 291        })
 292    });
 293    client
 294        .fake_event(dap::messages::Events::Stopped(dap::StoppedEvent {
 295            reason: dap::StoppedEventReason::Pause,
 296            description: None,
 297            thread_id: Some(1),
 298            preserve_focus_hint: None,
 299            text: None,
 300            all_threads_stopped: None,
 301            hit_breakpoint_ids: None,
 302        }))
 303        .await;
 304
 305    cx.run_until_parked();
 306
 307    editor.update_in(cx, |editor, window, cx| {
 308        pretty_assertions::assert_eq!(
 309            r#"
 310    static mut GLOBAL: 1: usize = 1;
 311
 312    fn main() {
 313        let x: 10 = 10;
 314        let value = 42;
 315        let y = 4;
 316        let tester = {
 317            let y = 10;
 318            let y = 5;
 319            let b = 3;
 320            vec![y, 20, 30]
 321        };
 322
 323        let caller = || {
 324            let x = 3;
 325            println!("x={}", x);
 326        };
 327
 328        caller();
 329
 330        unsafe {
 331            GLOBAL = 2;
 332        }
 333
 334        let result = value * 2 * x;
 335        println!("Simple test executed: value={}, result={}", value, result);
 336        assert!(true);
 337    }
 338    "#
 339            .unindent(),
 340            editor.snapshot(window, cx).text()
 341        );
 342    });
 343
 344    client.on_request::<dap::requests::StackTrace, _>(move |_, _| {
 345        Ok(dap::StackTraceResponse {
 346            stack_frames: vec![stack_frame_for_line(6)],
 347            total_frames: None,
 348        })
 349    });
 350    client
 351        .fake_event(dap::messages::Events::Stopped(dap::StoppedEvent {
 352            reason: dap::StoppedEventReason::Pause,
 353            description: None,
 354            thread_id: Some(1),
 355            preserve_focus_hint: None,
 356            text: None,
 357            all_threads_stopped: None,
 358            hit_breakpoint_ids: None,
 359        }))
 360        .await;
 361
 362    cx.run_until_parked();
 363
 364    editor.update_in(cx, |editor, window, cx| {
 365        pretty_assertions::assert_eq!(
 366            r#"
 367    static mut GLOBAL: 1: usize = 1;
 368
 369    fn main() {
 370        let x: 10 = 10;
 371        let value: 42 = 42;
 372        let y = 4;
 373        let tester = {
 374            let y = 10;
 375            let y = 5;
 376            let b = 3;
 377            vec![y, 20, 30]
 378        };
 379
 380        let caller = || {
 381            let x = 3;
 382            println!("x={}", x);
 383        };
 384
 385        caller();
 386
 387        unsafe {
 388            GLOBAL = 2;
 389        }
 390
 391        let result = value * 2 * x;
 392        println!("Simple test executed: value={}, result={}", value, result);
 393        assert!(true);
 394    }
 395    "#
 396            .unindent(),
 397            editor.snapshot(window, cx).text()
 398        );
 399    });
 400
 401    client.on_request::<dap::requests::StackTrace, _>(move |_, _| {
 402        Ok(dap::StackTraceResponse {
 403            stack_frames: vec![stack_frame_for_line(7)],
 404            total_frames: None,
 405        })
 406    });
 407    client
 408        .fake_event(dap::messages::Events::Stopped(dap::StoppedEvent {
 409            reason: dap::StoppedEventReason::Pause,
 410            description: None,
 411            thread_id: Some(1),
 412            preserve_focus_hint: None,
 413            text: None,
 414            all_threads_stopped: None,
 415            hit_breakpoint_ids: None,
 416        }))
 417        .await;
 418
 419    cx.run_until_parked();
 420
 421    editor.update_in(cx, |editor, window, cx| {
 422        pretty_assertions::assert_eq!(
 423            r#"
 424    static mut GLOBAL: 1: usize = 1;
 425
 426    fn main() {
 427        let x: 10 = 10;
 428        let value: 42 = 42;
 429        let y: 4 = 4;
 430        let tester = {
 431            let y = 10;
 432            let y = 5;
 433            let b = 3;
 434            vec![y, 20, 30]
 435        };
 436
 437        let caller = || {
 438            let x = 3;
 439            println!("x={}", x);
 440        };
 441
 442        caller();
 443
 444        unsafe {
 445            GLOBAL = 2;
 446        }
 447
 448        let result = value * 2 * x;
 449        println!("Simple test executed: value={}, result={}", value, result);
 450        assert!(true);
 451    }
 452    "#
 453            .unindent(),
 454            editor.snapshot(window, cx).text()
 455        );
 456    });
 457
 458    client.on_request::<dap::requests::StackTrace, _>(move |_, _| {
 459        Ok(dap::StackTraceResponse {
 460            stack_frames: vec![stack_frame_for_line(8)],
 461            total_frames: None,
 462        })
 463    });
 464    client
 465        .fake_event(dap::messages::Events::Stopped(dap::StoppedEvent {
 466            reason: dap::StoppedEventReason::Pause,
 467            description: None,
 468            thread_id: Some(1),
 469            preserve_focus_hint: None,
 470            text: None,
 471            all_threads_stopped: None,
 472            hit_breakpoint_ids: None,
 473        }))
 474        .await;
 475
 476    cx.run_until_parked();
 477
 478    editor.update_in(cx, |editor, window, cx| {
 479        pretty_assertions::assert_eq!(
 480            r#"
 481    static mut GLOBAL: 1: usize = 1;
 482
 483    fn main() {
 484        let x: 10 = 10;
 485        let value: 42 = 42;
 486        let y: 4 = 4;
 487        let tester = {
 488            let y = 10;
 489            let y = 5;
 490            let b = 3;
 491            vec![y, 20, 30]
 492        };
 493
 494        let caller = || {
 495            let x = 3;
 496            println!("x={}", x);
 497        };
 498
 499        caller();
 500
 501        unsafe {
 502            GLOBAL = 2;
 503        }
 504
 505        let result = value * 2 * x;
 506        println!("Simple test executed: value={}, result={}", value, result);
 507        assert!(true);
 508    }
 509    "#
 510            .unindent(),
 511            editor.snapshot(window, cx).text()
 512        );
 513    });
 514
 515    let local_variables = vec![
 516        Variable {
 517            name: "x".into(),
 518            value: "10".into(),
 519            type_: None,
 520            presentation_hint: None,
 521            evaluate_name: None,
 522            variables_reference: 0,
 523            named_variables: None,
 524            indexed_variables: None,
 525            memory_reference: None,
 526            declaration_location_reference: None,
 527            value_location_reference: None,
 528        },
 529        Variable {
 530            name: "y".into(),
 531            value: "10".into(),
 532            type_: None,
 533            presentation_hint: None,
 534            evaluate_name: None,
 535            variables_reference: 0,
 536            named_variables: None,
 537            indexed_variables: None,
 538            memory_reference: None,
 539            declaration_location_reference: None,
 540            value_location_reference: None,
 541        },
 542        Variable {
 543            name: "value".into(),
 544            value: "42".into(),
 545            type_: None,
 546            presentation_hint: None,
 547            evaluate_name: None,
 548            variables_reference: 0,
 549            named_variables: None,
 550            indexed_variables: None,
 551            memory_reference: None,
 552            declaration_location_reference: None,
 553            value_location_reference: None,
 554        },
 555    ];
 556
 557    client.on_request::<Variables, _>({
 558        let local_variables = Arc::new(local_variables.clone());
 559        move |_, _| {
 560            Ok(dap::VariablesResponse {
 561                variables: (*local_variables).clone(),
 562            })
 563        }
 564    });
 565    client.on_request::<dap::requests::StackTrace, _>(move |_, _| {
 566        Ok(dap::StackTraceResponse {
 567            stack_frames: vec![stack_frame_for_line(9)],
 568            total_frames: None,
 569        })
 570    });
 571    client
 572        .fake_event(dap::messages::Events::Stopped(dap::StoppedEvent {
 573            reason: dap::StoppedEventReason::Pause,
 574            description: None,
 575            thread_id: Some(1),
 576            preserve_focus_hint: None,
 577            text: None,
 578            all_threads_stopped: None,
 579            hit_breakpoint_ids: None,
 580        }))
 581        .await;
 582
 583    cx.run_until_parked();
 584
 585    editor.update_in(cx, |editor, window, cx| {
 586        pretty_assertions::assert_eq!(
 587            r#"
 588    static mut GLOBAL: 1: usize = 1;
 589
 590    fn main() {
 591        let x: 10 = 10;
 592        let value: 42 = 42;
 593        let y = 4;
 594        let tester = {
 595            let y: 10 = 10;
 596            let y = 5;
 597            let b = 3;
 598            vec![y, 20, 30]
 599        };
 600
 601        let caller = || {
 602            let x = 3;
 603            println!("x={}", x);
 604        };
 605
 606        caller();
 607
 608        unsafe {
 609            GLOBAL = 2;
 610        }
 611
 612        let result = value * 2 * x;
 613        println!("Simple test executed: value={}, result={}", value, result);
 614        assert!(true);
 615    }
 616    "#
 617            .unindent(),
 618            editor.snapshot(window, cx).text()
 619        );
 620    });
 621
 622    let local_variables = vec![
 623        Variable {
 624            name: "x".into(),
 625            value: "10".into(),
 626            type_: None,
 627            presentation_hint: None,
 628            evaluate_name: None,
 629            variables_reference: 0,
 630            named_variables: None,
 631            indexed_variables: None,
 632            memory_reference: None,
 633            declaration_location_reference: None,
 634            value_location_reference: None,
 635        },
 636        Variable {
 637            name: "y".into(),
 638            value: "5".into(),
 639            type_: None,
 640            presentation_hint: None,
 641            evaluate_name: None,
 642            variables_reference: 0,
 643            named_variables: None,
 644            indexed_variables: None,
 645            memory_reference: None,
 646            declaration_location_reference: None,
 647            value_location_reference: None,
 648        },
 649        Variable {
 650            name: "value".into(),
 651            value: "42".into(),
 652            type_: None,
 653            presentation_hint: None,
 654            evaluate_name: None,
 655            variables_reference: 0,
 656            named_variables: None,
 657            indexed_variables: None,
 658            memory_reference: None,
 659            declaration_location_reference: None,
 660            value_location_reference: None,
 661        },
 662    ];
 663
 664    client.on_request::<Variables, _>({
 665        let local_variables = Arc::new(local_variables.clone());
 666        move |_, _| {
 667            Ok(dap::VariablesResponse {
 668                variables: (*local_variables).clone(),
 669            })
 670        }
 671    });
 672    client.on_request::<dap::requests::StackTrace, _>(move |_, _| {
 673        Ok(dap::StackTraceResponse {
 674            stack_frames: vec![stack_frame_for_line(10)],
 675            total_frames: None,
 676        })
 677    });
 678    client
 679        .fake_event(dap::messages::Events::Stopped(dap::StoppedEvent {
 680            reason: dap::StoppedEventReason::Pause,
 681            description: None,
 682            thread_id: Some(1),
 683            preserve_focus_hint: None,
 684            text: None,
 685            all_threads_stopped: None,
 686            hit_breakpoint_ids: None,
 687        }))
 688        .await;
 689
 690    cx.run_until_parked();
 691
 692    editor.update_in(cx, |editor, window, cx| {
 693        pretty_assertions::assert_eq!(
 694            r#"
 695    static mut GLOBAL: 1: usize = 1;
 696
 697    fn main() {
 698        let x: 10 = 10;
 699        let value: 42 = 42;
 700        let y = 4;
 701        let tester = {
 702            let y = 10;
 703            let y: 5 = 5;
 704            let b = 3;
 705            vec![y, 20, 30]
 706        };
 707
 708        let caller = || {
 709            let x = 3;
 710            println!("x={}", x);
 711        };
 712
 713        caller();
 714
 715        unsafe {
 716            GLOBAL = 2;
 717        }
 718
 719        let result = value * 2 * x;
 720        println!("Simple test executed: value={}, result={}", value, result);
 721        assert!(true);
 722    }
 723    "#
 724            .unindent(),
 725            editor.snapshot(window, cx).text()
 726        );
 727    });
 728
 729    let local_variables = vec![
 730        Variable {
 731            name: "x".into(),
 732            value: "10".into(),
 733            type_: None,
 734            presentation_hint: None,
 735            evaluate_name: None,
 736            variables_reference: 0,
 737            named_variables: None,
 738            indexed_variables: None,
 739            memory_reference: None,
 740            declaration_location_reference: None,
 741            value_location_reference: None,
 742        },
 743        Variable {
 744            name: "y".into(),
 745            value: "5".into(),
 746            type_: None,
 747            presentation_hint: None,
 748            evaluate_name: None,
 749            variables_reference: 0,
 750            named_variables: None,
 751            indexed_variables: None,
 752            memory_reference: None,
 753            declaration_location_reference: None,
 754            value_location_reference: None,
 755        },
 756        Variable {
 757            name: "value".into(),
 758            value: "42".into(),
 759            type_: None,
 760            presentation_hint: None,
 761            evaluate_name: None,
 762            variables_reference: 0,
 763            named_variables: None,
 764            indexed_variables: None,
 765            memory_reference: None,
 766            declaration_location_reference: None,
 767            value_location_reference: None,
 768        },
 769        Variable {
 770            name: "b".into(),
 771            value: "3".into(),
 772            type_: None,
 773            presentation_hint: None,
 774            evaluate_name: None,
 775            variables_reference: 0,
 776            named_variables: None,
 777            indexed_variables: None,
 778            memory_reference: None,
 779            declaration_location_reference: None,
 780            value_location_reference: None,
 781        },
 782    ];
 783    client.on_request::<Variables, _>({
 784        let local_variables = Arc::new(local_variables.clone());
 785        move |_, _| {
 786            Ok(dap::VariablesResponse {
 787                variables: (*local_variables).clone(),
 788            })
 789        }
 790    });
 791    client.on_request::<dap::requests::StackTrace, _>(move |_, _| {
 792        Ok(dap::StackTraceResponse {
 793            stack_frames: vec![stack_frame_for_line(11)],
 794            total_frames: None,
 795        })
 796    });
 797    client
 798        .fake_event(dap::messages::Events::Stopped(dap::StoppedEvent {
 799            reason: dap::StoppedEventReason::Pause,
 800            description: None,
 801            thread_id: Some(1),
 802            preserve_focus_hint: None,
 803            text: None,
 804            all_threads_stopped: None,
 805            hit_breakpoint_ids: None,
 806        }))
 807        .await;
 808
 809    cx.run_until_parked();
 810
 811    editor.update_in(cx, |editor, window, cx| {
 812        pretty_assertions::assert_eq!(
 813            r#"
 814    static mut GLOBAL: 1: usize = 1;
 815
 816    fn main() {
 817        let x: 10 = 10;
 818        let value: 42 = 42;
 819        let y = 4;
 820        let tester = {
 821            let y = 10;
 822            let y: 5 = 5;
 823            let b: 3 = 3;
 824            vec![y, 20, 30]
 825        };
 826
 827        let caller = || {
 828            let x = 3;
 829            println!("x={}", x);
 830        };
 831
 832        caller();
 833
 834        unsafe {
 835            GLOBAL = 2;
 836        }
 837
 838        let result = value * 2 * x;
 839        println!("Simple test executed: value={}, result={}", value, result);
 840        assert!(true);
 841    }
 842    "#
 843            .unindent(),
 844            editor.snapshot(window, cx).text()
 845        );
 846    });
 847
 848    let local_variables = vec![
 849        Variable {
 850            name: "x".into(),
 851            value: "10".into(),
 852            type_: None,
 853            presentation_hint: None,
 854            evaluate_name: None,
 855            variables_reference: 0,
 856            named_variables: None,
 857            indexed_variables: None,
 858            memory_reference: None,
 859            declaration_location_reference: None,
 860            value_location_reference: None,
 861        },
 862        Variable {
 863            name: "y".into(),
 864            value: "4".into(),
 865            type_: None,
 866            presentation_hint: None,
 867            evaluate_name: None,
 868            variables_reference: 0,
 869            named_variables: None,
 870            indexed_variables: None,
 871            memory_reference: None,
 872            declaration_location_reference: None,
 873            value_location_reference: None,
 874        },
 875        Variable {
 876            name: "value".into(),
 877            value: "42".into(),
 878            type_: None,
 879            presentation_hint: None,
 880            evaluate_name: None,
 881            variables_reference: 0,
 882            named_variables: None,
 883            indexed_variables: None,
 884            memory_reference: None,
 885            declaration_location_reference: None,
 886            value_location_reference: None,
 887        },
 888        Variable {
 889            name: "tester".into(),
 890            value: "size=3".into(),
 891            type_: None,
 892            presentation_hint: None,
 893            evaluate_name: None,
 894            variables_reference: 0,
 895            named_variables: None,
 896            indexed_variables: None,
 897            memory_reference: None,
 898            declaration_location_reference: None,
 899            value_location_reference: None,
 900        },
 901    ];
 902    client.on_request::<Variables, _>({
 903        let local_variables = Arc::new(local_variables.clone());
 904        move |_, _| {
 905            Ok(dap::VariablesResponse {
 906                variables: (*local_variables).clone(),
 907            })
 908        }
 909    });
 910    client.on_request::<dap::requests::StackTrace, _>(move |_, _| {
 911        Ok(dap::StackTraceResponse {
 912            stack_frames: vec![stack_frame_for_line(14)],
 913            total_frames: None,
 914        })
 915    });
 916    client
 917        .fake_event(dap::messages::Events::Stopped(dap::StoppedEvent {
 918            reason: dap::StoppedEventReason::Pause,
 919            description: None,
 920            thread_id: Some(1),
 921            preserve_focus_hint: None,
 922            text: None,
 923            all_threads_stopped: None,
 924            hit_breakpoint_ids: None,
 925        }))
 926        .await;
 927
 928    cx.run_until_parked();
 929
 930    editor.update_in(cx, |editor, window, cx| {
 931        pretty_assertions::assert_eq!(
 932            r#"
 933    static mut GLOBAL: 1: usize = 1;
 934
 935    fn main() {
 936        let x: 10 = 10;
 937        let value: 42 = 42;
 938        let y: 4 = 4;
 939        let tester: size=3 = {
 940            let y = 10;
 941            let y = 5;
 942            let b = 3;
 943            vec![y, 20, 30]
 944        };
 945
 946        let caller = || {
 947            let x = 3;
 948            println!("x={}", x);
 949        };
 950
 951        caller();
 952
 953        unsafe {
 954            GLOBAL = 2;
 955        }
 956
 957        let result = value * 2 * x;
 958        println!("Simple test executed: value={}, result={}", value, result);
 959        assert!(true);
 960    }
 961    "#
 962            .unindent(),
 963            editor.snapshot(window, cx).text()
 964        );
 965    });
 966
 967    let local_variables = vec![
 968        Variable {
 969            name: "x".into(),
 970            value: "10".into(),
 971            type_: None,
 972            presentation_hint: None,
 973            evaluate_name: None,
 974            variables_reference: 0,
 975            named_variables: None,
 976            indexed_variables: None,
 977            memory_reference: None,
 978            declaration_location_reference: None,
 979            value_location_reference: None,
 980        },
 981        Variable {
 982            name: "y".into(),
 983            value: "4".into(),
 984            type_: None,
 985            presentation_hint: None,
 986            evaluate_name: None,
 987            variables_reference: 0,
 988            named_variables: None,
 989            indexed_variables: None,
 990            memory_reference: None,
 991            declaration_location_reference: None,
 992            value_location_reference: None,
 993        },
 994        Variable {
 995            name: "value".into(),
 996            value: "42".into(),
 997            type_: None,
 998            presentation_hint: None,
 999            evaluate_name: None,
1000            variables_reference: 0,
1001            named_variables: None,
1002            indexed_variables: None,
1003            memory_reference: None,
1004            declaration_location_reference: None,
1005            value_location_reference: None,
1006        },
1007        Variable {
1008            name: "tester".into(),
1009            value: "size=3".into(),
1010            type_: None,
1011            presentation_hint: None,
1012            evaluate_name: None,
1013            variables_reference: 0,
1014            named_variables: None,
1015            indexed_variables: None,
1016            memory_reference: None,
1017            declaration_location_reference: None,
1018            value_location_reference: None,
1019        },
1020        Variable {
1021            name: "caller".into(),
1022            value: "<not available>".into(),
1023            type_: None,
1024            presentation_hint: None,
1025            evaluate_name: None,
1026            variables_reference: 0,
1027            named_variables: None,
1028            indexed_variables: None,
1029            memory_reference: None,
1030            declaration_location_reference: None,
1031            value_location_reference: None,
1032        },
1033    ];
1034    client.on_request::<Variables, _>({
1035        let local_variables = Arc::new(local_variables.clone());
1036        move |_, _| {
1037            Ok(dap::VariablesResponse {
1038                variables: (*local_variables).clone(),
1039            })
1040        }
1041    });
1042    client.on_request::<dap::requests::StackTrace, _>(move |_, _| {
1043        Ok(dap::StackTraceResponse {
1044            stack_frames: vec![stack_frame_for_line(19)],
1045            total_frames: None,
1046        })
1047    });
1048    client
1049        .fake_event(dap::messages::Events::Stopped(dap::StoppedEvent {
1050            reason: dap::StoppedEventReason::Pause,
1051            description: None,
1052            thread_id: Some(1),
1053            preserve_focus_hint: None,
1054            text: None,
1055            all_threads_stopped: None,
1056            hit_breakpoint_ids: None,
1057        }))
1058        .await;
1059
1060    cx.run_until_parked();
1061
1062    editor.update_in(cx, |editor, window, cx| {
1063        pretty_assertions::assert_eq!(
1064            r#"
1065    static mut GLOBAL: 1: usize = 1;
1066
1067    fn main() {
1068        let x: 10 = 10;
1069        let value: 42 = 42;
1070        let y: 4 = 4;
1071        let tester: size=3 = {
1072            let y = 10;
1073            let y = 5;
1074            let b = 3;
1075            vec![y, 20, 30]
1076        };
1077
1078        let caller: <not available> = || {
1079            let x = 3;
1080            println!("x={}", x);
1081        };
1082
1083        caller();
1084
1085        unsafe {
1086            GLOBAL = 2;
1087        }
1088
1089        let result = value * 2 * x;
1090        println!("Simple test executed: value={}, result={}", value, result);
1091        assert!(true);
1092    }
1093    "#
1094            .unindent(),
1095            editor.snapshot(window, cx).text()
1096        );
1097    });
1098
1099    client.on_request::<dap::requests::StackTrace, _>(move |_, _| {
1100        Ok(dap::StackTraceResponse {
1101            stack_frames: vec![stack_frame_for_line(15)],
1102            total_frames: None,
1103        })
1104    });
1105    client
1106        .fake_event(dap::messages::Events::Stopped(dap::StoppedEvent {
1107            reason: dap::StoppedEventReason::Pause,
1108            description: None,
1109            thread_id: Some(1),
1110            preserve_focus_hint: None,
1111            text: None,
1112            all_threads_stopped: None,
1113            hit_breakpoint_ids: None,
1114        }))
1115        .await;
1116
1117    cx.run_until_parked();
1118
1119    editor.update_in(cx, |editor, window, cx| {
1120        pretty_assertions::assert_eq!(
1121            r#"
1122    static mut GLOBAL: 1: usize = 1;
1123
1124    fn main() {
1125        let x = 10;
1126        let value = 42;
1127        let y = 4;
1128        let tester = {
1129            let y = 10;
1130            let y = 5;
1131            let b = 3;
1132            vec![y, 20, 30]
1133        };
1134
1135        let caller = || {
1136            let x = 3;
1137            println!("x={}", x);
1138        };
1139
1140        caller();
1141
1142        unsafe {
1143            GLOBAL = 2;
1144        }
1145
1146        let result = value * 2 * x;
1147        println!("Simple test executed: value={}, result={}", value, result);
1148        assert!(true);
1149    }
1150    "#
1151            .unindent(),
1152            editor.snapshot(window, cx).text()
1153        );
1154    });
1155
1156    let local_variables = vec![Variable {
1157        name: "x".into(),
1158        value: "3".into(),
1159        type_: None,
1160        presentation_hint: None,
1161        evaluate_name: None,
1162        variables_reference: 0,
1163        named_variables: None,
1164        indexed_variables: None,
1165        memory_reference: None,
1166        declaration_location_reference: None,
1167        value_location_reference: None,
1168    }];
1169    client.on_request::<Variables, _>({
1170        let local_variables = Arc::new(local_variables.clone());
1171        move |_, _| {
1172            Ok(dap::VariablesResponse {
1173                variables: (*local_variables).clone(),
1174            })
1175        }
1176    });
1177    client.on_request::<dap::requests::StackTrace, _>(move |_, _| {
1178        Ok(dap::StackTraceResponse {
1179            stack_frames: vec![stack_frame_for_line(16)],
1180            total_frames: None,
1181        })
1182    });
1183    client
1184        .fake_event(dap::messages::Events::Stopped(dap::StoppedEvent {
1185            reason: dap::StoppedEventReason::Pause,
1186            description: None,
1187            thread_id: Some(1),
1188            preserve_focus_hint: None,
1189            text: None,
1190            all_threads_stopped: None,
1191            hit_breakpoint_ids: None,
1192        }))
1193        .await;
1194
1195    cx.run_until_parked();
1196
1197    editor.update_in(cx, |editor, window, cx| {
1198        pretty_assertions::assert_eq!(
1199            r#"
1200    static mut GLOBAL: 1: usize = 1;
1201
1202    fn main() {
1203        let x = 10;
1204        let value = 42;
1205        let y = 4;
1206        let tester = {
1207            let y = 10;
1208            let y = 5;
1209            let b = 3;
1210            vec![y, 20, 30]
1211        };
1212
1213        let caller = || {
1214            let x: 3 = 3;
1215            println!("x={}", x);
1216        };
1217
1218        caller();
1219
1220        unsafe {
1221            GLOBAL = 2;
1222        }
1223
1224        let result = value * 2 * x;
1225        println!("Simple test executed: value={}, result={}", value, result);
1226        assert!(true);
1227    }
1228    "#
1229            .unindent(),
1230            editor.snapshot(window, cx).text()
1231        );
1232    });
1233
1234    let local_variables = vec![
1235        Variable {
1236            name: "x".into(),
1237            value: "10".into(),
1238            type_: None,
1239            presentation_hint: None,
1240            evaluate_name: None,
1241            variables_reference: 0,
1242            named_variables: None,
1243            indexed_variables: None,
1244            memory_reference: None,
1245            declaration_location_reference: None,
1246            value_location_reference: None,
1247        },
1248        Variable {
1249            name: "y".into(),
1250            value: "4".into(),
1251            type_: None,
1252            presentation_hint: None,
1253            evaluate_name: None,
1254            variables_reference: 0,
1255            named_variables: None,
1256            indexed_variables: None,
1257            memory_reference: None,
1258            declaration_location_reference: None,
1259            value_location_reference: None,
1260        },
1261        Variable {
1262            name: "value".into(),
1263            value: "42".into(),
1264            type_: None,
1265            presentation_hint: None,
1266            evaluate_name: None,
1267            variables_reference: 0,
1268            named_variables: None,
1269            indexed_variables: None,
1270            memory_reference: None,
1271            declaration_location_reference: None,
1272            value_location_reference: None,
1273        },
1274        Variable {
1275            name: "tester".into(),
1276            value: "size=3".into(),
1277            type_: None,
1278            presentation_hint: None,
1279            evaluate_name: None,
1280            variables_reference: 0,
1281            named_variables: None,
1282            indexed_variables: None,
1283            memory_reference: None,
1284            declaration_location_reference: None,
1285            value_location_reference: None,
1286        },
1287        Variable {
1288            name: "caller".into(),
1289            value: "<not available>".into(),
1290            type_: None,
1291            presentation_hint: None,
1292            evaluate_name: None,
1293            variables_reference: 0,
1294            named_variables: None,
1295            indexed_variables: None,
1296            memory_reference: None,
1297            declaration_location_reference: None,
1298            value_location_reference: None,
1299        },
1300    ];
1301    client.on_request::<Variables, _>({
1302        let local_variables = Arc::new(local_variables.clone());
1303        move |_, _| {
1304            Ok(dap::VariablesResponse {
1305                variables: (*local_variables).clone(),
1306            })
1307        }
1308    });
1309    client.on_request::<dap::requests::Evaluate, _>(move |_, args| {
1310        assert_eq!("GLOBAL", args.expression);
1311        Ok(dap::EvaluateResponse {
1312            result: "2".into(),
1313            type_: None,
1314            presentation_hint: None,
1315            variables_reference: 0,
1316            named_variables: None,
1317            indexed_variables: None,
1318            memory_reference: None,
1319            value_location_reference: None,
1320        })
1321    });
1322    client.on_request::<dap::requests::StackTrace, _>(move |_, _| {
1323        Ok(dap::StackTraceResponse {
1324            stack_frames: vec![stack_frame_for_line(25)],
1325            total_frames: None,
1326        })
1327    });
1328    client
1329        .fake_event(dap::messages::Events::Stopped(dap::StoppedEvent {
1330            reason: dap::StoppedEventReason::Pause,
1331            description: None,
1332            thread_id: Some(1),
1333            preserve_focus_hint: None,
1334            text: None,
1335            all_threads_stopped: None,
1336            hit_breakpoint_ids: None,
1337        }))
1338        .await;
1339
1340    cx.run_until_parked();
1341
1342    editor.update_in(cx, |editor, window, cx| {
1343        pretty_assertions::assert_eq!(
1344            r#"
1345    static mut GLOBAL: 2: usize = 1;
1346
1347    fn main() {
1348        let x: 10 = 10;
1349        let value: 42 = 42;
1350        let y: 4 = 4;
1351        let tester: size=3 = {
1352            let y = 10;
1353            let y = 5;
1354            let b = 3;
1355            vec![y, 20, 30]
1356        };
1357
1358        let caller: <not available> = || {
1359            let x = 3;
1360            println!("x={}", x);
1361        };
1362
1363        caller();
1364
1365        unsafe {
1366            GLOBAL = 2;
1367        }
1368
1369        let result = value * 2 * x;
1370        println!("Simple test executed: value={}, result={}", value, result);
1371        assert!(true);
1372    }
1373    "#
1374            .unindent(),
1375            editor.snapshot(window, cx).text()
1376        );
1377    });
1378
1379    let local_variables = vec![
1380        Variable {
1381            name: "x".into(),
1382            value: "10".into(),
1383            type_: None,
1384            presentation_hint: None,
1385            evaluate_name: None,
1386            variables_reference: 0,
1387            named_variables: None,
1388            indexed_variables: None,
1389            memory_reference: None,
1390            declaration_location_reference: None,
1391            value_location_reference: None,
1392        },
1393        Variable {
1394            name: "y".into(),
1395            value: "4".into(),
1396            type_: None,
1397            presentation_hint: None,
1398            evaluate_name: None,
1399            variables_reference: 0,
1400            named_variables: None,
1401            indexed_variables: None,
1402            memory_reference: None,
1403            declaration_location_reference: None,
1404            value_location_reference: None,
1405        },
1406        Variable {
1407            name: "value".into(),
1408            value: "42".into(),
1409            type_: None,
1410            presentation_hint: None,
1411            evaluate_name: None,
1412            variables_reference: 0,
1413            named_variables: None,
1414            indexed_variables: None,
1415            memory_reference: None,
1416            declaration_location_reference: None,
1417            value_location_reference: None,
1418        },
1419        Variable {
1420            name: "tester".into(),
1421            value: "size=3".into(),
1422            type_: None,
1423            presentation_hint: None,
1424            evaluate_name: None,
1425            variables_reference: 0,
1426            named_variables: None,
1427            indexed_variables: None,
1428            memory_reference: None,
1429            declaration_location_reference: None,
1430            value_location_reference: None,
1431        },
1432        Variable {
1433            name: "caller".into(),
1434            value: "<not available>".into(),
1435            type_: None,
1436            presentation_hint: None,
1437            evaluate_name: None,
1438            variables_reference: 0,
1439            named_variables: None,
1440            indexed_variables: None,
1441            memory_reference: None,
1442            declaration_location_reference: None,
1443            value_location_reference: None,
1444        },
1445        Variable {
1446            name: "result".into(),
1447            value: "840".into(),
1448            type_: None,
1449            presentation_hint: None,
1450            evaluate_name: None,
1451            variables_reference: 0,
1452            named_variables: None,
1453            indexed_variables: None,
1454            memory_reference: None,
1455            declaration_location_reference: None,
1456            value_location_reference: None,
1457        },
1458    ];
1459    client.on_request::<Variables, _>({
1460        let local_variables = Arc::new(local_variables.clone());
1461        move |_, _| {
1462            Ok(dap::VariablesResponse {
1463                variables: (*local_variables).clone(),
1464            })
1465        }
1466    });
1467    client.on_request::<dap::requests::StackTrace, _>(move |_, _| {
1468        Ok(dap::StackTraceResponse {
1469            stack_frames: vec![stack_frame_for_line(26)],
1470            total_frames: None,
1471        })
1472    });
1473    client
1474        .fake_event(dap::messages::Events::Stopped(dap::StoppedEvent {
1475            reason: dap::StoppedEventReason::Pause,
1476            description: None,
1477            thread_id: Some(1),
1478            preserve_focus_hint: None,
1479            text: None,
1480            all_threads_stopped: None,
1481            hit_breakpoint_ids: None,
1482        }))
1483        .await;
1484
1485    cx.run_until_parked();
1486
1487    editor.update_in(cx, |editor, window, cx| {
1488        pretty_assertions::assert_eq!(
1489            r#"
1490    static mut GLOBAL: 2: usize = 1;
1491
1492    fn main() {
1493        let x: 10 = 10;
1494        let value: 42 = 42;
1495        let y: 4 = 4;
1496        let tester: size=3 = {
1497            let y = 10;
1498            let y = 5;
1499            let b = 3;
1500            vec![y, 20, 30]
1501        };
1502
1503        let caller: <not available> = || {
1504            let x = 3;
1505            println!("x={}", x);
1506        };
1507
1508        caller();
1509
1510        unsafe {
1511            GLOBAL = 2;
1512        }
1513
1514        let result: 840 = value * 2 * x;
1515        println!("Simple test executed: value={}, result={}", value, result);
1516        assert!(true);
1517    }
1518    "#
1519            .unindent(),
1520            editor.snapshot(window, cx).text()
1521        );
1522    });
1523}
1524
1525fn rust_lang() -> Language {
1526    Language::new(
1527        LanguageConfig {
1528            name: "Rust".into(),
1529            matcher: LanguageMatcher {
1530                path_suffixes: vec!["rs".to_string()],
1531                ..Default::default()
1532            },
1533            ..Default::default()
1534        },
1535        Some(tree_sitter_rust::LANGUAGE.into()),
1536    )
1537}
1538
1539#[gpui::test]
1540async fn test_python_inline_values(executor: BackgroundExecutor, cx: &mut TestAppContext) {
1541    init_test(cx);
1542
1543    let fs = FakeFs::new(executor.clone());
1544    let source_code = r#"
1545def process_data(untyped_param, typed_param: int, another_typed: str):
1546    # Local variables
1547    x = 10
1548    result = typed_param * 2
1549    text = "Hello, " + another_typed
1550
1551    # For loop with range
1552    sum_value = 0
1553    for i in range(5):
1554        sum_value += i
1555
1556    # Final result
1557    final_result = x + result + sum_value
1558    return final_result
1559"#
1560    .unindent();
1561    fs.insert_tree(path!("/project"), json!({ "main.py": source_code }))
1562        .await;
1563
1564    let project = Project::test(fs.clone(), [path!("/project").as_ref()], cx).await;
1565    let workspace = init_test_workspace(&project, cx).await;
1566    workspace
1567        .update(cx, |workspace, window, cx| {
1568            workspace.focus_panel::<DebugPanel>(window, cx);
1569        })
1570        .unwrap();
1571    let cx = &mut VisualTestContext::from_window(*workspace, cx);
1572
1573    let session = start_debug_session(&workspace, cx, |_| {}).unwrap();
1574    let client = session.update(cx, |session, _| session.adapter_client().unwrap());
1575
1576    let project_path = Path::new(path!("/project"));
1577    let worktree = project
1578        .update(cx, |project, cx| project.find_worktree(project_path, cx))
1579        .expect("This worktree should exist in project")
1580        .0;
1581
1582    let worktree_id = workspace
1583        .update(cx, |_, _, cx| worktree.read(cx).id())
1584        .unwrap();
1585
1586    let buffer = project
1587        .update(cx, |project, cx| {
1588            project.open_buffer((worktree_id, "main.py"), cx)
1589        })
1590        .await
1591        .unwrap();
1592
1593    buffer.update(cx, |buffer, cx| {
1594        buffer.set_language(Some(Arc::new(python_lang())), cx);
1595    });
1596
1597    let (editor, cx) = cx.add_window_view(|window, cx| {
1598        Editor::new(
1599            EditorMode::full(),
1600            MultiBuffer::build_from_buffer(buffer, cx),
1601            Some(project),
1602            window,
1603            cx,
1604        )
1605    });
1606
1607    editor.update_in(cx, |editor, window, cx| {
1608        if !editor.inline_values_enabled() {
1609            editor.toggle_inline_values(&ToggleInlineValues, window, cx);
1610        }
1611    });
1612
1613    client.on_request::<dap::requests::Threads, _>(move |_, _| {
1614        Ok(dap::ThreadsResponse {
1615            threads: vec![dap::Thread {
1616                id: 1,
1617                name: "Thread 1".into(),
1618            }],
1619        })
1620    });
1621
1622    client.on_request::<dap::requests::StackTrace, _>(move |_, args| {
1623        assert_eq!(args.thread_id, 1);
1624        Ok(dap::StackTraceResponse {
1625            stack_frames: vec![StackFrame {
1626                id: 1,
1627                name: "Stack Frame 1".into(),
1628                source: Some(dap::Source {
1629                    name: Some("main.py".into()),
1630                    path: Some(path!("/project/main.py").into()),
1631                    source_reference: None,
1632                    presentation_hint: None,
1633                    origin: None,
1634                    sources: None,
1635                    adapter_data: None,
1636                    checksums: None,
1637                }),
1638                line: 12,
1639                column: 1,
1640                end_line: None,
1641                end_column: None,
1642                can_restart: None,
1643                instruction_pointer_reference: None,
1644                module_id: None,
1645                presentation_hint: None,
1646            }],
1647            total_frames: None,
1648        })
1649    });
1650
1651    client.on_request::<dap::requests::Scopes, _>(move |_, _| {
1652        Ok(dap::ScopesResponse {
1653            scopes: vec![
1654                Scope {
1655                    name: "Local".into(),
1656                    presentation_hint: None,
1657                    variables_reference: 1,
1658                    named_variables: None,
1659                    indexed_variables: None,
1660                    expensive: false,
1661                    source: None,
1662                    line: None,
1663                    column: None,
1664                    end_line: None,
1665                    end_column: None,
1666                },
1667                Scope {
1668                    name: "Global".into(),
1669                    presentation_hint: None,
1670                    variables_reference: 2,
1671                    named_variables: None,
1672                    indexed_variables: None,
1673                    expensive: false,
1674                    source: None,
1675                    line: None,
1676                    column: None,
1677                    end_line: None,
1678                    end_column: None,
1679                },
1680            ],
1681        })
1682    });
1683
1684    client.on_request::<Variables, _>(move |_, args| match args.variables_reference {
1685        1 => Ok(dap::VariablesResponse {
1686            variables: vec![
1687                Variable {
1688                    name: "untyped_param".into(),
1689                    value: "test_value".into(),
1690                    type_: Some("str".into()),
1691                    presentation_hint: None,
1692                    evaluate_name: None,
1693                    variables_reference: 0,
1694                    named_variables: None,
1695                    indexed_variables: None,
1696                    memory_reference: None,
1697                    declaration_location_reference: None,
1698                    value_location_reference: None,
1699                },
1700                Variable {
1701                    name: "typed_param".into(),
1702                    value: "42".into(),
1703                    type_: Some("int".into()),
1704                    presentation_hint: None,
1705                    evaluate_name: None,
1706                    variables_reference: 0,
1707                    named_variables: None,
1708                    indexed_variables: None,
1709                    memory_reference: None,
1710                    declaration_location_reference: None,
1711                    value_location_reference: None,
1712                },
1713                Variable {
1714                    name: "another_typed".into(),
1715                    value: "world".into(),
1716                    type_: Some("str".into()),
1717                    presentation_hint: None,
1718                    evaluate_name: None,
1719                    variables_reference: 0,
1720                    named_variables: None,
1721                    indexed_variables: None,
1722                    memory_reference: None,
1723                    declaration_location_reference: None,
1724                    value_location_reference: None,
1725                },
1726                Variable {
1727                    name: "x".into(),
1728                    value: "10".into(),
1729                    type_: Some("int".into()),
1730                    presentation_hint: None,
1731                    evaluate_name: None,
1732                    variables_reference: 0,
1733                    named_variables: None,
1734                    indexed_variables: None,
1735                    memory_reference: None,
1736                    declaration_location_reference: None,
1737                    value_location_reference: None,
1738                },
1739                Variable {
1740                    name: "result".into(),
1741                    value: "84".into(),
1742                    type_: Some("int".into()),
1743                    presentation_hint: None,
1744                    evaluate_name: None,
1745                    variables_reference: 0,
1746                    named_variables: None,
1747                    indexed_variables: None,
1748                    memory_reference: None,
1749                    declaration_location_reference: None,
1750                    value_location_reference: None,
1751                },
1752                Variable {
1753                    name: "text".into(),
1754                    value: "Hello, world".into(),
1755                    type_: Some("str".into()),
1756                    presentation_hint: None,
1757                    evaluate_name: None,
1758                    variables_reference: 0,
1759                    named_variables: None,
1760                    indexed_variables: None,
1761                    memory_reference: None,
1762                    declaration_location_reference: None,
1763                    value_location_reference: None,
1764                },
1765                Variable {
1766                    name: "sum_value".into(),
1767                    value: "10".into(),
1768                    type_: Some("int".into()),
1769                    presentation_hint: None,
1770                    evaluate_name: None,
1771                    variables_reference: 0,
1772                    named_variables: None,
1773                    indexed_variables: None,
1774                    memory_reference: None,
1775                    declaration_location_reference: None,
1776                    value_location_reference: None,
1777                },
1778                Variable {
1779                    name: "i".into(),
1780                    value: "4".into(),
1781                    type_: Some("int".into()),
1782                    presentation_hint: None,
1783                    evaluate_name: None,
1784                    variables_reference: 0,
1785                    named_variables: None,
1786                    indexed_variables: None,
1787                    memory_reference: None,
1788                    declaration_location_reference: None,
1789                    value_location_reference: None,
1790                },
1791                Variable {
1792                    name: "final_result".into(),
1793                    value: "104".into(),
1794                    type_: Some("int".into()),
1795                    presentation_hint: None,
1796                    evaluate_name: None,
1797                    variables_reference: 0,
1798                    named_variables: None,
1799                    indexed_variables: None,
1800                    memory_reference: None,
1801                    declaration_location_reference: None,
1802                    value_location_reference: None,
1803                },
1804            ],
1805        }),
1806        _ => Ok(dap::VariablesResponse { variables: vec![] }),
1807    });
1808
1809    client
1810        .fake_event(dap::messages::Events::Stopped(dap::StoppedEvent {
1811            reason: dap::StoppedEventReason::Pause,
1812            description: None,
1813            thread_id: Some(1),
1814            preserve_focus_hint: None,
1815            text: None,
1816            all_threads_stopped: None,
1817            hit_breakpoint_ids: None,
1818        }))
1819        .await;
1820
1821    cx.run_until_parked();
1822
1823    editor.update_in(cx, |editor, window, cx| {
1824        pretty_assertions::assert_eq!(
1825            r#"
1826        def process_data(untyped_param: test_value, typed_param: 42: int, another_typed: world: str):
1827            # Local variables
1828            x: 10 = 10
1829            result: 84 = typed_param * 2
1830            text: Hello, world = "Hello, " + another_typed
1831
1832            # For loop with range
1833            sum_value: 10 = 0
1834            for i: 4 in range(5):
1835                sum_value += i
1836
1837            # Final result
1838            final_result = x + result + sum_value
1839            return final_result
1840        "#
1841            .unindent(),
1842            editor.snapshot(window, cx).text()
1843        );
1844    });
1845}
1846
1847fn python_lang() -> Language {
1848    Language::new(
1849        LanguageConfig {
1850            name: "Python".into(),
1851            matcher: LanguageMatcher {
1852                path_suffixes: vec!["py".to_string()],
1853                ..Default::default()
1854            },
1855            ..Default::default()
1856        },
1857        Some(tree_sitter_python::LANGUAGE.into()),
1858    )
1859}