How to use macro to reduce repeat test function?

pub struct Usage {
    value: [f64; 10],
    pos: usize,
}

impl Usage {
    pub fn new() -> Self {
        Usage {
            value: [0.0; 10],
            pos: 0,
        }
    }

    pub fn update(&mut self, f: f64) {
        self.value[self.pos] = f
    }

    pub fn signal1(&self) -> f64 {
        self.value[..2].iter().sum()
    }

    pub fn signal2(&self) -> f64 {
        self.value[4..6].iter().sum()
    }

    pub fn signal3(&self) -> f64 {
        self.value[5..9].iter().sum()
    }
}


fn get_value() -> [f64; 10] {
    [0.0, 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0]
}


fn get_signal(filename: &'static str) -> Vec<f64> {
    // read value for txt
    // here just for an example
    vec![0.0, 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0]
}


#[cfg(test)]
mod test {
    use crate::{get_signal, get_value, Usage};

    #[test]
    fn test_all() {
        // i had to write many function. but all of them repreat same logic
        // #[test]
        // fn signalx() {
        //     let val = get_value();
        //     let usgae = Usage::new(val);
        //    let start = n;
        //    let end = m;
        //     assert_eq!(usgae.signalx()[start..end], get_signal("signalx").as_slice()[start..end])
        // }
        // help me !!!
        // Is there a way to simplify this logic
        // for examples
        // signal_test!("signal1", 1, 3)

        // run cargo test will output
        // ```
        // test tests::signal1 ... ok
        // test tests::signal1 ... false
        // ```
    }

    #[test]
    fn signal1() {
        let val = get_value();
        let mut usgae = Usage::new();

        let mut signals = vec![];
        for v in val {
            usgae.update(v);
            signals.push(usgae.signal1())
        }
        let start = 0;
        let end = 9;
        assert_eq!(signals[start..end], get_signal("signal1")[start..end])
    }


    #[test]
    fn signal2() {
        let val = get_value();
        let mut usgae = Usage::new();

        let mut signals = vec![];
        for v in val {
            usgae.update(v);
            signals.push(usgae.signal2())
        }
        let start = 0;
        let end = 9;
        assert_eq!(signals[start..end], get_signal("signal2")[start..end])
    }

    #[test]
    fn signal3() {
        let val = get_value();
        let mut usgae = Usage::new();

        let mut signals = vec![];
        for v in val {
            usgae.update(v);
            signals.push(usgae.signal3())
        }
        let start = 0;
        let end = 9;
        assert_eq!(signals[start..end], get_signal("signal3")[start..end])
    }
}

can i use macro to reduce the test function? they all have the same logic

I'm still at an idiot level with macro programming

You don't need a macro for this, you could just write a plain old function and pass the range as an argument to it.

but i want to get this output

Nothing prevents you from calling that function from 3 different (trivial) #[test] functions. (Also, you can just include the signal/test name in the assertion message.)

Yeah, I seem to be too rigid

signals.push(usage.signal(range.clone()));

but here we need to call signal1, signal2 ... signal n? '

signal will contains different calculate logic, the self.value[3..6].iter().sum() is just an example. sorry for that

Then just pass the functions themselves instead of the range.

thanks

Skimming over the example this sound like something where the test_case library might help.

sound good, i will take a look.

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.