Skip to main content

wae_testing/
fixture.rs

1//! 测试数据生成器模块
2
3use crate::error::{TestingError, TestingResult};
4use rand::{RngExt, distr::Alphanumeric, prelude::IndexedRandom};
5
6/// Fixture trait - 测试数据接口
7pub trait Fixture: Sized {
8    /// 生成测试数据
9    fn generate() -> TestingResult<Self>;
10}
11
12/// Fixture 构建器 trait
13pub trait FixtureBuilder<T>: Sized {
14    /// 构建测试数据
15    fn build(self) -> TestingResult<T>;
16}
17
18/// 随机字符串生成器
19#[derive(Debug, Clone)]
20pub struct RandomString {
21    /// 字符串长度
22    pub length: usize,
23    /// 可选前缀
24    pub prefix: Option<String>,
25    /// 可选后缀
26    pub suffix: Option<String>,
27}
28
29impl Default for RandomString {
30    fn default() -> Self {
31        Self { length: 10, prefix: None, suffix: None }
32    }
33}
34
35impl RandomString {
36    /// 创建新的随机字符串生成器
37    pub fn new() -> Self {
38        Self::default()
39    }
40
41    /// 设置字符串长度
42    pub fn length(mut self, len: usize) -> Self {
43        self.length = len;
44        self
45    }
46
47    /// 设置前缀
48    pub fn prefix(mut self, prefix: impl Into<String>) -> Self {
49        self.prefix = Some(prefix.into());
50        self
51    }
52
53    /// 设置后缀
54    pub fn suffix(mut self, suffix: impl Into<String>) -> Self {
55        self.suffix = Some(suffix.into());
56        self
57    }
58
59    /// 生成随机字符串
60    pub fn generate(&self) -> TestingResult<String> {
61        let mut rng = rand::rng();
62        let random_part: String = (0..self.length).map(|_| rng.sample(Alphanumeric) as char).collect();
63
64        let mut result = String::new();
65        if let Some(ref prefix) = self.prefix {
66            result.push_str(prefix);
67        }
68        result.push_str(&random_part);
69        if let Some(ref suffix) = self.suffix {
70            result.push_str(suffix);
71        }
72
73        Ok(result)
74    }
75}
76
77impl Fixture for String {
78    fn generate() -> TestingResult<Self> {
79        RandomString::new().generate()
80    }
81}
82
83/// 随机数字生成器
84#[derive(Debug, Clone)]
85pub struct RandomNumber<T> {
86    /// 最小值
87    pub min: T,
88    /// 最大值
89    pub max: T,
90    _marker: std::marker::PhantomData<T>,
91}
92
93impl<T> RandomNumber<T> {
94    /// 创建新的随机数字生成器
95    pub fn new(min: T, max: T) -> Self {
96        Self { min, max, _marker: std::marker::PhantomData }
97    }
98}
99
100impl RandomNumber<i32> {
101    /// 生成随机 i32
102    pub fn generate(&self) -> TestingResult<i32> {
103        let mut rng = rand::rng();
104        Ok(rng.random_range(self.min..=self.max))
105    }
106}
107
108impl RandomNumber<i64> {
109    /// 生成随机 i64
110    pub fn generate(&self) -> TestingResult<i64> {
111        let mut rng = rand::rng();
112        Ok(rng.random_range(self.min..=self.max))
113    }
114}
115
116impl RandomNumber<u32> {
117    /// 生成随机 u32
118    pub fn generate(&self) -> TestingResult<u32> {
119        let mut rng = rand::rng();
120        Ok(rng.random_range(self.min..=self.max))
121    }
122}
123
124impl RandomNumber<u64> {
125    /// 生成随机 u64
126    pub fn generate(&self) -> TestingResult<u64> {
127        let mut rng = rand::rng();
128        Ok(rng.random_range(self.min..=self.max))
129    }
130}
131
132impl RandomNumber<f64> {
133    /// 生成随机 f64
134    pub fn generate(&self) -> TestingResult<f64> {
135        let mut rng = rand::rng();
136        Ok(rng.random_range(self.min..=self.max))
137    }
138}
139
140impl Fixture for i32 {
141    fn generate() -> TestingResult<Self> {
142        let generator: RandomNumber<i32> = RandomNumber::new(0, 1000000);
143        generator.generate()
144    }
145}
146
147impl Fixture for u64 {
148    fn generate() -> TestingResult<Self> {
149        RandomNumber::new(0u64, 1000000u64).generate()
150    }
151}
152
153/// 随机邮箱生成器
154#[derive(Debug, Clone)]
155pub struct RandomEmail {
156    /// 邮箱域名
157    pub domain: String,
158}
159
160impl Default for RandomEmail {
161    fn default() -> Self {
162        Self { domain: "test.example.com".to_string() }
163    }
164}
165
166impl RandomEmail {
167    /// 创建新的随机邮箱生成器
168    pub fn new() -> Self {
169        Self::default()
170    }
171
172    /// 设置域名
173    pub fn domain(mut self, domain: impl Into<String>) -> Self {
174        self.domain = domain.into();
175        self
176    }
177
178    /// 生成随机邮箱
179    pub fn generate(&self) -> TestingResult<String> {
180        let username = RandomString::new().length(8).generate()?;
181        Ok(format!("{}@{}", username, self.domain))
182    }
183}
184
185/// 随机 UUID 生成器
186#[derive(Debug, Clone, Default)]
187pub struct RandomUuid {
188    /// 是否使用 v4 版本
189    pub version4: bool,
190}
191
192impl RandomUuid {
193    /// 创建新的随机 UUID 生成器
194    pub fn new() -> Self {
195        Self { version4: true }
196    }
197
198    /// 使用 v7 版本
199    pub fn version7(mut self) -> Self {
200        self.version4 = false;
201        self
202    }
203
204    /// 生成随机 UUID
205    pub fn generate(&self) -> TestingResult<uuid::Uuid> {
206        if self.version4 { Ok(uuid::Uuid::new_v4()) } else { Ok(uuid::Uuid::now_v7()) }
207    }
208
209    /// 生成 UUID 字符串
210    pub fn generate_string(&self) -> TestingResult<String> {
211        Ok(self.generate()?.to_string())
212    }
213}
214
215impl Fixture for uuid::Uuid {
216    fn generate() -> TestingResult<Self> {
217        RandomUuid::new().generate()
218    }
219}
220
221/// 随机布尔值生成器
222#[derive(Debug, Clone, Default)]
223pub struct RandomBool {
224    /// 为 true 的概率 (0.0 - 1.0)
225    pub true_probability: f64,
226}
227
228impl RandomBool {
229    /// 创建新的随机布尔值生成器
230    pub fn new() -> Self {
231        Self { true_probability: 0.5 }
232    }
233
234    /// 设置 true 的概率
235    pub fn probability(mut self, prob: f64) -> Self {
236        self.true_probability = prob.clamp(0.0, 1.0);
237        self
238    }
239
240    /// 生成随机布尔值
241    pub fn generate(&self) -> TestingResult<bool> {
242        let mut rng = rand::rng();
243        Ok(rng.random_bool(self.true_probability))
244    }
245}
246
247impl Fixture for bool {
248    fn generate() -> TestingResult<Self> {
249        RandomBool::new().generate()
250    }
251}
252
253/// 随机选择器 - 从列表中随机选择
254#[derive(Debug, Clone)]
255pub struct RandomChoice<T> {
256    /// 可选项列表
257    pub items: Vec<T>,
258}
259
260impl<T: Clone> RandomChoice<T> {
261    /// 创建新的随机选择器
262    pub fn new(items: Vec<T>) -> Self {
263        Self { items }
264    }
265
266    /// 生成随机选择
267    pub fn generate(&self) -> TestingResult<T> {
268        let mut rng = rand::rng();
269        self.items.choose(&mut rng).cloned().ok_or_else(|| TestingError::FixtureError("No items to choose from".to_string()))
270    }
271}
272
273/// 随机日期时间生成器
274#[derive(Debug, Clone)]
275pub struct RandomDateTime {
276    /// 开始时间戳 (秒)
277    pub start_timestamp: i64,
278    /// 结束时间戳 (秒)
279    pub end_timestamp: i64,
280}
281
282impl Default for RandomDateTime {
283    fn default() -> Self {
284        Self { start_timestamp: 0, end_timestamp: 4102444800 }
285    }
286}
287
288impl RandomDateTime {
289    /// 创建新的随机日期时间生成器
290    pub fn new() -> Self {
291        Self::default()
292    }
293
294    /// 设置时间范围
295    pub fn range(mut self, start: i64, end: i64) -> Self {
296        self.start_timestamp = start;
297        self.end_timestamp = end;
298        self
299    }
300
301    /// 生成随机时间戳
302    pub fn generate_timestamp(&self) -> TestingResult<i64> {
303        let mut rng = rand::rng();
304        Ok(rng.random_range(self.start_timestamp..=self.end_timestamp))
305    }
306}
307
308/// 批量数据生成器
309pub struct FixtureGenerator;
310
311impl FixtureGenerator {
312    /// 生成指定数量的随机字符串
313    pub fn strings(count: usize, length: usize) -> TestingResult<Vec<String>> {
314        (0..count).map(|_| RandomString::new().length(length).generate()).collect()
315    }
316
317    /// 生成指定数量的随机邮箱
318    pub fn emails(count: usize, domain: &str) -> TestingResult<Vec<String>> {
319        (0..count).map(|_| RandomEmail::new().domain(domain).generate()).collect()
320    }
321
322    /// 生成指定数量的随机 UUID
323    pub fn uuids(count: usize) -> TestingResult<Vec<uuid::Uuid>> {
324        (0..count).map(|_| RandomUuid::new().generate()).collect()
325    }
326
327    /// 生成指定数量的随机 i32 数字
328    pub fn i32_numbers(count: usize, min: i32, max: i32) -> TestingResult<Vec<i32>> {
329        let mut rng = rand::rng();
330        (0..count).map(|_| Ok(rng.random_range(min..=max))).collect()
331    }
332
333    /// 生成指定数量的随机 u64 数字
334    pub fn u64_numbers(count: usize, min: u64, max: u64) -> TestingResult<Vec<u64>> {
335        let mut rng = rand::rng();
336        (0..count).map(|_| Ok(rng.random_range(min..=max))).collect()
337    }
338}