A lot of work on mocking to set up unit testing
This commit is contained in:
@@ -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"
|
||||
@@ -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)]
|
||||
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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};
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
{
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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),
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user