encoding_index_tests/
index_tests.rs

1// This is a part of encoding-next.
2// Copyright (c) 2013-2015, Kang Seonghoon.
3// See README.md and LICENSE.txt for details.
4
5//! Macros and utilities for testing indices.
6
7/// Makes a common test suite for single-byte indices.
8#[macro_export]
9macro_rules! single_byte_tests {
10    () => {
11        mod tests {
12            extern crate test;
13            use super::{backward, forward};
14
15            #[test]
16            fn test_correct_table() {
17                for i in 0x80..0x100 {
18                    let i = i as u8;
19                    let j = forward(i);
20                    if j != 0xffff {
21                        assert_eq!(backward(j as u32), i);
22                    }
23                }
24                for i in 0..0x110000 {
25                    let j = backward(i);
26                    if j != 0 {
27                        assert_eq!(forward(j) as u32, i);
28                    }
29                }
30            }
31
32            #[bench]
33            fn bench_forward_sequential_128(bencher: &mut test::Bencher) {
34                bencher.iter(|| {
35                    for i in 0x80..0x100 {
36                        test::black_box(forward(i as u8));
37                    }
38                })
39            }
40
41            // strongly prefers the performance for invalid characters
42            #[bench]
43            fn bench_backward_sequential_128(bencher: &mut test::Bencher) {
44                let mut start: u32 = 0;
45                bencher.iter(|| {
46                    for i in start..(start + 0x80) {
47                        test::black_box(backward(i));
48                    }
49                    start += 0x80;
50                })
51            }
52
53            // strongly prefers the performance for valid characters
54            #[bench]
55            fn bench_roundtrip_sequential_128(bencher: &mut test::Bencher) {
56                bencher.iter(|| {
57                    for i in 0x80..0x100 {
58                        let j = forward(i as u8);
59                        if j != 0 {
60                            test::black_box(backward(j as u32));
61                        }
62                    }
63                })
64            }
65        }
66    };
67}
68
69/// Makes a common test suite for multi-byte indices.
70#[macro_export]
71macro_rules! multi_byte_tests {
72    (@shared dups=[$($dups:pat),* $(,)*]) => ( // internal macro
73        fn in_dups(i: u16) -> bool {
74            match i { $($dups => true,)* _ => false }
75        }
76
77        #[test]
78        fn test_correct_table() {
79            for i in 0..0x10000 {
80                let i = i as u16;
81                if in_dups(i) { continue; }
82                let j = forward(i);
83                if j != 0xffff { assert_eq!(backward(j), i); }
84            }
85            for i in 0..0x110000 {
86                let j = backward(i);
87                if in_dups(j) { continue; }
88                if j != 0xffff { assert_eq!(forward(j), i); }
89            }
90        }
91
92        #[bench]
93        fn bench_forward_sequential_128(bencher: &mut test::Bencher) {
94            let mut start: u32 = 0;
95            bencher.iter(|| {
96                for i in start..(start + 0x80) {
97                    test::black_box(forward(i as u16));
98                }
99                start += 0x80;
100            })
101        }
102
103        #[bench]
104        fn bench_backward_sequential_128(bencher: &mut test::Bencher) {
105            let mut start: u32 = 0;
106            bencher.iter(|| {
107                for i in start..(start + 0x80) {
108                    test::black_box(backward(i));
109                }
110                start += 0x80;
111                if start >= 0x110000 { start = 0; }
112            })
113        }
114    );
115
116    (
117        dups = [$($dups:pat),* $(,)*]
118    ) => (
119        mod tests {
120            extern crate test;
121            use super::{forward, backward};
122
123            $crate::multi_byte_tests!(@shared dups=[$($dups),*]);
124        }
125    );
126
127    (
128        remap = [$remap_min:expr, $remap_max:expr],
129        dups = [$($dups:pat),* $(,)*]
130    ) => (
131        mod tests {
132            extern crate test;
133            use super::{forward, backward, backward_remapped};
134
135            $crate::multi_byte_tests!(@shared dups=[$($dups),*]);
136
137            static REMAP_MIN: u16 = $remap_min;
138            static REMAP_MAX: u16 = $remap_max;
139
140            #[test]
141            fn test_correct_remapping() {
142                for i in REMAP_MIN..(REMAP_MAX+1) {
143                    let j = forward(i);
144                    if j != 0xffff {
145                        let ii = backward_remapped(j);
146                        assert!(ii != i && ii != 0xffff);
147                        let jj = forward(ii);
148                        assert_eq!(j, jj);
149                    }
150                }
151            }
152
153            #[bench]
154            fn bench_backward_remapped_sequential_128(bencher: &mut test::Bencher) {
155                let mut start: u32 = 0;
156                bencher.iter(|| {
157                    for i in start..(start + 0x80) {
158                        test::black_box(backward_remapped(i));
159                    }
160                    start += 0x80;
161                    if start >= 0x110000 { start = 0; }
162                })
163            }
164        }
165    );
166}
167
168/// Makes a common test suite for multi-byte range indices.
169#[macro_export]
170macro_rules! multi_byte_range_tests {
171    (
172        key = [$minkey:expr, $maxkey:expr], key < $keyubound:expr,
173        value = [$minvalue:expr, $maxvalue:expr], value < $valueubound:expr
174    ) => {
175        mod tests {
176            extern crate test;
177            use super::{backward, forward};
178
179            static MIN_KEY: u32 = $minkey;
180            static MAX_KEY: u32 = $maxkey;
181            static KEY_UBOUND: u32 = $keyubound;
182            static MIN_VALUE: u32 = $minvalue;
183            static MAX_VALUE: u32 = $maxvalue;
184            static VALUE_UBOUND: u32 = $valueubound;
185
186            #[test]
187            #[allow(unused_comparisons)]
188            fn test_no_failure() {
189                for i in MIN_KEY.saturating_sub(1)..(MAX_KEY + 2) {
190                    forward(i);
191                }
192                for j in MIN_VALUE.saturating_sub(1)..(MAX_VALUE + 2) {
193                    backward(j);
194                }
195            }
196
197            #[test]
198            fn test_correct_table() {
199                for i in MIN_KEY..(MAX_KEY + 2) {
200                    let j = forward(i);
201                    if j == 0xffffffff {
202                        continue;
203                    }
204                    let i_ = backward(j);
205                    if i_ == 0xffffffff {
206                        continue;
207                    }
208                    assert!(
209                        i_ == i,
210                        "backward(forward({})) = backward({}) = {} != {}",
211                        i,
212                        j,
213                        i_,
214                        i
215                    );
216                }
217            }
218
219            #[bench]
220            fn bench_forward_sequential_128(bencher: &mut test::Bencher) {
221                let mut start: u32 = 0;
222                bencher.iter(|| {
223                    for i in start..(start + 0x80) {
224                        test::black_box(forward(i));
225                    }
226                    start += 0x80;
227                    if start >= KEY_UBOUND {
228                        start = 0;
229                    }
230                })
231            }
232
233            #[bench]
234            fn bench_backward_sequential_128(bencher: &mut test::Bencher) {
235                let mut start: u32 = 0;
236                bencher.iter(|| {
237                    for i in start..(start + 0x80) {
238                        test::black_box(backward(i));
239                    }
240                    start += 0x80;
241                    if start >= VALUE_UBOUND {
242                        start = 0;
243                    }
244                })
245            }
246        }
247    };
248}