use factorio_blueprint::{BlueprintCodec, Container}; use std::io::{BufReader, Read}; use std::path::PathBuf; fn examples() -> impl Iterator { let mut examples = std::env::current_exe().expect("can find test executable"); // target/debug/1/executable for _ in 0..4 { examples.pop(); } examples.push("tests/examples"); std::fs::read_dir(examples) .expect("should find examples dir") .map(|maybe_example| maybe_example.expect("should find file").path()) .inspect(|example| { dbg!(example); }) } fn container_examples() -> impl Iterator { examples().map(|path| { BlueprintCodec::decode(BufReader::new( std::fs::File::open(path).expect("can open example file"), )) .expect("container decoded successfully") }) } fn test_parse(reader: R) { let mut json_data = Vec::new(); BlueprintCodec::decode_reader(reader, |mut reader| { reader.read_to_end(&mut json_data).map(|_| ()) }) .expect("should have expected version"); let json_str = String::from_utf8(json_data).expect("json data should be valid utf-8"); if let Err(jserr) = serde_json::from_str::(&json_str) { use serde_json::error::Category; match jserr.classify() { Category::Syntax | Category::Data => { const SPACING: usize = 50; let mut col = jserr.column(); col -= col.min(SPACING); println!("bad json: {}", &json_str[col..col + 50]); } _ => {} } panic!("error: {}", jserr); } } #[test] fn can_parse_examples() { for example in examples() { let file_data = std::fs::read_to_string(example).expect("can read from file"); test_parse(file_data.trim().as_bytes()); } } #[test] fn can_read_from_untrimmed_files() { for example in examples() { test_parse(BufReader::new( std::fs::File::open(example).expect("can open example file"), )); } } #[test] fn roundtrip() { for container in container_examples() { let mut blueprint = Vec::new(); container .encode(&mut blueprint) .expect("encoding should succeed"); let roundtripped = Container::decode(&blueprint as &[u8]).expect("decoding should succeed"); assert_eq!(container, roundtripped); } }