Skip to content

Commit dbb1ded

Browse files
committed
Refactor unit tests
1 parent e8fcbcf commit dbb1ded

File tree

5 files changed

+158
-75
lines changed

5 files changed

+158
-75
lines changed

src/aarch64.rs

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -285,3 +285,20 @@ impl<N: Needle> Searcher<N> for NeonSearcher<N> {
285285
self.position
286286
}
287287
}
288+
289+
#[cfg(test)]
290+
mod tests {
291+
use super::NeonSearcher;
292+
293+
impl crate::tests::TestSearcher for NeonSearcher<&[u8]> {
294+
fn with_position(needle: &'static [u8], position: usize) -> NeonSearcher<&[u8]> {
295+
unsafe { NeonSearcher::with_position(needle, position) }
296+
}
297+
298+
fn search_in(&self, haystack: &[u8]) -> bool {
299+
unsafe { NeonSearcher::search_in(self, haystack) }
300+
}
301+
}
302+
303+
crate::generate_tests!(neon_searcher, NeonSearcher);
304+
}

src/lib.rs

Lines changed: 83 additions & 75 deletions
Original file line numberDiff line numberDiff line change
@@ -360,174 +360,182 @@ mod tests {
360360
assert_eq!(<&[u8] as Needle>::SIZE, None);
361361
}
362362

363-
fn search(haystack: &[u8], needle: &[u8]) -> bool {
363+
pub(crate) trait TestSearcher {
364+
fn with_position(needle: &'static [u8], position: usize) -> Self;
365+
fn search_in(&self, haystack: &[u8]) -> bool;
366+
}
367+
368+
fn search<S: TestSearcher>(haystack: &[u8], needle: &'static [u8]) -> bool {
364369
let result = haystack
365370
.windows(needle.len())
366371
.any(|window| window == needle);
367372

368373
for position in 0..needle.len() {
369-
cfg_if::cfg_if! {
370-
if #[cfg(any(target_arch = "x86", target_arch = "x86_64"))] {
371-
use crate::x86::{Avx2Searcher, DynamicAvx2Searcher};
372-
373-
let searcher = unsafe { Avx2Searcher::with_position(needle, position) };
374-
assert_eq!(unsafe { searcher.search_in(haystack) }, result);
375-
376-
let searcher = unsafe { DynamicAvx2Searcher::with_position(needle, position) };
377-
assert_eq!(unsafe { searcher.search_in(haystack) }, result);
378-
} else if #[cfg(target_arch = "wasm32")] {
379-
use crate::wasm32::Wasm32Searcher;
380-
381-
let searcher = unsafe { Wasm32Searcher::with_position(needle, position) };
382-
assert_eq!(unsafe { searcher.search_in(haystack) }, result);
383-
} else if #[cfg(target_arch = "aarch64")] {
384-
use crate::aarch64::NeonSearcher;
385-
386-
let searcher = unsafe { NeonSearcher::with_position(needle, position) };
387-
assert_eq!(unsafe { searcher.search_in(haystack) }, result);
388-
} else if #[cfg(not(feature = "stdsimd"))] {
389-
compile_error!("Unsupported architecture");
374+
let searcher = S::with_position(needle, position);
375+
assert_eq!(searcher.search_in(haystack), result);
376+
}
377+
378+
result
379+
}
380+
381+
#[macro_export]
382+
macro_rules! generate_tests {
383+
($mod: ident, $name:ident) => {
384+
mod $mod {
385+
use super::$name;
386+
387+
#[test]
388+
fn test_search_same() {
389+
$crate::tests::search_same::<$name<&[u8]>>();
390390
}
391-
}
392391

393-
cfg_if::cfg_if! {
394-
if #[cfg(feature = "stdsimd")] {
395-
use crate::stdsimd::StdSimdSearcher;
392+
#[test]
393+
fn test_search_different() {
394+
$crate::tests::search_different::<$name<&[u8]>>();
395+
}
396396

397-
let searcher = StdSimdSearcher::with_position(needle, position);
398-
assert_eq!(searcher.search_in(haystack), result);
397+
#[test]
398+
fn test_search_prefix() {
399+
$crate::tests::search_prefix::<$name<&[u8]>>();
399400
}
400-
}
401-
}
402401

403-
result
402+
#[test]
403+
fn test_search_suffix() {
404+
$crate::tests::search_suffix::<$name<&[u8]>>();
405+
}
406+
407+
#[test]
408+
fn test_search_multiple() {
409+
$crate::tests::search_multiple::<$name<&[u8]>>();
410+
}
411+
412+
#[test]
413+
fn test_search_middle() {
414+
$crate::tests::search_middle::<$name<&[u8]>>();
415+
}
416+
}
417+
};
404418
}
405419

406-
#[test]
407-
fn search_same() {
408-
assert!(search(b"x", b"x"));
420+
pub(crate) fn search_same<S: TestSearcher>() {
421+
assert!(search::<S>(b"x", b"x"));
409422

410-
assert!(search(b"xy", b"xy"));
423+
assert!(search::<S>(b"xy", b"xy"));
411424

412-
assert!(search(b"foo", b"foo"));
425+
assert!(search::<S>(b"foo", b"foo"));
413426

414-
assert!(search(
427+
assert!(search::<S>(
415428
b"Lorem ipsum dolor sit amet, consectetur adipiscing elit",
416429
b"Lorem ipsum dolor sit amet, consectetur adipiscing elit"
417430
));
418431

419-
assert!(search(
432+
assert!(search::<S>(
420433
b"Lorem ipsum dolor sit amet, consectetur adipiscing elit. Maecenas commodo posuere orci a consectetur. Ut mattis turpis ut auctor consequat. Aliquam iaculis fringilla mi, nec aliquet purus",
421434
b"Lorem ipsum dolor sit amet, consectetur adipiscing elit. Maecenas commodo posuere orci a consectetur. Ut mattis turpis ut auctor consequat. Aliquam iaculis fringilla mi, nec aliquet purus"
422435
));
423436
}
424437

425-
#[test]
426-
fn search_different() {
427-
assert!(!search(b"x", b"y"));
438+
pub(crate) fn search_different<S: TestSearcher>() {
439+
assert!(!search::<S>(b"x", b"y"));
428440

429-
assert!(!search(b"xy", b"xz"));
441+
assert!(!search::<S>(b"xy", b"xz"));
430442

431-
assert!(!search(b"bar", b"foo"));
443+
assert!(!search::<S>(b"bar", b"foo"));
432444

433-
assert!(!search(
445+
assert!(!search::<S>(
434446
b"Lorem ipsum dolor sit amet, consectetur adipiscing elit",
435447
b"foo"
436448
));
437449

438-
assert!(!search(
450+
assert!(!search::<S>(
439451
b"Lorem ipsum dolor sit amet, consectetur adipiscing elit. Maecenas commodo posuere orci a consectetur. Ut mattis turpis ut auctor consequat. Aliquam iaculis fringilla mi, nec aliquet purus",
440452
b"foo"
441453
));
442454

443-
assert!(!search(
455+
assert!(!search::<S>(
444456
b"Lorem ipsum dolor sit amet, consectetur adipiscing elit. Maecenas commodo posuere orci a consectetur. Ut mattis turpis ut auctor consequat. Aliquam iaculis fringilla mi, nec aliquet purus",
445457
b"foo bar baz qux quux quuz corge grault garply waldo fred plugh xyzzy thud"
446458
));
447459
}
448460

449-
#[test]
450-
fn search_prefix() {
451-
assert!(search(b"xy", b"x"));
461+
pub(crate) fn search_prefix<S: TestSearcher>() {
462+
assert!(search::<S>(b"xy", b"x"));
452463

453-
assert!(search(b"foobar", b"foo"));
464+
assert!(search::<S>(b"foobar", b"foo"));
454465

455-
assert!(search(
466+
assert!(search::<S>(
456467
b"Lorem ipsum dolor sit amet, consectetur adipiscing elit",
457468
b"Lorem"
458469
));
459470

460-
assert!(search(
471+
assert!(search::<S>(
461472
b"Lorem ipsum dolor sit amet, consectetur adipiscing elit. Maecenas commodo posuere orci a consectetur. Ut mattis turpis ut auctor consequat. Aliquam iaculis fringilla mi, nec aliquet purus",
462473
b"Lorem"
463474
));
464475

465-
assert!(search(
476+
assert!(search::<S>(
466477
b"Lorem ipsum dolor sit amet, consectetur adipiscing elit. Maecenas commodo posuere orci a consectetur. Ut mattis turpis ut auctor consequat. Aliquam iaculis fringilla mi, nec aliquet purus",
467478
b"Lorem ipsum dolor sit amet, consectetur adipiscing elit"
468479
));
469480
}
470481

471-
#[test]
472-
fn search_suffix() {
473-
assert!(search(b"xy", b"y"));
482+
pub(crate) fn search_suffix<S: TestSearcher>() {
483+
assert!(search::<S>(b"xy", b"y"));
474484

475-
assert!(search(b"foobar", b"bar"));
485+
assert!(search::<S>(b"foobar", b"bar"));
476486

477-
assert!(search(
487+
assert!(search::<S>(
478488
b"Lorem ipsum dolor sit amet, consectetur adipiscing elit",
479489
b"elit"
480490
));
481491

482-
assert!(search(
492+
assert!(search::<S>(
483493
b"Lorem ipsum dolor sit amet, consectetur adipiscing elit. Maecenas commodo posuere orci a consectetur. Ut mattis turpis ut auctor consequat. Aliquam iaculis fringilla mi, nec aliquet purus",
484494
b"purus"
485495
));
486496

487-
assert!(search(
497+
assert!(search::<S>(
488498
b"Lorem ipsum dolor sit amet, consectetur adipiscing elit. Maecenas commodo posuere orci a consectetur. Ut mattis turpis ut auctor consequat. Aliquam iaculis fringilla mi, nec aliquet purus",
489499
b"Aliquam iaculis fringilla mi, nec aliquet purus"
490500
));
491501
}
492502

493-
#[test]
494-
fn search_multiple() {
495-
assert!(search(b"xx", b"x"));
503+
pub(crate) fn search_multiple<S: TestSearcher>() {
504+
assert!(search::<S>(b"xx", b"x"));
496505

497-
assert!(search(b"xyxy", b"xy"));
506+
assert!(search::<S>(b"xyxy", b"xy"));
498507

499-
assert!(search(b"foobarfoo", b"foo"));
508+
assert!(search::<S>(b"foobarfoo", b"foo"));
500509

501-
assert!(search(
510+
assert!(search::<S>(
502511
b"Lorem ipsum dolor sit amet, consectetur adipiscing elit",
503512
b"it"
504513
));
505514

506-
assert!(search(
515+
assert!(search::<S>(
507516
b"Lorem ipsum dolor sit amet, consectetur adipiscing elit. Maecenas commodo posuere orci a consectetur. Ut mattis turpis ut auctor consequat. Aliquam iaculis fringilla mi, nec aliquet purus",
508517
b"conse"
509518
));
510519
}
511520

512-
#[test]
513-
fn search_middle() {
514-
assert!(search(b"xyz", b"y"));
521+
pub(crate) fn search_middle<S: TestSearcher>() {
522+
assert!(search::<S>(b"xyz", b"y"));
515523

516-
assert!(search(b"wxyz", b"xy"));
524+
assert!(search::<S>(b"wxyz", b"xy"));
517525

518-
assert!(search(b"foobarfoo", b"bar"));
526+
assert!(search::<S>(b"foobarfoo", b"bar"));
519527

520-
assert!(search(
528+
assert!(search::<S>(
521529
b"Lorem ipsum dolor sit amet, consectetur adipiscing elit",
522530
b"consectetur"
523531
));
524532

525-
assert!(search(
533+
assert!(search::<S>(
526534
b"Lorem ipsum dolor sit amet, consectetur adipiscing elit. Maecenas commodo posuere orci a consectetur. Ut mattis turpis ut auctor consequat. Aliquam iaculis fringilla mi, nec aliquet purus",
527535
b"orci"
528536
));
529537

530-
assert!(search(
538+
assert!(search::<S>(
531539
b"Lorem ipsum dolor sit amet, consectetur adipiscing elit. Maecenas commodo posuere orci a consectetur. Ut mattis turpis ut auctor consequat. Aliquam iaculis fringilla mi, nec aliquet purus",
532540
b"Maecenas commodo posuere orci a consectetur"
533541
));

src/stdsimd.rs

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -167,3 +167,20 @@ impl<N: Needle> StdSimdSearcher<N> {
167167
self.inlined_search_in(haystack)
168168
}
169169
}
170+
171+
#[cfg(test)]
172+
mod tests {
173+
use super::StdSimdSearcher;
174+
175+
impl crate::tests::TestSearcher for StdSimdSearcher<&[u8]> {
176+
fn with_position(needle: &'static [u8], position: usize) -> StdSimdSearcher<&[u8]> {
177+
StdSimdSearcher::with_position(needle, position)
178+
}
179+
180+
fn search_in(&self, haystack: &[u8]) -> bool {
181+
StdSimdSearcher::search_in(self, haystack)
182+
}
183+
}
184+
185+
crate::generate_tests!(std_simd_searcher, StdSimdSearcher);
186+
}

src/wasm32.rs

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -270,3 +270,20 @@ impl<N: Needle> Wasm32Searcher<N> {
270270
self.inlined_search_in(haystack)
271271
}
272272
}
273+
274+
#[cfg(test)]
275+
mod tests {
276+
use super::Wasm32Searcher;
277+
278+
impl crate::tests::TestSearcher for Wasm32Searcher<&[u8]> {
279+
fn with_position(needle: &'static [u8], position: usize) -> Wasm32Searcher<&[u8]> {
280+
unsafe { Wasm32Searcher::with_position(needle, position) }
281+
}
282+
283+
fn search_in(&self, haystack: &[u8]) -> bool {
284+
unsafe { Wasm32Searcher::search_in(self, haystack) }
285+
}
286+
}
287+
288+
crate::generate_tests!(wasm32_searcher, Wasm32Searcher);
289+
}

src/x86.rs

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -583,4 +583,28 @@ mod tests {
583583
assert_eq!(size_of::<DynamicAvx2Searcher::<[u8; 16]>>(), 160);
584584
assert_eq!(size_of::<DynamicAvx2Searcher::<Box<[u8]>>>(), 160);
585585
}
586+
587+
impl crate::tests::TestSearcher for Avx2Searcher<&[u8]> {
588+
fn with_position(needle: &'static [u8], position: usize) -> Avx2Searcher<&[u8]> {
589+
unsafe { Avx2Searcher::with_position(needle, position) }
590+
}
591+
592+
fn search_in(&self, haystack: &[u8]) -> bool {
593+
unsafe { Avx2Searcher::search_in(self, haystack) }
594+
}
595+
}
596+
597+
crate::generate_tests!(avx2_searcher, Avx2Searcher);
598+
599+
impl crate::tests::TestSearcher for DynamicAvx2Searcher<&[u8]> {
600+
fn with_position(needle: &'static [u8], position: usize) -> DynamicAvx2Searcher<&[u8]> {
601+
unsafe { DynamicAvx2Searcher::with_position(needle, position) }
602+
}
603+
604+
fn search_in(&self, haystack: &[u8]) -> bool {
605+
unsafe { DynamicAvx2Searcher::search_in(self, haystack) }
606+
}
607+
}
608+
609+
crate::generate_tests!(dynamic_avx2_searcher, DynamicAvx2Searcher);
586610
}

0 commit comments

Comments
 (0)