Files
gitks/tests/diff_test.rs
T
zhenyi dcb0fb74c5 feat(core): implement Git repository operations with gRPC services
- Add advertise_refs functionality for Git protocol communication
- Implement archive service with TAR/ZIP format support and streaming
- Create blame service for Git file annotation with line tracking
- Add branch management including create, delete, rename and compare operations
- Implement merge checking with conflict detection and fast-forward handling
- Add cherry-pick functionality for applying commits between branches
- Integrate gix library for Git repository operations and object handling
- Add comprehensive test suite covering all Git operations
- Implement proper error handling and repository validation
- Add pagination support for large result sets
- Create protobuf definitions for all Git operations and data structures
- Add build system for gRPC code generation and dependency management
2026-06-04 13:05:38 +08:00

237 lines
7.3 KiB
Rust

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("@@"));
}