#![cfg(test)]
#![allow(clippy::unwrap_used)]
use std::path::Path;
use panproto_vcs::{MemStore, Store};
use crate::import::import_git_repo;
fn create_test_git_repo(files: &[(&str, &[u8])]) -> (tempfile::TempDir, git2::Repository) {
let dir = tempfile::tempdir().unwrap();
let repo = git2::Repository::init(dir.path()).unwrap();
let sig = git2::Signature::new("Test", "test@example.com", &git2::Time::new(1000, 0)).unwrap();
let mut index = repo.index().unwrap();
for (path, content) in files {
let full_path = dir.path().join(path);
if let Some(parent) = full_path.parent() {
std::fs::create_dir_all(parent).unwrap();
}
std::fs::write(&full_path, content).unwrap();
index.add_path(Path::new(path)).unwrap();
}
index.write().unwrap();
let tree_oid = index.write_tree().unwrap();
{
let tree = repo.find_tree(tree_oid).unwrap();
repo.commit(Some("HEAD"), &sig, &sig, "Initial commit", &tree, &[])
.unwrap();
}
(dir, repo)
}
#[test]
fn import_single_typescript_file() {
let (_dir, git_repo) = create_test_git_repo(&[(
"main.ts",
b"function greet(name: string): string { return 'Hello, ' + name; }",
)]);
let mut store = MemStore::new();
let result = import_git_repo(&git_repo, &mut store, "HEAD").unwrap();
assert_eq!(result.commit_count, 1);
assert_ne!(result.head_id, panproto_vcs::ObjectId::ZERO);
assert_eq!(result.oid_map.len(), 1);
let commit_obj = store.get(&result.head_id).unwrap();
match &commit_obj {
panproto_vcs::Object::Commit(c) => {
assert_eq!(c.message, "Initial commit");
assert_eq!(c.author, "Test");
}
other => panic!("expected commit, got {}", other.type_name()),
}
}
#[test]
fn import_multi_file_project() {
let (_dir, git_repo) = create_test_git_repo(&[
(
"src/main.ts",
b"function main(): void { console.log('hello'); }",
),
(
"src/utils.ts",
b"export function add(a: number, b: number): number { return a + b; }",
),
("README.md", b"# Test Project\n\nA test project.\n"),
]);
let mut store = MemStore::new();
let result = import_git_repo(&git_repo, &mut store, "HEAD").unwrap();
assert_eq!(result.commit_count, 1);
let commit_obj = store.get(&result.head_id).unwrap();
let commit = match &commit_obj {
panproto_vcs::Object::Commit(c) => c,
other => panic!("expected commit, got {}", other.type_name()),
};
let schema_obj = store.get(&commit.schema_id).unwrap();
match &schema_obj {
panproto_vcs::Object::Schema(s) => {
assert!(
s.vertices.len() > 5,
"expected rich project schema, got {} vertices",
s.vertices.len()
);
}
other => panic!("expected schema, got {}", other.type_name()),
}
}
#[test]
fn import_multiple_commits() {
let dir = tempfile::tempdir().unwrap();
let repo = git2::Repository::init(dir.path()).unwrap();
let sig = git2::Signature::new("Dev", "dev@test.com", &git2::Time::new(1000, 0)).unwrap();
let file_path = dir.path().join("main.py");
std::fs::write(&file_path, b"x = 1\n").unwrap();
let mut index = repo.index().unwrap();
index.add_path(Path::new("main.py")).unwrap();
index.write().unwrap();
let tree_oid = index.write_tree().unwrap();
let tree = repo.find_tree(tree_oid).unwrap();
let commit1_oid = repo
.commit(Some("HEAD"), &sig, &sig, "First", &tree, &[])
.unwrap();
std::fs::write(&file_path, b"x = 1\ny = 2\n").unwrap();
let mut index = repo.index().unwrap();
index.add_path(Path::new("main.py")).unwrap();
index.write().unwrap();
let tree_oid = index.write_tree().unwrap();
let tree = repo.find_tree(tree_oid).unwrap();
let commit1 = repo.find_commit(commit1_oid).unwrap();
repo.commit(Some("HEAD"), &sig, &sig, "Second", &tree, &[&commit1])
.unwrap();
let mut store = MemStore::new();
let result = import_git_repo(&repo, &mut store, "HEAD").unwrap();
assert_eq!(result.commit_count, 2);
assert_eq!(result.oid_map.len(), 2);
let second_commit_obj = store.get(&result.head_id).unwrap();
match &second_commit_obj {
panproto_vcs::Object::Commit(c) => {
assert_eq!(c.message, "Second");
assert_eq!(c.parents.len(), 1);
let first_panproto_id = result.oid_map[0].1;
assert_eq!(c.parents[0], first_panproto_id);
}
other => panic!("expected commit, got {}", other.type_name()),
}
}