mod common; use gitks::pb::*; #[test] fn test_get_diff() { let (_dir, gb) = common::setup_bare_repo(); let result = gb .get_diff(GetDiffRequest { repository: None, base: Some(ObjectSelector { selector: Some(object_selector::Selector::Revision(ObjectName { revision: "main~3".into(), })), }), head: Some(ObjectSelector { selector: Some(object_selector::Selector::Revision(ObjectName { revision: "main".into(), })), }), options: None, pagination: None, }) .expect("get_diff"); assert!(!result.files.is_empty()); let paths: Vec<&str> = result.files.iter().map(|f| f.new_path.as_str()).collect(); assert!( paths.iter().any(|p| p.contains("src.txt")), "should include src.txt, got: {:?}", paths ); let stats = result.stats.unwrap(); assert!(stats.additions > 0 || stats.changed_files > 0); } #[test] fn test_get_diff_with_patch() { let (_dir, gb) = common::setup_bare_repo(); let result = gb .get_diff(GetDiffRequest { repository: None, base: Some(ObjectSelector { selector: Some(object_selector::Selector::Revision(ObjectName { revision: "main~1".into(), })), }), head: Some(ObjectSelector { selector: Some(object_selector::Selector::Revision(ObjectName { revision: "main".into(), })), }), options: Some(DiffOptions { include_patch: true, context_lines: 3, ..Default::default() }), pagination: None, }) .expect("get_diff with patch"); assert!(!result.files.is_empty()); for file in &result.files { if !file.binary { assert!( !file.patch.is_empty(), "non-binary file should have patch: {}", file.new_path ); } } } #[test] fn test_get_diff_with_rename_detection() { let (_dir, gb) = common::setup_bare_repo(); gb.create_commit(CreateCommitRequest { repository: None, branch: "main".into(), message: "rename file".into(), author: None, committer: None, actions: vec![ CreateCommitAction { action: create_commit_action::Action::CreateCommitActionCreate as i32, file_path: "renamed.txt".into(), previous_path: String::new(), content: b"source\n".to_vec(), encoding: String::new(), executable: false, last_commit_oid: None, }, CreateCommitAction { action: create_commit_action::Action::CreateCommitActionDelete as i32, file_path: "src.txt".into(), previous_path: String::new(), content: vec![], encoding: String::new(), executable: false, last_commit_oid: None, }, ], start_revision: Some(ObjectSelector { selector: Some(object_selector::Selector::Revision(ObjectName { revision: "main".into(), })), }), force: false, trailers: vec![], }) .expect("create rename commit"); let result = gb .get_diff(GetDiffRequest { repository: None, base: Some(ObjectSelector { selector: Some(object_selector::Selector::Revision(ObjectName { revision: "main~1".into(), })), }), head: Some(ObjectSelector { selector: Some(object_selector::Selector::Revision(ObjectName { revision: "main".into(), })), }), options: Some(DiffOptions { rename_detection: true, ..Default::default() }), pagination: None, }) .expect("get_diff with rename detection"); let has_rename = result .files .iter() .any(|f| f.change_type == diff_file::ChangeType::DiffFileChangeTypeRenamed as i32); assert!( has_rename, "should detect rename, files: {:?}", result.files.len() ); } #[test] fn test_get_commit_diff_root() { let (_dir, gb) = common::setup_bare_repo(); let commits = gb .list_commits(ListCommitsRequest { repository: None, revision: Some(ObjectSelector { selector: Some(object_selector::Selector::Revision(ObjectName { revision: "main".into(), })), }), path: String::new(), since: None, until: None, first_parent: false, all: false, reverse: true, max_parents: 0, min_parents: 0, pagination: Some(Pagination { page_size: 1, page_token: String::new(), }), }) .expect("list_commits for root"); let root_oid = commits.commits[0].oid.as_ref().unwrap().hex.clone(); let result = gb .get_commit_diff(GetCommitDiffRequest { repository: None, commit: Some(ObjectSelector { selector: Some(object_selector::Selector::Revision(ObjectName { revision: root_oid, })), }), options: None, pagination: None, }) .expect("get_commit_diff on root"); assert!(!result.files.is_empty(), "root commit should have files"); } #[test] fn test_get_diff_stats() { let (_dir, gb) = common::setup_bare_repo(); let stats = gb .get_diff_stats(GetDiffStatsRequest { repository: None, base: Some(ObjectSelector { selector: Some(object_selector::Selector::Revision(ObjectName { revision: "main~3".into(), })), }), head: Some(ObjectSelector { selector: Some(object_selector::Selector::Revision(ObjectName { revision: "main".into(), })), }), options: None, }) .expect("get_diff_stats"); assert!(stats.additions > 0 || stats.changed_files > 0); } #[test] fn test_get_patch() { let (_dir, gb) = common::setup_bare_repo(); let patches = gb .get_patch(GetPatchRequest { repository: None, base: Some(ObjectSelector { selector: Some(object_selector::Selector::Revision(ObjectName { revision: "main~1".into(), })), }), head: Some(ObjectSelector { selector: Some(object_selector::Selector::Revision(ObjectName { revision: "main".into(), })), }), options: None, }) .expect("get_patch"); assert!(!patches.is_empty()); let combined: String = patches .iter() .map(|p| String::from_utf8_lossy(&p.data).to_string()) .collect(); assert!(combined.contains("diff --git") || combined.contains("@@")); }