From d913e19883343af54cd4a46109ce7de3e2f08a54 Mon Sep 17 00:00:00 2001 From: Paul Spooren Date: Mon, 19 Aug 2024 14:50:01 +0200 Subject: [PATCH] test: add tests for controlflow While at it, fix the label handling and fix a typo in continue_if, where a `break` falsely replaced a `continue` Signed-off-by: Paul Spooren --- util/src/controlflow.rs | 91 +++++++++++++++++++++++++++++++++++++++-- 1 file changed, 88 insertions(+), 3 deletions(-) diff --git a/util/src/controlflow.rs b/util/src/controlflow.rs index 211a032..fa372b1 100644 --- a/util/src/controlflow.rs +++ b/util/src/controlflow.rs @@ -1,4 +1,7 @@ +/// A collection of control flow utility macros + #[macro_export] +/// A simple for loop to repeat a $body a number of times macro_rules! repeat { ($times:expr, $body:expr) => { for _ in 0..($times) { @@ -8,6 +11,7 @@ macro_rules! repeat { } #[macro_export] +/// Return unless the condition $cond is true, with return value $val, if given. macro_rules! return_unless { ($cond:expr) => { if !($cond) { @@ -22,6 +26,7 @@ macro_rules! return_unless { } #[macro_export] +/// Return if the condition $cond is true, with return value $val, if given. macro_rules! return_if { ($cond:expr) => { if $cond { @@ -36,13 +41,14 @@ macro_rules! return_if { } #[macro_export] +/// Break unless the condition is true, from the loop with label $val, if given. macro_rules! break_if { ($cond:expr) => { if $cond { break; } }; - ($cond:expr, $val:expr) => { + ($cond:expr, $val:tt) => { if $cond { break $val; } @@ -50,15 +56,94 @@ macro_rules! break_if { } #[macro_export] +/// Continue if the condition is true, in the loop with label $val, if given. macro_rules! continue_if { ($cond:expr) => { if $cond { continue; } }; - ($cond:expr, $val:expr) => { + ($cond:expr, $val:tt) => { if $cond { - break $val; + continue $val; } }; } + +#[cfg(test)] +mod tests { + #[test] + fn test_repeat() { + let mut sum = 0; + repeat!(10, { + sum += 1; + }); + assert_eq!(sum, 10); + } + + #[test] + fn test_return_unless() { + fn test_fn() -> i32 { + return_unless!(true, 1); + 0 + } + assert_eq!(test_fn(), 0); + + fn test_fn2() -> i32 { + return_unless!(false, 1); + 0 + } + assert_eq!(test_fn2(), 1); + } + + #[test] + fn test_return_if() { + fn test_fn() -> i32 { + return_if!(true, 1); + 0 + } + assert_eq!(test_fn(), 1); + + fn test_fn2() -> i32 { + return_if!(false, 1); + 0 + } + assert_eq!(test_fn2(), 0); + } + + #[test] + fn test_break_if() { + let mut sum = 0; + for i in 0..10 { + break_if!(i == 5); + sum += 1; + } + assert_eq!(sum, 5); + + let mut sum = 0; + 'one: for _ in 0..10 { + for j in 0..20 { + break_if!(j == 5, 'one); + sum += 1; + } + } + assert_eq!(sum, 5); + } + + #[test] + fn test_continue_if() { + let mut sum = 0; + for i in 0..10 { + continue_if!(i == 5); + sum += 1; + } + assert_eq!(sum, 9); + + let mut sum = 0; + 'one: for i in 0..10 { + continue_if!(i == 5, 'one); + sum += 1; + } + assert_eq!(sum, 9); + } +}