use std::collections::HashMap;
use biolib::binary_format::utils::InMemoryIndexableBuffer;
use biolib::binary_format::ModuleInput;
use biolib::binary_format::ModuleOutputV2;
#[test]
fn serialize_deserialize_empty() {
let stdin = b"";
let args: Vec<String> = vec![];
let files: HashMap<String, Vec<u8>> = HashMap::new();
let serialized = ModuleInput::serialize(stdin, &args, &files).unwrap();
let deserialized = ModuleInput::deserialize(&serialized).unwrap();
assert!(deserialized.stdin.is_empty());
assert!(deserialized.arguments.is_empty());
assert!(deserialized.files.is_empty());
}
#[test]
fn serialize_deserialize_with_stdin() {
let stdin = b"hello world";
let args: Vec<String> = vec![];
let files: HashMap<String, Vec<u8>> = HashMap::new();
let serialized = ModuleInput::serialize(stdin, &args, &files).unwrap();
let deserialized = ModuleInput::deserialize(&serialized).unwrap();
assert_eq!(deserialized.stdin, b"hello world");
assert!(deserialized.arguments.is_empty());
assert!(deserialized.files.is_empty());
}
#[test]
fn serialize_deserialize_with_args() {
let stdin = b"";
let args = vec!["--name".to_string(), "World".to_string()];
let files: HashMap<String, Vec<u8>> = HashMap::new();
let serialized = ModuleInput::serialize(stdin, &args, &files).unwrap();
let deserialized = ModuleInput::deserialize(&serialized).unwrap();
assert!(deserialized.stdin.is_empty());
assert_eq!(deserialized.arguments, vec!["--name", "World"]);
assert!(deserialized.files.is_empty());
}
#[test]
fn serialize_deserialize_with_files() {
let stdin = b"";
let args: Vec<String> = vec![];
let mut files = HashMap::new();
files.insert("input.txt".to_string(), b"file content".to_vec());
let serialized = ModuleInput::serialize(stdin, &args, &files).unwrap();
let deserialized = ModuleInput::deserialize(&serialized).unwrap();
assert!(deserialized.stdin.is_empty());
assert!(deserialized.arguments.is_empty());
assert_eq!(deserialized.files.len(), 1);
assert_eq!(deserialized.files["input.txt"], b"file content");
}
#[test]
fn serialize_deserialize_full() {
let stdin = b"stdin data";
let args = vec!["--flag".to_string(), "value".to_string()];
let mut files = HashMap::new();
files.insert("a.txt".to_string(), b"aaa".to_vec());
files.insert("b.bin".to_string(), vec![0u8, 1, 2, 255]);
let serialized = ModuleInput::serialize(stdin, &args, &files).unwrap();
let deserialized = ModuleInput::deserialize(&serialized).unwrap();
assert_eq!(deserialized.stdin, b"stdin data");
assert_eq!(deserialized.arguments, vec!["--flag", "value"]);
assert_eq!(deserialized.files.len(), 2);
assert_eq!(deserialized.files["a.txt"], b"aaa");
assert_eq!(deserialized.files["b.bin"], vec![0u8, 1, 2, 255]);
}
#[test]
fn reject_double_slash_in_file_path() {
let stdin = b"";
let args: Vec<String> = vec![];
let mut files = HashMap::new();
files.insert("path//to/file.txt".to_string(), b"data".to_vec());
let result = ModuleInput::serialize(stdin, &args, &files);
assert!(result.is_err());
}
#[test]
fn serialize_deserialize_binary_stdin() {
let stdin: Vec<u8> = (0..=255).collect();
let args: Vec<String> = vec![];
let files: HashMap<String, Vec<u8>> = HashMap::new();
let serialized = ModuleInput::serialize(&stdin, &args, &files).unwrap();
let deserialized = ModuleInput::deserialize(&serialized).unwrap();
assert_eq!(deserialized.stdin, stdin);
}
#[test]
fn serialize_deserialize_unicode_args() {
let stdin = b"";
let args = vec!["--emoji".to_string(), "hello".to_string()];
let files: HashMap<String, Vec<u8>> = HashMap::new();
let serialized = ModuleInput::serialize(stdin, &args, &files).unwrap();
let deserialized = ModuleInput::deserialize(&serialized).unwrap();
assert_eq!(deserialized.arguments[0], "--emoji");
assert_eq!(deserialized.arguments[1], "hello");
}
#[test]
fn module_output_v2_from_bytes() {
let mut data = Vec::new();
data.push(1u8); data.push(11u8); data.extend_from_slice(&5u64.to_be_bytes()); data.extend_from_slice(&3u64.to_be_bytes()); data.extend_from_slice(&0u64.to_be_bytes()); data.extend_from_slice(&0u64.to_be_bytes()); data.extend_from_slice(&0u16.to_be_bytes()); data.extend_from_slice(b"hello"); data.extend_from_slice(b"err");
let buffer = InMemoryIndexableBuffer::new(data);
let mut output = ModuleOutputV2::new(Box::new(buffer));
assert_eq!(output.get_exit_code().unwrap(), 0);
assert_eq!(output.get_stdout().unwrap(), b"hello");
assert_eq!(output.get_stderr().unwrap(), b"err");
assert!(output.get_files().unwrap().is_empty());
}
#[test]
fn module_output_v2_with_files() {
let mut data = Vec::new();
data.push(1u8); data.push(11u8);
let stdout = b"out";
let stderr = b"";
let file_path = b"/output.txt";
let file_data = b"file content here";
let files_info_len = 4 + file_path.len() + 8;
data.extend_from_slice(&(stdout.len() as u64).to_be_bytes());
data.extend_from_slice(&(stderr.len() as u64).to_be_bytes());
data.extend_from_slice(&(files_info_len as u64).to_be_bytes());
data.extend_from_slice(&(file_data.len() as u64).to_be_bytes());
data.extend_from_slice(&42u16.to_be_bytes()); data.extend_from_slice(stdout);
data.extend_from_slice(stderr);
data.extend_from_slice(&(file_path.len() as u32).to_be_bytes());
data.extend_from_slice(file_path);
data.extend_from_slice(&(file_data.len() as u64).to_be_bytes());
data.extend_from_slice(file_data);
let buffer = InMemoryIndexableBuffer::new(data);
let mut output = ModuleOutputV2::new(Box::new(buffer));
assert_eq!(output.get_exit_code().unwrap(), 42);
assert_eq!(output.get_stdout().unwrap(), b"out");
assert!(output.get_stderr().unwrap().is_empty());
let files = output.get_files().unwrap();
assert_eq!(files.len(), 1);
assert_eq!(files[0].path, "/output.txt");
let file_content = output.get_file_data(&files[0]).unwrap();
assert_eq!(file_content, b"file content here");
}