54 lines
3.8 KiB
TypeScript
54 lines
3.8 KiB
TypeScript
import test from 'node:test';
|
|
import assert from 'node:assert/strict';
|
|
import { compactResult, currentGrowthSettings, snapshotKey, type AnalysisSettings, type GrowthSnapshot } from '../models/analysis-history.ts';
|
|
import { parseAnalysisArchive } from '../storage/analysis-history.ts';
|
|
import type { ExactOptimizationResult } from './types.ts';
|
|
|
|
const growth: GrowthSnapshot = { collection: { a: { owned: true, awakening: 2 } }, memberBoards: { a: ['B1', 'G1'] }, boardCards: {}, memoryCount: 10, memberPowerUpPercent: 1 };
|
|
test('동일한 성장 상태는 입력 순서와 무관하게 공유하고 성장 차이는 구분한다', () => {
|
|
const reordered = { ...growth, memberBoards: { a: ['G1', 'B1'] } };
|
|
assert.equal(snapshotKey(growth), snapshotKey(reordered));
|
|
assert.notEqual(snapshotKey(growth), snapshotKey({ ...growth, memoryCount: 11 }));
|
|
});
|
|
test('현재 성장 비교는 저장 조건을 유지하고 보유 개화만 교체한다', () => {
|
|
const settings: AnalysisSettings = { songId: 'song', difficulty: 'expert', cardIds: ['a'], awakenings: [0], allBlueNodes: [true], generationBonusOverrides: [900], leaderCharacterId: 'a', leaderOutfitCardId: 'a' };
|
|
const current = currentGrowthSettings(settings, growth);
|
|
assert.deepEqual(current.awakenings, [2]); assert.deepEqual(settings.awakenings, [0]);
|
|
assert.deepEqual(current.generationBonusOverrides, [900]); assert.deepEqual(current.allBlueNodes, [true]);
|
|
assert.throws(() => currentGrowthSettings(settings, { ...growth, collection: {} }), /보유/);
|
|
});
|
|
test('기록은 노트별 배열을 제외하고 원본과 독립적으로 보존한다', () => {
|
|
const source = { notes: [{ timeSeconds: 1 }], scoreBySecond: [2], order: ['a'], expectedScore: 123 } as unknown as ExactOptimizationResult;
|
|
const saved = compactResult(source);
|
|
source.order = ['b'];
|
|
assert.deepEqual(saved.order, ['a']); assert.equal(saved.expectedScore, 123);
|
|
assert.equal('notes' in saved, false); assert.equal('scoreBySecond' in saved, false);
|
|
});
|
|
test('기록 백업은 잘못된 구조와 누락된 성장 참조를 거부한다', () => {
|
|
assert.throws(() => parseAnalysisArchive('{}'));
|
|
assert.throws(() => parseAnalysisArchive(JSON.stringify({ schemaVersion: 1, snapshots: [], records: [{ settings: {}, result: {}, snapshotId: 'missing' }] })));
|
|
assert.deepEqual(parseAnalysisArchive('{"schemaVersion":1,"snapshots":[],"records":[]}').records, []);
|
|
});
|
|
|
|
test('성장 상태를 공유하는 기록 백업을 손실 없이 읽고 잘못된 개화를 거부한다', () => {
|
|
const ids = ['a', 'b', 'c', 'd', 'e'];
|
|
const record = {
|
|
id: 'record', name: '기록', title: '곡', analyzedAt: '2026-09-06T00:00:00Z', snapshotId: 'snapshot', overallPower: 1000, durationSeconds: 120,
|
|
settings: { songId: 'song', difficulty: 'expert', cardIds: ids, awakenings: [0, 1, 2, 3, 4], leaderCharacterId: 'a', leaderOutfitCardId: 'a' },
|
|
result: { expectedScore: 100, theoreticalMaxScore: 120, baselineScore: 50, perfectNoteScore: 10, order: ids, cooldownReductions: Object.fromEntries(ids.map((id) => [id, 0])) }
|
|
};
|
|
const archive = { schemaVersion: 1, snapshots: [{ id: 'snapshot', growth }], records: [record, { ...record, id: 'second' }] };
|
|
const parsed = parseAnalysisArchive(JSON.stringify(archive));
|
|
assert.equal(parsed.records.length, 2); assert.equal(parsed.snapshots.length, 1);
|
|
assert.deepEqual(parsed.snapshots[0].growth, growth);
|
|
for (const difficulty of ['easy', 'normal', 'hard', 'expert']) {
|
|
record.settings.difficulty = difficulty;
|
|
assert.equal(parseAnalysisArchive(JSON.stringify(archive)).records[0].settings.difficulty, difficulty);
|
|
}
|
|
record.settings.difficulty = 'invalid';
|
|
assert.throws(() => parseAnalysisArchive(JSON.stringify(archive)));
|
|
record.settings.difficulty = 'expert';
|
|
record.settings.awakenings[0] = 8;
|
|
assert.throws(() => parseAnalysisArchive(JSON.stringify(archive)));
|
|
});
|