git_tests.rs

  1use std::path::Path;
  2
  3use call::ActiveCall;
  4use git::status::{FileStatus, StatusCode, TrackedStatus};
  5use git_ui::project_diff::ProjectDiff;
  6use gpui::{AppContext as _, TestAppContext, VisualTestContext};
  7use project::ProjectPath;
  8use serde_json::json;
  9use util::{path, rel_path::rel_path};
 10use workspace::{MultiWorkspace, Workspace};
 11
 12//
 13use crate::TestServer;
 14
 15#[gpui::test]
 16async fn test_project_diff(cx_a: &mut TestAppContext, cx_b: &mut TestAppContext) {
 17    let mut server = TestServer::start(cx_a.background_executor.clone()).await;
 18    let client_a = server.create_client(cx_a, "user_a").await;
 19    let client_b = server.create_client(cx_b, "user_b").await;
 20    cx_a.set_name("cx_a");
 21    cx_b.set_name("cx_b");
 22
 23    server
 24        .create_room(&mut [(&client_a, cx_a), (&client_b, cx_b)])
 25        .await;
 26
 27    client_a
 28        .fs()
 29        .insert_tree(
 30            path!("/a"),
 31            json!({
 32                ".git": {},
 33                "changed.txt": "after\n",
 34                "unchanged.txt": "unchanged\n",
 35                "created.txt": "created\n",
 36                "secret.pem": "secret-changed\n",
 37            }),
 38        )
 39        .await;
 40
 41    client_a.fs().set_head_and_index_for_repo(
 42        Path::new(path!("/a/.git")),
 43        &[
 44            ("changed.txt", "before\n".to_string()),
 45            ("unchanged.txt", "unchanged\n".to_string()),
 46            ("deleted.txt", "deleted\n".to_string()),
 47            ("secret.pem", "shh\n".to_string()),
 48        ],
 49    );
 50    let (project_a, worktree_id) = client_a.build_local_project(path!("/a"), cx_a).await;
 51    let active_call_a = cx_a.read(ActiveCall::global);
 52    let project_id = active_call_a
 53        .update(cx_a, |call, cx| call.share_project(project_a.clone(), cx))
 54        .await
 55        .unwrap();
 56
 57    cx_b.update(editor::init);
 58    cx_b.update(git_ui::init);
 59    let project_b = client_b.join_remote_project(project_id, cx_b).await;
 60    let window_b = cx_b.add_window(|window, cx| {
 61        let workspace = cx.new(|cx| {
 62            Workspace::new(
 63                None,
 64                project_b.clone(),
 65                client_b.app_state.clone(),
 66                window,
 67                cx,
 68            )
 69        });
 70        MultiWorkspace::new(workspace, window, cx)
 71    });
 72    let cx_b = &mut VisualTestContext::from_window(*window_b, cx_b);
 73    let workspace_b = window_b
 74        .root(cx_b)
 75        .unwrap()
 76        .read_with(cx_b, |multi_workspace, _| {
 77            multi_workspace.workspace().clone()
 78        });
 79
 80    cx_b.update(|window, cx| {
 81        window
 82            .focused(cx)
 83            .unwrap()
 84            .dispatch_action(&git_ui::project_diff::Diff, window, cx)
 85    });
 86    let diff = workspace_b.update(cx_b, |workspace, cx| {
 87        workspace.active_item(cx).unwrap().act_as::<ProjectDiff>(cx)
 88    });
 89    let diff = diff.unwrap();
 90    cx_b.run_until_parked();
 91
 92    diff.update(cx_b, |diff, cx| {
 93        assert_eq!(
 94            diff.excerpt_paths(cx),
 95            vec![
 96                rel_path("changed.txt").into_arc(),
 97                rel_path("deleted.txt").into_arc(),
 98                rel_path("created.txt").into_arc()
 99            ]
100        );
101    });
102
103    client_a
104        .fs()
105        .insert_tree(
106            path!("/a"),
107            json!({
108                ".git": {},
109                "changed.txt": "before\n",
110                "unchanged.txt": "changed\n",
111                "created.txt": "created\n",
112                "secret.pem": "secret-changed\n",
113            }),
114        )
115        .await;
116    cx_b.run_until_parked();
117
118    project_b.update(cx_b, |project, cx| {
119        let project_path = ProjectPath {
120            worktree_id,
121            path: rel_path("unchanged.txt").into(),
122        };
123        let status = project.project_path_git_status(&project_path, cx);
124        assert_eq!(
125            status.unwrap(),
126            FileStatus::Tracked(TrackedStatus {
127                worktree_status: StatusCode::Modified,
128                index_status: StatusCode::Unmodified,
129            })
130        );
131    });
132
133    diff.update(cx_b, |diff, cx| {
134        assert_eq!(
135            diff.excerpt_paths(cx),
136            vec![
137                rel_path("deleted.txt").into_arc(),
138                rel_path("unchanged.txt").into_arc(),
139                rel_path("created.txt").into_arc()
140            ]
141        );
142    });
143}