way-lib-rust 0.0.3

foundation for all Ampliway services
Documentation
pub trait V1 {
    fn make(&self) -> String;

    fn is_valid(&self, value: String) -> bool;
}

#[cfg(test)]
mod tests {
    use super::V1;
    use crate::id::v1::id::ID;
    use crate::id::v1::mock::Mock;
    use rand::distributions::Alphanumeric;
    use rand::thread_rng;
    use rand::Rng;
    use std::panic;
    use std::sync::Arc;
    use std::thread;

    #[test]
    fn make_success() {
        let total_interactions = 100;

        let mock_module = Mock::new();

        for _ in 1..total_interactions {
            let random_id: String = thread_rng()
                .sample_iter(&Alphanumeric)
                .take(26)
                .map(char::from)
                .collect();

            mock_module.expected_make(random_id);
        }

        let modules: Vec<Arc<dyn V1 + Sync + Send>> =
            vec![Arc::new(ID::new()), Arc::new(mock_module)];

        for module in modules {
            let threads: Vec<_> = (1..total_interactions)
                .map(|_| {
                    let module_internal = module.clone();

                    thread::spawn(move || {
                        let value = module_internal.make();

                        assert!(value.len() == 26, "value '{}' must have 26 chars", value);

                        for char in value.chars() {
                            assert!(
                                !char.is_whitespace(),
                                "value '{}' can't have blank spaces",
                                value
                            );
                            assert!(
                                char.is_lowercase() || char.is_numeric(),
                                "value '{}' must be lower case or numeric",
                                value
                            );
                            assert!(
                                char.is_ascii_alphanumeric(),
                                "value '{}' must be a alphabet letter",
                                value
                            );
                        }
                    })
                })
                .collect();

            for handle in threads {
                handle.join().unwrap();
            }
        }
    }

    #[test]
    fn is_valid_true() {
        let total_interactions = 100;

        let mock_module = Mock::new();

        for _ in 1..total_interactions {
            let random_id: String = thread_rng()
                .sample_iter(&Alphanumeric)
                .take(26)
                .map(char::from)
                .collect();

            mock_module.expected_make(random_id);
        }

        let modules: Vec<Arc<dyn V1 + Sync + Send>> =
            vec![Arc::new(ID::new()), Arc::new(mock_module)];

        for module in modules {
            let threads: Vec<_> = (1..total_interactions)
                .map(|_| {
                    let module_internal = module.clone();

                    thread::spawn(move || {
                        let value = module_internal.make();

                        assert!(module_internal.is_valid(value));
                    })
                })
                .collect();

            for handle in threads {
                handle.join().unwrap();
            }
        }
    }

    #[test]
    fn is_valid_false() {
        let mut values: Vec<String> = vec![];

        for count in 0..100 {
            if count == 26 {
                continue;
            }

            let random_id: String = thread_rng()
                .sample_iter(&Alphanumeric)
                .take(count)
                .map(char::from)
                .collect();

            values.push(random_id.to_lowercase());
        }

        let modules: Vec<Arc<dyn V1 + Sync + Send>> =
            vec![Arc::new(ID::new()), Arc::new(Mock::new())];

        for module in modules {
            let threads: Vec<_> = values
                .to_vec()
                .into_iter()
                .map(|value| {
                    let module_internal = module.clone();

                    thread::spawn(move || {
                        assert!(module_internal.is_valid(value.to_string()) == false);
                    })
                })
                .collect();

            for handle in threads {
                handle.join().unwrap();
            }
        }
    }

    #[test]
    fn make_mock_panic_initialize() {
        let random_id: String = thread_rng()
            .sample_iter(&Alphanumeric)
            .take(26)
            .map(char::from)
            .collect();

        let random_id = random_id.to_lowercase();

        assert_eq!(
        panic::catch_unwind(|| {
            let mock_module = Mock::new_options(random_id.clone());

            mock_module.make();
        }).err().and_then(move |a| a.downcast_ref::<String>().map(|s| {
            s == &format!("no values were found for this mock instance ({}), you did'nt initialize the mock correctly, to do so use the 'new' function as shown below: Mock::new()", random_id.clone())
        })),
        Some(true));
    }

    #[test]
    fn make_mock_panic_no_values() {
        let random_id: String = thread_rng()
            .sample_iter(&Alphanumeric)
            .take(26)
            .map(char::from)
            .collect();

        let random_id = random_id.to_lowercase();

        assert_eq!(
        panic::catch_unwind(|| {
            let mock_module = Mock::new_options(random_id.clone());

            mock_module.expected_make("value_a".to_string());

            mock_module.make();
            mock_module.make();
        }).err().and_then(move |a| a.downcast_ref::<String>().map(|s| {
            s == &format!("no value found for the requested mock instance ({}), you must set the value expected by the mock using the 'expected_make' function as shown below: mock_instance.expected_make(\"my_value\".to_string())", random_id.clone())
        })),
        Some(true));
    }
}