Skip to content

Commit

Permalink
Coverage (#468)
Browse files Browse the repository at this point in the history
Up the reported coverage on coveralls by adding some missing tests,
especially for types. Also removes/replaces some old, faulty or
non-idiomatic code.

While unit testing might seem a bit bloaty (especially with this many
additions), I'd argue that writing somewhat sensible tests is the only
good way to somewhat reliably keep things from breaking in larger
projects/bigger codebases, such as these.

Most of these tests should, hopefully, be of acceptable quality,
although I do admit that when writing tests, I sometimes just like to
turn my brain off
  • Loading branch information
bitfl0wer authored Jan 24, 2024
2 parents ed3786c + 60f55d9 commit 9aa921a
Show file tree
Hide file tree
Showing 33 changed files with 1,253 additions and 220 deletions.
6 changes: 3 additions & 3 deletions src/api/channels/messages.rs
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ impl Message {
chorus_request.deserialize_response::<Message>(user).await
} else {
for (index, attachment) in message.attachments.iter_mut().enumerate() {
attachment.get_mut(index).unwrap().set_id(index as i16);
attachment.get_mut(index).unwrap().id = Some(index as i16);
}
let mut form = reqwest::multipart::Form::new();
let payload_json = to_string(&message).unwrap();
Expand All @@ -45,8 +45,8 @@ impl Message {
form = form.part("payload_json", payload_field);

for (index, attachment) in message.attachments.unwrap().into_iter().enumerate() {
let (attachment_content, current_attachment) = attachment.move_content();
let (attachment_filename, _) = current_attachment.move_filename();
let attachment_content = attachment.content;
let attachment_filename = attachment.filename;
let part_name = format!("files[{}]", index);
let content_disposition = format!(
"form-data; name=\"{}\"'; filename=\"{}\"",
Expand Down
21 changes: 8 additions & 13 deletions src/instance.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ use reqwest::Client;
use serde::{Deserialize, Serialize};

use crate::errors::ChorusResult;
use crate::gateway::{Gateway, GatewayHandle};
use crate::gateway::{Gateway, GatewayHandle, Shared};
use crate::ratelimiter::ChorusRequest;
use crate::types::types::subconfigs::limits::rates::RateLimits;
use crate::types::{
Expand Down Expand Up @@ -37,8 +37,6 @@ impl PartialEq for Instance {
}
}

impl Eq for Instance {}

impl std::hash::Hash for Instance {
fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
self.urls.hash(state);
Expand Down Expand Up @@ -73,7 +71,6 @@ impl PartialEq for LimitsInformation {
}

impl Instance {

pub(crate) fn clone_limits_if_some(&self) -> Option<HashMap<LimitType, Limit>> {
if self.limits_information.is_some() {
return Some(self.limits_information.as_ref().unwrap().ratelimits.clone());
Expand Down Expand Up @@ -156,11 +153,11 @@ impl fmt::Display for Token {
/// It is used for most authenticated actions on a Spacebar server.
/// It also has its own [Gateway] connection.
pub struct ChorusUser {
pub belongs_to: Arc<RwLock<Instance>>,
pub belongs_to: Shared<Instance>,
pub token: String,
pub limits: Option<HashMap<LimitType, Limit>>,
pub settings: Arc<RwLock<UserSettings>>,
pub object: Arc<RwLock<User>>,
pub settings: Shared<UserSettings>,
pub object: Shared<User>,
pub gateway: GatewayHandle,
}

Expand All @@ -172,8 +169,6 @@ impl PartialEq for ChorusUser {
}
}

impl Eq for ChorusUser {}

impl ChorusUser {
pub fn token(&self) -> String {
self.token.clone()
Expand All @@ -189,11 +184,11 @@ impl ChorusUser {
/// This isn't the prefered way to create a ChorusUser.
/// See [Instance::login_account] and [Instance::register_account] instead.
pub fn new(
belongs_to: Arc<RwLock<Instance>>,
belongs_to: Shared<Instance>,
token: String,
limits: Option<HashMap<LimitType, Limit>>,
settings: Arc<RwLock<UserSettings>>,
object: Arc<RwLock<User>>,
settings: Shared<UserSettings>,
object: Shared<User>,
gateway: GatewayHandle,
) -> ChorusUser {
ChorusUser {
Expand All @@ -211,7 +206,7 @@ impl ChorusUser {
/// registering or logging in to the Instance, where you do not yet have a User object, but still
/// need to make a RateLimited request. To use the [`GatewayHandle`], you will have to identify
/// first.
pub(crate) async fn shell(instance: Arc<RwLock<Instance>>, token: String) -> ChorusUser {
pub(crate) async fn shell(instance: Shared<Instance>, token: String) -> ChorusUser {
let settings = Arc::new(RwLock::new(UserSettings::default()));
let object = Arc::new(RwLock::new(User::default()));
let wss_url = instance.read().unwrap().urls.wss.clone();
Expand Down
17 changes: 8 additions & 9 deletions src/types/entities/application.rs
Original file line number Diff line number Diff line change
@@ -1,10 +1,9 @@
use std::sync::{Arc, RwLock};

use bitflags::bitflags;
use serde::{Deserialize, Serialize};
use serde_json::Value;
use serde_repr::{Deserialize_repr, Serialize_repr};

use crate::gateway::Shared;
use crate::types::utils::Snowflake;
use crate::types::{Team, User};

Expand All @@ -27,7 +26,7 @@ pub struct Application {
pub bot_require_code_grant: bool,
pub verify_key: String,
#[cfg_attr(feature = "sqlx", sqlx(skip))]
pub owner: Arc<RwLock<User>>,
pub owner: Shared<User>,
pub flags: u64,
#[cfg(feature = "sqlx")]
pub redirect_uris: Option<sqlx::types::Json<Vec<String>>>,
Expand All @@ -49,7 +48,7 @@ pub struct Application {
#[cfg(feature = "sqlx")]
pub install_params: Option<sqlx::types::Json<InstallParams>>,
#[cfg(not(feature = "sqlx"))]
pub install_params: Option<Arc<RwLock<InstallParams>>>,
pub install_params: Option<Shared<InstallParams>>,
pub terms_of_service_url: Option<String>,
pub privacy_policy_url: Option<String>,
#[cfg_attr(feature = "sqlx", sqlx(skip))]
Expand Down Expand Up @@ -142,7 +141,7 @@ pub struct ApplicationCommand {
pub application_id: Snowflake,
pub name: String,
pub description: String,
pub options: Vec<Arc<RwLock<ApplicationCommandOption>>>,
pub options: Vec<Shared<ApplicationCommandOption>>,
}

#[derive(Debug, Clone, Serialize, Deserialize)]
Expand All @@ -154,7 +153,7 @@ pub struct ApplicationCommandOption {
pub description: String,
pub required: bool,
pub choices: Vec<ApplicationCommandOptionChoice>,
pub options: Arc<RwLock<Vec<ApplicationCommandOption>>>,
pub options: Shared<Vec<ApplicationCommandOption>>,
}

#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
Expand Down Expand Up @@ -190,14 +189,14 @@ pub enum ApplicationCommandOptionType {
pub struct ApplicationCommandInteractionData {
pub id: Snowflake,
pub name: String,
pub options: Vec<Arc<RwLock<ApplicationCommandInteractionDataOption>>>,
pub options: Vec<Shared<ApplicationCommandInteractionDataOption>>,
}

#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ApplicationCommandInteractionDataOption {
pub name: String,
pub value: Value,
pub options: Vec<Arc<RwLock<ApplicationCommandInteractionDataOption>>>,
pub options: Vec<Shared<ApplicationCommandInteractionDataOption>>,
}

#[derive(Debug, Default, Clone, Serialize, Deserialize)]
Expand All @@ -206,7 +205,7 @@ pub struct GuildApplicationCommandPermissions {
pub id: Snowflake,
pub application_id: Snowflake,
pub guild_id: Snowflake,
pub permissions: Vec<Arc<RwLock<ApplicationCommandPermission>>>,
pub permissions: Vec<Shared<ApplicationCommandPermission>>,
}

#[derive(Debug, Default, Clone, PartialEq, Serialize, Deserialize)]
Expand Down
70 changes: 0 additions & 70 deletions src/types/entities/attachment.rs
Original file line number Diff line number Diff line change
Expand Up @@ -55,73 +55,3 @@ pub struct PartialDiscordFileAttachment {
#[serde(skip_serializing)]
pub content: Vec<u8>,
}

impl PartialDiscordFileAttachment {
/// Moves `self.content` out of `self` and returns it.
pub fn move_content(self) -> (Vec<u8>, PartialDiscordFileAttachment) {
let content = self.content;
let updated_struct = PartialDiscordFileAttachment {
id: self.id,
filename: self.filename,
description: self.description,
content_type: self.content_type,
size: self.size,
url: self.url,
proxy_url: self.proxy_url,
height: self.height,
width: self.width,
ephemeral: self.ephemeral,
duration_secs: self.duration_secs,
waveform: self.waveform,
content: Vec::new(),
};
(content, updated_struct)
}

/// Moves `self.filename` out of `self` and returns it.
pub fn move_filename(self) -> (String, PartialDiscordFileAttachment) {
let filename = self.filename;
let updated_struct = PartialDiscordFileAttachment {
id: self.id,
filename: String::new(),
description: self.description,
content_type: self.content_type,
size: self.size,
url: self.url,
proxy_url: self.proxy_url,
height: self.height,
width: self.width,

ephemeral: self.ephemeral,
duration_secs: self.duration_secs,
waveform: self.waveform,
content: self.content,
};
(filename, updated_struct)
}

/// Moves `self.content_type` out of `self` and returns it.
pub fn move_content_type(self) -> (Option<String>, PartialDiscordFileAttachment) {
let content_type = self.content_type;
let updated_struct = PartialDiscordFileAttachment {
id: self.id,
filename: self.filename,
description: self.description,
content_type: None,
size: self.size,
url: self.url,
proxy_url: self.proxy_url,
height: self.height,
width: self.width,
ephemeral: self.ephemeral,
duration_secs: self.duration_secs,
waveform: self.waveform,
content: self.content,
};
(content_type, updated_struct)
}

pub fn set_id(&mut self, id: i16) {
self.id = Some(id);
}
}
5 changes: 2 additions & 3 deletions src/types/entities/audit_log.rs
Original file line number Diff line number Diff line change
@@ -1,14 +1,13 @@
use std::sync::{Arc, RwLock};

use serde::{Deserialize, Serialize};

use crate::gateway::Shared;
use crate::types::utils::Snowflake;

#[derive(Serialize, Deserialize, Debug, Default, Clone)]
/// See <https://discord.com/developers/docs/resources/audit-log#audit-log-entry-object>
pub struct AuditLogEntry {
pub target_id: Option<String>,
pub changes: Option<Vec<Arc<RwLock<AuditLogChange>>>>,
pub changes: Option<Vec<Shared<AuditLogChange>>>,
pub user_id: Option<Snowflake>,
pub id: Snowflake,
// to:do implement an enum for these types
Expand Down
9 changes: 4 additions & 5 deletions src/types/entities/auto_moderation.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
use std::sync::{Arc, RwLock};

use crate::gateway::Shared;
#[cfg(feature = "client")]
use crate::gateway::Updateable;

Expand All @@ -21,8 +20,8 @@ pub struct AutoModerationRule {
pub creator_id: Snowflake,
pub event_type: AutoModerationRuleEventType,
pub trigger_type: AutoModerationRuleTriggerType,
pub trigger_metadata: Arc<RwLock<AutoModerationRuleTriggerMetadata>>,
pub actions: Vec<Arc<RwLock<AutoModerationAction>>>,
pub trigger_metadata: Shared<AutoModerationRuleTriggerMetadata>,
pub actions: Vec<Shared<AutoModerationAction>>,
pub enabled: bool,
pub exempt_roles: Vec<Snowflake>,
pub exempt_channels: Vec<Snowflake>,
Expand Down Expand Up @@ -99,7 +98,7 @@ pub enum AutoModerationRuleKeywordPresetType {
pub struct AutoModerationAction {
#[serde(rename = "type")]
pub action_type: AutoModerationActionType,
pub metadata: Option<Arc<RwLock<AutoModerationActionMetadata>>>,
pub metadata: Option<Shared<AutoModerationActionMetadata>>,
}

#[derive(Serialize_repr, Deserialize_repr, Debug, Clone, Default)]
Expand Down
9 changes: 4 additions & 5 deletions src/types/entities/channel.rs
Original file line number Diff line number Diff line change
@@ -1,11 +1,10 @@
use std::sync::{Arc, RwLock};

use chrono::{DateTime, Utc};
use serde::{Deserialize, Serialize};
use serde_aux::prelude::deserialize_string_from_number;
use serde_repr::{Deserialize_repr, Serialize_repr};
use std::fmt::Debug;

use crate::gateway::Shared;
use crate::types::{
entities::{GuildMember, User},
utils::Snowflake,
Expand Down Expand Up @@ -71,13 +70,13 @@ pub struct Channel {
pub permission_overwrites: Option<sqlx::types::Json<Vec<PermissionOverwrite>>>,
#[cfg(not(feature = "sqlx"))]
#[cfg_attr(feature = "client", observe_option_vec)]
pub permission_overwrites: Option<Vec<Arc<RwLock<PermissionOverwrite>>>>,
pub permission_overwrites: Option<Vec<Shared<PermissionOverwrite>>>,
pub permissions: Option<String>,
pub position: Option<i32>,
pub rate_limit_per_user: Option<i32>,
#[cfg_attr(feature = "sqlx", sqlx(skip))]
#[cfg_attr(feature = "client", observe_option_vec)]
pub recipients: Option<Vec<Arc<RwLock<User>>>>,
pub recipients: Option<Vec<Shared<User>>>,
pub rtc_region: Option<String>,
#[cfg_attr(feature = "sqlx", sqlx(skip))]
pub thread_metadata: Option<ThreadMetadata>,
Expand Down Expand Up @@ -171,7 +170,7 @@ pub struct ThreadMember {
pub user_id: Option<Snowflake>,
pub join_timestamp: Option<String>,
pub flags: Option<u64>,
pub member: Option<Arc<RwLock<GuildMember>>>,
pub member: Option<Shared<GuildMember>>,
}

#[derive(Debug, Deserialize, Serialize, Clone, PartialEq, Eq)]
Expand Down
15 changes: 12 additions & 3 deletions src/types/entities/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,20 +15,29 @@ impl ConfigEntity {
let Some(v) = self.value.as_ref() else {
return None;
};
Some(v.as_str().expect("value is not a string").to_string())
let Some(v) = v.as_str() else {
return None;
};
Some(v.to_string())
}

pub fn as_bool(&self) -> Option<bool> {
let Some(v) = self.value.as_ref() else {
return None;
};
Some(v.as_bool().expect("value is not a boolean"))
let Some(v) = v.as_bool() else {
return None;
};
Some(v)
}

pub fn as_int(&self) -> Option<i64> {
let Some(v) = self.value.as_ref() else {
return None;
};
Some(v.as_i64().expect("value is not a number"))
let Some(v) = v.as_i64() else {
return None;
};
Some(v)
}
}
Loading

0 comments on commit 9aa921a

Please sign in to comment.