1 | use std::convert::TryFrom; |
2 | use std::ops::RangeBounds; |
3 | |
4 | fn test_char_coverage<R>(n: usize, range: R) |
5 | where |
6 | R: Iterator<Item = char> + RangeBounds<char> + Clone, |
7 | { |
8 | use std::collections::HashSet; |
9 | |
10 | let all: HashSet<char> = range.clone().collect(); |
11 | let mut covered = HashSet::new(); |
12 | for _ in 0..n { |
13 | let c = fastrand::char(range.clone()); |
14 | assert!(all.contains(&c)); |
15 | covered.insert(c); |
16 | } |
17 | assert_eq!(covered, all); |
18 | } |
19 | |
20 | #[test] |
21 | fn test_char() { |
22 | // ASCII control chars. |
23 | let nul = 0u8 as char; |
24 | let soh = 1u8 as char; |
25 | let stx = 2u8 as char; |
26 | // Some undefined Hangul Jamo codepoints just before |
27 | // the surrogate area. |
28 | let last_jamo = char::try_from(0xd7ffu32).unwrap(); |
29 | let penultimate_jamo = char::try_from(last_jamo as u32 - 1).unwrap(); |
30 | // Private-use codepoints just after the surrogate area. |
31 | let first_private = char::try_from(0xe000u32).unwrap(); |
32 | let second_private = char::try_from(first_private as u32 + 1).unwrap(); |
33 | // Private-use codepoints at the end of Unicode space. |
34 | let last_private = std::char::MAX; |
35 | let penultimate_private = char::try_from(last_private as u32 - 1).unwrap(); |
36 | |
37 | test_char_coverage(100, nul..stx); |
38 | test_char_coverage(100, nul..=soh); |
39 | |
40 | test_char_coverage(400, penultimate_jamo..second_private); |
41 | test_char_coverage(400, penultimate_jamo..=second_private); |
42 | |
43 | test_char_coverage(100, penultimate_private..=last_private); |
44 | } |
45 | |