use crate::state::{SocialCognition, StateValue};
use crate::types::Duration;
use serde::{Deserialize, Serialize};
pub const TB_PRESENT_THRESHOLD: f32 = 0.5;
const CARING_BUFFER_EXPONENT: f32 = 3.0;
pub const PB_PRESENT_THRESHOLD: f32 = 0.5;
pub const HOPELESSNESS_THRESHOLD: f32 = 0.5;
pub const AC_PRESENCE_THRESHOLD: f64 = 0.4;
#[must_use]
pub fn is_ac_present(ac_score: f64) -> bool {
ac_score >= AC_PRESENCE_THRESHOLD
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
pub struct ITSConvergence {
pub tb_present: bool,
pub pb_present: bool,
pub ac_present: bool,
pub all_factors_present: bool,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
pub enum ITSRiskLevel {
NoRisk,
DesireOnly,
CapabilityOnly,
BothPresentButNotConvergent,
HighestRisk,
}
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub struct MentalHealth {
depression: StateValue,
self_worth: StateValue,
hopelessness: StateValue,
interpersonal_hopelessness: StateValue,
acquired_capability: StateValue,
}
impl MentalHealth {
const DEPRESSION_DECAY_HALF_LIFE: Duration = Duration::weeks(1);
const SELF_WORTH_DECAY_HALF_LIFE: Duration = Duration::days(3);
const HOPELESSNESS_DECAY_HALF_LIFE: Duration = Duration::days(3);
const INTERPERSONAL_HOPELESSNESS_DECAY_HALF_LIFE: Duration = Duration::weeks(2);
#[must_use]
pub fn new() -> Self {
MentalHealth {
depression: StateValue::new(0.1)
.with_bounds(0.0, 1.0)
.with_decay_half_life(Self::DEPRESSION_DECAY_HALF_LIFE),
self_worth: StateValue::new(0.6)
.with_bounds(0.0, 1.0)
.with_decay_half_life(Self::SELF_WORTH_DECAY_HALF_LIFE),
hopelessness: StateValue::new(0.1)
.with_bounds(0.0, 1.0)
.with_decay_half_life(Self::HOPELESSNESS_DECAY_HALF_LIFE),
interpersonal_hopelessness: StateValue::new(0.1)
.with_bounds(0.0, 1.0)
.with_decay_half_life(Self::INTERPERSONAL_HOPELESSNESS_DECAY_HALF_LIFE),
acquired_capability: StateValue::new_no_decay(0.0).with_bounds(0.0, 1.0),
}
}
#[must_use]
pub fn compute_thwarted_belongingness(&self, social: &SocialCognition) -> f32 {
let loneliness = social.loneliness_effective();
let caring = social.perceived_reciprocal_caring_effective();
let tb = loneliness * (1.0 - caring).powf(CARING_BUFFER_EXPONENT);
tb.clamp(0.0, 1.0)
}
#[must_use]
pub fn compute_perceived_burdensomeness(&self, social: &SocialCognition) -> f32 {
let liability = social.perceived_liability_effective();
let self_hate = social.self_hate_effective();
let pb = liability * self_hate;
pb.clamp(0.0, 1.0)
}
#[must_use]
pub fn compute_suicidal_desire(&self, social: &SocialCognition) -> f32 {
let hopelessness = self.interpersonal_hopelessness.effective();
let tb = self.compute_thwarted_belongingness(social);
let pb = self.compute_perceived_burdensomeness(social);
if !self.is_tb_present(social)
|| !self.is_pb_present(social)
|| hopelessness < HOPELESSNESS_THRESHOLD
{
return 0.0;
}
let desire = tb * pb;
desire.clamp(0.0, 1.0)
}
#[must_use]
pub fn compute_attempt_risk(&self, social: &SocialCognition) -> f32 {
let desire = self.compute_suicidal_desire(social);
if desire <= 0.0 {
return 0.0;
}
let convergence = self.its_convergence(social);
if !convergence.all_factors_present {
return 0.0;
}
let capability = self.acquired_capability.effective();
let risk = desire * capability;
risk.clamp(0.0, 1.0)
}
#[must_use]
pub fn compute_dormant_risk(&self, social: &SocialCognition) -> f32 {
let desire = self.compute_suicidal_desire(social);
let capability = self.acquired_capability.effective();
let dormant_risk = capability * (1.0 - desire);
dormant_risk.clamp(0.0, 1.0)
}
#[must_use]
pub fn is_tb_present(&self, social: &SocialCognition) -> bool {
self.compute_thwarted_belongingness(social) >= TB_PRESENT_THRESHOLD
}
#[must_use]
pub fn is_pb_present(&self, social: &SocialCognition) -> bool {
let liability = social.perceived_liability_effective();
let self_hate = social.self_hate_effective();
if liability < PB_PRESENT_THRESHOLD || self_hate < PB_PRESENT_THRESHOLD {
return false;
}
self.compute_perceived_burdensomeness(social) >= PB_PRESENT_THRESHOLD
}
#[must_use]
pub fn is_interpersonal_hopelessness_present(&self) -> bool {
self.interpersonal_hopelessness.effective() >= HOPELESSNESS_THRESHOLD
}
#[must_use]
pub fn its_convergence(&self, social: &SocialCognition) -> ITSConvergence {
let tb_present = self.is_tb_present(social);
let pb_present = self.is_pb_present(social);
let ac_present = is_ac_present(self.acquired_capability.effective() as f64);
let all_factors_present = tb_present && pb_present && ac_present;
ITSConvergence {
tb_present,
pb_present,
ac_present,
all_factors_present,
}
}
#[must_use]
pub fn its_risk_level(&self, social: &SocialCognition) -> ITSRiskLevel {
let tb_present = self.is_tb_present(social);
let pb_present = self.is_pb_present(social);
let hopelessness_present = self.interpersonal_hopelessness.effective() >= HOPELESSNESS_THRESHOLD;
let ac_present = is_ac_present(self.acquired_capability.effective() as f64);
let desire_present = tb_present && pb_present && hopelessness_present;
match (desire_present, ac_present) {
(true, true) => ITSRiskLevel::HighestRisk,
(true, false) => ITSRiskLevel::DesireOnly,
(false, true) if tb_present && pb_present => ITSRiskLevel::BothPresentButNotConvergent,
(false, true) => ITSRiskLevel::CapabilityOnly,
(false, false) => ITSRiskLevel::NoRisk,
}
}
#[must_use]
pub fn with_depression_base(mut self, value: f32) -> Self {
self.depression.set_base(value);
self
}
#[must_use]
pub fn with_self_worth_base(mut self, value: f32) -> Self {
self.self_worth.set_base(value);
self
}
#[must_use]
pub fn with_hopelessness_base(mut self, value: f32) -> Self {
self.hopelessness.set_base(value);
self
}
#[must_use]
pub fn with_interpersonal_hopelessness_base(mut self, value: f32) -> Self {
self.interpersonal_hopelessness.set_base(value);
self
}
#[must_use]
pub fn with_acquired_capability_base(mut self, value: f32) -> Self {
self.acquired_capability.set_base(value);
self
}
#[must_use]
pub fn depression_effective(&self) -> f32 {
self.depression.effective()
}
#[must_use]
pub fn self_worth_effective(&self) -> f32 {
self.self_worth.effective()
}
#[must_use]
pub fn hopelessness_effective(&self) -> f32 {
self.hopelessness.effective()
}
#[must_use]
pub fn interpersonal_hopelessness_effective(&self) -> f32 {
self.interpersonal_hopelessness.effective()
}
#[must_use]
pub fn acquired_capability_effective(&self) -> f32 {
self.acquired_capability.effective()
}
#[must_use]
pub fn depression(&self) -> &StateValue {
&self.depression
}
#[must_use]
pub fn self_worth(&self) -> &StateValue {
&self.self_worth
}
#[must_use]
pub fn hopelessness(&self) -> &StateValue {
&self.hopelessness
}
#[must_use]
pub fn interpersonal_hopelessness(&self) -> &StateValue {
&self.interpersonal_hopelessness
}
#[must_use]
pub fn acquired_capability(&self) -> &StateValue {
&self.acquired_capability
}
pub fn depression_mut(&mut self) -> &mut StateValue {
&mut self.depression
}
pub fn self_worth_mut(&mut self) -> &mut StateValue {
&mut self.self_worth
}
pub fn hopelessness_mut(&mut self) -> &mut StateValue {
&mut self.hopelessness
}
pub fn interpersonal_hopelessness_mut(&mut self) -> &mut StateValue {
&mut self.interpersonal_hopelessness
}
pub fn acquired_capability_mut(&mut self) -> &mut StateValue {
&mut self.acquired_capability
}
pub fn shift_self_worth_base(&mut self, amount: f32) {
self.self_worth.shift_base(amount);
}
pub fn shift_interpersonal_hopelessness_base(&mut self, amount: f32) {
self.interpersonal_hopelessness.shift_base(amount);
}
pub fn shift_acquired_capability_base(&mut self, amount: f32) {
self.acquired_capability.shift_base(amount);
}
pub fn add_depression_delta(&mut self, amount: f32) {
self.depression.add_delta(amount);
}
pub fn add_self_worth_delta(&mut self, amount: f32) {
self.self_worth.add_delta(amount);
}
pub fn add_hopelessness_delta(&mut self, amount: f32) {
self.hopelessness.add_delta(amount);
}
pub fn add_interpersonal_hopelessness_delta(&mut self, amount: f32) {
self.interpersonal_hopelessness.add_delta(amount);
}
pub fn add_acquired_capability_delta(&mut self, amount: f32) {
self.acquired_capability.add_delta(amount);
}
pub fn add_self_worth_chronic_delta(&mut self, amount: f32) {
self.self_worth.add_chronic_delta(amount);
}
pub fn add_interpersonal_hopelessness_chronic_delta(&mut self, amount: f32) {
self.interpersonal_hopelessness.add_chronic_delta(amount);
}
pub fn apply_decay(&mut self, elapsed: Duration) {
self.depression.apply_decay(elapsed);
self.self_worth.apply_decay(elapsed);
self.hopelessness.apply_decay(elapsed);
self.interpersonal_hopelessness.apply_decay(elapsed);
}
pub fn reset_deltas(&mut self) {
self.depression.reset_delta();
self.self_worth.reset_delta();
self.hopelessness.reset_delta();
self.interpersonal_hopelessness.reset_delta();
}
}
impl Default for MentalHealth {
fn default() -> Self {
MentalHealth::new()
}
}
#[cfg(test)]
mod tests {
use super::*;
use crate::state::SocialCognition;
#[test]
fn thwarted_belongingness_multiplicative_buffer() {
let mh = MentalHealth::new();
let social = SocialCognition::new()
.with_loneliness_base(0.8)
.with_perceived_reciprocal_caring_base(0.2);
let tb = mh.compute_thwarted_belongingness(&social);
assert!((tb - 0.4096).abs() < 0.01);
let social2 = SocialCognition::new()
.with_loneliness_base(0.2)
.with_perceived_reciprocal_caring_base(0.8);
let tb2 = mh.compute_thwarted_belongingness(&social2);
assert!((tb2 - 0.0016).abs() < 0.01);
}
#[test]
fn perceived_burdensomeness_multiplicative_formula() {
let mh = MentalHealth::new();
let social = SocialCognition::new()
.with_perceived_liability_base(0.8)
.with_self_hate_base(0.8);
let pb = mh.compute_perceived_burdensomeness(&social);
assert!((pb - 0.64).abs() < 0.01);
let social2 = SocialCognition::new()
.with_perceived_liability_base(0.8)
.with_self_hate_base(0.1);
let pb2 = mh.compute_perceived_burdensomeness(&social2);
assert!((pb2 - 0.08).abs() < 0.01);
}
#[test]
fn acquired_capability_never_decays() {
let mut mh = MentalHealth::new();
mh.add_acquired_capability_delta(0.5);
mh.apply_decay(Duration::years(100));
assert!((mh.acquired_capability().delta() - 0.5).abs() < f32::EPSILON);
assert!(!mh.acquired_capability().decays());
}
#[test]
fn desire_requires_tb_pb_hopelessness() {
let mut mh = MentalHealth::new().with_interpersonal_hopelessness_base(0.6);
let social = SocialCognition::new()
.with_loneliness_base(0.9)
.with_perceived_reciprocal_caring_base(0.1)
.with_perceived_liability_base(0.9)
.with_self_hate_base(0.9);
let desire = mh.compute_suicidal_desire(&social);
assert!(desire > 0.0);
mh = MentalHealth::new().with_interpersonal_hopelessness_base(0.2); let desire2 = mh.compute_suicidal_desire(&social);
assert!((desire2 - 0.0).abs() < f32::EPSILON);
}
#[test]
fn interpersonal_hopelessness_measures_permanence() {
let mh = MentalHealth::new().with_interpersonal_hopelessness_base(0.8);
assert!(mh.is_interpersonal_hopelessness_present());
let mh2 = MentalHealth::new()
.with_hopelessness_base(0.8)
.with_interpersonal_hopelessness_base(0.2);
assert!(!mh2.is_interpersonal_hopelessness_present());
}
#[test]
fn attempt_risk_requires_desire_and_capability() {
let mh = MentalHealth::new()
.with_interpersonal_hopelessness_base(0.7)
.with_acquired_capability_base(0.8);
let social = SocialCognition::new()
.with_loneliness_base(0.9)
.with_perceived_reciprocal_caring_base(0.1)
.with_perceived_liability_base(0.9)
.with_self_hate_base(0.9);
let risk = mh.compute_attempt_risk(&social);
assert!(risk > 0.0);
let mh2 = MentalHealth::new()
.with_interpersonal_hopelessness_base(0.7)
.with_acquired_capability_base(0.0);
let risk2 = mh2.compute_attempt_risk(&social);
assert!((risk2 - 0.0).abs() < f32::EPSILON);
}
#[test]
fn dormant_risk_high_ac_low_desire() {
let mh = MentalHealth::new()
.with_interpersonal_hopelessness_base(0.2)
.with_acquired_capability_base(0.9);
let low_desire_social = SocialCognition::new()
.with_loneliness_base(0.1)
.with_perceived_reciprocal_caring_base(0.9)
.with_perceived_liability_base(0.1)
.with_self_hate_base(0.1);
let risk = mh.compute_dormant_risk(&low_desire_social);
assert!(risk > 0.7);
}
#[test]
fn dormant_risk_high_desire_low_latent_risk() {
let mh = MentalHealth::new()
.with_interpersonal_hopelessness_base(0.8)
.with_acquired_capability_base(0.9);
let high_desire_social = SocialCognition::new()
.with_loneliness_base(1.0)
.with_perceived_reciprocal_caring_base(0.0)
.with_perceived_liability_base(1.0)
.with_self_hate_base(1.0);
let risk = mh.compute_dormant_risk(&high_desire_social);
assert!(risk < 0.3);
}
#[test]
fn dormant_risk_low_ac_remains_low() {
let mh = MentalHealth::new()
.with_interpersonal_hopelessness_base(0.8)
.with_acquired_capability_base(0.1);
let high_desire_social = SocialCognition::new()
.with_loneliness_base(0.9)
.with_perceived_reciprocal_caring_base(0.1)
.with_perceived_liability_base(0.9)
.with_self_hate_base(0.9);
let risk = mh.compute_dormant_risk(&high_desire_social);
assert!(risk < 0.2);
}
#[test]
fn attempt_risk_requires_ac_threshold() {
let mh = MentalHealth::new()
.with_interpersonal_hopelessness_base(0.8)
.with_acquired_capability_base((AC_PRESENCE_THRESHOLD - 0.05) as f32);
let social = SocialCognition::new()
.with_loneliness_base(0.9)
.with_perceived_reciprocal_caring_base(0.1)
.with_perceived_liability_base(0.9)
.with_self_hate_base(0.9);
let risk = mh.compute_attempt_risk(&social);
assert!((risk - 0.0).abs() < f32::EPSILON);
}
#[test]
fn its_convergence_reports_presence() {
let mh = MentalHealth::new()
.with_interpersonal_hopelessness_base(0.7)
.with_acquired_capability_base((AC_PRESENCE_THRESHOLD + 0.1) as f32);
let social = SocialCognition::new()
.with_loneliness_base(0.9)
.with_perceived_reciprocal_caring_base(0.1)
.with_perceived_liability_base(0.9)
.with_self_hate_base(0.9);
let convergence = mh.its_convergence(&social);
assert!(convergence.tb_present);
assert!(convergence.pb_present);
assert!(convergence.ac_present);
assert!(convergence.all_factors_present);
}
#[test]
fn tb_threshold_check() {
let mh = MentalHealth::new();
let low_tb_social = SocialCognition::new()
.with_loneliness_base(0.2)
.with_perceived_reciprocal_caring_base(0.8);
assert!(!mh.is_tb_present(&low_tb_social));
let high_tb_social = SocialCognition::new()
.with_loneliness_base(0.9)
.with_perceived_reciprocal_caring_base(0.1);
assert!(mh.is_tb_present(&high_tb_social));
}
#[test]
fn pb_threshold_check() {
let mh = MentalHealth::new();
let low_pb_social = SocialCognition::new()
.with_perceived_liability_base(0.2)
.with_self_hate_base(0.2);
assert!(!mh.is_pb_present(&low_pb_social));
let imbalanced_liability_social = SocialCognition::new()
.with_perceived_liability_base(0.9)
.with_self_hate_base(0.2);
assert!(!mh.is_pb_present(&imbalanced_liability_social));
let imbalanced_self_hate_social = SocialCognition::new()
.with_perceived_liability_base(0.2)
.with_self_hate_base(0.9);
assert!(!mh.is_pb_present(&imbalanced_self_hate_social));
let high_pb_social = SocialCognition::new()
.with_perceived_liability_base(0.8)
.with_self_hate_base(0.8);
assert!(mh.is_pb_present(&high_pb_social));
}
#[test]
fn new_creates_healthy_defaults() {
let mh = MentalHealth::new();
assert!(mh.depression_effective() < 0.3);
assert!(mh.self_worth_effective() > 0.5);
assert!(mh.hopelessness_effective() < 0.3);
assert!(mh.interpersonal_hopelessness_effective() < 0.3);
assert!(mh.acquired_capability_effective() < 0.1);
}
#[test]
fn builder_methods_work() {
let mh = MentalHealth::new()
.with_depression_base(0.5)
.with_self_worth_base(0.3)
.with_hopelessness_base(0.4)
.with_interpersonal_hopelessness_base(0.6)
.with_acquired_capability_base(0.2);
assert!((mh.depression().base() - 0.5).abs() < f32::EPSILON);
assert!((mh.self_worth().base() - 0.3).abs() < f32::EPSILON);
assert!((mh.hopelessness().base() - 0.4).abs() < f32::EPSILON);
assert!((mh.interpersonal_hopelessness().base() - 0.6).abs() < f32::EPSILON);
assert!((mh.acquired_capability().base() - 0.2).abs() < f32::EPSILON);
}
#[test]
fn delta_modifiers_work() {
let mut mh = MentalHealth::new();
mh.add_depression_delta(0.3);
assert!((mh.depression().delta() - 0.3).abs() < f32::EPSILON);
mh.add_self_worth_delta(-0.2);
assert!((mh.self_worth().delta() - (-0.2)).abs() < f32::EPSILON);
}
#[test]
fn decay_does_not_affect_ac() {
let mut mh = MentalHealth::new();
mh.add_depression_delta(0.5);
mh.add_acquired_capability_delta(0.5);
mh.apply_decay(Duration::weeks(4));
assert!(mh.depression().delta() < 0.3);
assert!((mh.acquired_capability().delta() - 0.5).abs() < f32::EPSILON);
}
#[test]
fn reset_deltas_does_not_affect_ac() {
let mut mh = MentalHealth::new();
mh.add_depression_delta(0.5);
mh.add_acquired_capability_delta(0.5);
mh.reset_deltas();
assert!(mh.depression().delta().abs() < f32::EPSILON);
assert!((mh.acquired_capability().delta() - 0.5).abs() < f32::EPSILON);
}
#[test]
fn default_is_new() {
let mh = MentalHealth::default();
assert!(mh.depression_effective() < 0.3);
}
#[test]
fn clone_and_equality() {
let mh1 = MentalHealth::new().with_depression_base(0.5);
let mh2 = mh1.clone();
assert_eq!(mh1, mh2);
}
#[test]
fn debug_format() {
let mh = MentalHealth::new();
let debug = format!("{:?}", mh);
assert!(debug.contains("MentalHealth"));
}
#[test]
fn mutable_references_work() {
let mut mh = MentalHealth::new();
mh.depression_mut().add_delta(0.2);
assert!((mh.depression().delta() - 0.2).abs() < f32::EPSILON);
}
#[test]
fn threshold_constants_defined() {
assert!(TB_PRESENT_THRESHOLD > 0.0 && TB_PRESENT_THRESHOLD <= 1.0);
assert!(PB_PRESENT_THRESHOLD > 0.0 && PB_PRESENT_THRESHOLD <= 1.0);
assert!(HOPELESSNESS_THRESHOLD > 0.0 && HOPELESSNESS_THRESHOLD <= 1.0);
assert!(AC_PRESENCE_THRESHOLD > 0.0 && AC_PRESENCE_THRESHOLD <= 1.0);
}
#[test]
fn ac_presence_helper_uses_threshold() {
assert!(!is_ac_present(AC_PRESENCE_THRESHOLD - 0.01));
assert!(is_ac_present(AC_PRESENCE_THRESHOLD));
}
#[test]
fn its_risk_level_distinguishes_desire_and_capability() {
let social = SocialCognition::new()
.with_loneliness_base(0.9)
.with_perceived_reciprocal_caring_base(0.1)
.with_perceived_liability_base(0.9)
.with_self_hate_base(0.9);
let desire_only = MentalHealth::new()
.with_interpersonal_hopelessness_base(0.8)
.with_acquired_capability_base(0.1);
assert_eq!(
desire_only.its_risk_level(&social),
ITSRiskLevel::DesireOnly
);
let low_desire_social = SocialCognition::new()
.with_loneliness_base(0.2)
.with_perceived_reciprocal_caring_base(0.8)
.with_perceived_liability_base(0.2)
.with_self_hate_base(0.2);
let capability_only = MentalHealth::new()
.with_interpersonal_hopelessness_base(0.2)
.with_acquired_capability_base(0.8);
assert_eq!(
capability_only.its_risk_level(&low_desire_social),
ITSRiskLevel::CapabilityOnly
);
}
#[test]
fn its_risk_level_detects_non_convergent_state() {
let social = SocialCognition::new()
.with_loneliness_base(0.9)
.with_perceived_reciprocal_caring_base(0.1)
.with_perceived_liability_base(0.9)
.with_self_hate_base(0.9);
let mh = MentalHealth::new()
.with_interpersonal_hopelessness_base(0.1)
.with_acquired_capability_base(0.9);
assert_eq!(
mh.its_risk_level(&social),
ITSRiskLevel::BothPresentButNotConvergent
);
}
#[test]
fn its_risk_level_handles_highest_and_no_risk_states() {
let high_risk_social = SocialCognition::new()
.with_loneliness_base(0.9)
.with_perceived_reciprocal_caring_base(0.1)
.with_perceived_liability_base(0.9)
.with_self_hate_base(0.9);
let highest_risk = MentalHealth::new()
.with_interpersonal_hopelessness_base(0.9)
.with_acquired_capability_base(0.9);
assert_eq!(
highest_risk.its_risk_level(&high_risk_social),
ITSRiskLevel::HighestRisk
);
let low_risk_social = SocialCognition::new()
.with_loneliness_base(0.1)
.with_perceived_reciprocal_caring_base(0.9)
.with_perceived_liability_base(0.1)
.with_self_hate_base(0.1);
let no_risk = MentalHealth::new()
.with_interpersonal_hopelessness_base(0.1)
.with_acquired_capability_base(0.1);
assert_eq!(no_risk.its_risk_level(&low_risk_social), ITSRiskLevel::NoRisk);
}
#[test]
fn all_mutable_refs() {
let mut mh = MentalHealth::new();
mh.self_worth_mut().add_delta(-0.2);
mh.hopelessness_mut().add_delta(0.3);
mh.interpersonal_hopelessness_mut().add_delta(0.4);
assert!((mh.self_worth().delta() - (-0.2)).abs() < f32::EPSILON);
assert!((mh.hopelessness().delta() - 0.3).abs() < f32::EPSILON);
assert!((mh.interpersonal_hopelessness().delta() - 0.4).abs() < f32::EPSILON);
}
#[test]
fn add_interpersonal_hopelessness_delta_test() {
let mut mh = MentalHealth::new();
mh.add_interpersonal_hopelessness_delta(0.5);
assert!((mh.interpersonal_hopelessness().delta() - 0.5).abs() < f32::EPSILON);
}
#[test]
fn add_hopelessness_delta_test() {
let mut mh = MentalHealth::new();
mh.add_hopelessness_delta(0.4);
assert!((mh.hopelessness().delta() - 0.4).abs() < f32::EPSILON);
}
#[test]
fn base_shift_and_chronic_delta_helpers_work() {
let mut mh = MentalHealth::new();
let initial_self_worth = mh.self_worth().base();
let initial_interpersonal = mh.interpersonal_hopelessness().base();
let initial_ac = mh.acquired_capability().base();
mh.shift_self_worth_base(-0.2);
mh.shift_interpersonal_hopelessness_base(0.3);
mh.shift_acquired_capability_base(0.4);
assert!(
(mh.self_worth().base() - (initial_self_worth - 0.2)).abs() < f32::EPSILON
);
assert!(
(mh.interpersonal_hopelessness().base() - (initial_interpersonal + 0.3)).abs()
< f32::EPSILON
);
assert!(
(mh.acquired_capability().base() - (initial_ac + 0.4)).abs() < f32::EPSILON
);
mh.add_self_worth_chronic_delta(0.15);
mh.add_interpersonal_hopelessness_chronic_delta(-0.25);
assert!(
(mh.self_worth().chronic_delta() - 0.15).abs() < f32::EPSILON
);
assert!(
(mh.interpersonal_hopelessness().chronic_delta() - (-0.25)).abs() < f32::EPSILON
);
}
}