test: add deterministic resilience matrix
This commit is contained in:
@@ -9,6 +9,10 @@ import { createSun } from '@/scene/world/sun';
|
||||
import { createCar } from '@/scene/world/car';
|
||||
import { createSign } from '@/scene/world/sign';
|
||||
import { createParticles } from '@/scene/world/particles';
|
||||
import { isTestFault, recordTestFaultEvent } from '@/testing/fault-hooks';
|
||||
|
||||
declare const __PORTFOLIO_TEST_BUILD__: boolean;
|
||||
const TEST_BUILD = typeof __PORTFOLIO_TEST_BUILD__ !== 'undefined' && __PORTFOLIO_TEST_BUILD__;
|
||||
|
||||
const skyColors: Readonly<Record<EnvironmentChapter, number>> = {
|
||||
'deep-night': 0x040713,
|
||||
@@ -29,6 +33,18 @@ export function createChaseCamera(aspect = 1) {
|
||||
export async function createProceduralSceneGeneration(
|
||||
context: SceneBuildContext,
|
||||
): Promise<SceneGeneration> {
|
||||
if (TEST_BUILD && isTestFault('F1-shader')) {
|
||||
recordTestFaultEvent('shader-rejected');
|
||||
throw new Error('Injected shader failure');
|
||||
}
|
||||
if (TEST_BUILD && isTestFault('F1-texture')) {
|
||||
recordTestFaultEvent('texture-rejected');
|
||||
throw new Error('Injected texture failure');
|
||||
}
|
||||
if (TEST_BUILD && isTestFault('F1-car')) {
|
||||
recordTestFaultEvent('car-rejected');
|
||||
throw new Error('Injected car failure');
|
||||
}
|
||||
if (context.signal.aborted) throw new DOMException('Scene build aborted', 'AbortError');
|
||||
const canvas = context.canvas as HTMLCanvasElement;
|
||||
if (typeof canvas.getContext !== 'function') throw new Error('A canvas element is required');
|
||||
@@ -104,6 +120,7 @@ export async function createProceduralSceneGeneration(
|
||||
let driveDistance = 0;
|
||||
let lastNow: number | null = null;
|
||||
let disposed = false;
|
||||
let renderedFrames = 0;
|
||||
|
||||
const resize = (): void => {
|
||||
const nextWidth = Math.max(1, canvas.clientWidth || canvas.width || 1);
|
||||
@@ -128,6 +145,14 @@ export async function createProceduralSceneGeneration(
|
||||
return {
|
||||
render(snapshot: Readonly<JourneySnapshot>, now: number) {
|
||||
if (disposed) return;
|
||||
if (
|
||||
TEST_BUILD
|
||||
&& isTestFault('F3-post-first-frame-exception')
|
||||
&& renderedFrames > 0
|
||||
) {
|
||||
recordTestFaultEvent('post-first-frame-exception');
|
||||
throw new Error('Injected post-first-frame exception');
|
||||
}
|
||||
resize();
|
||||
const deltaSeconds = lastNow === null ? 0 : Math.min(0.1, Math.max(0, (now - lastNow) / 1000));
|
||||
lastNow = now;
|
||||
@@ -152,6 +177,7 @@ export async function createProceduralSceneGeneration(
|
||||
} else {
|
||||
renderer.render(scene, camera);
|
||||
}
|
||||
renderedFrames += 1;
|
||||
},
|
||||
dispose() {
|
||||
if (disposed) return;
|
||||
|
||||
Reference in New Issue
Block a user