use std::fs;
use std::path::{Path, PathBuf};
use std::sync::atomic::{AtomicU64, Ordering};
use kcode_rust_libs_v2::{Error, File, Lib, create, docs, open};
static TEST_COUNTER: AtomicU64 = AtomicU64::new(0);
struct TestRoot(PathBuf);
impl TestRoot {
fn new(label: &str) -> Self {
let counter = TEST_COUNTER.fetch_add(1, Ordering::Relaxed);
let path = std::env::temp_dir().join(format!(
"kcode-rust-libs-v2-integration-{label}-{}-{counter}",
std::process::id()
));
fs::create_dir(&path).unwrap();
Self(path)
}
fn path(&self) -> &Path {
&self.0
}
}
impl Drop for TestRoot {
fn drop(&mut self) {
let _ = fs::remove_dir_all(&self.0);
}
}
fn contents_mut<'a>(library: &'a mut Lib, path: &str) -> &'a mut String {
&mut library
.files
.iter_mut()
.find(|file| file.path == path)
.unwrap()
.contents
}
#[test]
fn create_open_and_docs_return_source_once_without_a_lockfile() {
let root = TestRoot::new("open");
let created = create(root.path(), "demo", "private-token").unwrap();
assert_eq!(
created
.files
.iter()
.map(|file| file.path.as_str())
.collect::<Vec<_>>(),
["Cargo.toml", "Documentation.md", "src/lib.rs"]
);
assert_eq!(
created
.files
.iter()
.filter(|file| file.path == "Documentation.md")
.count(),
1
);
assert!(created.files.iter().all(|file| file.path != "Cargo.lock"));
let opened = open(root.path(), "demo", "private-token").unwrap();
assert_eq!(opened.files, created.files);
assert_eq!(
docs(root.path(), "demo").unwrap(),
("0.1.0".to_owned(), String::new())
);
}
#[test]
fn open_and_docs_migrate_a_legacy_flat_library() {
let root = TestRoot::new("migration");
let repository = root.path().join("legacy");
fs::create_dir(&repository).unwrap();
fs::create_dir(repository.join("src")).unwrap();
fs::write(
repository.join("Cargo.toml"),
"[package]\nname = \"legacy\"\nversion = \"2.3.4\"\nedition = \"2024\"\n",
)
.unwrap();
fs::write(repository.join("Documentation.md"), "legacy API\n").unwrap();
fs::write(repository.join("src/lib.rs"), "pub fn legacy() {}\n").unwrap();
fs::write(repository.join("Cargo.lock"), "version = 4\n").unwrap();
let opened = open(root.path(), "legacy", "private-token").unwrap();
assert!(opened.files.iter().all(|file| file.path != "Cargo.lock"));
assert_eq!(
docs(root.path(), "legacy").unwrap(),
("2.3.4".to_owned(), "legacy API\n".to_owned())
);
assert!(repository.join("HEAD").is_file());
assert!(repository.join(".lock").is_file());
assert!(repository.join("generations").is_dir());
}
#[test]
fn complete_replacement_removes_omitted_files_and_refreshes_identity() {
let root = TestRoot::new("replace");
let mut library = create(root.path(), "demo", "private-token").unwrap();
library.files.push(File {
path: "tests/temporary.rs".to_owned(),
contents: "#[test]\nfn temporary() {}\n".to_owned(),
});
library.write().unwrap();
assert!(
open(root.path(), "demo", "private-token")
.unwrap()
.files
.iter()
.any(|file| file.path == "tests/temporary.rs")
);
library
.files
.retain(|file| file.path != "tests/temporary.rs");
*contents_mut(&mut library, "Documentation.md") = "second write\n".to_owned();
library.write().unwrap();
let reopened = open(root.path(), "demo", "private-token").unwrap();
assert!(
reopened
.files
.iter()
.all(|file| file.path != "tests/temporary.rs")
);
assert_eq!(
reopened
.files
.iter()
.find(|file| file.path == "Documentation.md")
.unwrap()
.contents,
"second write\n"
);
}
#[test]
fn two_writers_from_one_snapshot_cannot_both_commit() {
let root = TestRoot::new("stale");
create(root.path(), "demo", "private-token").unwrap();
let mut first = open(root.path(), "demo", "private-token").unwrap();
let mut second = open(root.path(), "demo", "private-token").unwrap();
*contents_mut(&mut first, "Documentation.md") = "first\n".to_owned();
*contents_mut(&mut second, "Documentation.md") = "second\n".to_owned();
first.write().unwrap();
let error = second.write().unwrap_err();
assert!(error.to_string().starts_with("stale_snapshot:"));
assert_eq!(docs(root.path(), "demo").unwrap().1, "first\n");
}
#[test]
fn invalid_paths_lockfiles_and_metadata_fail_before_commit() {
let root = TestRoot::new("invalid");
let mut library = create(root.path(), "demo", "private-token").unwrap();
let original = library.files.clone();
library.files.push(File {
path: "../escape".to_owned(),
contents: "bad".to_owned(),
});
assert!(library.write().is_err());
library.files = original.clone();
library.files.push(File {
path: "Cargo.lock".to_owned(),
contents: "version = 4\n".to_owned(),
});
assert!(library.write().is_err());
library.files = original;
*contents_mut(&mut library, "Cargo.toml") =
"[package]\nname = \"demo\"\nversion = \"1.2.3-beta\"\n".to_owned();
assert!(library.write().is_err());
assert_eq!(docs(root.path(), "demo").unwrap().0, "0.1.0");
}
#[test]
fn empty_tokens_fail_before_creating_roots_and_dropped_handles_hold_no_lock() {
let parent = TestRoot::new("token");
let root = parent.path().join("libraries");
let error: Error = create(&root, "demo", " ").unwrap_err();
assert!(error.to_string().starts_with("invalid_token:"));
assert!(!root.exists());
let root = TestRoot::new("drop");
let library = create(root.path(), "demo", "private-token").unwrap();
drop(library);
let mut reopened = open(root.path(), "demo", "private-token").unwrap();
*contents_mut(&mut reopened, "Documentation.md") = "unblocked\n".to_owned();
reopened.write().unwrap();
}