Open marktani opened 11 months ago
I've encountered the same issue. I solved it in a hacky way by reimplementing SafeEmail.
#[cfg(test)]
mod tests {
use fake::locales::{self, Data};
use quickcheck::{Arbitrary, Gen};
#[derive(Debug, Clone)]
struct ValidEmailFixture(pub String);
impl Arbitrary for ValidEmailFixture {
fn arbitrary(g: &mut Gen) -> Self {
let username = g
.choose(locales::EN::NAME_FIRST_NAME)
.unwrap()
.to_lowercase();
let domain = g.choose(&["com", "net", "org"]).unwrap();
let email = format!("{username}@example.{domain}");
Self(email)
}
}
#[quickcheck_macros::quickcheck]
fn valid_emails_are_parsed_successfully(email: ValidEmailFixture) -> bool {
SubscriberEmail::parse(email.0).is_ok()
}
}
Not ideal but also not too bad.
Zero to Production's author, Luca Palmieri, posted an excerpt that covers OP's code above if anyone wants to follow along.
Same issue here @BurntSushi. How to use quickcheck
together with other tools like fake
which needs an RNG
I've encountered the same issue. I solved it in a hacky way by reimplementing SafeEmail.
#[cfg(test)] mod tests { use fake::locales::{self, Data}; use quickcheck::{Arbitrary, Gen}; #[derive(Debug, Clone)] struct ValidEmailFixture(pub String); impl Arbitrary for ValidEmailFixture { fn arbitrary(g: &mut Gen) -> Self { let username = g .choose(locales::EN::NAME_FIRST_NAME) .unwrap() .to_lowercase(); let domain = g.choose(&["com", "net", "org"]).unwrap(); let email = format!("{username}@example.{domain}"); Self(email) } } #[quickcheck_macros::quickcheck] fn valid_emails_are_parsed_successfully(email: ValidEmailFixture) -> bool { SubscriberEmail::parse(email.0).is_ok() } }
Not ideal but also not too bad.
Zero to Production's author, Luca Palmieri, posted an excerpt that covers OP's code above if anyone wants to follow along.
An extension for more context if you came here from the same book - This is exactly how fake is implmenting the safeEmail function.
impl<L: Data + Copy> Dummy<SafeEmail<L>> for String {
fn dummy_with_rng<R: Rng + ?Sized>(c: &SafeEmail<L>, rng: &mut R) -> Self {
let username: String = FirstName(c.0).fake_with_rng::<&str, _>(rng).to_lowercase();
let domain = ["com", "net", "org"].choose(rng).unwrap();
format!("{}@example.{}", username, domain)
}
}
For more information, there is #265 to read for why rng is no longer a dependency.
Enough Digging, Enjoy coding :3
Following the zero2production book With
quickcheck = "0.9.2"
,quickcheck_macros = "0.9.1"
andfake = "~2.3"
, the following works, because the functionArbitrary::arbitrary
expected aGen
trait, andGen
used to be a trait:Then we pass the mutable reference
g
intoSafeEmail().fake_with_rng(g);
and it works -fake
generates random valid emails.However, in
quickcheck = "1"
,quickcheck::Gen
is no trait anymore, only a struct. I haven't found out how to access the innerrng: rand::rngs::SmallRng
ofGen
to pass it intoSafeEmail().fake_with_rng
and getfake
to work withquickcheck
.How is it still possible in 1+?