ruffle/wstr/src/tests.rs

213 lines
6.5 KiB
Rust
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

use super::pattern::Searcher;
use super::*;
use alloc::vec::Vec;
use core::fmt::Debug;
macro_rules! bstr {
($str:literal) => {
WStr::from_units($str)
};
}
macro_rules! wstr {
($($char:literal)*) => {
WStr::from_units(&[$($char as u16),*])
}
}
#[test]
fn roundtrip() {
fn test<'a>(units: impl Into<Units<&'a [u8], &'a [u16]>>) {
let units = units.into();
let s = WStr::from_units(units);
let conv = s.units();
let eq = match (units, conv) {
(Units::Bytes(a), Units::Bytes(b)) => a == b,
(Units::Wide(a), Units::Wide(b)) => a == b,
_ => false,
};
assert!(eq, "expected {:?}, got {:?}", units, conv);
}
test(b"");
test(<&[u16]>::default());
test(b"Hello!");
test(&[
'H' as u16, 'e' as u16, 'l' as u16, 'l' as u16, 'o' as u16, '!' as u16,
]);
}
#[test]
#[rustfmt::skip]
#[allow(clippy::eq_op)]
fn eq() {
let a1 = bstr!(b"hello");
let b1 = bstr!(b"world");
let a2 = wstr!('h''e''l''l''o');
let b2 = wstr!('w''o''r''l''d');
assert_eq!(a1, a1); assert_eq!(a2, a1); assert_ne!(b1, a1); assert_ne!(b2, a1);
assert_eq!(a1, a2); assert_eq!(a2, a2); assert_ne!(b1, a2); assert_ne!(b2, a2);
assert_ne!(a1, b1); assert_ne!(a2, b1); assert_eq!(b1, b1); assert_eq!(b2, b1);
assert_ne!(a1, b2); assert_ne!(a2, b2); assert_eq!(b1, b2); assert_eq!(b2, b2);
}
#[test]
#[rustfmt::skip]
#[allow(clippy::eq_op)]
fn cmp() {
let a1 = bstr!(b"hello");
let b1 = bstr!(b"world");
let a2 = wstr!('h''e''l''l''o');
let b2 = wstr!('w''o''r''l''d');
assert!(a1 == a1); assert!(a2 == a1); assert!(b1 > a1); assert!(b2 > a1);
assert!(a1 == a2); assert!(a2 == a2); assert!(b1 > a2); assert!(b2 > a2);
assert!(a1 < b1); assert!(a2 < b1); assert!(b1 == b1); assert!(b2 == b1);
assert!(a1 < b2); assert!(a2 < b2); assert!(b1 == b2); assert!(b2 == b2);
}
#[test]
fn fmt() {
let a = bstr!(b"Hello world!");
let b = wstr!('H''e''l''l''o'' ''w''o''r''l''d''!');
let c = bstr!(b"\t\n\x03");
let d = wstr!(0x202d 0x202e);
assert_eq!(format!("{}", a), "Hello world!");
assert_eq!(format!("{}", b), "Hello world!");
assert_eq!(format!("{}", c), "\t\n\x03");
assert_eq!(format!("{}", d), "\u{202d}\u{202e}");
assert_eq!(format!("{:?}", a), "\"Hello world!\"");
assert_eq!(format!("{:?}", b), "\"Hello world!\"");
assert_eq!(format!("{:?}", c), "\"\\t\\n\\u{3}\"");
assert_eq!(format!("{:?}", d), "\"\\u{202d}\\u{202e}\"");
}
#[test]
fn buf_concat_bytes() {
let mut s = WString::new();
assert_eq!(s, bstr!(b""));
s.push_byte(b'a');
assert_eq!(s, bstr!(b"a"));
s.push(b'b'.into());
assert_eq!(s, bstr!(b"ab"));
s.push_utf8("cd");
assert_eq!(s, bstr!(b"abcd"));
s.push_str(bstr!(b"ef"));
assert_eq!(s, bstr!(b"abcdef"));
s.push_char('g');
assert_eq!(s, bstr!(b"abcdefg"));
assert!(matches!(s.units(), Units::Bytes(_)));
}
#[test]
fn buf_concat_wide() {
let mut s = WString::new();
assert_eq!(s, bstr!(b""));
s.push_byte(b'a');
assert_eq!(s, bstr!(b"a"));
s.push('€' as u16);
assert_eq!(s, wstr!('a''€'));
s.push_utf8("😀");
assert_eq!(s, wstr!('a''€' 0xd83d 0xde00));
s.push_str(bstr!(b"!"));
assert_eq!(s, wstr!('a''€' 0xd83d 0xde00 '!'));
s.push_char('😀');
assert_eq!(s, wstr!('a''€' 0xd83d 0xde00 '!' 0xd83d 0xde00));
assert!(matches!(s.units(), Units::Wide(_)));
}
#[test]
fn offset_in() {
let bstr = bstr!(b"abcdefghijk");
assert_eq!(bstr.offset_in(bstr), Some(0));
assert_eq!(bstr[3..6].offset_in(bstr), Some(3));
assert_eq!(bstr.offset_in(&bstr[3..6]), None);
assert_eq!(bstr[..3].offset_in(&bstr[6..]), None);
assert_eq!(bstr[6..].offset_in(&bstr[..3]), None);
let wstr = wstr!('a''b''c''d''e''f''g''h''i''j''k');
assert_eq!(wstr.offset_in(wstr), Some(0));
assert_eq!(wstr[3..6].offset_in(wstr), Some(3));
assert_eq!(wstr.offset_in(&wstr[3..6]), None);
assert_eq!(wstr[..3].offset_in(&wstr[6..]), None);
assert_eq!(wstr[6..].offset_in(&wstr[..3]), None);
assert_eq!(bstr.offset_in(wstr), None);
}
fn test_pattern<'a, P: Pattern<'a> + Clone + Debug>(
haystack: &'a WStr,
pattern: P,
forwards: &[(usize, usize)],
backwards: Option<&[(usize, usize)]>,
) {
let mut searcher = pattern.clone().into_searcher(haystack);
let mut actual: Vec<_> = core::iter::from_fn(|| searcher.next_match()).collect();
assert_eq!(
actual, forwards,
"incorrect forwards matching: haystack={:?}; pattern={:?}",
haystack, pattern
);
searcher = pattern.clone().into_searcher(haystack);
actual = core::iter::from_fn(|| searcher.next_match_back()).collect();
actual.reverse();
assert_eq!(
actual,
backwards.unwrap_or(forwards),
"incorrect backwards matching: haystack={:?}; pattern={:?}",
haystack,
pattern
);
}
#[test]
fn char_patterns() {
test_pattern(bstr!(b"a"), b'a', &[(0, 1)], None);
let bytes = bstr!(b"abaabbcab");
test_pattern(bytes, b'b', &[(1, 2), (4, 5), (5, 6), (8, 9)], None);
test_pattern(bytes, b'd', &[], None);
test_pattern(bytes, 'c' as u16, &[(6, 7)], None);
test_pattern(bytes, '↓' as u16, &[], None);
let wide = wstr!('↓''a''a''↓''a');
test_pattern(wide, b'c', &[], None);
test_pattern(wide, '↓' as u16, &[(0, 1), (3, 4)], None);
}
#[test]
fn multi_char_patterns() {
let bytes = bstr!(b"abcdabcd");
let matches = &[(0, 1), (2, 3), (4, 5), (6, 7)];
test_pattern(bytes, &[b'a', b'c'][..], matches, None);
test_pattern(bytes, &['a' as u16, 'c' as u16][..], matches, None);
let wide = wstr!('↓''a''b''↓''b''c');
test_pattern(wide, &[b'a', b'b'][..], &[(1, 2), (2, 3), (4, 5)], None);
test_pattern(wide, &['↓' as u16, '' as u16][..], &[(0, 1), (3, 4)], None);
// Don't test `FnMut(u16) -> bool` because it isn't `Debug`
}
#[test]
fn str_patterns() {
test_pattern(bstr!(b"aa"), bstr!(b""), &[(0, 0), (1, 1), (2, 2)], None);
test_pattern(bstr!(b"abcde"), bstr!(b"abcde"), &[(0, 5)], None);
let bytes = bstr!(b"bbabbbabbbba");
let matches = &[(0, 2), (3, 5), (7, 9), (9, 11)];
let matches_rev = &[(0, 2), (4, 6), (7, 9), (9, 11)];
test_pattern(bytes, bstr!(b"bb"), matches, Some(matches_rev));
test_pattern(bytes, wstr!('b''b'), matches, Some(matches_rev));
let wide = wstr!('↓''↓''a''a''↓''↓''a''a''↓''↓');
test_pattern(wide, bstr!(b"aa"), &[(2, 4), (6, 8)], None);
test_pattern(wide, wstr!('↓''a'), &[(1, 3), (5, 7)], None);
}