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