#[ cfg(feature = "enabled") ]
use crates_tools ::CrateArchive;
#[ cfg(feature = "enabled") ]
#[ test ]
fn test_empty_crate_name()
{
let result = CrateArchive ::download_crates_io("", "0.1.0");
assert!(result.is_err(), "Empty crate name should return Err");
let err_msg = format!("{}", result.unwrap_err());
assert!(!err_msg.is_empty(), "Error message should not be empty");
}
#[ cfg(feature = "enabled") ]
#[ test ]
fn test_empty_version()
{
let result = CrateArchive ::download_crates_io("test_experimental_c", "");
assert!(result.is_err(), "Empty version should return Err");
let err_msg = format!("{}", result.unwrap_err());
assert!(!err_msg.is_empty(), "Error message should not be empty");
}
#[ cfg(feature = "enabled") ]
#[ test ]
fn test_invalid_version_format()
{
let test_cases = vec![
"latest",
"1.x",
"v1.0.0",
"1.0",
"1",
];
for invalid_version in test_cases
{
let result = CrateArchive ::download_crates_io("test_experimental_c", invalid_version);
assert!(
result.is_err(),
"Invalid version '{invalid_version}' should return Err, not panic"
);
}
}
#[ cfg(feature = "enabled") ]
#[ test ]
fn test_very_long_crate_name()
{
let long_name = "a".repeat(1000);
let result = CrateArchive ::download_crates_io(&long_name, "0.1.0");
assert!(result.is_err(), "Very long crate name should return Err");
}
#[ cfg(feature = "enabled") ]
#[ test ]
fn test_single_file_archive()
{
use flate2 ::write ::GzEncoder;
use flate2 ::Compression;
use tar ::Builder;
use std ::io ::Write;
let mut tar_data = Vec ::new();
{
let mut builder = Builder ::new(&mut tar_data);
let content = b"single file content";
let mut header = tar ::Header ::new_gnu();
header.set_path("single.txt").unwrap();
header.set_size(content.len() as u64);
header.set_cksum();
builder.append(&header, &content[..]).unwrap();
builder.finish().unwrap();
}
let mut encoder = GzEncoder ::new(Vec ::new(), Compression ::default());
encoder.write_all(&tar_data).unwrap();
let compressed = encoder.finish().unwrap();
let archive = CrateArchive ::decode(compressed)
.expect("Single-file archive should decode successfully");
let files = archive.list();
assert_eq!(files.len(), 1, "Archive should contain exactly 1 file");
let content = archive.content_bytes("single.txt")
.expect("File should exist in archive");
assert_eq!(content, b"single file content");
}
#[ cfg(feature = "enabled") ]
#[ test ]
fn test_zero_byte_files()
{
use flate2 ::write ::GzEncoder;
use flate2 ::Compression;
use tar ::Builder;
use std ::io ::Write;
let mut tar_data = Vec ::new();
{
let mut builder = Builder ::new(&mut tar_data);
let content = b"";
let mut header = tar ::Header ::new_gnu();
header.set_path("empty.txt").unwrap();
header.set_size(0);
header.set_cksum();
builder.append(&header, &content[..]).unwrap();
builder.finish().unwrap();
}
let mut encoder = GzEncoder ::new(Vec ::new(), Compression ::default());
encoder.write_all(&tar_data).unwrap();
let compressed = encoder.finish().unwrap();
let archive = CrateArchive ::decode(compressed)
.expect("Archive with zero-byte file should decode");
let files = archive.list();
assert_eq!(files.len(), 1, "Archive should contain the file");
let content = archive.content_bytes("empty.txt")
.expect("Zero-byte file should exist");
assert_eq!(content.len(), 0, "Content should be empty");
let text = core ::str ::from_utf8(content)
.expect("Empty content should be valid UTF-8");
assert_eq!(text, "", "Should be empty string");
}
#[ cfg(feature = "enabled") ]
#[ test ]
fn test_corrupted_gzip_data()
{
let corrupted_data = vec![ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ];
let result = CrateArchive ::decode(corrupted_data);
assert!(result.is_err(), "Corrupted gzip should return Err");
}
#[ cfg(feature = "enabled") ]
#[ test ]
fn test_truncated_archive()
{
use flate2 ::write ::GzEncoder;
use flate2 ::Compression;
use tar ::Builder;
use std ::io ::Write;
let mut tar_data = Vec ::new();
{
let mut builder = Builder ::new(&mut tar_data);
let content = b"test content";
let mut header = tar ::Header ::new_gnu();
header.set_path("test.txt").unwrap();
header.set_size(content.len() as u64);
header.set_cksum();
builder.append(&header, &content[..]).unwrap();
builder.finish().unwrap();
}
let mut encoder = GzEncoder ::new(Vec ::new(), Compression ::default());
encoder.write_all(&tar_data).unwrap();
let mut compressed = encoder.finish().unwrap();
compressed.truncate(compressed.len() / 2);
let result = CrateArchive ::decode(compressed);
assert!(result.is_err(), "Truncated archive should return Err");
}
#[ cfg(feature = "enabled") ]
#[ test ]
fn test_unicode_filenames()
{
use flate2 ::write ::GzEncoder;
use flate2 ::Compression;
use tar ::Builder;
use std ::io ::Write;
let test_filenames = vec![
"测试.txt", "テスト.txt", "файл.txt", "ملف.txt", "😀_emoji.txt", "café.txt", ];
let mut tar_data = Vec ::new();
{
let mut builder = Builder ::new(&mut tar_data);
for filename in &test_filenames
{
let content = format!("content of {filename}");
let content_bytes = content.as_bytes();
let mut header = tar ::Header ::new_gnu();
header.set_path(filename).unwrap();
header.set_size(content_bytes.len() as u64);
header.set_cksum();
builder.append(&header, content_bytes).unwrap();
}
builder.finish().unwrap();
}
let mut encoder = GzEncoder ::new(Vec ::new(), Compression ::default());
encoder.write_all(&tar_data).unwrap();
let compressed = encoder.finish().unwrap();
let archive = CrateArchive ::decode(compressed)
.expect("Archive with Unicode filenames should decode");
let files = archive.list();
assert_eq!(files.len(), test_filenames.len(), "All files should be listed");
for filename in &test_filenames
{
let content = archive.content_bytes(filename)
.unwrap_or_else(|| panic!("Should find file: {filename}"));
let expected = format!("content of {filename}");
let actual = core ::str ::from_utf8(content)
.expect("Content should be valid UTF-8");
assert_eq!(actual, expected, "Content should match for {filename}");
}
}
#[ cfg(feature = "enabled") ]
#[ test ]
fn test_special_characters_in_filenames()
{
use flate2 ::write ::GzEncoder;
use flate2 ::Compression;
use tar ::Builder;
use std ::io ::Write;
let test_filenames = vec![
"file with spaces.txt",
"file'with'quotes.txt",
"file\"with\"doublequotes.txt",
"file(with)parens.txt",
"file[with]brackets.txt",
"file{with}braces.txt",
];
let mut tar_data = Vec ::new();
{
let mut builder = Builder ::new(&mut tar_data);
for filename in &test_filenames
{
let content = b"test content";
let mut header = tar ::Header ::new_gnu();
header.set_path(filename).unwrap();
header.set_size(content.len() as u64);
header.set_cksum();
builder.append(&header, &content[..]).unwrap();
}
builder.finish().unwrap();
}
let mut encoder = GzEncoder ::new(Vec ::new(), Compression ::default());
encoder.write_all(&tar_data).unwrap();
let compressed = encoder.finish().unwrap();
let archive = CrateArchive ::decode(compressed)
.expect("Archive with special char filenames should decode");
for filename in &test_filenames
{
let content = archive.content_bytes(filename)
.unwrap_or_else(|| panic!("Should find file: {filename}"));
assert_eq!(content, b"test content", "Content should match for {filename}");
}
}
#[ cfg(feature = "enabled") ]
#[ test ]
fn test_partial_utf8_sequences()
{
use flate2 ::write ::GzEncoder;
use flate2 ::Compression;
use tar ::Builder;
use std ::io ::Write;
let partial_utf8: Vec< u8 > = vec![ 0xF0, 0x9F ];
assert!(core ::str ::from_utf8(&partial_utf8).is_err(), "Test data must be invalid UTF-8");
let mut tar_data = Vec ::new();
{
let mut builder = Builder ::new(&mut tar_data);
let mut header = tar ::Header ::new_gnu();
header.set_path("partial.bin").unwrap();
header.set_size(partial_utf8.len() as u64);
header.set_cksum();
builder.append(&header, &partial_utf8[..]).unwrap();
builder.finish().unwrap();
}
let mut encoder = GzEncoder ::new(Vec ::new(), Compression ::default());
encoder.write_all(&tar_data).unwrap();
let compressed = encoder.finish().unwrap();
let archive = CrateArchive ::decode(compressed)
.expect("Archive with partial UTF-8 should decode");
let content = archive.content_bytes("partial.bin")
.expect("File should exist");
assert!(
core ::str ::from_utf8(content).is_err(),
"Partial UTF-8 should fail validation"
);
assert_eq!(content, &partial_utf8[..], "Binary content should be preserved");
}
#[ cfg(feature = "enabled") ]
#[ test ]
fn test_null_bytes_in_content()
{
use flate2 ::write ::GzEncoder;
use flate2 ::Compression;
use tar ::Builder;
use std ::io ::Write;
let content_with_nulls: Vec< u8 > = vec![
b'H', b'e', b'l', b'l', b'o', 0x00, b'W', b'o', b'r', b'l', b'd', 0x00,
];
let mut tar_data = Vec ::new();
{
let mut builder = Builder ::new(&mut tar_data);
let mut header = tar ::Header ::new_gnu();
header.set_path("with_nulls.bin").unwrap();
header.set_size(content_with_nulls.len() as u64);
header.set_cksum();
builder.append(&header, &content_with_nulls[..]).unwrap();
builder.finish().unwrap();
}
let mut encoder = GzEncoder ::new(Vec ::new(), Compression ::default());
encoder.write_all(&tar_data).unwrap();
let compressed = encoder.finish().unwrap();
let archive = CrateArchive ::decode(compressed)
.expect("Archive with null bytes should decode");
let content = archive.content_bytes("with_nulls.bin")
.expect("File should exist");
assert_eq!(content, &content_with_nulls[..], "Null bytes should be preserved");
let utf8_result = core ::str ::from_utf8(content);
if let Ok(text) = utf8_result
{
assert!(text.contains('\0'), "Null characters should be in string");
}
}
#[ cfg(feature = "enabled") ]
#[ test ]
fn test_no_panics_on_error_conditions()
{
let _ = CrateArchive ::download_crates_io("nonexistent_crate_xyz", "0.1.0");
let _ = CrateArchive ::download_crates_io("", "0.1.0");
let _ = CrateArchive ::download_crates_io("test", "");
let _ = CrateArchive ::decode(vec![ 0xFF, 0xFF, 0xFF ]);
let _ = CrateArchive ::decode(vec![]);
}