#![cfg(ironman)] use ck3save::{ models::{Gamestate, HeaderBorrowed, HeaderOwned}, Ck3File, Encoding, EnvTokens, FailedResolveStrategy, }; mod utils; #[test] fn test_ck3_binary_header() { let data = include_bytes!("fixtures/header.bin"); let file = Ck3File::from_slice(&data[..]).unwrap(); assert_eq!(file.encoding(), Encoding::Binary); let header = file.parse_metadata().unwrap(); let header: HeaderOwned = header.deserializer().build(&EnvTokens).unwrap(); assert_eq!(header.meta_data.version, String::from("1.0.2")); } #[test] fn test_ck3_binary_header_borrowed() { let data = include_bytes!("fixtures/header.bin"); let file = Ck3File::from_slice(&data[..]).unwrap(); assert_eq!(file.encoding(), Encoding::Binary); let header = file.parse_metadata().unwrap(); let header: HeaderBorrowed = header.deserializer().build(&EnvTokens).unwrap(); assert_eq!(header.meta_data.version, String::from("1.0.2")); } #[test] fn test_ck3_binary_save() -> Result<(), Box> { let data = utils::request("af_Munso_867_Ironman.ck3"); let file = Ck3File::from_slice(&data[..])?; assert_eq!(file.encoding(), Encoding::BinaryZip); let mut zip_sink = Vec::new(); let parsed_file = file.parse(&mut zip_sink)?; let game: Gamestate = parsed_file.deserializer().build(&EnvTokens)?; assert_eq!(game.meta_data.version, String::from("1.0.2")); Ok(()) } #[test] fn test_ck3_binary_save_header_borrowed() { let data = utils::request("af_Munso_867_Ironman.ck3"); let file = Ck3File::from_slice(&data[..]).unwrap(); assert_eq!(file.encoding(), Encoding::BinaryZip); let header = file.parse_metadata().unwrap(); let header: HeaderBorrowed = header.deserializer().build(&EnvTokens).unwrap(); assert_eq!(file.encoding(), Encoding::BinaryZip); assert_eq!(header.meta_data.version, "1.0.2"); } #[test] fn test_ck3_binary_autosave() -> Result<(), Box> { let data = utils::request_zip("autosave.zip"); let file = Ck3File::from_slice(&data[..])?; assert_eq!(file.encoding(), Encoding::Binary); let mut zip_sink = Vec::new(); let parsed_file = file.parse(&mut zip_sink)?; let game: Gamestate = parsed_file.deserializer().build(&EnvTokens)?; assert_eq!(game.meta_data.version, String::from("1.0.2")); let header = file.parse_metadata()?; let header: HeaderBorrowed = header.deserializer().build(&EnvTokens)?; assert_eq!(header.meta_data.version, String::from("1.0.2")); let binary = parsed_file.as_binary().unwrap(); let out = binary .melter() .on_failed_resolve(FailedResolveStrategy::Error) .melt(&EnvTokens)?; twoway::find_bytes(out.data(), b"gold=0.044").unwrap(); twoway::find_bytes(out.data(), b"gold=4.647").unwrap(); Ok(()) } #[test] fn test_ck3_binary_save_tokens() -> Result<(), Box> { let data = utils::request("af_Munso_867_Ironman.ck3"); let file = Ck3File::from_slice(&data[..])?; let mut zip_sink = Vec::new(); let parsed_file = file.parse(&mut zip_sink)?; let save: Gamestate = parsed_file.deserializer().build(&EnvTokens)?; assert_eq!(file.encoding(), Encoding::BinaryZip); assert_eq!(save.meta_data.version, String::from("1.0.2")); Ok(()) } #[test] fn test_roundtrip_header_melt() { let data = include_bytes!("fixtures/header.bin"); let file = Ck3File::from_slice(&data[..]).unwrap(); let header = file.parse_metadata().unwrap(); let binary = header.as_binary().unwrap(); let out = binary.melter().melt(&EnvTokens).unwrap(); let file = Ck3File::from_slice(out.data()).unwrap(); let header = file.parse_metadata().unwrap(); let header: HeaderOwned = header.deserializer().build(&EnvTokens).unwrap(); assert_eq!(file.encoding(), Encoding::Text); assert_eq!(header.meta_data.version, String::from("1.0.2")); } #[test] fn test_header_melt() { let data = include_bytes!("fixtures/header.bin"); let file = Ck3File::from_slice(&data[..]).unwrap(); let header = file.parse_metadata().unwrap(); let binary = header.as_binary().unwrap(); let out = binary.melter().melt(&EnvTokens).unwrap(); let melted = include_bytes!("fixtures/header.melted"); assert_eq!(&melted[..], out.data()); } #[test] fn test_melt_no_crash() { let data = include_bytes!("fixtures/melt.crash1"); assert!(Ck3File::from_slice(&data[..]).is_err()); } #[test] fn test_ck3_binary_save_patch_1_3() -> Result<(), Box> { let data = utils::request("ck3-1.3-test.ck3"); let file = Ck3File::from_slice(&data[..])?; let mut zip_sink = Vec::new(); let parsed_file = file.parse(&mut zip_sink)?; let binary = parsed_file.as_binary().unwrap(); let out = binary .melter() .on_failed_resolve(FailedResolveStrategy::Error) .melt(&EnvTokens)?; let file = Ck3File::from_slice(out.data())?; let mut zip_sink = Vec::new(); let parsed_file = file.parse(&mut zip_sink)?; let save: Gamestate = parsed_file .deserializer() .on_failed_resolve(FailedResolveStrategy::Error) .build(&EnvTokens)?; assert_eq!(save.meta_data.version, String::from("1.3.0")); Ok(()) } #[test] fn test_ck3_1_0_3_old_cloud_and_local_tokens() -> Result<(), Box> { let data = utils::request("ck3-1.0.3-local.ck3"); let file = Ck3File::from_slice(&data[..])?; let mut zip_sink = Vec::new(); let parsed_file = file.parse(&mut zip_sink)?; assert_eq!(file.encoding(), Encoding::BinaryZip); let binary = parsed_file.as_binary().unwrap(); let out = binary .melter() .on_failed_resolve(FailedResolveStrategy::Error) .melt(&EnvTokens)?; let file = Ck3File::from_slice(out.data())?; let mut zip_sink = Vec::new(); let parsed_file = file.parse(&mut zip_sink)?; assert_eq!(file.encoding(), Encoding::Text); let save: Gamestate = parsed_file .deserializer() .on_failed_resolve(FailedResolveStrategy::Error) .build(&EnvTokens)?; assert_eq!(save.meta_data.version, String::from("1.0.3")); Ok(()) } #[test] fn decode_and_melt_gold_correctly() -> Result<(), Box> { let data = utils::request("ck3-1.3.1.ck3"); let file = Ck3File::from_slice(&data)?; let mut zip_sink = Vec::new(); let parsed_file = file.parse(&mut zip_sink)?; let save: Gamestate = parsed_file .deserializer() .on_failed_resolve(FailedResolveStrategy::Error) .build(&EnvTokens)?; assert_eq!(file.encoding(), Encoding::BinaryZip); let character = save.living.get(&16322).unwrap(); assert_eq!( character.alive_data.as_ref().and_then(|x| x.health), Some(4.728) ); assert_eq!( character.alive_data.as_ref().and_then(|x| x.income), Some(11.087) ); assert_eq!( character.alive_data.as_ref().and_then(|x| x.gold), Some(133.04397) ); let binary = parsed_file.as_binary().unwrap(); let out = binary .melter() .on_failed_resolve(FailedResolveStrategy::Error) .melt(&EnvTokens)?; twoway::find_bytes(out.data(), b"gold=133.04397").unwrap(); twoway::find_bytes(out.data(), b"vassal_power_value=200").unwrap(); Ok(()) } #[test] fn parse_patch16() -> Result<(), Box> { let data = utils::request("ck3-1.6.ck3"); let file = Ck3File::from_slice(&data)?; let mut zip_sink = Vec::new(); let parsed_file = file.parse(&mut zip_sink)?; let save: Gamestate = parsed_file .deserializer() .on_failed_resolve(FailedResolveStrategy::Error) .build(&EnvTokens)?; assert_eq!(save.meta_data.version.as_str(), "1.6.0"); Ok(()) } #[test] fn melt_patch14() -> Result<(), Box> { let data = utils::request("ck3-1.4-normal.ck3"); let expected = utils::request_zip("ck3-1.4-normal_melted.zip"); let file = Ck3File::from_slice(&data[..])?; let mut zip_sink = Vec::new(); let parsed_file = file.parse(&mut zip_sink)?; let binary = parsed_file.as_binary().unwrap(); let out = binary .melter() .on_failed_resolve(FailedResolveStrategy::Error) .melt(&EnvTokens)?; assert!( eq(out.data(), &expected), "patch 1.4 did not melt currently" ); Ok(()) } #[test] fn melt_patch15() -> Result<(), Box> { let data = utils::request("ck3-1.5-normal.ck3"); let expected = utils::request_zip("ck3-1.5-normal_melted.zip"); let file = Ck3File::from_slice(&data[..])?; let mut zip_sink = Vec::new(); let parsed_file = file.parse(&mut zip_sink)?; let binary = parsed_file.as_binary().unwrap(); let out = binary .melter() .on_failed_resolve(FailedResolveStrategy::Error) .melt(&EnvTokens)?; assert!( eq(out.data(), &expected), "patch 1.5 did not melt currently" ); Ok(()) } fn eq(a: &[u8], b: &[u8]) -> bool { for (ai, bi) in a.iter().zip(b.iter()) { if ai != bi { return false; } } a.len() == b.len() }