revolt_database/util/
test_fixtures.rs1use std::collections::HashMap;
2
3use once_cell::sync::Lazy;
4use regex::{Captures, Regex};
5use serde_json::from_str;
6
7use crate::{Channel, Database, Member, Server, User};
8
9static RE_ID: Lazy<Regex> = Lazy::new(|| Regex::new("__ID:(\\d+)__").unwrap());
10
11#[derive(Debug, Deserialize)]
12#[serde(tag = "_object_type")]
13enum LoadedFixture {
14 User(User),
15 Channel(Channel),
16 Server(Server),
17 ServerMember(Member),
18}
19
20pub async fn load_fixture(db: &Database, input: &str) -> HashMap<String, String> {
21 let mut ids = HashMap::<String, String>::new();
22 let input = RE_ID.replace_all(input, |cap: &Captures| {
23 let d = cap.get(1).unwrap().as_str();
24
25 if !ids.contains_key(d) {
26 ids.insert(d.to_string(), ulid::Ulid::new().to_string());
27 }
28
29 ids.get(d).unwrap().clone()
30 });
31
32 let items: Vec<LoadedFixture> = from_str(&input).expect("Failed to deserialise fixture");
34
35 for item in items {
37 #[allow(clippy::disallowed_methods)]
38 match item {
39 LoadedFixture::User(user) => db.insert_user(&user).await.unwrap(),
40 LoadedFixture::Channel(channel) => db.insert_channel(&channel).await.unwrap(),
41 LoadedFixture::Server(server) => db.insert_server(&server).await.unwrap(),
42 LoadedFixture::ServerMember(member) => db.insert_member(&member).await.unwrap(),
43 }
44 }
45
46 ids
48}
49
50#[async_trait]
51pub trait FetchFixture {
52 async fn user(&self, db: &Database, d: usize) -> User;
53 async fn channel(&self, db: &Database, d: usize) -> Channel;
54 async fn server(&self, db: &Database, d: usize) -> Server;
55 async fn member(&self, db: &Database, d_server: usize, d_user: usize) -> Member;
56}
57
58#[async_trait]
59impl FetchFixture for HashMap<String, String> {
60 async fn user(&self, db: &Database, d: usize) -> User {
61 db.fetch_user(self.get(&d.to_string()).unwrap())
62 .await
63 .unwrap()
64 }
65
66 async fn channel(&self, db: &Database, d: usize) -> Channel {
67 db.fetch_channel(self.get(&d.to_string()).unwrap())
68 .await
69 .unwrap()
70 }
71
72 async fn server(&self, db: &Database, d: usize) -> Server {
73 db.fetch_server(self.get(&d.to_string()).unwrap())
74 .await
75 .unwrap()
76 }
77
78 async fn member(&self, db: &Database, d_server: usize, d_user: usize) -> Member {
79 db.fetch_member(
80 self.get(&d_server.to_string()).unwrap(),
81 self.get(&d_user.to_string()).unwrap(),
82 )
83 .await
84 .unwrap()
85 }
86}
87
88#[macro_export]
89macro_rules! fixture {
90 ( $database:expr, $name:expr, $( $variable:ident $type:ident $id: expr )+ ) => {
91 use $crate::util::test_fixtures::FetchFixture;
92
93 let fixtures = $crate::util::test_fixtures::load_fixture(
94 &$database,
95 include_str!(concat!(env!("CARGO_MANIFEST_DIR"), "/fixtures/", $name, ".json")),
96 )
97 .await;
98
99 $(
100 let $variable = fixtures.$type(&$database, $id).await;
101 )+
102 };
103}