use raff::prelude::*;
use std::io::{Cursor, Read};
#[test]
fn test_raff_header() {
#[rustfmt::skip]
let data = &[
0xF0, 0x9F, 0xA6, 0x8A, 0x52, 0x41, 0x46, 0x46, 0x30, 0x2E, 0x32, 0x0A, 0x1A, b'T', b'e', b's', b't', b'.', b'A', b'p', b'p', 0, 0, 0, 0, 0, 0, 0, 0, 0x00, 0x01 ];
let mut stream = Cursor::new(&data[..]);
let (header, app_header) = read_raff_header(&mut stream).unwrap();
assert_eq!(header.major, 0);
assert_eq!(header.minor, 2);
assert_eq!(app_header.as_string(), "Test.App");
}
#[test]
fn test_write_raff_header() {
let mut stream = Cursor::new(Vec::new());
let app_header = RaffApplicationHeader::with_str("Test.App", 0, 2).unwrap();
write_raff_header(&mut stream, &app_header).expect("should write");
#[rustfmt::skip]
let expected_start = &[
0xF0, 0x9F, 0xA6, 0x8A, 0x52, 0x41, 0x46, 0x46, 0x30, 0x2E, 0x32, 0x0A, 0x1A, ];
assert_eq!(&stream.get_ref()[..13], expected_start);
let empty = &[0xff; 0x53];
write_chunk(&mut stream, "xb".try_into().unwrap(), empty).expect("Failed to write empty");
let buffer = stream.into_inner();
let mut stream = Cursor::new(buffer);
let (_raff_header, _app_header) =
read_raff_header(&mut stream).expect("Failed to read headers");
let header = read_chunk_header(&mut stream).expect("Failed to read chunk header");
assert_eq!(header.tag.name, "xb".try_into().unwrap());
assert_eq!(header.size, 0x53);
let mut data = vec![0u8; header.size as usize];
stream.read_exact(&mut data).unwrap();
assert_eq!(data, empty);
assert_eq!(stream.position() as usize, stream.get_ref().len());
}
#[test]
fn is_valid_char() {
assert!(is_valid_tag_char(b'a'));
assert!(is_valid_tag_char(b'z'));
assert!(is_valid_tag_char(b'A'));
assert!(is_valid_tag_char(b'Z'));
assert!(is_valid_tag_char(b'0'));
assert!(is_valid_tag_char(b'9'));
assert!(is_valid_tag_char(b'_'));
}
#[test]
fn test_application_header_creation() {
let header = RaffApplicationHeader::with_str("MyGame.SaveFile", 1, 0).unwrap();
assert_eq!(header.as_string(), "MyGame.SaveFile");
assert_eq!(header.app_major, 1);
assert_eq!(header.app_minor, 0);
}
#[test]
fn test_application_header_short_names() {
let header = RaffApplicationHeader::with_str("Game", 2, 5).unwrap();
assert_eq!(header.as_string(), "Game");
}
#[test]
fn test_application_header_full_length() {
let header = RaffApplicationHeader::with_str("1234567890123456", 9, 9).unwrap();
assert_eq!(header.as_string(), "1234567890123456");
}
#[test]
fn test_application_header_too_long() {
let result = RaffApplicationHeader::with_str("ThisIsTooLongForSixteenBytes", 1, 0);
assert!(result.is_err());
}
#[test]
fn test_application_header_utf8() {
let header = RaffApplicationHeader::with_str("Game🎮.Save", 1, 0).unwrap();
assert_eq!(header.as_string(), "Game🎮.Save");
let mut stream = Cursor::new(Vec::new());
header.serialize(&mut stream).unwrap();
stream.set_position(0);
let deserialized = RaffApplicationHeader::deserialize(&mut stream).unwrap();
assert_eq!(deserialized.as_string(), "Game🎮.Save");
}
#[test]
fn test_application_header_utf8_byte_limit() {
let header = RaffApplicationHeader::with_str("🎮🎮🎮🎮", 1, 0);
assert!(header.is_ok());
let header = RaffApplicationHeader::with_str("🎮🎮🎮🎮🎮", 1, 0);
assert!(header.is_err());
}
#[test]
fn test_application_header_serialize_deserialize() {
let header = RaffApplicationHeader::with_str("Editor.Palette", 1, 5).unwrap();
let mut stream = Cursor::new(Vec::new());
header.serialize(&mut stream).expect("should serialize");
assert_eq!(stream.get_ref().len(), 18);
stream.set_position(0);
let deserialized = RaffApplicationHeader::deserialize(&mut stream).unwrap();
assert_eq!(header, deserialized);
assert_eq!(deserialized.as_string(), "Editor.Palette");
assert_eq!(deserialized.app_major, 1);
assert_eq!(deserialized.app_minor, 5);
}
#[test]
fn test_write_raff_header_with_app() {
let mut stream = Cursor::new(Vec::new());
write_raff_header_with_app(&mut stream, "TestApp.Config", 1, 2).expect("should write");
assert_eq!(stream.get_ref().len(), 31);
stream.set_position(0);
let (raff_header, app_header) = read_raff_header(&mut stream).unwrap();
assert_eq!(raff_header.major, 0);
assert_eq!(raff_header.minor, 2);
assert_eq!(app_header.as_string(), "TestApp.Config");
assert_eq!(app_header.app_major, 1);
assert_eq!(app_header.app_minor, 2);
}
#[test]
fn test_complete_raff_file_with_app_header() {
let mut stream = Cursor::new(Vec::new());
write_raff_header_with_app(&mut stream, "CoolGame.Save", 1, 0).unwrap();
write_chunk(&mut stream, "dt".try_into().unwrap(), b"Hello, World!").unwrap();
write_chunk(&mut stream, "md".try_into().unwrap(), b"metadata").unwrap();
let buffer = stream.into_inner();
let mut stream = Cursor::new(buffer);
let (_raff_header, app_header) = read_raff_header(&mut stream).unwrap();
assert_eq!(app_header.as_string(), "CoolGame.Save");
assert_eq!(app_header.app_major, 1);
assert_eq!(app_header.app_minor, 0);
let chunk1 = read_chunk_header(&mut stream).unwrap();
assert_eq!(chunk1.tag.name, "dt".try_into().unwrap());
assert_eq!(chunk1.size, 13);
let mut data1 = vec![0u8; chunk1.size as usize];
stream.read_exact(&mut data1).unwrap();
assert_eq!(&data1, b"Hello, World!");
let chunk2 = read_chunk_header(&mut stream).unwrap();
assert_eq!(chunk2.tag.name, "md".try_into().unwrap());
assert_eq!(chunk2.size, 8);
let mut data2 = vec![0u8; chunk2.size as usize];
stream.read_exact(&mut data2).unwrap();
assert_eq!(&data2, b"metadata");
}