use super::*; use crate::{parser::*, Flags}; #[test] #[cfg(not(miri))] // Very slow in miri fn roundtrip() { let mut s = String::new(); for a in 0u8..=255 { for b in 0u8..=255 { let f = TestFlags::from_bits_retain(a | b); s.clear(); to_writer(&f, &mut s).unwrap(); assert_eq!(f, from_str::(&s).unwrap()); } } } #[test] #[cfg(not(miri))] // Very slow in miri fn roundtrip_truncate() { let mut s = String::new(); for a in 0u8..=255 { for b in 0u8..=255 { let f = TestFlags::from_bits_retain(a | b); s.clear(); to_writer_truncate(&f, &mut s).unwrap(); assert_eq!( TestFlags::from_bits_truncate(f.bits()), from_str_truncate::(&s).unwrap() ); } } } #[test] #[cfg(not(miri))] // Very slow in miri fn roundtrip_strict() { let mut s = String::new(); for a in 0u8..=255 { for b in 0u8..=255 { let f = TestFlags::from_bits_retain(a | b); s.clear(); to_writer_strict(&f, &mut s).unwrap(); let mut strict = TestFlags::empty(); for (_, flag) in f.iter_names() { strict |= flag; } let f = strict; if let Ok(s) = from_str_strict::(&s) { assert_eq!(f, s); } } } } mod from_str { use super::*; #[test] fn valid() { assert_eq!(0, from_str::("").unwrap().bits()); assert_eq!(1, from_str::("A").unwrap().bits()); assert_eq!(1, from_str::(" A ").unwrap().bits()); assert_eq!( 1 | 1 << 1 | 1 << 2, from_str::("A | B | C").unwrap().bits() ); assert_eq!( 1 | 1 << 1 | 1 << 2, from_str::("A\n|\tB\r\n| C ").unwrap().bits() ); assert_eq!( 1 | 1 << 1 | 1 << 2, from_str::("A|B|C").unwrap().bits() ); assert_eq!(1 << 3, from_str::("0x8").unwrap().bits()); assert_eq!(1 | 1 << 3, from_str::("A | 0x8").unwrap().bits()); assert_eq!( 1 | 1 << 1 | 1 << 3, from_str::("0x1 | 0x8 | B").unwrap().bits() ); assert_eq!( 1 | 1 << 1, from_str::("一 | 二").unwrap().bits() ); } #[test] fn invalid() { assert!(from_str::("a") .unwrap_err() .to_string() .starts_with("unrecognized named flag")); assert!(from_str::("A & B") .unwrap_err() .to_string() .starts_with("unrecognized named flag")); assert!(from_str::("0xg") .unwrap_err() .to_string() .starts_with("invalid hex flag")); assert!(from_str::("0xffffffffffff") .unwrap_err() .to_string() .starts_with("invalid hex flag")); } } mod to_writer { use super::*; #[test] fn cases() { assert_eq!("", write(TestFlags::empty())); assert_eq!("A", write(TestFlags::A)); assert_eq!("A | B | C", write(TestFlags::all())); assert_eq!("0x8", write(TestFlags::from_bits_retain(1 << 3))); assert_eq!( "A | 0x8", write(TestFlags::A | TestFlags::from_bits_retain(1 << 3)) ); assert_eq!("", write(TestZero::ZERO)); assert_eq!("ABC", write(TestFlagsInvert::all())); assert_eq!("0x1", write(TestOverlapping::from_bits_retain(1))); assert_eq!("A", write(TestOverlappingFull::C)); assert_eq!( "A | D", write(TestOverlappingFull::C | TestOverlappingFull::D) ); } fn write(value: F) -> String where F::Bits: crate::parser::WriteHex, { let mut s = String::new(); to_writer(&value, &mut s).unwrap(); s } } mod from_str_truncate { use super::*; #[test] fn valid() { assert_eq!(0, from_str_truncate::("").unwrap().bits()); assert_eq!(1, from_str_truncate::("A").unwrap().bits()); assert_eq!(1, from_str_truncate::(" A ").unwrap().bits()); assert_eq!( 1 | 1 << 1 | 1 << 2, from_str_truncate::("A | B | C").unwrap().bits() ); assert_eq!( 1 | 1 << 1 | 1 << 2, from_str_truncate::("A\n|\tB\r\n| C ") .unwrap() .bits() ); assert_eq!( 1 | 1 << 1 | 1 << 2, from_str_truncate::("A|B|C").unwrap().bits() ); assert_eq!(0, from_str_truncate::("0x8").unwrap().bits()); assert_eq!(1, from_str_truncate::("A | 0x8").unwrap().bits()); assert_eq!( 1 | 1 << 1, from_str_truncate::("0x1 | 0x8 | B") .unwrap() .bits() ); assert_eq!( 1 | 1 << 1, from_str_truncate::("一 | 二").unwrap().bits() ); } } mod to_writer_truncate { use super::*; #[test] fn cases() { assert_eq!("", write(TestFlags::empty())); assert_eq!("A", write(TestFlags::A)); assert_eq!("A | B | C", write(TestFlags::all())); assert_eq!("", write(TestFlags::from_bits_retain(1 << 3))); assert_eq!( "A", write(TestFlags::A | TestFlags::from_bits_retain(1 << 3)) ); assert_eq!("", write(TestZero::ZERO)); assert_eq!("ABC", write(TestFlagsInvert::all())); assert_eq!("0x1", write(TestOverlapping::from_bits_retain(1))); assert_eq!("A", write(TestOverlappingFull::C)); assert_eq!( "A | D", write(TestOverlappingFull::C | TestOverlappingFull::D) ); } fn write(value: F) -> String where F::Bits: crate::parser::WriteHex, { let mut s = String::new(); to_writer_truncate(&value, &mut s).unwrap(); s } } mod from_str_strict { use super::*; #[test] fn valid() { assert_eq!(0, from_str_strict::("").unwrap().bits()); assert_eq!(1, from_str_strict::("A").unwrap().bits()); assert_eq!(1, from_str_strict::(" A ").unwrap().bits()); assert_eq!( 1 | 1 << 1 | 1 << 2, from_str_strict::("A | B | C").unwrap().bits() ); assert_eq!( 1 | 1 << 1 | 1 << 2, from_str_strict::("A\n|\tB\r\n| C ") .unwrap() .bits() ); assert_eq!( 1 | 1 << 1 | 1 << 2, from_str_strict::("A|B|C").unwrap().bits() ); assert_eq!( 1 | 1 << 1, from_str_strict::("一 | 二").unwrap().bits() ); } #[test] fn invalid() { assert!(from_str_strict::("a") .unwrap_err() .to_string() .starts_with("unrecognized named flag")); assert!(from_str_strict::("A & B") .unwrap_err() .to_string() .starts_with("unrecognized named flag")); assert!(from_str_strict::("0x1") .unwrap_err() .to_string() .starts_with("invalid hex flag")); assert!(from_str_strict::("0xg") .unwrap_err() .to_string() .starts_with("invalid hex flag")); assert!(from_str_strict::("0xffffffffffff") .unwrap_err() .to_string() .starts_with("invalid hex flag")); } } mod to_writer_strict { use super::*; #[test] fn cases() { assert_eq!("", write(TestFlags::empty())); assert_eq!("A", write(TestFlags::A)); assert_eq!("A | B | C", write(TestFlags::all())); assert_eq!("", write(TestFlags::from_bits_retain(1 << 3))); assert_eq!( "A", write(TestFlags::A | TestFlags::from_bits_retain(1 << 3)) ); assert_eq!("", write(TestZero::ZERO)); assert_eq!("ABC", write(TestFlagsInvert::all())); assert_eq!("", write(TestOverlapping::from_bits_retain(1))); assert_eq!("A", write(TestOverlappingFull::C)); assert_eq!( "A | D", write(TestOverlappingFull::C | TestOverlappingFull::D) ); } fn write(value: F) -> String where F::Bits: crate::parser::WriteHex, { let mut s = String::new(); to_writer_strict(&value, &mut s).unwrap(); s } }