| use realalloc::string::ToString; | |
| use super::*; | |
| #[test] | |
| fn code_point_from_u32() { | |
| assert!(CodePoint::from_u32(0).is_some()); | |
| assert!(CodePoint::from_u32(0xD800).is_some()); | |
| assert!(CodePoint::from_u32(0x10FFFF).is_some()); | |
| assert!(CodePoint::from_u32(0x110000).is_none()); | |
| } | |
| #[test] | |
| fn code_point_to_u32() { | |
| fn c(value: u32) -> CodePoint { | |
| CodePoint::from_u32(value).unwrap() | |
| } | |
| assert_eq!(c(0).to_u32(), 0); | |
| assert_eq!(c(0xD800).to_u32(), 0xD800); | |
| assert_eq!(c(0x10FFFF).to_u32(), 0x10FFFF); | |
| } | |
| #[test] | |
| fn code_point_to_lead_surrogate() { | |
| fn c(value: u32) -> CodePoint { | |
| CodePoint::from_u32(value).unwrap() | |
| } | |
| assert_eq!(c(0).to_lead_surrogate(), None); | |
| assert_eq!(c(0xE9).to_lead_surrogate(), None); | |
| assert_eq!(c(0xD800).to_lead_surrogate(), Some(0xD800)); | |
| assert_eq!(c(0xDBFF).to_lead_surrogate(), Some(0xDBFF)); | |
| assert_eq!(c(0xDC00).to_lead_surrogate(), None); | |
| assert_eq!(c(0xDFFF).to_lead_surrogate(), None); | |
| assert_eq!(c(0x1F4A9).to_lead_surrogate(), None); | |
| assert_eq!(c(0x10FFFF).to_lead_surrogate(), None); | |
| } | |
| #[test] | |
| fn code_point_to_trail_surrogate() { | |
| fn c(value: u32) -> CodePoint { | |
| CodePoint::from_u32(value).unwrap() | |
| } | |
| assert_eq!(c(0).to_trail_surrogate(), None); | |
| assert_eq!(c(0xE9).to_trail_surrogate(), None); | |
| assert_eq!(c(0xD800).to_trail_surrogate(), None); | |
| assert_eq!(c(0xDBFF).to_trail_surrogate(), None); | |
| assert_eq!(c(0xDC00).to_trail_surrogate(), Some(0xDC00)); | |
| assert_eq!(c(0xDFFF).to_trail_surrogate(), Some(0xDFFF)); | |
| assert_eq!(c(0x1F4A9).to_trail_surrogate(), None); | |
| assert_eq!(c(0x10FFFF).to_trail_surrogate(), None); | |
| } | |
| #[test] | |
| fn code_point_from_char() { | |
| assert_eq!(CodePoint::from_char('a').to_u32(), 0x61); | |
| assert_eq!(CodePoint::from_char('š©').to_u32(), 0x1F4A9); | |
| } | |
| #[test] | |
| fn code_point_to_string() { | |
| assert_eq!(format!("{:?}", CodePoint::from_char('a')), "U+0061"); | |
| assert_eq!(format!("{:?}", CodePoint::from_char('š©')), "U+1F4A9"); | |
| } | |
| #[test] | |
| fn code_point_to_char() { | |
| fn c(value: u32) -> CodePoint { | |
| CodePoint::from_u32(value).unwrap() | |
| } | |
| assert_eq!(c(0x61).to_char(), Some('a')); | |
| assert_eq!(c(0x1F4A9).to_char(), Some('š©')); | |
| assert_eq!(c(0xD800).to_char(), None); | |
| } | |
| #[test] | |
| fn code_point_to_char_lossy() { | |
| fn c(value: u32) -> CodePoint { | |
| CodePoint::from_u32(value).unwrap() | |
| } | |
| assert_eq!(c(0x61).to_char_lossy(), 'a'); | |
| assert_eq!(c(0x1F4A9).to_char_lossy(), 'š©'); | |
| assert_eq!(c(0xD800).to_char_lossy(), '\u{FFFD}'); | |
| } | |
| #[test] | |
| fn wtf8buf_new() { | |
| assert_eq!(Wtf8Buf::new().as_bytes(), b""); | |
| } | |
| #[test] | |
| fn wtf8buf_from_str() { | |
| assert_eq!(Wtf8Buf::from_str("").as_bytes(), b""); | |
| assert_eq!(Wtf8Buf::from_str("aĆ© š©").as_bytes(), b"a\xC3\xA9 \xF0\x9F\x92\xA9"); | |
| } | |
| #[test] | |
| fn wtf8buf_from_string() { | |
| assert_eq!(Wtf8Buf::from_string(String::from("")).as_bytes(), b""); | |
| assert_eq!( | |
| Wtf8Buf::from_string(String::from("aĆ© š©")).as_bytes(), | |
| b"a\xC3\xA9 \xF0\x9F\x92\xA9" | |
| ); | |
| } | |
| #[test] | |
| fn wtf8buf_from_wide() { | |
| let buf = Wtf8Buf::from_wide(&[]); | |
| assert_eq!(buf.as_bytes(), b""); | |
| assert!(buf.is_known_utf8); | |
| let buf = Wtf8Buf::from_wide(&[0x61, 0xE9, 0x20, 0xD83D, 0xDCA9]); | |
| assert_eq!(buf.as_bytes(), b"a\xC3\xA9 \xF0\x9F\x92\xA9"); | |
| assert!(buf.is_known_utf8); | |
| let buf = Wtf8Buf::from_wide(&[0x61, 0xE9, 0x20, 0xD83D, 0xD83D, 0xDCA9]); | |
| assert_eq!(buf.as_bytes(), b"a\xC3\xA9 \xED\xA0\xBD\xF0\x9F\x92\xA9"); | |
| assert!(!buf.is_known_utf8); | |
| let buf = Wtf8Buf::from_wide(&[0xD800]); | |
| assert_eq!(buf.as_bytes(), b"\xED\xA0\x80"); | |
| assert!(!buf.is_known_utf8); | |
| let buf = Wtf8Buf::from_wide(&[0xDBFF]); | |
| assert_eq!(buf.as_bytes(), b"\xED\xAF\xBF"); | |
| assert!(!buf.is_known_utf8); | |
| let buf = Wtf8Buf::from_wide(&[0xDC00]); | |
| assert_eq!(buf.as_bytes(), b"\xED\xB0\x80"); | |
| assert!(!buf.is_known_utf8); | |
| let buf = Wtf8Buf::from_wide(&[0xDFFF]); | |
| assert_eq!(buf.as_bytes(), b"\xED\xBF\xBF"); | |
| assert!(!buf.is_known_utf8); | |
| } | |
| #[test] | |
| fn wtf8buf_push_str() { | |
| let mut string = Wtf8Buf::new(); | |
| assert_eq!(string.as_bytes(), b""); | |
| assert!(string.is_known_utf8); | |
| string.push_str("aĆ© š©"); | |
| assert_eq!(string.as_bytes(), b"a\xC3\xA9 \xF0\x9F\x92\xA9"); | |
| assert!(string.is_known_utf8); | |
| } | |
| #[test] | |
| fn wtf8buf_push_char() { | |
| let mut string = Wtf8Buf::from_str("aƩ "); | |
| assert_eq!(string.as_bytes(), b"a\xC3\xA9 "); | |
| assert!(string.is_known_utf8); | |
| string.push_char('š©'); | |
| assert_eq!(string.as_bytes(), b"a\xC3\xA9 \xF0\x9F\x92\xA9"); | |
| assert!(string.is_known_utf8); | |
| } | |
| #[test] | |
| fn wtf8buf_push() { | |
| let mut string = Wtf8Buf::from_str("aƩ "); | |
| assert_eq!(string.as_bytes(), b"a\xC3\xA9 "); | |
| assert!(string.is_known_utf8); | |
| string.push(CodePoint::from_char('š©')); | |
| assert_eq!(string.as_bytes(), b"a\xC3\xA9 \xF0\x9F\x92\xA9"); | |
| assert!(string.is_known_utf8); | |
| fn c(value: u32) -> CodePoint { | |
| CodePoint::from_u32(value).unwrap() | |
| } | |
| let mut string = Wtf8Buf::new(); | |
| string.push(c(0xD83D)); // lead | |
| assert!(!string.is_known_utf8); | |
| string.push(c(0xDCA9)); // trail | |
| assert_eq!(string.as_bytes(), b"\xF0\x9F\x92\xA9"); // Magic! | |
| let mut string = Wtf8Buf::new(); | |
| string.push(c(0xD83D)); // lead | |
| assert!(!string.is_known_utf8); | |
| string.push(c(0x20)); // not surrogate | |
| string.push(c(0xDCA9)); // trail | |
| assert_eq!(string.as_bytes(), b"\xED\xA0\xBD \xED\xB2\xA9"); | |
| let mut string = Wtf8Buf::new(); | |
| string.push(c(0xD800)); // lead | |
| assert!(!string.is_known_utf8); | |
| string.push(c(0xDBFF)); // lead | |
| assert_eq!(string.as_bytes(), b"\xED\xA0\x80\xED\xAF\xBF"); | |
| let mut string = Wtf8Buf::new(); | |
| string.push(c(0xD800)); // lead | |
| assert!(!string.is_known_utf8); | |
| string.push(c(0xE000)); // not surrogate | |
| assert_eq!(string.as_bytes(), b"\xED\xA0\x80\xEE\x80\x80"); | |
| let mut string = Wtf8Buf::new(); | |
| string.push(c(0xD7FF)); // not surrogate | |
| assert!(string.is_known_utf8); | |
| string.push(c(0xDC00)); // trail | |
| assert!(!string.is_known_utf8); | |
| assert_eq!(string.as_bytes(), b"\xED\x9F\xBF\xED\xB0\x80"); | |
| let mut string = Wtf8Buf::new(); | |
| string.push(c(0x61)); // not surrogate, < 3 bytes | |
| assert!(string.is_known_utf8); | |
| string.push(c(0xDC00)); // trail | |
| assert!(!string.is_known_utf8); | |
| assert_eq!(string.as_bytes(), b"\x61\xED\xB0\x80"); | |
| let mut string = Wtf8Buf::new(); | |
| string.push(c(0xDC00)); // trail | |
| assert!(!string.is_known_utf8); | |
| assert_eq!(string.as_bytes(), b"\xED\xB0\x80"); | |
| } | |
| #[test] | |
| fn wtf8buf_push_wtf8() { | |
| let mut string = Wtf8Buf::from_str("aƩ"); | |
| assert_eq!(string.as_bytes(), b"a\xC3\xA9"); | |
| string.push_wtf8(Wtf8::from_str(" š©")); | |
| assert_eq!(string.as_bytes(), b"a\xC3\xA9 \xF0\x9F\x92\xA9"); | |
| assert!(string.is_known_utf8); | |
| fn w(v: &[u8]) -> &Wtf8 { | |
| unsafe { Wtf8::from_bytes_unchecked(v) } | |
| } | |
| let mut string = Wtf8Buf::new(); | |
| string.push_wtf8(w(b"\xED\xA0\xBD")); // lead | |
| string.push_wtf8(w(b"\xED\xB2\xA9")); // trail | |
| assert_eq!(string.as_bytes(), b"\xF0\x9F\x92\xA9"); // Magic! | |
| let mut string = Wtf8Buf::new(); | |
| string.push_wtf8(w(b"\xED\xA0\xBD")); // lead | |
| string.push_wtf8(w(b" ")); // not surrogate | |
| string.push_wtf8(w(b"\xED\xB2\xA9")); // trail | |
| assert_eq!(string.as_bytes(), b"\xED\xA0\xBD \xED\xB2\xA9"); | |
| assert!(!string.is_known_utf8); | |
| let mut string = Wtf8Buf::new(); | |
| string.push_wtf8(w(b"\xED\xA0\x80")); // lead | |
| string.push_wtf8(w(b"\xED\xAF\xBF")); // lead | |
| assert_eq!(string.as_bytes(), b"\xED\xA0\x80\xED\xAF\xBF"); | |
| assert!(!string.is_known_utf8); | |
| let mut string = Wtf8Buf::new(); | |
| string.push_wtf8(w(b"\xED\xA0\x80")); // lead | |
| string.push_wtf8(w(b"\xEE\x80\x80")); // not surrogate | |
| assert_eq!(string.as_bytes(), b"\xED\xA0\x80\xEE\x80\x80"); | |
| assert!(!string.is_known_utf8); | |
| let mut string = Wtf8Buf::new(); | |
| string.push_wtf8(w(b"\xED\x9F\xBF")); // not surrogate | |
| string.push_wtf8(w(b"\xED\xB0\x80")); // trail | |
| assert_eq!(string.as_bytes(), b"\xED\x9F\xBF\xED\xB0\x80"); | |
| assert!(!string.is_known_utf8); | |
| let mut string = Wtf8Buf::new(); | |
| string.push_wtf8(w(b"a")); // not surrogate, < 3 bytes | |
| string.push_wtf8(w(b"\xED\xB0\x80")); // trail | |
| assert_eq!(string.as_bytes(), b"\x61\xED\xB0\x80"); | |
| assert!(!string.is_known_utf8); | |
| let mut string = Wtf8Buf::new(); | |
| string.push_wtf8(w(b"\xED\xB0\x80")); // trail | |
| assert_eq!(string.as_bytes(), b"\xED\xB0\x80"); | |
| assert!(!string.is_known_utf8); | |
| } | |
| #[test] | |
| fn wtf8buf_truncate() { | |
| let mut string = Wtf8Buf::from_str("aƩ"); | |
| assert!(string.is_known_utf8); | |
| string.truncate(3); | |
| assert_eq!(string.as_bytes(), b"a\xC3\xA9"); | |
| assert!(string.is_known_utf8); | |
| string.truncate(1); | |
| assert_eq!(string.as_bytes(), b"a"); | |
| assert!(string.is_known_utf8); | |
| string.truncate(0); | |
| assert_eq!(string.as_bytes(), b""); | |
| assert!(string.is_known_utf8); | |
| } | |
| #[test] | |
| fn wtf8buf_truncate_around_non_bmp() { | |
| let mut string = Wtf8Buf::from_str("š©"); | |
| assert!(string.is_known_utf8); | |
| string.truncate(4); | |
| assert_eq!(string.as_bytes(), b"\xF0\x9F\x92\xA9"); | |
| assert!(string.is_known_utf8); | |
| string.truncate(0); | |
| assert_eq!(string.as_bytes(), b""); | |
| assert!(string.is_known_utf8); | |
| } | |
| #[test] | |
| #[should_panic] | |
| fn wtf8buf_truncate_fail_code_point_boundary() { | |
| let mut string = Wtf8Buf::from_str("aƩ"); | |
| string.truncate(2); | |
| } | |
| #[test] | |
| fn wtf8buf_truncate_invalid_len() { | |
| let mut string = Wtf8Buf::from_str("aƩ"); | |
| string.truncate(4); | |
| assert_eq!(string, Wtf8Buf::from_str("aƩ")); | |
| } | |
| #[test] | |
| #[should_panic] | |
| fn wtf8buf_truncate_splitting_non_bmp3() { | |
| let mut string = Wtf8Buf::from_str("š©"); | |
| assert!(string.is_known_utf8); | |
| string.truncate(3); | |
| } | |
| #[test] | |
| #[should_panic] | |
| fn wtf8buf_truncate_splitting_non_bmp2() { | |
| let mut string = Wtf8Buf::from_str("š©"); | |
| assert!(string.is_known_utf8); | |
| string.truncate(2); | |
| } | |
| #[test] | |
| #[should_panic] | |
| fn wtf8buf_truncate_splitting_non_bmp1() { | |
| let mut string = Wtf8Buf::from_str("š©"); | |
| assert!(string.is_known_utf8); | |
| string.truncate(1); | |
| } | |
| #[test] | |
| fn wtf8buf_into_string() { | |
| let mut string = Wtf8Buf::from_str("aĆ© š©"); | |
| assert!(string.is_known_utf8); | |
| assert_eq!(string.clone().into_string(), Ok(String::from("aĆ© š©"))); | |
| string.push(CodePoint::from_u32(0xD800).unwrap()); | |
| assert!(!string.is_known_utf8); | |
| assert_eq!(string.clone().into_string(), Err(string)); | |
| } | |
| #[test] | |
| fn wtf8buf_into_string_lossy() { | |
| let mut string = Wtf8Buf::from_str("aĆ© š©"); | |
| assert_eq!(string.clone().into_string_lossy(), String::from("aĆ© š©")); | |
| string.push(CodePoint::from_u32(0xD800).unwrap()); | |
| assert_eq!(string.clone().into_string_lossy(), String::from("aĆ© š©ļæ½")); | |
| } | |
| #[test] | |
| fn wtf8buf_from_iterator() { | |
| fn f(values: &[u32]) -> Wtf8Buf { | |
| values.iter().map(|&c| CodePoint::from_u32(c).unwrap()).collect::<Wtf8Buf>() | |
| } | |
| assert_eq!( | |
| f(&[0x61, 0xE9, 0x20, 0x1F4A9]), | |
| Wtf8Buf { bytes: b"a\xC3\xA9 \xF0\x9F\x92\xA9".to_vec(), is_known_utf8: true } | |
| ); | |
| assert_eq!(f(&[0xD83D, 0xDCA9]).as_bytes(), b"\xF0\x9F\x92\xA9"); // Magic! | |
| assert_eq!( | |
| f(&[0xD83D, 0x20, 0xDCA9]), | |
| Wtf8Buf { bytes: b"\xED\xA0\xBD \xED\xB2\xA9".to_vec(), is_known_utf8: false } | |
| ); | |
| assert_eq!( | |
| f(&[0xD800, 0xDBFF]), | |
| Wtf8Buf { bytes: b"\xED\xA0\x80\xED\xAF\xBF".to_vec(), is_known_utf8: false } | |
| ); | |
| assert_eq!( | |
| f(&[0xD800, 0xE000]), | |
| Wtf8Buf { bytes: b"\xED\xA0\x80\xEE\x80\x80".to_vec(), is_known_utf8: false } | |
| ); | |
| assert_eq!( | |
| f(&[0xD7FF, 0xDC00]), | |
| Wtf8Buf { bytes: b"\xED\x9F\xBF\xED\xB0\x80".to_vec(), is_known_utf8: false } | |
| ); | |
| assert_eq!( | |
| f(&[0x61, 0xDC00]), | |
| Wtf8Buf { bytes: b"\x61\xED\xB0\x80".to_vec(), is_known_utf8: false } | |
| ); | |
| assert_eq!(f(&[0xDC00]), Wtf8Buf { bytes: b"\xED\xB0\x80".to_vec(), is_known_utf8: false }); | |
| } | |
| #[test] | |
| fn wtf8buf_extend() { | |
| fn e(initial: &[u32], extended: &[u32]) -> Wtf8Buf { | |
| fn c(value: &u32) -> CodePoint { | |
| CodePoint::from_u32(*value).unwrap() | |
| } | |
| let mut string = initial.iter().map(c).collect::<Wtf8Buf>(); | |
| string.extend(extended.iter().map(c)); | |
| string | |
| } | |
| assert_eq!( | |
| e(&[0x61, 0xE9], &[0x20, 0x1F4A9]), | |
| Wtf8Buf { bytes: b"a\xC3\xA9 \xF0\x9F\x92\xA9".to_vec(), is_known_utf8: true } | |
| ); | |
| assert_eq!(e(&[0xD83D], &[0xDCA9]).as_bytes(), b"\xF0\x9F\x92\xA9"); // Magic! | |
| assert_eq!( | |
| e(&[0xD83D, 0x20], &[0xDCA9]), | |
| Wtf8Buf { bytes: b"\xED\xA0\xBD \xED\xB2\xA9".to_vec(), is_known_utf8: false } | |
| ); | |
| assert_eq!( | |
| e(&[0xD800], &[0xDBFF]), | |
| Wtf8Buf { bytes: b"\xED\xA0\x80\xED\xAF\xBF".to_vec(), is_known_utf8: false } | |
| ); | |
| assert_eq!( | |
| e(&[0xD800], &[0xE000]), | |
| Wtf8Buf { bytes: b"\xED\xA0\x80\xEE\x80\x80".to_vec(), is_known_utf8: false } | |
| ); | |
| assert_eq!( | |
| e(&[0xD7FF], &[0xDC00]), | |
| Wtf8Buf { bytes: b"\xED\x9F\xBF\xED\xB0\x80".to_vec(), is_known_utf8: false } | |
| ); | |
| assert_eq!( | |
| e(&[0x61], &[0xDC00]), | |
| Wtf8Buf { bytes: b"\x61\xED\xB0\x80".to_vec(), is_known_utf8: false } | |
| ); | |
| assert_eq!( | |
| e(&[], &[0xDC00]), | |
| Wtf8Buf { bytes: b"\xED\xB0\x80".to_vec(), is_known_utf8: false } | |
| ); | |
| } | |
| #[test] | |
| fn wtf8buf_show() { | |
| let mut string = Wtf8Buf::from_str("a\tĆ© \u{7f}š©\r"); | |
| string.push(CodePoint::from_u32(0xD800).unwrap()); | |
| assert_eq!(format!("{string:?}"), "\"a\\tƩ \\u{7f}\u{1f4a9}\\r\\u{d800}\""); | |
| } | |
| #[test] | |
| fn wtf8buf_as_slice() { | |
| assert_eq!(Wtf8Buf::from_str("aƩ").as_slice(), Wtf8::from_str("aƩ")); | |
| } | |
| #[test] | |
| fn wtf8buf_show_str() { | |
| let text = "a\tĆ© š©\r"; | |
| let string = Wtf8Buf::from_str(text); | |
| assert_eq!(format!("{text:?}"), format!("{string:?}")); | |
| } | |
| #[test] | |
| fn wtf8_from_str() { | |
| assert_eq!(&Wtf8::from_str("").as_bytes(), b""); | |
| assert_eq!(&Wtf8::from_str("aĆ© š©").as_bytes(), b"a\xC3\xA9 \xF0\x9F\x92\xA9"); | |
| } | |
| #[test] | |
| fn wtf8_len() { | |
| assert_eq!(Wtf8::from_str("").len(), 0); | |
| assert_eq!(Wtf8::from_str("aĆ© š©").len(), 8); | |
| } | |
| #[test] | |
| fn wtf8_slice() { | |
| assert_eq!(&Wtf8::from_str("aĆ© š©")[1..4].as_bytes(), b"\xC3\xA9 "); | |
| } | |
| #[test] | |
| #[should_panic] | |
| fn wtf8_slice_not_code_point_boundary() { | |
| let _ = &Wtf8::from_str("aĆ© š©")[2..4]; | |
| } | |
| #[test] | |
| fn wtf8_slice_from() { | |
| assert_eq!(&Wtf8::from_str("aĆ© š©")[1..].as_bytes(), b"\xC3\xA9 \xF0\x9F\x92\xA9"); | |
| } | |
| #[test] | |
| #[should_panic] | |
| fn wtf8_slice_from_not_code_point_boundary() { | |
| let _ = &Wtf8::from_str("aĆ© š©")[2..]; | |
| } | |
| #[test] | |
| fn wtf8_slice_to() { | |
| assert_eq!(&Wtf8::from_str("aĆ© š©")[..4].as_bytes(), b"a\xC3\xA9 "); | |
| } | |
| #[test] | |
| #[should_panic] | |
| fn wtf8_slice_to_not_code_point_boundary() { | |
| let _ = &Wtf8::from_str("aĆ© š©")[5..]; | |
| } | |
| #[test] | |
| fn wtf8_ascii_byte_at() { | |
| let slice = Wtf8::from_str("aĆ© š©"); | |
| assert_eq!(slice.ascii_byte_at(0), b'a'); | |
| assert_eq!(slice.ascii_byte_at(1), b'\xFF'); | |
| assert_eq!(slice.ascii_byte_at(2), b'\xFF'); | |
| assert_eq!(slice.ascii_byte_at(3), b' '); | |
| assert_eq!(slice.ascii_byte_at(4), b'\xFF'); | |
| } | |
| #[test] | |
| fn wtf8_code_points() { | |
| fn c(value: u32) -> CodePoint { | |
| CodePoint::from_u32(value).unwrap() | |
| } | |
| fn cp(string: &Wtf8Buf) -> Vec<Option<char>> { | |
| string.code_points().map(|c| c.to_char()).collect::<Vec<_>>() | |
| } | |
| let mut string = Wtf8Buf::from_str("Ć© "); | |
| assert_eq!(cp(&string), [Some('Ć©'), Some(' ')]); | |
| string.push(c(0xD83D)); | |
| assert_eq!(cp(&string), [Some('Ć©'), Some(' '), None]); | |
| string.push(c(0xDCA9)); | |
| assert_eq!(cp(&string), [Some('Ć©'), Some(' '), Some('š©')]); | |
| } | |
| #[test] | |
| fn wtf8_as_str() { | |
| assert_eq!(Wtf8::from_str("").as_str(), Ok("")); | |
| assert_eq!(Wtf8::from_str("aĆ© š©").as_str(), Ok("aĆ© š©")); | |
| let mut string = Wtf8Buf::new(); | |
| string.push(CodePoint::from_u32(0xD800).unwrap()); | |
| assert!(string.as_str().is_err()); | |
| } | |
| #[test] | |
| fn wtf8_to_string_lossy() { | |
| assert_eq!(to_string_lossy(Wtf8::from_str("")), Cow::Borrowed("")); | |
| assert_eq!(to_string_lossy(Wtf8::from_str("aĆ© š©")), Cow::Borrowed("aĆ© š©")); | |
| let mut string = Wtf8Buf::from_str("aĆ© š©"); | |
| string.push(CodePoint::from_u32(0xD800).unwrap()); | |
| let expected: Cow<'_, str> = Cow::Owned(String::from("aĆ© š©ļæ½")); | |
| assert_eq!(to_string_lossy(&string), expected); | |
| } | |
| #[test] | |
| fn wtf8_display() { | |
| fn d(b: &[u8]) -> String { | |
| (&unsafe { Wtf8::from_bytes_unchecked(b) }).to_string() | |
| } | |
| assert_eq!("", d("".as_bytes())); | |
| assert_eq!("aĆ© š©", d("aĆ© š©".as_bytes())); | |
| let mut string = Wtf8Buf::from_str("aĆ© š©"); | |
| string.push(CodePoint::from_u32(0xD800).unwrap()); | |
| assert_eq!("aĆ© š©ļæ½", d(string.as_ref())); | |
| } | |
| #[test] | |
| fn wtf8_encode_wide() { | |
| let mut string = Wtf8Buf::from_str("aƩ "); | |
| string.push(CodePoint::from_u32(0xD83D).unwrap()); | |
| string.push_char('š©'); | |
| assert_eq!( | |
| string.encode_wide().collect::<Vec<_>>(), | |
| vec![0x61, 0xE9, 0x20, 0xD83D, 0xD83D, 0xDCA9] | |
| ); | |
| } | |
| #[test] | |
| fn wtf8_encode_wide_size_hint() { | |
| let string = Wtf8Buf::from_str("\u{12345}"); | |
| let mut iter = string.encode_wide(); | |
| assert_eq!((1, Some(8)), iter.size_hint()); | |
| iter.next().unwrap(); | |
| assert_eq!((1, Some(1)), iter.size_hint()); | |
| iter.next().unwrap(); | |
| assert_eq!((0, Some(0)), iter.size_hint()); | |
| assert!(iter.next().is_none()); | |
| } | |
| #[test] | |
| fn wtf8_encode_wide_debug() { | |
| let mut string = Wtf8Buf::from_str("aƩ "); | |
| string.push(CodePoint::from_u32(0xD83D).unwrap()); | |
| string.push_char('š©'); | |
| assert_eq!( | |
| format!("{:?}", string.encode_wide()), | |
| r#"EncodeWide(['a', 'Ć©', ' ', 0xD83D, 0xD83D, 0xDCA9])"# | |
| ); | |
| } | |
| #[test] | |
| fn wtf8_clone_into() { | |
| let mut string = Wtf8Buf::new(); | |
| clone_into(Wtf8::from_str("green"), &mut string); | |
| assert_eq!(string.as_bytes(), b"green"); | |
| let mut string = Wtf8Buf::from_str("green"); | |
| clone_into(Wtf8::from_str(""), &mut string); | |
| assert_eq!(string.as_bytes(), b""); | |
| let mut string = Wtf8Buf::from_str("red"); | |
| clone_into(Wtf8::from_str("green"), &mut string); | |
| assert_eq!(string.as_bytes(), b"green"); | |
| let mut string = Wtf8Buf::from_str("green"); | |
| clone_into(Wtf8::from_str("red"), &mut string); | |
| assert_eq!(string.as_bytes(), b"red"); | |
| let mut string = Wtf8Buf::from_str("green"); | |
| assert!(string.is_known_utf8); | |
| clone_into(unsafe { Wtf8::from_bytes_unchecked(b"\xED\xA0\x80") }, &mut string); | |
| assert_eq!(string.as_bytes(), b"\xED\xA0\x80"); | |
| assert!(!string.is_known_utf8); | |
| } | |
| #[test] | |
| fn wtf8_make_ascii_lowercase() { | |
| let mut lowercase = Wtf8Buf::from_str(""); | |
| lowercase.make_ascii_lowercase(); | |
| assert_eq!(lowercase.as_bytes(), b""); | |
| let mut lowercase = Wtf8Buf::from_str("GrEeN gRaPeS! š"); | |
| lowercase.make_ascii_lowercase(); | |
| assert_eq!(lowercase.as_bytes(), b"green grapes! \xf0\x9f\x8d\x87"); | |
| let mut lowercase = to_owned(unsafe { Wtf8::from_bytes_unchecked(b"\xED\xA0\x80") }); | |
| lowercase.make_ascii_lowercase(); | |
| assert_eq!(lowercase.as_bytes(), b"\xED\xA0\x80"); | |
| assert!(!lowercase.is_known_utf8); | |
| } | |
| #[test] | |
| fn wtf8_make_ascii_uppercase() { | |
| let mut uppercase = Wtf8Buf::from_str(""); | |
| uppercase.make_ascii_uppercase(); | |
| assert_eq!(uppercase.as_bytes(), b""); | |
| let mut uppercase = Wtf8Buf::from_str("GrEeN gRaPeS! š"); | |
| uppercase.make_ascii_uppercase(); | |
| assert_eq!(uppercase.as_bytes(), b"GREEN GRAPES! \xf0\x9f\x8d\x87"); | |
| let mut uppercase = to_owned(unsafe { Wtf8::from_bytes_unchecked(b"\xED\xA0\x80") }); | |
| uppercase.make_ascii_uppercase(); | |
| assert_eq!(uppercase.as_bytes(), b"\xED\xA0\x80"); | |
| assert!(!uppercase.is_known_utf8); | |
| } | |
| #[test] | |
| fn wtf8_to_owned() { | |
| let string = to_owned(unsafe { Wtf8::from_bytes_unchecked(b"\xED\xA0\x80") }); | |
| assert_eq!(string.as_bytes(), b"\xED\xA0\x80"); | |
| assert!(!string.is_known_utf8); | |
| } | |
| #[test] | |
| fn wtf8_valid_utf8_boundaries() { | |
| let mut string = Wtf8Buf::from_str("aĆ© š©"); | |
| string.push(CodePoint::from_u32(0xD800).unwrap()); | |
| string.push(CodePoint::from_u32(0xD800).unwrap()); | |
| string.check_utf8_boundary(0); | |
| string.check_utf8_boundary(1); | |
| string.check_utf8_boundary(3); | |
| string.check_utf8_boundary(4); | |
| string.check_utf8_boundary(8); | |
| string.check_utf8_boundary(14); | |
| assert_eq!(string.len(), 14); | |
| string.push_char('a'); | |
| string.check_utf8_boundary(14); | |
| string.check_utf8_boundary(15); | |
| let mut string = Wtf8Buf::from_str("a"); | |
| string.push(CodePoint::from_u32(0xD800).unwrap()); | |
| string.check_utf8_boundary(1); | |
| let mut string = Wtf8Buf::from_str("\u{D7FF}"); | |
| string.push(CodePoint::from_u32(0xD800).unwrap()); | |
| string.check_utf8_boundary(3); | |
| let mut string = Wtf8Buf::new(); | |
| string.push(CodePoint::from_u32(0xD800).unwrap()); | |
| string.push_char('\u{D7FF}'); | |
| string.check_utf8_boundary(3); | |
| } | |
| #[test] | |
| #[should_panic(expected = "byte index 4 is out of bounds")] | |
| fn wtf8_utf8_boundary_out_of_bounds() { | |
| let string = Wtf8::from_str("aƩ"); | |
| string.check_utf8_boundary(4); | |
| } | |
| #[test] | |
| #[should_panic(expected = "byte index 1 is not a codepoint boundary")] | |
| fn wtf8_utf8_boundary_inside_codepoint() { | |
| let string = Wtf8::from_str("Ć©"); | |
| string.check_utf8_boundary(1); | |
| } | |
| #[test] | |
| #[should_panic(expected = "byte index 1 is not a codepoint boundary")] | |
| fn wtf8_utf8_boundary_inside_surrogate() { | |
| let mut string = Wtf8Buf::new(); | |
| string.push(CodePoint::from_u32(0xD800).unwrap()); | |
| string.check_utf8_boundary(1); | |
| } | |
| #[test] | |
| #[should_panic(expected = "byte index 3 lies between surrogate codepoints")] | |
| fn wtf8_utf8_boundary_between_surrogates() { | |
| let mut string = Wtf8Buf::new(); | |
| string.push(CodePoint::from_u32(0xD800).unwrap()); | |
| string.push(CodePoint::from_u32(0xD800).unwrap()); | |
| string.check_utf8_boundary(3); | |
| } | |
| #[test] | |
| fn wobbled_wtf8_plus_bytes_isnt_utf8() { | |
| let mut string: Wtf8Buf = to_owned(unsafe { Wtf8::from_bytes_unchecked(b"\xED\xA0\x80") }); | |
| assert!(!string.is_known_utf8); | |
| unsafe { | |
| string.extend_from_slice_unchecked(b"some utf-8"); | |
| } | |
| assert!(!string.is_known_utf8); | |
| } | |
| #[test] | |
| fn wobbled_wtf8_plus_str_isnt_utf8() { | |
| let mut string: Wtf8Buf = to_owned(unsafe { Wtf8::from_bytes_unchecked(b"\xED\xA0\x80") }); | |
| assert!(!string.is_known_utf8); | |
| string.push_str("some utf-8"); | |
| assert!(!string.is_known_utf8); | |
| } | |
| #[test] | |
| fn unwobbly_wtf8_plus_utf8_is_utf8() { | |
| let mut string: Wtf8Buf = Wtf8Buf::from_str("hello world"); | |
| assert!(string.is_known_utf8); | |
| string.push_str("some utf-8"); | |
| assert!(string.is_known_utf8); | |
| } |