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) => {
43 db.insert_or_merge_member(&member).await.unwrap();
44 }
45 }
46 }
47
48 ids
50}
51
52#[async_trait]
53pub trait FetchFixture {
54 async fn user(&self, db: &Database, d: usize) -> User;
55 async fn channel(&self, db: &Database, d: usize) -> Channel;
56 async fn server(&self, db: &Database, d: usize) -> Server;
57 async fn member(&self, db: &Database, d_server: usize, d_user: usize) -> Member;
58}
59
60#[async_trait]
61impl FetchFixture for HashMap<String, String> {
62 async fn user(&self, db: &Database, d: usize) -> User {
63 db.fetch_user(self.get(&d.to_string()).unwrap())
64 .await
65 .unwrap()
66 }
67
68 async fn channel(&self, db: &Database, d: usize) -> Channel {
69 db.fetch_channel(self.get(&d.to_string()).unwrap())
70 .await
71 .unwrap()
72 }
73
74 async fn server(&self, db: &Database, d: usize) -> Server {
75 db.fetch_server(self.get(&d.to_string()).unwrap())
76 .await
77 .unwrap()
78 }
79
80 async fn member(&self, db: &Database, d_server: usize, d_user: usize) -> Member {
81 db.fetch_member(
82 self.get(&d_server.to_string()).unwrap(),
83 self.get(&d_user.to_string()).unwrap(),
84 )
85 .await
86 .unwrap()
87 }
88}
89
90#[macro_export]
91macro_rules! fixture {
92 ( $database:expr, $name:expr, $( $variable:ident $type:ident $id: expr )+ ) => {
93 use $crate::util::test_fixtures::FetchFixture;
94
95 let fixtures = $crate::util::test_fixtures::load_fixture(
96 &$database,
97 include_str!(concat!(env!("CARGO_MANIFEST_DIR"), "/fixtures/", $name, ".json")),
98 )
99 .await;
100
101 $(
102 let $variable = fixtures.$type(&$database, $id).await;
103 )+
104 };
105}