Files
healer-man/server/arena-character.test.mjs
T
2026-09-11 14:26:15 -04:00

64 lines
3.9 KiB
JavaScript

import assert from "node:assert/strict";
import test from "node:test";
import { arenaKitForLoadout } from "./arena-character-kit.mjs";
import { ArenaSimulation } from "./arena-simulation.mjs";
import { ARENA_STAGES } from "./arena-stages.mjs";
function fixture() {
const kit = arenaKitForLoadout({classId:"priest",talents:{},actions:{"primary:face-left":"priest-flash-heal","primary:face-bottom":"priest-smite"}});
const simulation = new ArenaSimulation({id:"character-kit",stage:{ ...ARENA_STAGES[0], id:"test-floorless", lineOfSight:[] },bracket:"2v2",mode:"practice",ruleset:"wow",startedAt:0,
participants:[{actorId:"player",characterId:"saved-priest",name:"My Priest",team:0,role:"healer",isBot:false,characterKit:kit},
{actorId:"ally",team:0,role:"damage",isBot:false},{actorId:"enemy",team:1,role:"damage",isBot:false}]});
for(let i=0;i<200;i++)simulation.step();
const player=simulation.actor("player"), ally=simulation.actor("ally"), enemy=simulation.actor("enemy");
player.position=[0,0,0];ally.position=[1,0,0];enemy.position=[2,0,0];
return {simulation,player,ally,enemy,kit};
}
test("all arena spawns have finite character transforms before the first movement",()=>{
for(const stage of ARENA_STAGES) {
const simulation=new ArenaSimulation({id:stage.id,stage,bracket:"2v2",mode:"practice",ruleset:"wow",participants:[
{actorId:"left",team:0,role:"healer",isBot:false},{actorId:"right",team:1,role:"damage",isBot:false}]});
for(const actor of simulation.snapshot().actors) {
assert.ok(Number.isFinite(actor.facing),stage.id);
assert.ok(actor.position.every(Number.isFinite),stage.id);
assert.deepEqual(actor.position,stage.teamSpawns[actor.team],stage.id);
}
}
});
test("saved priest identity, spell bindings, and usable mana reach the snapshot",()=>{
const {simulation,kit}=fixture();
const player=simulation.snapshot().actors.find(actor=>actor.id==="player");
assert.equal(player.characterId,"saved-priest");assert.equal(player.classId,"priest");
assert.equal(player.actionBindings["primary:face-left"],"priest-flash-heal");
assert.ok(player.resource>kit.abilities["priest-flash-heal"].cost.amount);
assert.equal(simulation.receiveIntent("player",{sequence:1,type:"ability",abilityId:"heal"}).reason,"unknown-ability");
});
test("saved Flash Heal pays mana, has a cast time, heals the chosen ally and reports cooldown",()=>{
const {simulation,player,ally}=fixture();ally.health=200;
const resource=player.resource;
assert.equal(simulation.receiveIntent("player",{sequence:1,type:"ability",abilityId:"priest-flash-heal",targetActorId:"ally"}).accepted,true);
assert.equal(player.resource,resource);assert.equal(ally.health,200);
assert.equal(simulation.receiveIntent("player",{sequence:2,type:"ability",abilityId:"priest-flash-heal",targetActorId:"ally"}).reason,"already-casting");
for(let i=0;i<30;i++)simulation.step();
assert.ok(ally.health>200);assert.ok(player.resource<resource);assert.equal(player.health,player.maxHealth);assert.equal(player.casting,null);
});
test("movement cancels a real spell and impossible targets give feedback",()=>{
const {simulation,player,enemy}=fixture();
enemy.position=[1000,0,0];
assert.equal(simulation.receiveIntent("player",{sequence:1,type:"ability",abilityId:"priest-smite",targetActorId:"enemy"}).reason,"out-of-range");
assert.equal(simulation.receiveIntent("player",{sequence:2,type:"ability",abilityId:"priest-flash-heal",targetActorId:"player"}).accepted,true);
simulation.receiveIntent("player",{sequence:3,type:"movement",movement:{x:1,z:0}});simulation.step();
assert.equal(player.casting,null);
});
test("Shadowfiend uses the character summoning engine",()=>{
const {simulation,player}=fixture();
player.facing=Math.PI/2;
assert.equal(simulation.receiveIntent("player",{sequence:1,type:"ability",abilityId:"wow335-priest-shadowfiend",targetActorId:"enemy"}).accepted,true);
assert.ok(player.combat.summons.length>0);
});