use crate::file;
use crate::repo::{self, pijul};
use crate::testing::{
repo_path, setup_test_repo, setup_test_repo_in_subdir, DEFAULT_IGNORE_FILE,
INITIAL_LOG_LEN,
};
use assert_matches::assert_matches;
use libpijul::key::SKey;
use tempfile::tempdir;
use test_log::test;
use std::collections::BTreeSet;
use std::sync::Arc;
#[test]
fn test_load_repo() {
let dir = tempdir().unwrap();
let result =
repo::load(&dir.path().join("howdoyouopensomethingthatdoesntexist"));
assert!(result.is_err());
assert_matches!(result.unwrap_err(), repo::LoadError::DoesntExist(_));
let dir = tempdir().unwrap();
let result = repo::load(dir.path());
assert!(result.is_err());
assert_matches!(result.unwrap_err(), repo::LoadError::NotPijulRepo(_));
#[cfg(unix)]
{
let subdir = "inaccessible";
let repo = setup_test_repo_in_subdir(subdir);
let repo_path = repo_path(&repo);
std::fs::set_permissions(repo.rootdir.path(), <std::fs::Permissions as std::os::unix::fs::PermissionsExt>::from_mode(0o000)).unwrap();
assert!(std::fs::exists(&repo_path).is_err());
let result = repo::load(&repo.rootdir.path().join(subdir));
assert!(result.is_err());
assert_matches!(
result.unwrap_err(),
repo::LoadError::Inaccessible(_, _)
);
}
let repo = setup_test_repo();
let repo_path = repo_path(&repo);
let (_internal, state) = repo::load(&repo_path).unwrap();
let repo::State {
dir_name,
channel,
other_channels,
untracked_files,
changed_files,
short_log,
remotes: _,
} = state.unwrap();
assert_eq!(
&dir_name,
&repo_path
.components()
.next_back()
.unwrap()
.as_os_str()
.to_string_lossy()
);
assert_eq!(&channel, libpijul::DEFAULT_CHANNEL);
assert_eq!(other_channels, BTreeSet::<String>::new());
assert!(untracked_files.is_empty());
assert!(changed_files.is_empty());
assert_eq!(short_log.len(), 2);
}
#[test]
fn test_current_channel() {
let repo = setup_test_repo();
let repo_path = repo_path(&repo);
let mut repo = pijul::Repository::find_root(Some(&repo_path)).unwrap();
assert_eq!(
repo::current_channel(&repo).unwrap(),
libpijul::DEFAULT_CHANNEL
);
let new_channel_name = "NEW CHANNEL!".to_string();
repo::new_channel(&mut repo, new_channel_name.clone()).unwrap();
assert_eq!(repo::current_channel(&repo).unwrap(), new_channel_name);
}
#[test]
fn test_record() {
let repo = setup_test_repo();
let repo_path = repo_path(&repo);
let (internal, _state) = repo::load(&repo_path).unwrap();
let log = repo::get_log(&internal.repo, None, None, None).unwrap();
assert_eq!(log.len(), INITIAL_LOG_LEN);
let file_path = DEFAULT_IGNORE_FILE;
let full_file_path = repo_path.join(DEFAULT_IGNORE_FILE);
std::fs::write(&full_file_path, "some content").unwrap();
let skey = Arc::new(SKey::generate(None));
let msg = "some message";
let to_record = crate::to_record::State::default();
repo::record(
&internal,
msg.to_string(),
None,
skey,
"ID".to_string(),
to_record,
)
.unwrap();
let log = repo::get_log(&internal.repo, None, None, None).unwrap();
assert_eq!(log.len(), INITIAL_LOG_LEN + 1);
let repo::LogEntry {
hash: _,
message,
description,
file_paths,
timestamp: _,
} = log.first().unwrap();
assert_eq!(message, msg);
assert_eq!(description, &None);
assert_eq!(file_paths.len(), 1);
assert_eq!(file_paths.first().unwrap(), file_path);
}
#[test]
fn test_diff_and_changed_files() {
let repo = setup_test_repo();
let repo_path = repo_path(&repo);
let (internal, _state) = repo::load(&repo_path).unwrap();
let diff = repo::get_diff(&internal.repo).unwrap();
assert!(diff.changes.is_empty());
std::fs::write(repo_path.join(DEFAULT_IGNORE_FILE), "some content")
.unwrap();
let diff = repo::get_diff(&internal.repo).unwrap();
assert_eq!(diff.changes.len(), 1);
assert_matches!(
diff.changes.first().unwrap(),
libpijul::change::BaseHunk::Replacement { .. }
);
let changed_files = repo::changed_files(&internal.repo, &diff).unwrap();
assert_eq!(changed_files.len(), 1);
let path = file::Path {
raw: DEFAULT_IGNORE_FILE.to_string(),
is_dir: false,
};
let changed_file_diff = changed_files.get(&path).unwrap();
assert_eq!(changed_file_diff.len(), 1);
assert_matches!(
changed_file_diff.first().unwrap(),
repo::ChangedFileDiff::Replacement { .. }
);
}
#[test]
fn test_untracked_files() {
let repo = setup_test_repo();
let repo_path = repo_path(&repo);
let (internal, _state) = repo::load(&repo_path).unwrap();
let untracked_files = repo::untracked_files(&internal.repo).unwrap();
assert!(untracked_files.is_empty());
let new_file = "new_file";
std::fs::write(repo_path.join(new_file), "some content").unwrap();
let untracked_files = repo::untracked_files(&internal.repo).unwrap();
assert_eq!(untracked_files.len(), 1);
assert_eq!(untracked_files.first().unwrap().raw, new_file);
}
#[test]
fn test_add_and_rm() {
let repo = setup_test_repo();
let repo_path = repo_path(&repo);
let (mut internal, _state) = repo::load(&repo_path).unwrap();
let diff = repo::get_diff(&internal.repo).unwrap();
assert!(diff.changes.is_empty());
let new_file = "new_file";
std::fs::write(repo_path.join(new_file), "some content").unwrap();
let recursive = false;
repo::add(&mut internal.repo, new_file, recursive).unwrap();
let diff = repo::get_diff(&internal.repo).unwrap();
assert_eq!(diff.changes.len(), 1);
assert_matches!(
diff.changes.first().unwrap(),
libpijul::change::BaseHunk::FileAdd { .. }
);
repo::rm(&mut internal.repo, new_file).unwrap();
let adiff = repo::get_diff(&internal.repo).unwrap();
assert!(adiff.changes.is_empty());
let new_dir = "a";
std::fs::create_dir(repo_path.join(new_dir)).unwrap();
let new_file = "new_file";
std::fs::write(repo_path.join(new_dir).join(new_file), "some content")
.unwrap();
let recursive = true;
repo::add(&mut internal.repo, new_dir, recursive).unwrap();
let diff = repo::get_diff(&internal.repo).unwrap();
assert_eq!(diff.changes.len(), 2);
}
#[test]
fn test_log() {
let repo = setup_test_repo();
let repo_path = repo_path(&repo);
let (internal, _state) = repo::load(&repo_path).unwrap();
let mut log = repo::get_log(&internal.repo, None, None, None).unwrap();
assert_eq!(2, INITIAL_LOG_LEN);
assert_eq!(log.len(), INITIAL_LOG_LEN);
let change_1 = log.pop().unwrap();
let change_0 = log.pop().unwrap();
let limit = 1;
let mut log =
repo::get_log(&internal.repo, None, None, Some(limit)).unwrap();
assert_eq!(log.len(), limit);
assert_eq!(log.pop().unwrap(), change_0);
let offset = 1;
let mut log =
repo::get_log(&internal.repo, None, Some(offset), None).unwrap();
assert_eq!(log.len(), INITIAL_LOG_LEN - 1);
assert_eq!(log.pop().unwrap(), change_1);
}