674 lines · 21.2 KB · Rust
RawDownload
use gpui::{AppContext, Entity, Task, TestAppContext};use itertools::Itertools;use paths::tasks_file;use pretty_assertions::assert_eq;use serde_json::json;use settings::SettingsLocation;use std::path::Path;use std::sync::Arc;use util::rel_path::rel_path; use project::task_store::{TaskSettingsLocation, TaskStore}; use project::{WorktreeId, task_inventory::*};use test_inventory::*; mod test_inventory {    use gpui::{AppContext as _, Entity, Task, TestAppContext};    use itertools::Itertools;    use task::TaskContext;    use worktree::WorktreeId;     use crate::Inventory;     use super::TaskSourceKind;     pub(super) fn task_template_names(        inventory: &Entity<Inventory>,        worktree: Option<WorktreeId>,        cx: &mut TestAppContext,    ) -> Task<Vec<String>> {        let new_tasks = inventory.update(cx, |inventory, cx| {            inventory.list_tasks(None, None, worktree, cx)        });        cx.background_spawn(async move {            new_tasks                .await                .into_iter()                .map(|(_, task)| task.label)                .sorted()                .collect()        })    }     pub(super) fn register_task_used(        inventory: &Entity<Inventory>,        task_name: &str,        cx: &mut TestAppContext,    ) -> Task<()> {        let tasks = inventory.update(cx, |inventory, cx| {            inventory.list_tasks(None, None, None, cx)        });         let task_name = task_name.to_owned();        let inventory = inventory.clone();        cx.spawn(|mut cx| async move {            let (task_source_kind, task) = tasks                .await                .into_iter()                .find(|(_, task)| task.label == task_name)                .unwrap_or_else(|| panic!("Failed to find task with name {task_name}"));             let id_base = task_source_kind.to_id_base();            inventory.update(&mut cx, |inventory, _| {                inventory.task_scheduled(                    task_source_kind.clone(),                    task.resolve_task(&id_base, &TaskContext::default())                        .unwrap_or_else(|| panic!("Failed to resolve task with name {task_name}")),                )            });        })    }     pub(super) fn register_worktree_task_used(        inventory: &Entity<Inventory>,        worktree_id: WorktreeId,        task_name: &str,        cx: &mut TestAppContext,    ) -> Task<()> {        let tasks = inventory.update(cx, |inventory, cx| {            inventory.list_tasks(None, None, Some(worktree_id), cx)        });         let inventory = inventory.clone();        let task_name = task_name.to_owned();        cx.spawn(|mut cx| async move {            let (task_source_kind, task) = tasks                .await                .into_iter()                .find(|(_, task)| task.label == task_name)                .unwrap_or_else(|| panic!("Failed to find task with name {task_name}"));            let id_base = task_source_kind.to_id_base();            inventory.update(&mut cx, |inventory, _| {                inventory.task_scheduled(                    task_source_kind.clone(),                    task.resolve_task(&id_base, &TaskContext::default())                        .unwrap_or_else(|| panic!("Failed to resolve task with name {task_name}")),                );            });        })    }     pub(super) async fn list_tasks(        inventory: &Entity<Inventory>,        worktree: Option<WorktreeId>,        cx: &mut TestAppContext,    ) -> Vec<(TaskSourceKind, String)> {        let task_context = &TaskContext::default();        inventory            .update(cx, |inventory, cx| {                inventory.list_tasks(None, None, worktree, cx)            })            .await            .into_iter()            .filter_map(|(source_kind, task)| {                let id_base = source_kind.to_id_base();                Some((source_kind, task.resolve_task(&id_base, task_context)?))            })            .map(|(source_kind, resolved_task)| (source_kind, resolved_task.resolved_label))            .collect()    }} #[gpui::test]async fn test_task_list_sorting(cx: &mut TestAppContext) {    init_test(cx);    let inventory = cx.update(|cx| Inventory::new(cx));    let initial_tasks = resolved_task_names(&inventory, None, cx).await;    assert!(        initial_tasks.is_empty(),        "No tasks expected for empty inventory, but got {initial_tasks:?}"    );    let initial_tasks = task_template_names(&inventory, None, cx).await;    assert!(        initial_tasks.is_empty(),        "No tasks expected for empty inventory, but got {initial_tasks:?}"    );    cx.run_until_parked();    let expected_initial_state = [        "1_a_task".to_string(),        "1_task".to_string(),        "2_task".to_string(),        "3_task".to_string(),    ];     inventory.update(cx, |inventory, _| {        inventory            .update_file_based_tasks(                TaskSettingsLocation::Global(tasks_file()),                Some(&mock_tasks_from_names(                    expected_initial_state.iter().map(|name| name.as_str()),                )),            )            .unwrap();    });    assert_eq!(        task_template_names(&inventory, None, cx).await,        &expected_initial_state,    );    assert_eq!(        resolved_task_names(&inventory, None, cx).await,        &expected_initial_state,        "Tasks with equal amount of usages should be sorted alphanumerically"    );     register_task_used(&inventory, "2_task", cx).await;    assert_eq!(        task_template_names(&inventory, None, cx).await,        &expected_initial_state,    );    assert_eq!(        resolved_task_names(&inventory, None, cx).await,        vec![            "2_task".to_string(),            "1_a_task".to_string(),            "1_task".to_string(),            "3_task".to_string()        ],    );     register_task_used(&inventory, "1_task", cx).await;    register_task_used(&inventory, "1_task", cx).await;    register_task_used(&inventory, "1_task", cx).await;    register_task_used(&inventory, "3_task", cx).await;    assert_eq!(        task_template_names(&inventory, None, cx).await,        &expected_initial_state,    );    assert_eq!(        resolved_task_names(&inventory, None, cx).await,        vec![            "3_task".to_string(),            "1_task".to_string(),            "2_task".to_string(),            "1_a_task".to_string(),        ],        "Most recently used task should be at the top"    );     let worktree_id = WorktreeId::from_usize(0);    let local_worktree_location = SettingsLocation {        worktree_id,        path: rel_path("foo"),    };    inventory.update(cx, |inventory, _| {        inventory            .update_file_based_tasks(                TaskSettingsLocation::Worktree(local_worktree_location),                Some(&mock_tasks_from_names(["worktree_task_1"])),            )            .unwrap();    });    assert_eq!(        resolved_task_names(&inventory, None, cx).await,        vec![            "3_task".to_string(),            "1_task".to_string(),            "2_task".to_string(),            "1_a_task".to_string(),        ],        "Most recently used task should be at the top"    );    assert_eq!(        resolved_task_names(&inventory, Some(worktree_id), cx).await,        vec![            "3_task".to_string(),            "1_task".to_string(),            "2_task".to_string(),            "worktree_task_1".to_string(),            "1_a_task".to_string(),        ],    );    register_worktree_task_used(&inventory, worktree_id, "worktree_task_1", cx).await;    assert_eq!(        resolved_task_names(&inventory, Some(worktree_id), cx).await,        vec![            "worktree_task_1".to_string(),            "3_task".to_string(),            "1_task".to_string(),            "2_task".to_string(),            "1_a_task".to_string(),        ],        "Most recently used worktree task should be at the top"    );     inventory.update(cx, |inventory, _| {        inventory            .update_file_based_tasks(                TaskSettingsLocation::Global(tasks_file()),                Some(&mock_tasks_from_names(                    ["10_hello", "11_hello"]                        .into_iter()                        .chain(expected_initial_state.iter().map(|name| name.as_str())),                )),            )            .unwrap();    });    cx.run_until_parked();    let expected_updated_state = [        "10_hello".to_string(),        "11_hello".to_string(),        "1_a_task".to_string(),        "1_task".to_string(),        "2_task".to_string(),        "3_task".to_string(),    ];    assert_eq!(        task_template_names(&inventory, None, cx).await,        &expected_updated_state,    );    assert_eq!(        resolved_task_names(&inventory, None, cx).await,        vec![            "worktree_task_1".to_string(),            "1_a_task".to_string(),            "1_task".to_string(),            "2_task".to_string(),            "3_task".to_string(),            "10_hello".to_string(),            "11_hello".to_string(),        ],        "After global tasks update, worktree task usage is not erased and it's the first still; global task is back to regular order as its file was updated"    );     register_task_used(&inventory, "11_hello", cx).await;    assert_eq!(        task_template_names(&inventory, None, cx).await,        &expected_updated_state,    );    assert_eq!(        resolved_task_names(&inventory, None, cx).await,        vec![            "11_hello".to_string(),            "worktree_task_1".to_string(),            "1_a_task".to_string(),            "1_task".to_string(),            "2_task".to_string(),            "3_task".to_string(),            "10_hello".to_string(),        ],    );} #[gpui::test]async fn test_reloading_debug_scenarios(cx: &mut TestAppContext) {    init_test(cx);    let inventory = cx.update(|cx| Inventory::new(cx));    inventory.update(cx, |inventory, _| {        inventory            .update_file_based_scenarios(                TaskSettingsLocation::Global(Path::new("")),                Some(                    r#"                        [{                            "label": "test scenario",                            "adapter": "CodeLLDB",                            "request": "launch",                            "program": "wowzer",                        }]                        "#,                ),            )            .unwrap();    });     let (_, scenario) = inventory        .update(cx, |this, cx| {            this.list_debug_scenarios(&TaskContexts::default(), vec![], vec![], false, cx)        })        .await        .1        .first()        .unwrap()        .clone();     inventory.update(cx, |this, _| {        this.scenario_scheduled(scenario.clone(), Default::default(), None, None);    });     assert_eq!(        inventory            .update(cx, |this, cx| {                this.list_debug_scenarios(&Default::default(), vec![], vec![], false, cx)            })            .await            .0            .first()            .unwrap()            .clone()            .0,        scenario    );     inventory.update(cx, |this, _| {        this.update_file_based_scenarios(            TaskSettingsLocation::Global(Path::new("")),            Some(                r#"                        [{                            "label": "test scenario",                            "adapter": "Delve",                            "request": "launch",                            "program": "wowzer",                        }]                        "#,            ),        )        .unwrap();    });     assert_eq!(        inventory            .update(cx, |this, cx| {                this.list_debug_scenarios(&Default::default(), vec![], vec![], false, cx)            })            .await            .0            .first()            .unwrap()            .0            .adapter,        "Delve",    );     inventory.update(cx, |this, _| {        this.update_file_based_scenarios(            TaskSettingsLocation::Global(Path::new("")),            Some(                r#"                        [{                            "label": "testing scenario",                            "adapter": "Delve",                            "request": "launch",                            "program": "wowzer",                        }]                        "#,            ),        )        .unwrap();    });     assert!(        inventory            .update(cx, |this, cx| {                this.list_debug_scenarios(&TaskContexts::default(), vec![], vec![], false, cx)            })            .await            .0            .is_empty(),    );} #[gpui::test]async fn test_inventory_static_task_filters(cx: &mut TestAppContext) {    init_test(cx);    let inventory = cx.update(|cx| Inventory::new(cx));    let common_name = "common_task_name";    let worktree_1 = WorktreeId::from_usize(1);    let worktree_2 = WorktreeId::from_usize(2);     cx.run_until_parked();    let worktree_independent_tasks = vec![        (            TaskSourceKind::AbsPath {                id_base: "global tasks.json".into(),                abs_path: paths::tasks_file().clone(),            },            common_name.to_string(),        ),        (            TaskSourceKind::AbsPath {                id_base: "global tasks.json".into(),                abs_path: paths::tasks_file().clone(),            },            "static_source_1".to_string(),        ),        (            TaskSourceKind::AbsPath {                id_base: "global tasks.json".into(),                abs_path: paths::tasks_file().clone(),            },            "static_source_2".to_string(),        ),    ];    let worktree_1_tasks = [        (            TaskSourceKind::Worktree {                id: worktree_1,                directory_in_worktree: rel_path(".zed").into(),                id_base: "local worktree tasks from directory \".zed\"".into(),            },            common_name.to_string(),        ),        (            TaskSourceKind::Worktree {                id: worktree_1,                directory_in_worktree: rel_path(".zed").into(),                id_base: "local worktree tasks from directory \".zed\"".into(),            },            "worktree_1".to_string(),        ),    ];    let worktree_2_tasks = [        (            TaskSourceKind::Worktree {                id: worktree_2,                directory_in_worktree: rel_path(".zed").into(),                id_base: "local worktree tasks from directory \".zed\"".into(),            },            common_name.to_string(),        ),        (            TaskSourceKind::Worktree {                id: worktree_2,                directory_in_worktree: rel_path(".zed").into(),                id_base: "local worktree tasks from directory \".zed\"".into(),            },            "worktree_2".to_string(),        ),    ];     inventory.update(cx, |inventory, _| {        inventory            .update_file_based_tasks(                TaskSettingsLocation::Global(tasks_file()),                Some(&mock_tasks_from_names(                    worktree_independent_tasks                        .iter()                        .map(|(_, name)| name.as_str()),                )),            )            .unwrap();        inventory            .update_file_based_tasks(                TaskSettingsLocation::Worktree(SettingsLocation {                    worktree_id: worktree_1,                    path: rel_path(".zed"),                }),                Some(&mock_tasks_from_names(                    worktree_1_tasks.iter().map(|(_, name)| name.as_str()),                )),

Lines 1–500 of 674.