attach_modal.rs

  1use crate::{attach_modal::Candidate, tests::start_debug_session_with, *};
  2use attach_modal::AttachModal;
  3use dap::{FakeAdapter, adapters::DebugTaskDefinition};
  4use gpui::{BackgroundExecutor, TestAppContext, VisualTestContext};
  5use menu::Confirm;
  6use project::{FakeFs, Project};
  7use serde_json::json;
  8use task::AttachRequest;
  9use tests::{init_test, init_test_workspace};
 10use util::path;
 11
 12#[gpui::test]
 13async fn test_direct_attach_to_process(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
 30    let _session = start_debug_session_with(
 31        &workspace,
 32        cx,
 33        DebugTaskDefinition {
 34            adapter: "fake-adapter".into(),
 35            label: "label".into(),
 36            config: json!({
 37               "request": "attach",
 38              "process_id": 10,
 39            }),
 40            tcp_connection: None,
 41        },
 42        |client| {
 43            client.on_request::<dap::requests::Attach, _>(move |_, args| {
 44                let raw = &args.raw;
 45                assert_eq!(raw["request"], "attach");
 46                assert_eq!(raw["process_id"], 10);
 47
 48                Ok(())
 49            });
 50        },
 51    )
 52    .unwrap();
 53
 54    cx.run_until_parked();
 55
 56    // assert we didn't show the attach modal
 57    workspace
 58        .update(cx, |workspace, _window, cx| {
 59            assert!(workspace.active_modal::<AttachModal>(cx).is_none());
 60        })
 61        .unwrap();
 62}
 63
 64#[gpui::test]
 65async fn test_show_attach_modal_and_select_process(
 66    executor: BackgroundExecutor,
 67    cx: &mut TestAppContext,
 68) {
 69    init_test(cx);
 70
 71    let fs = FakeFs::new(executor.clone());
 72
 73    fs.insert_tree(
 74        path!("/project"),
 75        json!({
 76            "main.rs": "First line\nSecond line\nThird line\nFourth line",
 77        }),
 78    )
 79    .await;
 80
 81    let project = Project::test(fs, [path!("/project").as_ref()], cx).await;
 82    let workspace = init_test_workspace(&project, cx).await;
 83    let cx = &mut VisualTestContext::from_window(*workspace, cx);
 84    // Set up handlers for sessions spawned via modal.
 85    let _initialize_subscription =
 86        project::debugger::test::intercept_debug_sessions(cx, |client| {
 87            client.on_request::<dap::requests::Attach, _>(move |_, args| {
 88                let raw = &args.raw;
 89                assert_eq!(raw["request"], "attach");
 90                assert_eq!(raw["process_id"], 1);
 91
 92                Ok(())
 93            });
 94        });
 95    let attach_modal = workspace
 96        .update(cx, |workspace, window, cx| {
 97            let workspace_handle = cx.weak_entity();
 98            workspace.toggle_modal(window, cx, |window, cx| {
 99                AttachModal::with_processes(
100                    workspace_handle,
101                    task::ZedDebugConfig {
102                        adapter: FakeAdapter::ADAPTER_NAME.into(),
103                        request: dap::DebugRequest::Attach(AttachRequest::default()),
104                        label: "attach example".into(),
105                        stop_on_entry: None,
106                    },
107                    vec![
108                        Candidate {
109                            pid: 0,
110                            name: "fake-binary-1".into(),
111                            command: vec![],
112                        },
113                        Candidate {
114                            pid: 3,
115                            name: "real-binary-1".into(),
116                            command: vec![],
117                        },
118                        Candidate {
119                            pid: 1,
120                            name: "fake-binary-2".into(),
121                            command: vec![],
122                        },
123                    ]
124                    .into_iter()
125                    .collect(),
126                    true,
127                    window,
128                    cx,
129                )
130            });
131
132            workspace.active_modal::<AttachModal>(cx).unwrap()
133        })
134        .unwrap();
135
136    cx.run_until_parked();
137
138    // assert we got the expected processes
139    workspace
140        .update(cx, |_, window, cx| {
141            let names =
142                attach_modal.update(cx, |modal, cx| attach_modal::_process_names(modal, cx));
143            // Initially all processes are visible.
144            assert_eq!(3, names.len());
145            attach_modal.update(cx, |this, cx| {
146                this.picker.update(cx, |this, cx| {
147                    this.set_query("fakb", window, cx);
148                })
149            })
150        })
151        .unwrap();
152    cx.run_until_parked();
153    // assert we got the expected processes
154    workspace
155        .update(cx, |_, _, cx| {
156            let names =
157                attach_modal.update(cx, |modal, cx| attach_modal::_process_names(modal, cx));
158            // Initially all processes are visible.
159            assert_eq!(2, names.len());
160        })
161        .unwrap();
162    // select the only existing process
163    cx.dispatch_action(Confirm);
164
165    cx.run_until_parked();
166
167    // assert attach modal was dismissed
168    workspace
169        .update(cx, |workspace, _window, cx| {
170            assert!(workspace.active_modal::<AttachModal>(cx).is_none());
171        })
172        .unwrap();
173}