use { proptest::{arbitrary::any, prelude::*, proptest, sample::Index, test_runner::Config}, regenboog::RgbaU8, std::io::Cursor, ttb::{Reader, ReaderEvent, Writer}, }; fn read_write_case( build_name: &str, build_description: &str, type_names: &[String], palette: &[RgbaU8], bricks: &[(Index, i32, i32, i32, u8, Index)], ) { let mut buf = Vec::new(); let write_cursor = Cursor::new(&mut buf); let mut writer = Writer::new(write_cursor); writer .write_header(build_name, build_description, palette) .unwrap(); for &(tyid_idx, x, y, z, orientation, color_id_idx) in bricks { let tyid = tyid_idx.index(type_names.len()); let color_id = color_id_idx.index(palette.len()) as u8; writer .write_brick(&type_names[tyid], x, y, z, orientation, color_id) .unwrap(); } writer.finish().unwrap(); { use std::io::Write; let mut f = std::fs::File::create("/tmp/testcaseoutput").unwrap(); f.write_all(&buf[..]).unwrap(); } let read_cursor = Cursor::new(&buf); let mut reader = Reader::new(read_cursor); { let event = reader.next_event().unwrap(); assert_eq!( event, Some(ReaderEvent::Meta { build_name, build_description, }) ); } for (id, &color) in palette.into_iter().enumerate() { let event = reader.next_event().unwrap(); assert_eq!( event, Some(ReaderEvent::Color { id: id as u8, color, }) ); } for &(tyid_idx, x, y, z, orientation, color_id_idx) in bricks { let tyid = tyid_idx.index(type_names.len()); let color_id = color_id_idx.index(palette.len()) as u8; let event = reader.next_event().unwrap(); assert_eq!( event, Some(ReaderEvent::Brick { brick_type: &type_names[tyid], x, y, z, orientation, color_id, }) ); } } proptest! { #![proptest_config(Config::with_cases(2))] #[test] fn read_write_big( mut build_name in ".{0,255}", mut build_desc in ".{0,65535}", mut type_names in proptest::collection::vec(".{0,255}", 1..1024), palette in proptest::collection::vec([any::(); 4].prop_map(|x| RgbaU8::from(x)), 1..256), bricks in proptest::collection::vec((any::(), any::(), any::(), any::(), 0u8..4, any::()), 0..5000), ) { while build_name.len() > 255 { build_name.pop().unwrap(); } while build_desc.len() > 65535 { build_desc.pop().unwrap(); } for type_name in &mut type_names { while type_name.len() > 255 { type_name.pop().unwrap(); } } read_write_case(&build_name, &build_desc, &type_names, &palette, &bricks); } } proptest! { #![proptest_config(Config::with_cases(128))] #[test] fn read_write_small( mut build_name in ".{0,255}", mut build_desc in ".{0,255}", mut type_names in proptest::collection::vec(".{0,255}", 1..16), palette in proptest::collection::vec([any::(); 4].prop_map(|x| RgbaU8::from(x)), 1..256), bricks in proptest::collection::vec((any::(), any::(), any::(), any::(), 0u8..4, any::()), 0..800), ) { while build_name.len() > 255 { build_name.pop().unwrap(); } while build_desc.len() > 65535 { build_desc.pop().unwrap(); } for type_name in &mut type_names { while type_name.len() > 255 { type_name.pop().unwrap(); } } read_write_case(&build_name, &build_desc, &type_names, &palette, &bricks); } } proptest! { #![proptest_config(Config::with_cases(512))] #[test] fn read_write_tiny( mut build_name in ".{0,255}", mut build_desc in ".{0,255}", mut type_names in proptest::collection::vec(".{0,255}", 1..4), palette in proptest::collection::vec([any::(); 4].prop_map(|x| RgbaU8::from(x)), 1..256), bricks in proptest::collection::vec((any::(), any::(), any::(), any::(), 0u8..4, any::()), 0..128), ) { while build_name.len() > 255 { build_name.pop().unwrap(); } while build_desc.len() > 65535 { build_desc.pop().unwrap(); } for type_name in &mut type_names { while type_name.len() > 255 { type_name.pop().unwrap(); } } read_write_case(&build_name, &build_desc, &type_names, &palette, &bricks); } }