/* * SPDX-FileCopyrightText: syuilo and misskey-project * SPDX-License-Identifier: AGPL-3.0-only */ import { describe, expect, test } from 'vitest'; import { createEmptyHeapSnapshotData, renderHeapSnapshotTable, summarizeHeapSnapshotDataSamples, type HeapSnapshotData, type HeapSnapshotReport, } from '../src/heap-snapshot'; function snapshot(total: number): HeapSnapshotData { const data = createEmptyHeapSnapshotData(); data.categories.total = total; return data; } function report(totals: number[]): HeapSnapshotReport { const samples = totals.map((total, index) => ({ round: index + 1, data: snapshot(total), })); const summary = summarizeHeapSnapshotDataSamples(samples, sample => sample.data); if (summary == null) throw new Error('expected heap snapshot samples to produce a summary'); return { summary, samples, }; } function totalRow(markdown: string) { const row = markdown.split('\n').find(line => line.includes('**Total**')); if (row === undefined) throw new Error('expected heap snapshot table to contain a Total row'); return row; } describe('renderHeapSnapshotTable', () => { test('leaves a threshold-sized delta uncoloured when it is within observed noise', () => { const row = totalRow(renderHeapSnapshotTable( report([1_000_000, 1_100_000, 1_200_000]), report([1_100_000, 1_200_000, 1_300_000]), )); expect(row).toContain('$\\text{+100 KB}$'); expect(row).not.toContain('within noise'); expect(row).not.toContain('\\color{orange}'); }); test('colours both delta lines for a clear increase at or above the absolute threshold', () => { const row = totalRow(renderHeapSnapshotTable( report([1_000_000, 1_000_000, 1_000_000]), report([1_200_000, 1_200_000, 1_200_000]), )); expect(row).toContain('$\\color{orange}{\\text{+200 KB}}$'); expect(row).toContain('$\\color{orange}{\\text{+20\\\\%}}$'); expect(row).not.toContain('increase'); }); test('leaves both delta lines uncoloured below the absolute threshold', () => { const row = totalRow(renderHeapSnapshotTable( report([1_000_000, 1_000_000, 1_000_000]), report([1_050_000, 1_050_000, 1_050_000]), )); expect(row).toContain('$\\text{+50 KB}$
$\\text{+5\\\\%}$'); expect(row.split('|')[4]).not.toContain('\\color{'); }); test('throws when only one snapshot per side reaches the renderer', () => { expect(() => renderHeapSnapshotTable( report([1_000_000]), report([1_200_000]), )).toThrow('At least two samples per side are required'); }); test('uses two-line formatting only for Total and puts a five-column separator after it', () => { const table = renderHeapSnapshotTable( report([1_000_000, 1_000_000, 1_000_000]), report([1_200_000, 1_200_000, 1_200_000]), ); const lines = table.split('\n'); const totalIndex = lines.findIndex(line => line.includes('**Total**')); const categoryRow = lines.find(line => line.includes('**Code**')); expect(lines.slice(0, 2)).toStrictEqual([ '| Metric | @ Base | @ Head | Δ | MAD |', '| --- | ---: | ---: | ---: | ---: |', ]); expect(table).not.toContain('Result'); expect(totalIndex).toBeGreaterThan(1); expect(lines[totalIndex].match(/
/g)).toHaveLength(3); expect(lines[totalIndex + 1]).toBe('| | | | | |'); expect(categoryRow).toBeDefined(); expect(categoryRow).not.toContain('
'); expect(categoryRow).not.toContain('
'); expect(categoryRow).not.toContain('→'); }); });