attach_modal.rs

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