use kcode_web_libs::{File, Lib, create, docs, open};
use std::fs;
use tempfile::TempDir;
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_the_complete_sorted_source() {
let root = TempDir::new().unwrap();
let created = create(root.path(), "Example_lib-2").unwrap();
assert_eq!(
created
.files
.iter()
.map(|file| file.path.as_str())
.collect::<Vec<_>>(),
["Documentation.md", "index.js", "kcode-web.json", "tests.js"]
);
let opened = open(root.path(), "Example_lib-2").unwrap();
assert_eq!(opened.files, created.files);
let (version, documentation) = docs(root.path(), "Example_lib-2").unwrap();
assert_eq!(version, "0.1.0");
assert!(documentation.starts_with("# Example_lib-2\n"));
}
#[test]
fn complete_replacement_removes_omitted_files_and_old_generations() {
let root = TempDir::new().unwrap();
let mut library = create(root.path(), "demo").unwrap();
library.files.push(File {
path: "temporary.js".to_owned(),
contents: "export {};".to_owned(),
});
library.write().unwrap();
library.files.retain(|file| file.path != "temporary.js");
*contents_mut(&mut library, "Documentation.md") = "second write\n".to_owned();
library.write().unwrap();
let reopened = open(root.path(), "demo").unwrap();
assert!(
reopened
.files
.iter()
.all(|file| file.path != "temporary.js")
);
assert_eq!(
reopened
.files
.iter()
.find(|file| file.path == "Documentation.md")
.unwrap()
.contents,
"second write\n"
);
assert_eq!(
fs::read_dir(root.path().join("demo/generations"))
.unwrap()
.count(),
1
);
}
#[test]
fn two_writers_from_one_snapshot_cannot_both_commit() {
let root = TempDir::new().unwrap();
create(root.path(), "demo").unwrap();
let mut first = open(root.path(), "demo").unwrap();
let mut second = open(root.path(), "demo").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_and_metadata_fail_before_commit() {
let root = TempDir::new().unwrap();
let mut library = create(root.path(), "demo").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;
*contents_mut(&mut library, "kcode-web.json") =
r#"{"name":"demo","version":"1.2.3-beta","entry":"index.js","tests":"tests.js"}"#
.to_owned();
assert!(library.write().is_err());
assert_eq!(docs(root.path(), "demo").unwrap().0, "0.1.0");
}
#[test]
fn check_uses_current_in_memory_source_without_requiring_a_write() {
let root = TempDir::new().unwrap();
let mut library = create(root.path(), "demo").unwrap();
library.files.push(File {
path: "../not-committed".to_owned(),
contents: "bad".to_owned(),
});
let error = library.check().unwrap_err();
assert!(error.to_string().starts_with("invalid_source:"));
}
#[test]
fn publish_rechecks_the_current_in_memory_source() {
let root = TempDir::new().unwrap();
let mut library = create(root.path(), "demo").unwrap();
*contents_mut(&mut library, "kcode-web.json") =
r#"{"name":"demo","version":"1.2.3-beta","entry":"index.js","tests":"tests.js"}"#
.to_owned();
let error = library.publish().unwrap_err();
assert!(error.to_string().starts_with("invalid_source:"));
assert!(!root.path().join(".published").exists());
}
#[cfg(unix)]
#[test]
fn docs_does_not_traverse_unrelated_source_but_open_rejects_symlinks() {
use std::os::unix::fs::symlink;
let root = TempDir::new().unwrap();
create(root.path(), "demo").unwrap();
let repository = root.path().join("demo");
let generation = fs::read_to_string(repository.join("HEAD"))
.unwrap()
.trim()
.to_owned();
symlink(
root.path(),
repository
.join("generations")
.join(generation)
.join("unrelated-link"),
)
.unwrap();
assert_eq!(docs(root.path(), "demo").unwrap().0, "0.1.0");
assert!(open(root.path(), "demo").is_err());
}