first commmit

This commit is contained in:
jakciehan
2026-05-06 08:17:32 +08:00
commit 427a33c55b
269 changed files with 20906 additions and 0 deletions
+110
View File
@@ -0,0 +1,110 @@
import { Logger } from '@common/Logger';
import { CORE_PERF_THRESHOLDS, PerfMonitor } from '@common/PerfMonitor';
import {
PERF_TOUCH_RESPONSE_MAX_MS,
PERF_COMBO_RECOGNITION_MAX_MS,
MAX_FIRST_PACKAGE_BYTES,
MAX_AUDIO_BUNDLE_BYTES,
MAX_MEMORY_PEAK_BYTES,
} from '@common/Constants';
describe('PerfMonitor — threshold catalog (req 18 & 20)', () => {
it('includes every KPI threshold called out in requirements 20.1-20.5', () => {
const names = CORE_PERF_THRESHOLDS.map((t) => t.metric);
expect(names).toContain('input/touchStart');
expect(names).toContain('jump/state_toggle_ms');
expect(names).toContain('input/combo_recognition_ms');
expect(names).toContain('input/parabolic_accuracy');
expect(names).toContain('jump/air_jump_block_rate');
});
});
describe('PerfMonitor — pass/fail evaluation', () => {
function seedPassing(logger: Logger): void {
for (let i = 0; i < 100; i++) {
logger.metric({ name: 'input/touchStart', value: 20 });
logger.metric({ name: 'jump/state_toggle_ms', value: 25 });
logger.metric({ name: 'input/combo_recognition_ms', value: 40 });
}
logger.metric({ name: 'input/parabolic_accuracy', value: 0.97 });
logger.metric({ name: 'jump/air_jump_block_rate', value: 0.995 });
}
it('passes when all metrics are within budget', () => {
const logger = new Logger();
seedPassing(logger);
const monitor = new PerfMonitor(logger);
const report = monitor.collectReport();
expect(report.allPassing).toBe(true);
});
it('fails when no samples exist for a threshold', () => {
const monitor = new PerfMonitor(new Logger());
const report = monitor.collectReport();
expect(report.allPassing).toBe(false);
expect(report.checks[0].reason).toMatch(/no samples/);
});
it('fails when p95 latency exceeds the limit', () => {
const logger = new Logger();
seedPassing(logger);
// Push a huge batch of slow touches so p95 exceeds budget.
for (let i = 0; i < 200; i++) {
logger.metric({ name: 'input/touchStart', value: PERF_TOUCH_RESPONSE_MAX_MS + 50 });
}
const report = new PerfMonitor(logger).collectReport();
const touchCheck = report.checks.find((c) => c.threshold.metric === 'input/touchStart')!;
expect(touchCheck.passing).toBe(false);
});
it('fails when parabolic accuracy drops below 95%', () => {
const logger = new Logger();
seedPassing(logger);
logger.resetMetrics();
logger.metric({ name: 'input/touchStart', value: 20 });
logger.metric({ name: 'jump/state_toggle_ms', value: 20 });
logger.metric({ name: 'input/combo_recognition_ms', value: 20 });
logger.metric({ name: 'input/parabolic_accuracy', value: 0.8 });
logger.metric({ name: 'jump/air_jump_block_rate', value: 0.999 });
const report = new PerfMonitor(logger).collectReport();
expect(report.allPassing).toBe(false);
});
it('evaluates build-size budget when provided', () => {
const logger = new Logger();
logger.metric({ name: 'input/touchStart', value: 10 });
logger.metric({ name: 'jump/state_toggle_ms', value: 10 });
logger.metric({ name: 'input/combo_recognition_ms', value: 10 });
logger.metric({ name: 'input/parabolic_accuracy', value: 1 });
logger.metric({ name: 'jump/air_jump_block_rate', value: 1 });
const monitor = new PerfMonitor(logger);
const okReport = monitor.collectReport({
firstPackageBytes: MAX_FIRST_PACKAGE_BYTES - 1,
audioBundleBytes: MAX_AUDIO_BUNDLE_BYTES - 1,
memoryPeakBytes: MAX_MEMORY_PEAK_BYTES - 1,
});
expect(okReport.sizeBudgetPassing).toBe(true);
expect(okReport.allPassing).toBe(true);
const badReport = monitor.collectReport({
firstPackageBytes: MAX_FIRST_PACKAGE_BYTES + 1,
audioBundleBytes: MAX_AUDIO_BUNDLE_BYTES + 1,
memoryPeakBytes: MAX_MEMORY_PEAK_BYTES + 1,
});
expect(badReport.sizeBudgetPassing).toBe(false);
expect(badReport.allPassing).toBe(false);
});
it('honours the <= comparator at exactly the boundary', () => {
const logger = new Logger();
logger.metric({ name: 'input/touchStart', value: PERF_TOUCH_RESPONSE_MAX_MS });
logger.metric({ name: 'jump/state_toggle_ms', value: 10 });
logger.metric({ name: 'input/combo_recognition_ms', value: PERF_COMBO_RECOGNITION_MAX_MS });
logger.metric({ name: 'input/parabolic_accuracy', value: 1 });
logger.metric({ name: 'jump/air_jump_block_rate', value: 1 });
const report = new PerfMonitor(logger).collectReport();
const touch = report.checks.find((c) => c.threshold.metric === 'input/touchStart')!;
expect(touch.passing).toBe(true);
});
});