use kcode_k1_rust_code_document::RustCodeDocument;
use kcode_k1_rust_package::{AuthorityId, LibraryFamily, LibraryId, SourceFile, SourcePackage};
use kcode_k1_transaction_id::TxId;
use semver::Version;
use std::ops::Range;
fn identity() -> LibraryId {
let authority = AuthorityId::new(TxId::from_bytes([7; 12]));
let family = LibraryFamily::new(authority, "demo").unwrap();
LibraryId::new(family, Version::new(0, 1, 0)).unwrap()
}
fn default_manifest() -> String {
RustCodeDocument::approved_default(identity())
.unwrap()
.manifest()
.to_owned()
}
fn document_with_code(code: &str) -> RustCodeDocument {
RustCodeDocument::new(
identity(),
"# Consumer contract\n",
default_manifest(),
code,
)
.unwrap()
}
fn ranges(code: &str) -> Vec<Range<usize>> {
document_with_code(code).code_chunk_ranges()
}
fn whole(end: usize) -> Vec<Range<usize>> {
std::iter::once(0..end).collect()
}
fn reconstruct(code: &str, ranges: &[Range<usize>]) -> String {
ranges.iter().map(|range| &code[range.clone()]).collect()
}
#[test]
fn approved_default_is_exact_and_round_trips() {
let document = RustCodeDocument::approved_default(identity()).unwrap();
let expected_manifest = concat!(
"[package]\n",
"name = \"k1-070707070707070707070707-demo\"\n",
"version = \"0.1.0\"\n",
"edition = \"2024\"\n",
"rust-version = \"1.97\"\n",
"license = \"MIT\"\n",
"autobins = false\n",
"autoexamples = false\n",
"autotests = false\n",
"autobenches = false\n\n",
"[lib]\n",
"name = \"demo\"\n",
"path = \"src/lib.rs\"\n\n",
"[lints.rust]\n",
"unsafe_code = \"forbid\"\n\n",
"[workspace]\n",
"resolver = \"3\"\n"
);
assert_eq!(
document.documentation(),
"# Consumer contract\n\n`run` performs no operation.\n"
);
assert_eq!(document.manifest(), expected_manifest);
assert_eq!(document.code(), "pub fn run() {}\n");
assert_eq!(document.identity(), &identity());
let package = document.clone().into_source_package();
let paths: Vec<&str> = package.files().iter().map(|file| file.path()).collect();
assert_eq!(paths, ["Cargo.toml", "Documentation.md", "src/lib.rs"]);
let recovered = RustCodeDocument::from_source_package(package.clone()).unwrap();
assert_eq!(recovered.into_source_package(), package);
}
#[test]
fn shape_utf8_identity_and_targets_are_enforced() {
let base = RustCodeDocument::approved_default(identity())
.unwrap()
.into_source_package();
let mut extra = base.files().to_vec();
extra.push(SourceFile::new("README.md", b"extra".to_vec()));
let extra = SourcePackage::new(identity(), extra).unwrap();
assert!(RustCodeDocument::from_source_package(extra).is_err());
let missing: Vec<SourceFile> = base
.files()
.iter()
.filter(|file| file.path() != "src/lib.rs")
.cloned()
.collect();
let missing = SourcePackage::new(identity(), missing).unwrap();
assert!(RustCodeDocument::from_source_package(missing).is_err());
let mut non_utf: Vec<SourceFile> = base
.files()
.iter()
.filter(|file| file.path() != "src/lib.rs")
.cloned()
.collect();
non_utf.push(SourceFile::new("src/lib.rs", vec![0xff]));
let non_utf = SourcePackage::new(identity(), non_utf).unwrap();
assert!(RustCodeDocument::from_source_package(non_utf).is_err());
let changed = default_manifest().replace(
"k1-070707070707070707070707-demo",
"k1-070707070707070707070707-other",
);
assert!(RustCodeDocument::new(identity(), "docs", changed, "code").is_err());
let noncanonical =
default_manifest().replace("license = \"MIT\"\n", "license = \"MIT\"\nauthors = []\n");
assert!(RustCodeDocument::new(identity(), "docs", noncanonical, "code").is_err());
let bin = format!(
"{}\n[[bin]]\nname = \"tool\"\npath = \"src/lib.rs\"\n",
default_manifest()
);
assert!(RustCodeDocument::new(identity(), "docs", bin, "code").is_err());
let example = format!("{}\n[[example]]\nname = \"sample\"\n", default_manifest());
assert!(RustCodeDocument::new(identity(), "docs", example, "code").is_err());
}
#[test]
fn dependency_forms_remain_supported() {
let additions = concat!(
"[dependencies]\n",
"serde = \"1\"\n",
"peer = { package = \"k1-090909090909090909090909-peer\", version = \"0.3\", registry = \"k1\" }\n\n",
"[lints.rust]"
);
let manifest = default_manifest().replace("[lints.rust]", additions);
let document =
RustCodeDocument::new(identity(), "docs", manifest.clone(), "pub fn run() {}\n").unwrap();
assert_eq!(document.manifest(), manifest);
assert_eq!(
document.clone().into_source_package().dependencies().len(),
1
);
assert_eq!(
RustCodeDocument::from_source_package(document.into_source_package())
.unwrap()
.manifest(),
manifest
);
}
#[test]
fn every_content_preserves_line_endings_bom_and_final_newline() {
let documentation = "\u{feff}# Contract\r\n\r\nExact";
let manifest = default_manifest().replace('\n', "\r\n");
let code = "\u{feff}pub fn run() {\r\n}";
let document =
RustCodeDocument::new(identity(), documentation, manifest.clone(), code).unwrap();
assert_eq!(document.documentation(), documentation);
assert_eq!(document.manifest(), manifest);
assert_eq!(document.code(), code);
assert_eq!(reconstruct(code, &document.code_chunk_ranges()), code);
let default = RustCodeDocument::approved_default(identity()).unwrap();
assert!(default.documentation().ends_with('\n'));
assert!(default.manifest().ends_with('\n'));
assert!(default.code().ends_with('\n'));
}
#[test]
fn top_level_items_split_on_unicode_scalar_floor() {
let first = format!("const FIRST: &str = r#\"{}\"#;", "é".repeat(810));
let second = format!("const SECOND: &str = r#\"{}\"#;", "界".repeat(810));
let code = format!("{first}\n{second}\n");
let chunks = ranges(&code);
assert_eq!(chunks.len(), 2);
assert_eq!(chunks[0], 0..first.len());
assert_eq!(reconstruct(&code, &chunks), code);
assert!(
chunks
.iter()
.all(|range| code[range.clone()].chars().count() >= 800)
);
}
#[test]
fn direct_impl_and_trait_members_are_safe_points() {
let text = "x".repeat(810);
let code = format!(
"struct Unit;\nimpl Unit {{\nfn one() -> &'static str {{ r#\"{text}\"# }}\nfn two() -> &'static str {{ r#\"{text}\"# }}\n}}\ntrait Work {{\nfn three() -> &'static str {{ r#\"{text}\"# }}\nfn four() -> &'static str {{ r#\"{text}\"# }}\n}}\n"
);
let chunks = ranges(&code);
assert_eq!(chunks.len(), 4);
assert_eq!(reconstruct(&code, &chunks), code);
assert!(
chunks
.iter()
.all(|range| code[range.clone()].chars().count() >= 800)
);
}
#[test]
fn attributes_raw_strings_macros_comments_and_nesting_stay_indivisible() {
let first = [
"#[allow(dead_code)]\nfn complex() {\nlet raw = r###\"",
&"}\"#/*".repeat(180),
"\"###;\nmacro_rules! local { () => {{ raw.len() }}; }\nlet _ = local!();\n/* kept */\n}",
]
.concat();
let second = format!(
"#[allow(dead_code)]\nfn second() {{ let _ = r#\"{}\"#; }}",
"z".repeat(900)
);
let code = format!("{first} // trailing\r\n{second}");
let chunks = ranges(&code);
assert_eq!(chunks.len(), 2);
assert_eq!(chunks[0], 0..first.len());
assert_eq!(reconstruct(&code, &chunks), code);
}
#[test]
fn malformed_small_huge_and_short_tail_use_whole_file_fallbacks() {
assert_eq!(ranges(""), whole(0));
let small = "pub fn run() {}\n";
assert_eq!(ranges(small), whole(small.len()));
let malformed = format!("fn broken({}", "x".repeat(2000));
assert_eq!(ranges(&malformed), whole(malformed.len()));
let huge = format!("const ONLY: &str = r#\"{}\"#;", "q".repeat(5000));
assert_eq!(ranges(&huge), whole(huge.len()));
let first = format!("const FIRST: &str = r#\"{}\"#;", "a".repeat(900));
let short_tail = format!("{first}\nconst T: u8 = 1;");
assert_eq!(ranges(&short_tail), whole(short_tail.len()));
}