use std::collections::VecDeque;
use proc_macro2::Span;
use syn::Ident;
use super::IdentGenerator;
#[derive(Default, Clone)]
#[allow(clippy::module_name_repetitions)]
pub struct MockIdentGenerator {
idents: VecDeque<&'static str>,
calls: usize,
}
impl MockIdentGenerator {
#[must_use]
pub fn new() -> Self {
Self::default()
}
#[allow(dead_code)]
pub fn reset(&mut self) {
self.idents.clear();
self.calls = 0;
}
pub fn push_ident(&mut self, ident: &'static str) {
self.idents.push_back(ident);
}
#[allow(dead_code)]
#[must_use]
pub const fn was_called(&self) -> bool {
self.calls > 0
}
#[must_use]
pub const fn was_not_called(&self) -> bool {
self.calls == 0
}
#[allow(dead_code)]
#[must_use]
pub const fn was_called_once(&self) -> bool {
self.calls == 1
}
#[allow(dead_code)]
#[must_use]
pub const fn was_called_n_times(&self, times: usize) -> bool {
self.calls == times
}
#[must_use]
pub fn has_no_idents_remaining(&self) -> bool {
self.idents.is_empty()
}
}
impl IdentGenerator for MockIdentGenerator {
fn generate(&mut self, prefix: Option<&'static str>, span: Span) -> Ident {
let mock_str = self
.idents
.pop_front()
.expect("should have added enough mock idents for test case");
self.calls += 1;
prefix.map_or_else(
|| Ident::new(mock_str, span),
|ident| Ident::new(format!("{ident}_{mock_str}").as_str(), span),
)
}
}
#[cfg(test)]
mod test {
use proc_macro2::Span;
use syn::Ident;
use crate::ident_generator::IdentGenerator;
use super::MockIdentGenerator;
#[test]
fn ident() {
let mut mock_ident_gen = MockIdentGenerator::new();
mock_ident_gen.push_ident("mock_1");
assert_eq!(
mock_ident_gen.ident(),
Ident::new("mock_1", Span::call_site())
);
}
#[test]
fn prefixed() {
let mut mock_ident_gen = MockIdentGenerator::new();
mock_ident_gen.push_ident("mock_1");
assert_eq!(
mock_ident_gen.prefixed("prefix"),
Ident::new("prefix_mock_1", Span::call_site())
);
}
#[test]
fn spanned() {
let mut mock_ident_gen = MockIdentGenerator::new();
mock_ident_gen.push_ident("mock_1");
assert_eq!(
mock_ident_gen.spanned(Span::mixed_site()),
Ident::new("mock_1", Span::mixed_site())
);
}
#[test]
fn prefixed_spanned() {
let mut mock_ident_gen = MockIdentGenerator::new();
mock_ident_gen.push_ident("mock_1");
assert_eq!(
mock_ident_gen.generate(Some("prefix"), Span::mixed_site()),
Ident::new("prefix_mock_1", Span::mixed_site())
);
}
#[test]
#[should_panic]
fn panics() {
let mut mock_ident_gen = MockIdentGenerator::new();
let _ = mock_ident_gen.ident();
}
#[test]
fn call_count_not_called() {
let mock_ident_gen = MockIdentGenerator::new();
assert!(mock_ident_gen.was_not_called());
assert!(!mock_ident_gen.was_called());
}
#[test]
fn call_count_called() {
let mut mock_ident_gen = MockIdentGenerator::new();
mock_ident_gen.push_ident("mock_1");
let _ = mock_ident_gen.ident();
assert!(!mock_ident_gen.was_not_called());
assert!(mock_ident_gen.was_called());
}
#[test]
fn call_count_called_n_times() {
let mut mock_ident_gen = MockIdentGenerator::new();
mock_ident_gen.push_ident("mock_1");
mock_ident_gen.push_ident("mock_2");
mock_ident_gen.push_ident("mock_3");
mock_ident_gen.push_ident("mock_4");
mock_ident_gen.push_ident("mock_5");
assert!(mock_ident_gen.was_not_called());
let _ = mock_ident_gen.ident();
assert!(mock_ident_gen.was_called_once());
assert!(mock_ident_gen.was_called_n_times(1));
let _ = mock_ident_gen.ident();
assert!(mock_ident_gen.was_called_n_times(2));
let _ = mock_ident_gen.ident();
assert!(mock_ident_gen.was_called_n_times(3));
let _ = mock_ident_gen.ident();
assert!(mock_ident_gen.was_called_n_times(4));
let _ = mock_ident_gen.ident();
assert!(mock_ident_gen.was_called_n_times(5));
}
#[test]
fn has_no_idents_remaining() {
let mut mock_ident_gen = MockIdentGenerator::new();
mock_ident_gen.push_ident("mock_1");
assert!(!mock_ident_gen.has_no_idents_remaining());
let _ = mock_ident_gen.ident();
assert!(mock_ident_gen.has_no_idents_remaining());
mock_ident_gen.push_ident("mock_1");
assert!(!mock_ident_gen.has_no_idents_remaining());
let _ = mock_ident_gen.ident();
assert!(mock_ident_gen.has_no_idents_remaining());
}
}