import { resolveUnsetSize, UnresolvedLevelSizeError } from '../src/game/wilderness.ts' import type { WildernessPiece, WildernessRequest } from '../src/game/wilderness.ts' import type { Ds1, Ds1Cell } from '../src/formats/ds1.ts' function makeMockDs1(width: number, height: number): Ds1 { const cells: Ds1Cell[][] = [] for (let y = 0; y < height; y += 1) { const row: Ds1Cell[] = [] for (let x = 0; x < width; x += 1) { row.push({ walls: [], floors: [{ prop1: 2, sequence: 0, style: 1, unknown1: 0, unknown2: 0, hidden: false }], shadows: [], substitutions: [], }) } cells.push(row) } return { version: 7, width, height, act: 5, substitutionType: 0, wallLayers: 1, floorLayers: 1, cells, objects: [], npcPathOffset: null, } } console.log('=== STARTING ADVERSARIAL STRESS TEST FOR resolveUnsetSize ===') let failures = 0 function assert(condition: boolean, msg: string) { if (!condition) { console.error(`FAIL: ${msg}`) failures++ } else { console.log(`PASS: ${msg}`) } } // 1. Anti-silent failure: Empty pieces throws UnresolvedLevelSizeError try { resolveUnsetSize({ levelId: 111, levelName: 'Act 5 - Barricade 1', levelTypeName: 'Act 5 - Barricade', sizeX: -1, sizeY: -1, subType: 10, subTheme: 0, seed: 12345, pieces: [], substitutions: [], }) assert(false, 'Expected empty pieces to throw UnresolvedLevelSizeError') } catch (err) { assert(err instanceof UnresolvedLevelSizeError, 'Empty pieces throws instance of UnresolvedLevelSizeError') assert((err as Error).message.includes('Level 111 (Act 5 - Barricade 1)'), 'Error message contains level info') } // 2. Anti-silent failure: Non-barricade pieces throw UnresolvedLevelSizeError try { resolveUnsetSize({ levelId: 111, levelName: 'Act 5 - Barricade 1', levelTypeName: 'Act 5 - Barricade', sizeX: -1, sizeY: -1, subType: 10, subTheme: 0, seed: 12345, pieces: [ { name: 'Act 5 - Siege 1', border: false, levels: [makeMockDs1(10, 10)] }, ], substitutions: [], }) assert(false, 'Expected non-barricade pieces to throw UnresolvedLevelSizeError') } catch (err) { assert(err instanceof UnresolvedLevelSizeError, 'Non-barricade pieces throw instance of UnresolvedLevelSizeError') } // 3. Fuzzing pieces dimensions: 10,000 random dimensions test let allBoundsHold = true let allAspectRatiosHold = true for (let i = 0; i < 10000; i++) { const randW1 = Math.floor(Math.random() * 2000) - 500 // -500 to 1500 const randH1 = Math.floor(Math.random() * 2000) - 500 const randW2 = Math.floor(Math.random() * 2000) - 500 const randH2 = Math.floor(Math.random() * 2000) - 500 const res = resolveUnsetSize({ levelId: 111, levelName: 'Act 5 - Barricade 1', levelTypeName: 'Act 5 - Barricade', sizeX: -1, sizeY: -1, subType: 10, subTheme: 0, seed: i, pieces: [ { name: 'Act 5 - Barricade Entrance', border: false, levels: [makeMockDs1(randW1, randH1)] }, { name: 'Act 5 - Barricade Exit', border: false, levels: [makeMockDs1(randW2, randH2)] }, ], substitutions: [], }) if (res.sizeX < 48 || res.sizeX > 64 || res.sizeY < 160 || res.sizeY > 192) { allBoundsHold = false console.error(`Bounds failure at iteration ${i}: sizeX=${res.sizeX}, sizeY=${res.sizeY}`) break } if (res.sizeY <= res.sizeX || (res.sizeY / res.sizeX) < 2.5) { allAspectRatiosHold = false console.error(`Aspect ratio failure at iteration ${i}: sizeX=${res.sizeX}, sizeY=${res.sizeY}`) break } } assert(allBoundsHold, '10,000 random input tests: sizeX in [48..64] and sizeY in [160..192] strictly hold') assert(allAspectRatiosHold, '10,000 random input tests: sizeY > sizeX and aspect ratio >= 2.5 strictly hold') // 4. Overrides const overrideRes = resolveUnsetSize({ levelId: 111, levelName: 'Act 5 - Barricade 1', levelTypeName: 'Act 5 - Barricade', sizeX: -1, sizeY: -1, sizeOverride: { x: 72, y: 144 }, subType: 10, subTheme: 0, seed: 999, pieces: [], substitutions: [], }) assert(overrideRes.sizeX === 72 && overrideRes.sizeY === 144, 'sizeOverride is respected exactly') if (failures > 0) { console.error(`\nFAILED: ${failures} assertions failed!`) process.exit(1) } else { console.log('\nSUCCESS: All adversarial checks passed!') }