diff --git a/tests/roleHandlers/harvester.handler.test.ts b/tests/roleHandlers/harvester.handler.test.ts index 4c6081b..0fc791a 100644 --- a/tests/roleHandlers/harvester.handler.test.ts +++ b/tests/roleHandlers/harvester.handler.test.ts @@ -6,74 +6,73 @@ import { } from '@/utils/positions'; import '~/tests/__mocks__/screeps'; -// ─── Helpers ──────────────────────────────────────────────────────────────── - -function makeMatrix(fill: string = PositionSpotStatus.EMPTY) { - const m = createSourcePositionMatrix(fill as any); - return m; -} - -function makeState(overrides: Partial = {}): GameState { - const spots = makeMatrix(); - return { - sourcesStates: { - src1: { spots }, - }, - ...overrides, - } as unknown as GameState; -} - -function makeCreepMemory(overrides: Partial = {}): CreepMemory { - return { - role: 'harvester', - spawnId: 'spawn1', - ...overrides, - } as CreepMemory; -} - -function makeStore(used: number, capacity: number) { - return { - getFreeCapacity: (_res: string) => capacity - used, - getUsedCapacity: (_res: string) => used, - }; -} - -function makePos(x = 0, y = 0, roomName = 'W1N1') { - return new (global as any).RoomPosition(x, y, roomName); -} - -function makeSource(id = 'src1', x = 5, y = 5, roomName = 'W1N1') { - return { - id, - pos: makePos(x, y, roomName), - } as unknown as Source; -} - -function makeSpawn(id = 'spawn1') { - return { id } as unknown as StructureSpawn; -} - -function makeCreep( - memoryOverrides: Partial = {}, - storeUsed = 0, - storeCapacity = 50 -): Creep { - const memory = makeCreepMemory(memoryOverrides); - return { - name: 'Creep1', - memory, - store: makeStore(storeUsed, storeCapacity), - pos: makePos(), - room: {}, - harvest: jest.fn().mockReturnValue((global as any).OK), - moveTo: jest.fn().mockReturnValue((global as any).OK), - transfer: jest.fn().mockReturnValue((global as any).OK), - } as unknown as Creep; -} - -// ─── Tests ─────────────────────────────────────────────────────────────────── - describe('HarvesterHandler', () => { + type FixtureOptions = { + memory?: Partial; + storeUsed?: number; + storeCapacity?: number; + stateOverrides?: Partial; + sourceId?: string; + spawnId?: string; + }; + + const createFixture = ({ + memory = {}, + storeUsed = 0, + storeCapacity = 50, + stateOverrides = {}, + sourceId = 'src1', + spawnId = 'spawn1', + }: FixtureOptions = {}) => { + const state = { + sourcesStates: { + [sourceId]: { + spots: createSourcePositionMatrix( + PositionSpotStatus.EMPTY as any + ), + }, + }, + ...stateOverrides, + } as unknown as GameState; + + const source = { + id: sourceId, + pos: new (global as any).RoomPosition(5, 5, 'W1N1'), + } as unknown as Source; + + const spawn = { id: spawnId } as unknown as StructureSpawn; + + const creep = { + name: 'Creep1', + memory: { + role: 'harvester', + spawnId, + ...memory, + } as CreepMemory, + store: { + getFreeCapacity: (_res: string) => storeCapacity - storeUsed, + getUsedCapacity: (_res: string) => storeUsed, + }, + pos: new (global as any).RoomPosition(0, 0, 'W1N1'), + room: {}, + harvest: jest.fn().mockReturnValue((global as any).OK), + moveTo: jest.fn().mockReturnValue((global as any).OK), + transfer: jest.fn().mockReturnValue((global as any).OK), + } as unknown as Creep; + + return { + state, + source, + spawn, + creep, + memory: creep.memory, + mockSource: (value: Source | null = source) => + jest.spyOn(getById, 'getSourceById').mockReturnValue(value), + mockSpawn: (value: StructureSpawn | null = spawn) => + jest.spyOn(getById, 'getSpawnById').mockReturnValue(value), + }; + }; + beforeEach(() => { jest.clearAllMocks(); jest.spyOn(console, 'log').mockImplementation(() => {}); @@ -83,16 +82,14 @@ describe('HarvesterHandler', () => { jest.restoreAllMocks(); }); - // ── destroy ────────────────────────────────────────────────────────────── - describe('destroy', () => { it('releases the source spot from destination and clears it', () => { - const state = makeState(); - state.sourcesStates['src1'].spots[0] = PositionSpotStatus.OCCUPIED; - - const memory = makeCreepMemory({ - destination: { type: 'source', id: 'src1', sourceSpot: 0 }, + const { state, memory } = createFixture({ + memory: { + destination: { type: 'source', id: 'src1', sourceSpot: 0 }, + }, }); + state.sourcesStates['src1'].spots[0] = PositionSpotStatus.OCCUPIED; HarvesterHandler.destroy(memory, state); @@ -103,16 +100,16 @@ describe('HarvesterHandler', () => { }); it('releases the source spot from previousDestination and clears it', () => { - const state = makeState(); - state.sourcesStates['src1'].spots[2] = PositionSpotStatus.OCCUPIED; - - const memory = makeCreepMemory({ - previousDestination: { - type: 'source', - id: 'src1', - sourceSpot: 2, + const { state, memory } = createFixture({ + memory: { + previousDestination: { + type: 'source', + id: 'src1', + sourceSpot: 2, + }, }, }); + state.sourcesStates['src1'].spots[2] = PositionSpotStatus.OCCUPIED; HarvesterHandler.destroy(memory, state); @@ -123,14 +120,14 @@ describe('HarvesterHandler', () => { }); it('does nothing when destination is not a source', () => { - const state = makeState(); - const memory = makeCreepMemory({ - destination: { type: 'spawn', id: 'spawn1' }, + const { state, memory } = createFixture({ + memory: { + destination: { type: 'spawn', id: 'spawn1' }, + }, }); HarvesterHandler.destroy(memory, state); - // None of the source spots should have changed expect( state.sourcesStates['src1'].spots.every( (s: PositionSpotStatus) => @@ -141,29 +138,25 @@ describe('HarvesterHandler', () => { }); it('does nothing when memory has no destination', () => { - const state = makeState(); - const memory = makeCreepMemory(); + const { state, memory } = createFixture(); expect(() => HarvesterHandler.destroy(memory, state)).not.toThrow(); }); }); - // ── validateCreepMemory (via run) ──────────────────────────────────────── - describe('validateCreepMemory (via run)', () => { it('releases previousDestination source spot and deletes it', () => { - const state = makeState(); - state.sourcesStates['src1'].spots[1] = PositionSpotStatus.OCCUPIED; - - const creep = makeCreep({ - previousDestination: { - type: 'source', - id: 'src1', - sourceSpot: 1, + const { state, creep, mockSource } = createFixture({ + memory: { + previousDestination: { + type: 'source', + id: 'src1', + sourceSpot: 1, + }, }, }); - - jest.spyOn(getById, 'getSourceById').mockReturnValue(null); + state.sourcesStates['src1'].spots[1] = PositionSpotStatus.OCCUPIED; + mockSource(null); HarvesterHandler.run(creep, state); @@ -174,19 +167,16 @@ describe('HarvesterHandler', () => { }); it('transitions from source to spawn destination when energy is full', () => { - const state = makeState(); - const source = makeSource(); - jest.spyOn(getById, 'getSourceById').mockReturnValue(source); - jest.spyOn(getById, 'getSpawnById').mockReturnValue(makeSpawn()); - - const creep = makeCreep( - { + const { state, creep, mockSource, mockSpawn } = createFixture({ + memory: { destination: { type: 'source', id: 'src1', sourceSpot: 0 }, spawnId: 'spawn1', }, - 50, // used = full - 50 - ); + storeUsed: 50, + storeCapacity: 50, + }); + mockSource(); + mockSpawn(); HarvesterHandler.run(creep, state); @@ -195,16 +185,14 @@ describe('HarvesterHandler', () => { }); it('clears spawn destination when energy is empty', () => { - const state = makeState(); - jest.spyOn(getById, 'getSpawnById').mockReturnValue(makeSpawn()); - - const creep = makeCreep( - { + const { state, creep, mockSpawn } = createFixture({ + memory: { destination: { type: 'spawn', id: 'spawn1' }, }, - 0, // used = 0 - 50 - ); + storeUsed: 0, + storeCapacity: 50, + }); + mockSpawn(); HarvesterHandler.run(creep, state); @@ -212,14 +200,10 @@ describe('HarvesterHandler', () => { }); }); - // ── onFindNewSource ─────────────────────────────────────────────────────── - describe('onFindNewSource', () => { it('assigns the first available source spot to the creep', () => { - const state = makeState(); - jest.spyOn(getById, 'getSourceById').mockReturnValue(makeSource()); - - const creep = makeCreep(); // no destination, empty store + const { state, creep, mockSource } = createFixture(); + mockSource(); HarvesterHandler.run(creep, state); @@ -228,18 +212,13 @@ describe('HarvesterHandler', () => { }); it('does not assign a source when all spots are occupied', () => { - const state = makeState(); - // Fill all non-center spots with OCCUPIED + const { state, creep, mockSource } = createFixture(); state.sourcesStates['src1'].spots = state.sourcesStates[ 'src1' ].spots.map((s: PositionSpotStatus) => - s === PositionSpotStatus.CENTER - ? s - : PositionSpotStatus.OCCUPIED + s === PositionSpotStatus.CENTER ? s : PositionSpotStatus.OCCUPIED ) as any; - - jest.spyOn(getById, 'getSourceById').mockReturnValue(makeSource()); - const creep = makeCreep(); + mockSource(); HarvesterHandler.run(creep, state); @@ -247,19 +226,14 @@ describe('HarvesterHandler', () => { }); }); - // ── onSourceDestination ─────────────────────────────────────────────────── - describe('onSourceDestination', () => { it('harvests when in range', () => { - const state = makeState(); - const source = makeSource(); - jest.spyOn(getById, 'getSourceById').mockReturnValue(source); - - const creep = makeCreep( - { destination: { type: 'source', id: 'src1', sourceSpot: 0 } }, - 0, - 50 - ); + const { state, source, creep, mockSource } = createFixture({ + memory: { + destination: { type: 'source', id: 'src1', sourceSpot: 0 }, + }, + }); + mockSource(); (creep.harvest as jest.Mock).mockReturnValue((global as any).OK); HarvesterHandler.run(creep, state); @@ -269,15 +243,12 @@ describe('HarvesterHandler', () => { }); it('moves to source when not in range', () => { - const state = makeState(); - const source = makeSource(); - jest.spyOn(getById, 'getSourceById').mockReturnValue(source); - - const creep = makeCreep( - { destination: { type: 'source', id: 'src1', sourceSpot: 0 } }, - 0, - 50 - ); + const { state, creep, mockSource } = createFixture({ + memory: { + destination: { type: 'source', id: 'src1', sourceSpot: 0 }, + }, + }); + mockSource(); (creep.harvest as jest.Mock).mockReturnValue( (global as any).ERR_NOT_IN_RANGE ); @@ -288,39 +259,32 @@ describe('HarvesterHandler', () => { }); it('logs and returns when source is not found', () => { - const state = makeState(); - jest.spyOn(getById, 'getSourceById').mockReturnValue(null); - - const creep = makeCreep( - { + const { state, creep, mockSource } = createFixture({ + memory: { destination: { type: 'source', id: 'unknown', sourceSpot: 0, }, }, - 0, - 50 - ); + }); + mockSource(null); expect(() => HarvesterHandler.run(creep, state)).not.toThrow(); expect(creep.harvest).not.toHaveBeenCalled(); }); }); - // ── onSpawnDestination ──────────────────────────────────────────────────── - describe('onSpawnDestination', () => { it('transfers energy when in range', () => { - const state = makeState(); - const spawn = makeSpawn(); - jest.spyOn(getById, 'getSpawnById').mockReturnValue(spawn); - - const creep = makeCreep( - { destination: { type: 'spawn', id: 'spawn1' } }, - 50, - 50 - ); + const { state, spawn, creep, mockSpawn } = createFixture({ + memory: { + destination: { type: 'spawn', id: 'spawn1' }, + }, + storeUsed: 50, + storeCapacity: 50, + }); + mockSpawn(); (creep.transfer as jest.Mock).mockReturnValue((global as any).OK); HarvesterHandler.run(creep, state); @@ -333,15 +297,14 @@ describe('HarvesterHandler', () => { }); it('moves to spawn when not in range', () => { - const state = makeState(); - const spawn = makeSpawn(); - jest.spyOn(getById, 'getSpawnById').mockReturnValue(spawn); - - const creep = makeCreep( - { destination: { type: 'spawn', id: 'spawn1' } }, - 50, - 50 - ); + const { state, spawn, creep, mockSpawn } = createFixture({ + memory: { + destination: { type: 'spawn', id: 'spawn1' }, + }, + storeUsed: 50, + storeCapacity: 50, + }); + mockSpawn(); (creep.transfer as jest.Mock).mockReturnValue( (global as any).ERR_NOT_IN_RANGE ); @@ -355,14 +318,14 @@ describe('HarvesterHandler', () => { }); it('logs and returns when spawn is not found', () => { - const state = makeState(); - jest.spyOn(getById, 'getSpawnById').mockReturnValue(null); - - const creep = makeCreep( - { destination: { type: 'spawn', id: 'spawn1' } }, - 50, - 50 - ); + const { state, creep, mockSpawn } = createFixture({ + memory: { + destination: { type: 'spawn', id: 'spawn1' }, + }, + storeUsed: 50, + storeCapacity: 50, + }); + mockSpawn(null); expect(() => HarvesterHandler.run(creep, state)).not.toThrow(); expect(creep.transfer).not.toHaveBeenCalled(); diff --git a/tests/roleHandlers/upgrader.handler.test.ts b/tests/roleHandlers/upgrader.handler.test.ts index e74fd14..2ddaf8b 100644 --- a/tests/roleHandlers/upgrader.handler.test.ts +++ b/tests/roleHandlers/upgrader.handler.test.ts @@ -6,73 +6,79 @@ import { } from '@/utils/positions'; import '~/tests/__mocks__/screeps'; -// ─── Helpers ──────────────────────────────────────────────────────────────── - -function makeState(overrides: Partial = {}): GameState { - const spots = createSourcePositionMatrix(PositionSpotStatus.EMPTY); - return { - sourcesStates: { - src1: { spots }, - }, - ...overrides, - } as unknown as GameState; -} - -function makeCreepMemory(overrides: Partial = {}): CreepMemory { - return { - role: 'upgrader', - spawnId: 'spawn1', - ...overrides, - } as CreepMemory; -} - -function makeStore(used: number, capacity: number) { - return { - getFreeCapacity: (_res: string) => capacity - used, - getUsedCapacity: (_res: string) => used, - }; -} - -function makePos(x = 0, y = 0, roomName = 'W1N1') { - return new (global as any).RoomPosition(x, y, roomName); -} - -function makeSource(id = 'src1', x = 5, y = 5, roomName = 'W1N1') { - return { - id, - pos: makePos(x, y, roomName), - } as unknown as Source; -} - -function makeController(id = 'ctrl1') { - return { id } as unknown as StructureController; -} - -function makeCreep( - memoryOverrides: Partial = {}, - storeUsed = 0, - storeCapacity = 50, - controller: StructureController | null = null -): Creep { - const memory = makeCreepMemory(memoryOverrides); - return { - name: 'Creep1', - memory, - store: makeStore(storeUsed, storeCapacity), - pos: makePos(), - room: { - controller: - controller !== null ? (controller ?? makeController()) : null, - }, - harvest: jest.fn().mockReturnValue((global as any).OK), - moveTo: jest.fn().mockReturnValue((global as any).OK), - upgradeController: jest.fn().mockReturnValue((global as any).OK), - } as unknown as Creep; -} - -// ─── Tests ─────────────────────────────────────────────────────────────────── - describe('UpgraderHandler', () => { + type FixtureOptions = { + memory?: Partial; + storeUsed?: number; + storeCapacity?: number; + stateOverrides?: Partial; + sourceId?: string; + controllerId?: string; + controllerInRoom?: StructureController | null; + }; + + const createFixture = ({ + memory = {}, + storeUsed = 0, + storeCapacity = 50, + stateOverrides = {}, + sourceId = 'src1', + controllerId = 'ctrl1', + controllerInRoom = null, + }: FixtureOptions = {}) => { + const state = { + sourcesStates: { + [sourceId]: { + spots: createSourcePositionMatrix( + PositionSpotStatus.EMPTY as any + ), + }, + }, + ...stateOverrides, + } as unknown as GameState; + + const source = { + id: sourceId, + pos: new (global as any).RoomPosition(5, 5, 'W1N1'), + } as unknown as Source; + + const controller = { id: controllerId } as StructureController; + + const creep = { + name: 'Creep1', + memory: { + role: 'upgrader', + spawnId: 'spawn1', + ...memory, + } as CreepMemory, + store: { + getFreeCapacity: (_res: string) => storeCapacity - storeUsed, + getUsedCapacity: (_res: string) => storeUsed, + }, + pos: new (global as any).RoomPosition(0, 0, 'W1N1'), + room: { + controller: controllerInRoom, + }, + harvest: jest.fn().mockReturnValue((global as any).OK), + moveTo: jest.fn().mockReturnValue((global as any).OK), + upgradeController: jest.fn().mockReturnValue((global as any).OK), + } as unknown as Creep; + + return { + state, + source, + controller, + creep, + memory: creep.memory, + mockSource: (value: Source | null = source) => + jest.spyOn(getById, 'getSourceById').mockReturnValue(value), + mockController: (value: StructureController | null = controller) => + jest + .spyOn(getById, 'getControllerById') + .mockReturnValue(value), + }; + }; + beforeEach(() => { jest.clearAllMocks(); jest.spyOn(console, 'log').mockImplementation(() => {}); @@ -82,16 +88,14 @@ describe('UpgraderHandler', () => { jest.restoreAllMocks(); }); - // ── destroy ────────────────────────────────────────────────────────────── - describe('destroy', () => { it('releases the source spot from destination and clears it', () => { - const state = makeState(); - state.sourcesStates['src1'].spots[0] = PositionSpotStatus.OCCUPIED; - - const memory = makeCreepMemory({ - destination: { type: 'source', id: 'src1', sourceSpot: 0 }, + const { state, memory } = createFixture({ + memory: { + destination: { type: 'source', id: 'src1', sourceSpot: 0 }, + }, }); + state.sourcesStates['src1'].spots[0] = PositionSpotStatus.OCCUPIED; UpgraderHandler.destroy(memory, state); @@ -102,16 +106,16 @@ describe('UpgraderHandler', () => { }); it('releases the source spot from previousDestination and clears it', () => { - const state = makeState(); - state.sourcesStates['src1'].spots[3] = PositionSpotStatus.OCCUPIED; - - const memory = makeCreepMemory({ - previousDestination: { - type: 'source', - id: 'src1', - sourceSpot: 3, + const { state, memory } = createFixture({ + memory: { + previousDestination: { + type: 'source', + id: 'src1', + sourceSpot: 3, + }, }, }); + state.sourcesStates['src1'].spots[3] = PositionSpotStatus.OCCUPIED; UpgraderHandler.destroy(memory, state); @@ -122,9 +126,10 @@ describe('UpgraderHandler', () => { }); it('does nothing when destination is not a source', () => { - const state = makeState(); - const memory = makeCreepMemory({ - destination: { type: 'controller', id: 'ctrl1' }, + const { state, memory } = createFixture({ + memory: { + destination: { type: 'controller', id: 'ctrl1' }, + }, }); UpgraderHandler.destroy(memory, state); @@ -139,29 +144,25 @@ describe('UpgraderHandler', () => { }); it('does nothing when memory has no destination', () => { - const state = makeState(); - const memory = makeCreepMemory(); + const { state, memory } = createFixture(); expect(() => UpgraderHandler.destroy(memory, state)).not.toThrow(); }); }); - // ── validateCreepMemory (via run) ──────────────────────────────────────── - describe('validateCreepMemory (via run)', () => { it('releases previousDestination source spot and deletes it', () => { - const state = makeState(); - state.sourcesStates['src1'].spots[1] = PositionSpotStatus.OCCUPIED; - - const creep = makeCreep({ - previousDestination: { - type: 'source', - id: 'src1', - sourceSpot: 1, + const { state, creep, mockSource } = createFixture({ + memory: { + previousDestination: { + type: 'source', + id: 'src1', + sourceSpot: 1, + }, }, }); - - jest.spyOn(getById, 'getSourceById').mockReturnValue(null); + state.sourcesStates['src1'].spots[1] = PositionSpotStatus.OCCUPIED; + mockSource(null); UpgraderHandler.run(creep, state); @@ -172,23 +173,21 @@ describe('UpgraderHandler', () => { }); it('transitions from source to controller destination when energy is full', () => { - const state = makeState(); - const source = makeSource(); - jest.spyOn(getById, 'getSourceById').mockReturnValue(source); - - const controller = makeController(); - jest.spyOn(getById, 'getControllerById').mockReturnValue( - controller - ); - - const creep = makeCreep( - { - destination: { type: 'source', id: 'src1', sourceSpot: 0 }, - }, - 50, // full - 50, - controller - ); + const { state, controller, creep, mockSource, mockController } = + createFixture({ + memory: { + destination: { + type: 'source', + id: 'src1', + sourceSpot: 0, + }, + }, + storeUsed: 50, + storeCapacity: 50, + controllerInRoom: { id: 'ctrl1' } as StructureController, + }); + mockSource(); + mockController(controller); UpgraderHandler.run(creep, state); @@ -197,43 +196,36 @@ describe('UpgraderHandler', () => { }); it('clears controller destination when energy is empty', () => { - const state = makeState(); - const controller = makeController(); - jest.spyOn(getById, 'getControllerById').mockReturnValue( - controller - ); - - const creep = makeCreep( - { destination: { type: 'controller', id: 'ctrl1' } }, - 0, // empty - 50, - controller - ); + const { state, controller, creep, mockController } = createFixture({ + memory: { + destination: { type: 'controller', id: 'ctrl1' }, + }, + storeUsed: 0, + storeCapacity: 50, + controllerInRoom: { id: 'ctrl1' } as StructureController, + }); + mockController(controller); UpgraderHandler.run(creep, state); expect(creep.memory.destination).toBeUndefined(); }); - it('clears destination and logs when room has no controller during source→controller transition', () => { - const state = makeState(); - // Occupy all spots so onFindNewSource cannot reassign a source + it('clears destination and logs when room has no controller during source->controller transition', () => { + const { state, creep, mockSource } = createFixture({ + memory: { + destination: { type: 'source', id: 'src1', sourceSpot: 0 }, + }, + storeUsed: 50, + storeCapacity: 50, + controllerInRoom: null, + }); state.sourcesStates['src1'].spots = state.sourcesStates[ 'src1' ].spots.map((s: PositionSpotStatus) => - s === PositionSpotStatus.CENTER - ? s - : PositionSpotStatus.OCCUPIED + s === PositionSpotStatus.CENTER ? s : PositionSpotStatus.OCCUPIED ) as any; - - jest.spyOn(getById, 'getSourceById').mockReturnValue(makeSource()); - - const creep = makeCreep( - { destination: { type: 'source', id: 'src1', sourceSpot: 0 } }, - 50, - 50, - null // no controller in room - ); + mockSource(); UpgraderHandler.run(creep, state); @@ -241,14 +233,10 @@ describe('UpgraderHandler', () => { }); }); - // ── onFindNewSource ─────────────────────────────────────────────────────── - describe('onFindNewSource', () => { it('assigns the first available source spot to the creep', () => { - const state = makeState(); - jest.spyOn(getById, 'getSourceById').mockReturnValue(makeSource()); - - const creep = makeCreep(); // no destination, empty store + const { state, creep, mockSource } = createFixture(); + mockSource(); UpgraderHandler.run(creep, state); @@ -257,17 +245,13 @@ describe('UpgraderHandler', () => { }); it('does not assign a source when all spots are occupied', () => { - const state = makeState(); + const { state, creep, mockSource } = createFixture(); state.sourcesStates['src1'].spots = state.sourcesStates[ 'src1' ].spots.map((s: PositionSpotStatus) => - s === PositionSpotStatus.CENTER - ? s - : PositionSpotStatus.OCCUPIED + s === PositionSpotStatus.CENTER ? s : PositionSpotStatus.OCCUPIED ) as any; - - jest.spyOn(getById, 'getSourceById').mockReturnValue(makeSource()); - const creep = makeCreep(); + mockSource(); UpgraderHandler.run(creep, state); @@ -275,19 +259,14 @@ describe('UpgraderHandler', () => { }); }); - // ── onSourceDestination ─────────────────────────────────────────────────── - describe('onSourceDestination', () => { it('harvests when in range', () => { - const state = makeState(); - const source = makeSource(); - jest.spyOn(getById, 'getSourceById').mockReturnValue(source); - - const creep = makeCreep( - { destination: { type: 'source', id: 'src1', sourceSpot: 0 } }, - 0, - 50 - ); + const { state, source, creep, mockSource } = createFixture({ + memory: { + destination: { type: 'source', id: 'src1', sourceSpot: 0 }, + }, + }); + mockSource(); (creep.harvest as jest.Mock).mockReturnValue((global as any).OK); UpgraderHandler.run(creep, state); @@ -297,15 +276,12 @@ describe('UpgraderHandler', () => { }); it('moves to source when not in range', () => { - const state = makeState(); - const source = makeSource(); - jest.spyOn(getById, 'getSourceById').mockReturnValue(source); - - const creep = makeCreep( - { destination: { type: 'source', id: 'src1', sourceSpot: 0 } }, - 0, - 50 - ); + const { state, creep, mockSource } = createFixture({ + memory: { + destination: { type: 'source', id: 'src1', sourceSpot: 0 }, + }, + }); + mockSource(); (creep.harvest as jest.Mock).mockReturnValue( (global as any).ERR_NOT_IN_RANGE ); @@ -316,42 +292,33 @@ describe('UpgraderHandler', () => { }); it('logs and returns when source is not found', () => { - const state = makeState(); - jest.spyOn(getById, 'getSourceById').mockReturnValue(null); - - const creep = makeCreep( - { + const { state, creep, mockSource } = createFixture({ + memory: { destination: { type: 'source', id: 'unknown', sourceSpot: 0, }, }, - 0, - 50 - ); + }); + mockSource(null); expect(() => UpgraderHandler.run(creep, state)).not.toThrow(); expect(creep.harvest).not.toHaveBeenCalled(); }); }); - // ── onControllerDestination ─────────────────────────────────────────────── - describe('onControllerDestination', () => { it('upgrades controller when in range', () => { - const state = makeState(); - const controller = makeController(); - jest.spyOn(getById, 'getControllerById').mockReturnValue( - controller - ); - - const creep = makeCreep( - { destination: { type: 'controller', id: 'ctrl1' } }, - 50, - 50, - controller - ); + const { state, controller, creep, mockController } = createFixture({ + memory: { + destination: { type: 'controller', id: 'ctrl1' }, + }, + storeUsed: 50, + storeCapacity: 50, + controllerInRoom: { id: 'ctrl1' } as StructureController, + }); + mockController(controller); (creep.upgradeController as jest.Mock).mockReturnValue( (global as any).OK ); @@ -363,18 +330,15 @@ describe('UpgraderHandler', () => { }); it('moves to controller when not in range', () => { - const state = makeState(); - const controller = makeController(); - jest.spyOn(getById, 'getControllerById').mockReturnValue( - controller - ); - - const creep = makeCreep( - { destination: { type: 'controller', id: 'ctrl1' } }, - 50, - 50, - controller - ); + const { state, controller, creep, mockController } = createFixture({ + memory: { + destination: { type: 'controller', id: 'ctrl1' }, + }, + storeUsed: 50, + storeCapacity: 50, + controllerInRoom: { id: 'ctrl1' } as StructureController, + }); + mockController(controller); (creep.upgradeController as jest.Mock).mockReturnValue( (global as any).ERR_NOT_IN_RANGE ); @@ -388,14 +352,14 @@ describe('UpgraderHandler', () => { }); it('logs and returns when controller is not found by ID', () => { - const state = makeState(); - jest.spyOn(getById, 'getControllerById').mockReturnValue(null); - - const creep = makeCreep( - { destination: { type: 'controller', id: 'ctrl1' } }, - 50, - 50 - ); + const { state, creep, mockController } = createFixture({ + memory: { + destination: { type: 'controller', id: 'ctrl1' }, + }, + storeUsed: 50, + storeCapacity: 50, + }); + mockController(null); expect(() => UpgraderHandler.run(creep, state)).not.toThrow(); expect(creep.upgradeController).not.toHaveBeenCalled();