use json::JsonValue; use std::net::IpAddr; use i_dunno::{decode, encode_all, ConfusionLevel}; // Later, if i_dunno Python fixes the bugs I reported, re-run it // to generate more examples. fn s(v: &JsonValue) -> &str { v.as_str().unwrap() } fn a(v: &JsonValue) -> Vec { v.members() .map(|s| String::from(s.as_str().unwrap())) .collect() } fn to_hex(enc: Vec) -> Vec { enc.iter().map(|s| to_hex_str(s)).collect::>() } fn to_hex_str(s: &str) -> String { s.as_bytes().iter().map(|c| format!("{:02x}", c)).collect() } #[test] fn our_behaviour_should_match_examples() { let examples_txt = include_str!("examples.txt"); let examples = examples_txt.split('\n'); for line in examples { if line == "" { continue; } let case = json::parse(&line) .expect(&format!("Unable to parse line: {}", line)); let addr = s(&case["addr"]).parse().unwrap(); let expected_min = a(&case["minimum"]); let expected_sat = a(&case["satisfactory"]); let expected_del = a(&case["delightful"]); assert_match(&addr, ConfusionLevel::Minimum, expected_min); assert_match(&addr, ConfusionLevel::Satisfactory, expected_sat); assert_match(&addr, ConfusionLevel::Delightful, expected_del); } } fn assert_match(addr: &IpAddr, level: ConfusionLevel, expected: Vec) { let encoded: Vec = encode_all(addr.clone(), level).take(10).collect(); for enc in &expected { if let Some(decoded_addr) = decode(&String::from_utf8(hex::decode(enc).unwrap()).unwrap()) { if *addr != decoded_addr { panic!( "String '{}' decoded into '{}' but we expected '{}'.", enc, decoded_addr, addr ); } } else { panic!("String '{}' did not decode into an IP address!", enc); } } let actual = to_hex(encoded); if actual != expected { panic!( r#"\ IP {} did not encode as expected at {:?} level.\ Actual: {:?}\ Expected: {:?}\ "#, addr, level, actual, expected ); } }