import assert from 'node:assert/strict'; import test from 'node:test'; import { activeWindowKey, calculateActiveImpacts } from './active-impact.ts'; import { buildExactSkillWindows } from './exact-optimizer.ts'; import type { ExactSongChart, OptimizerCard } from './types.ts'; test('영향력은 겹친 액티브와 스페셜을 반영하며 제외 후 복원 효과로 갱신된다', () => { const cards: OptimizerCard[] = [100, 50].map((scoreUpPercent, index) => ({ id: String(index), name: String(index), active: { cooldownSeconds: 10, durationSeconds: 2, scoreUpPercent }, special: { durationSeconds: 2, scoreUpPercent: index === 0 ? 100 : 0 } })); const chart: ExactSongChart = { songId: 'synthetic', difficulty: 'expert', durationSeconds: 22, scoreRatio: 1, notes: [10, 20].map((timeSeconds) => ({ timeSeconds, type: 'regular', isFlick: false })), specialStartSeconds: [10, null] }; const windows = buildExactSkillWindows(cards, {}, chart).activeWindows; const key = (cardId: string, startSeconds: number) => activeWindowKey({ cardId, startSeconds }); const impacts = calculateActiveImpacts(cards, {}, chart, { perfectNoteScore: 1000 }, windows); assert.deepEqual(impacts.get(key('0', 10)), { scoreChange: -1000, strength: 1 }); assert.deepEqual(impacts.get(key('0', 20)), { scoreChange: -500, strength: 0.5 }); assert.deepEqual(impacts.get(key('1', 10)), { scoreChange: 0, strength: 0 }); const after = calculateActiveImpacts(cards, {}, chart, { perfectNoteScore: 1000, excludedActiveWindows: [{ cardId: '0', startSeconds: 10 }] }, windows); assert.deepEqual(after.get(key('0', 10)), { scoreChange: 1000, strength: 1 }); assert.deepEqual(after.get(key('1', 10)), { scoreChange: -1000, strength: 1 }); const empty = calculateActiveImpacts(cards, {}, { ...chart, notes: [] }, { perfectNoteScore: 1000 }, windows); assert.ok([...empty.values()].every((value) => value.scoreChange === 0 && value.strength === 0)); });