// DRY guard (BUG-5 fix): nextTurn and computeTurnOrderAfterRemoval share one // advance core (nextActiveAfter). Both must pick the SAME next-active target // for identical state. If this goes RED, the two paths drifted. 'use strict'; const shared = require('@ttrpg/shared'); const { makeParticipant, startEncounter, nextTurn, toggleParticipantActive } = shared; function p(id, init, extra = {}) { return makeParticipant({ id, name: id, type: 'monster', initiative: init, maxHp: 100, currentHp: 100, ...extra }); } function enc(ps, extra = {}) { return { name:'t', participants:ps, isStarted:false, isPaused:false, round:0, currentTurnParticipantId:null, turnOrderIds:[], ...extra }; } describe('DRY: deact-current advance == nextTurn advance', () => { test('mid-round: same target (not current)', () => { // order a,b,c. a current. nextTurn → b. deact a → advance → b. const e = enc([p('a',10),p('b',5),p('c',3)], { isStarted:true, turnOrderIds:['a','b','c'], currentTurnParticipantId:'a' }); const nt = nextTurn(e).patch.currentTurnParticipantId; const deact = toggleParticipantActive(e, 'a').patch.currentTurnParticipantId; expect(deact).toBe(nt); expect(deact).toBe('b'); }); test('mid-round with inactive skipper: same target', () => { // order a,x,b,c; x inactive. a current. nextTurn → b. deact a → b. const x = p('x',7,{ isActive:false }); const e = enc([p('a',10),x,p('b',5),p('c',3)], { isStarted:true, turnOrderIds:['a','x','b','c'], currentTurnParticipantId:'a' }); const nt = nextTurn(e).patch.currentTurnParticipantId; const deact = toggleParticipantActive(e, 'a').patch.currentTurnParticipantId; expect(deact).toBe(nt); expect(deact).toBe('b'); }); test('wrap: same target + round bump', () => { // order a,b,c. c current. nextTurn → wrap → a (r+1). deact c → wrap → a (r+1). const e = enc([p('a',10),p('b',5),p('c',3)], { isStarted:true, turnOrderIds:['a','b','c'], currentTurnParticipantId:'c', round:2 }); const nt = nextTurn(e).patch; const deact = toggleParticipantActive(e, 'c').patch; expect(deact.currentTurnParticipantId).toBe(nt.currentTurnParticipantId); expect(deact.currentTurnParticipantId).toBe('a'); expect(deact.round).toBe(nt.round); expect(deact.round).toBe(3); }); });