-
-
Notifications
You must be signed in to change notification settings - Fork 85
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Ability to generate values with all optional members present #128
Comments
With a little fiddling, I found that I can get use fake::{Fake, Faker};
let MAGIC_NUMBER = 1u64 << 31;
let mut rng = rand::rngs::mock::StepRng::new(MAGIC_NUMBER, 0);
for _ in 0..1000 {
let foo: Option<f64> = Faker.fake_with_rng(&mut rng);
assert!(foo.is_some());
} The above comes at the cost of randomness - in the above the |
A more complete implementation of an RNG which will always be use rand::{rngs::mock::StepRng, Error, RngCore};
use rand_core::impls;
use serde::{Deserialize, Serialize};
#[derive(Debug, Deserialize, Clone, Eq, PartialEq, Serialize)]
pub struct AlwaysTrueRng {
inner: StepRng,
increment: u64,
}
impl AlwaysTrueRng {
/// Currently implemented using StepRng's `true` range.
/// See https://github.com/rust-random/rand/pull/1304
fn new(initial: u64, increment: u64) -> Self {
AlwaysTrueRng {
inner: StepRng::new(initial, increment),
increment,
}
}
}
impl Default for AlwaysTrueRng {
fn default() -> Self {
AlwaysTrueRng::new(1 << 31, (1 << 31) + 1)
}
}
impl RngCore for AlwaysTrueRng {
#[inline]
fn next_u32(&mut self) -> u32 {
self.next_u64() as u32
}
#[inline]
fn next_u64(&mut self) -> u64 {
let mut rv = self.inner.next_u64();
if rv & (1 << 31) == 0 {
self.inner = StepRng::new(rv | 1 << 31, self.increment);
rv = self.inner.next_u64();
}
rv
}
#[inline]
fn fill_bytes(&mut self, dest: &mut [u8]) {
impls::fill_bytes_via_next(self, dest);
}
#[inline]
fn try_fill_bytes(&mut self, dest: &mut [u8]) -> Result<(), Error> {
self.fill_bytes(dest);
Ok(())
}
} Now the only extra detail needed is to adjust array/Vec/etc fakers to use |
released 2.6.0, now you can use below use fake::{Dummy, Fake, Faker, Opt, Optional};
#[derive(Debug, Dummy)]
pub struct Order {
#[dummy(faker = "0..200")]
pub a: Option<u64>,
#[dummy(faker = "Opt(0..200, 100)", from = "Optional<u64>")]
pub always_some: Option<u64>,
#[dummy(expr = "Some((0..200).fake())")]
pub always_some_v2: Option<u64>,
#[dummy(faker = "Opt(0..200, 0)", from = "Optional<u64>")]
pub always_none: Option<u64>,
#[dummy(expr="None")]
pub always_none_v2: Option<u64>,
#[dummy(faker = "0..200")]
pub c: Option<Option<u64>>,
#[dummy(expr = "Opt(Opt(0..200, 50), 50).fake::<Optional<Optional<u64>>>().0.map(|v| v.0)")]
pub d: Option<Option<u64>>,
}
fn main() {
let opt: Optional<usize> = Opt(0..100, 100).fake();
println!("{:?}", opt);
let opt: Optional<Optional<usize>> = Opt(Opt(0..200, 50), 20).fake();
println!("{:?}", opt.0.map(|v| v.0));
let opt: Option<usize> = Opt(0..100, 100).fake::<Optional<usize>>().into();
println!("{:?}", opt);
let o: Order = Faker.fake();
println!("{:?}", o);
} |
Using |
Often I would like a
fake
generated object with all of the optional data fields filled in, and any arrays to have at least one item. This is useful when the objective of the test requires some deeply nested member to exist, and I dont mind the perf hit of all the other optionals also being generated. Currently I need to manually call fake for each level of the nested structure to remove anyNone
or empty arrays which may exist.I tried using a constant RNG which only returns
1
usingStepRng
, but it still usedNone
all the time, and arrays were always empty.There are also times I would like a fake object with none of the optional data fields filled in, so that may also be useful to consider this at the same time, but I find that this isnt critical, and when it is, setting a part of the data structure to
None
is easy, and self-explanatory in the code.While not the same #54 by @tujh2 seems to have similar objectives, just in my case I am looking for 100% or 0% as the ratios.
The text was updated successfully, but these errors were encountered: