A lot of work on mocking to set up unit testing

This commit is contained in:
2023-01-04 17:24:13 +01:00
parent 3c6aecb0e9
commit a1e13af793
33 changed files with 1320 additions and 719 deletions

View File

@@ -14,3 +14,4 @@ atomic_float = "0.1.0"
[dev-dependencies]
pkmn_lib_interface = { path = "../pkmn_lib_interface", features = ["mock_data"] }
mockall = "0.11.2"

View File

@@ -1,6 +1,7 @@
#![feature(inline_const)]
#![feature(inline_const_pat)]
#![feature(wasm_abi)]
#![feature(trait_upcasting)]
#![cfg_attr(not(test), no_std)]
#![allow(incomplete_features)]

View File

@@ -1,4 +1,5 @@
use crate::script;
use alloc::boxed::Box;
use core::any::Any;
use pkmn_lib_interface::app_interface::{ExecutingMove, Pokemon};
use pkmn_lib_interface::handling::{Script, ScriptCapabilities};
@@ -38,3 +39,56 @@ impl Script for Acrobatics {
self
}
}
#[cfg(test)]
mod tests {
use super::*;
use alloc::rc::Rc;
use pkmn_lib_interface::app_interface::{Item, MockExecutingMove, MockItem, MockPokemon};
fn mock_executing_move(has_held_item: bool) -> ExecutingMove {
let mut mv = MockExecutingMove::new();
mv.expect_user().returning(move || {
let mut user = MockPokemon::new();
user.expect_held_item().returning(move || {
if has_held_item {
Some(Rc::new(MockItem::new()))
} else {
None
}
});
Rc::new(user)
});
Rc::new(mv)
}
#[test]
fn without_held_item_doubles_power() {
let mv = mock_executing_move(false);
let script = Acrobatics::new();
let mut base_power = 50u8;
script.change_base_power(mv, Rc::new(MockPokemon::new()), 0, &mut base_power);
assert_eq!(100, base_power);
}
#[test]
fn without_held_item_does_not_overflow() {
let mv = mock_executing_move(false);
let script = Acrobatics::new();
let mut base_power = 200u8;
script.change_base_power(mv, Rc::new(MockPokemon::new()), 0, &mut base_power);
assert_eq!(255, base_power);
}
#[test]
fn with_held_item_does_nothing() {
let mv = mock_executing_move(true);
let script = Acrobatics::new();
let mut base_power = 50u8;
script.change_base_power(mv, Rc::new(MockPokemon::new()), 0, &mut base_power);
assert_eq!(50, base_power);
}
}

View File

@@ -1,3 +1,4 @@
use alloc::boxed::Box;
use core::any::Any;
use core::mem::transmute;
use pkmn_lib_interface::app_interface::{ExecutingMove, Pokemon, Statistic};
@@ -25,7 +26,7 @@ impl Script for Acupressure {
}
fn on_secondary_effect(&self, mv: ExecutingMove, target: Pokemon, hit: u8) {
if target == mv.user() {
if target.equals(&mv.user()) {
mv.get_hit_data(&target, hit).fail();
return;
}

View File

@@ -1,3 +1,4 @@
use alloc::boxed::Box;
use core::any::Any;
use pkmn_lib_interface::app_interface::{ExecutingMove, Pokemon};
use pkmn_lib_interface::handling::{Script, ScriptCapabilities};

View File

@@ -14,7 +14,7 @@ impl Assist {
let mon = party.get_pokemon(mon_index);
if let Some(mon) = mon {
// Ignore moves from the user
if mon == *user {
if mon.equals(user) {
continue;
}
// Iterate over all moves. We make the assumption of 4 moves.

View File

@@ -3,7 +3,8 @@ use alloc::boxed::Box;
use core::any::Any;
use core::sync::atomic::{AtomicBool, Ordering};
use pkmn_lib_interface::app_interface::{
BattleSide, DamageSource, DataLibrary, ExecutingMove, Pokemon, TurnChoice,
BattleSide, BattleSideImpl, DamageSource, DataLibrary, ExecutingMove, Pokemon, TurnChoice,
WithVolatile,
};
use pkmn_lib_interface::handling::{Script, ScriptCapabilities};
@@ -25,9 +26,10 @@ impl Script for Assurance {
]
}
#[cfg(not(test))]
fn on_before_turn(&self, choice: TurnChoice) {
if let TurnChoice::Move(data) = &choice {
let side: BattleSide = choice
let side: BattleSideImpl = choice
.user()
.battle()
.unwrap()
@@ -48,10 +50,10 @@ impl Script for Assurance {
_hit: u8,
base_power: &mut u8,
) {
if let Some(s) = target
.battle_side()
.get_volatile::<AssuranceData>(AssuranceData::get_const_name())
{
if let Some(s) = pkmn_lib_interface::app_interface::get_volatile_as::<AssuranceData>(
target.battle_side().as_ref(),
AssuranceData::get_const_name(),
) {
if s.has_hit.load(Ordering::Relaxed) {
*base_power *= 2;
}
@@ -86,8 +88,9 @@ impl Script for AssuranceData {
&[ScriptCapabilities::OnEndTurn, ScriptCapabilities::OnDamage]
}
#[cfg(not(test))]
fn on_end_turn(&self) {
let side: BattleSide = self.get_owner().unwrap();
let side: BattleSideImpl = self.get_owner().unwrap();
side.remove_volatile(self);
}

View File

@@ -5,7 +5,9 @@ use crate::weather::hail::Hail;
use alloc::boxed::Box;
use core::any::Any;
use core::sync::atomic::{AtomicU32, Ordering};
use pkmn_lib_interface::app_interface::{BattleSide, ExecutingMove, MoveCategory, Pokemon};
use pkmn_lib_interface::app_interface::{
BattleSide, BattleSideImpl, ExecutingMove, MoveCategory, Pokemon, WithVolatile,
};
use pkmn_lib_interface::handling::ScriptCapabilities::OnEndTurn;
use pkmn_lib_interface::handling::{Script, ScriptCapabilities};
@@ -63,6 +65,7 @@ impl Script for AuroraVeilEffect {
&[ScriptCapabilities::ChangeIncomingDamage, OnEndTurn]
}
#[cfg(not(test))]
fn change_incoming_damage(
&self,
mv: ExecutingMove,
@@ -73,7 +76,7 @@ impl Script for AuroraVeilEffect {
if mv.get_hit_data(&target, hit).is_critical() {
return;
}
let side: BattleSide = self.get_owner().unwrap();
let side: BattleSideImpl = self.get_owner().unwrap();
if side.has_volatile(ReflectEffect::get_const_name())
&& mv.use_move().category() == MoveCategory::Physical
{

View File

@@ -45,11 +45,11 @@ impl Script for ChangeAllTargetStats {
fn on_secondary_effect(&self, mv: ExecutingMove, target: Pokemon, _hit: u8) {
let user = mv.user();
let amount = self.amount.load(Ordering::SeqCst);
target.change_stat_boost(Statistic::Attack, amount, user == target);
target.change_stat_boost(Statistic::Defense, amount, user == target);
target.change_stat_boost(Statistic::SpecialAttack, amount, user == target);
target.change_stat_boost(Statistic::SpecialDefense, amount, user == target);
target.change_stat_boost(Statistic::Speed, amount, user == target);
target.change_stat_boost(Statistic::Attack, amount, user.equals(&target));
target.change_stat_boost(Statistic::Defense, amount, user.equals(&target));
target.change_stat_boost(Statistic::SpecialAttack, amount, user.equals(&target));
target.change_stat_boost(Statistic::SpecialDefense, amount, user.equals(&target));
target.change_stat_boost(Statistic::Speed, amount, user.equals(&target));
}
fn as_any(&self) -> &dyn Any {

View File

@@ -54,7 +54,7 @@ macro_rules! change_stat_effect {
target.change_stat_boost(
Statistic::$stat,
self.amount.load(Ordering::SeqCst),
mv.user() == target,
mv.user().equals(&target),
);
}

View File

@@ -27,7 +27,7 @@ impl Script for CurePartyStatus {
for index in 0..p.length() {
let mon = p.get_pokemon(index);
if let Some(mon) = mon {
if mon != user {
if !mon.equals(&user) {
mon.clear_status();
}
}