From d78e6ebd26ce28ff049cd046a9fc3b233f6bf049 Mon Sep 17 00:00:00 2001 From: Victor Bodinaud Date: Thu, 8 Oct 2026 12:49:23 +0200 Subject: [PATCH] feat(sim): move items from shelf back to backroom --- src/sim/inventory.ts | 12 ++++++++++++ tests/sim/inventory.test.ts | 25 ++++++++++++++++++++++++- 2 files changed, 36 insertions(+), 1 deletion(-) diff --git a/src/sim/inventory.ts b/src/sim/inventory.ts index c84d0ec..35b175d 100644 --- a/src/sim/inventory.ts +++ b/src/sim/inventory.ts @@ -64,6 +64,18 @@ export function stockSlot(inv: Inventory, slotId: string, item: ItemRef, qty: nu return moved; } +/** Moves up to `qty` items from the slot back to the backroom. Returns the quantity moved. */ +export function unstockSlot(inv: Inventory, slotId: string, qty: number): number { + const slot = getSlot(inv, slotId); + if (!slot.item || slot.qty === 0) return 0; + const moved = Math.min(qty, slot.qty); + if (moved <= 0) return 0; + addToBackroom(inv, slot.item, moved); + slot.qty -= moved; + if (slot.qty === 0) slot.item = null; + return moved; +} + export function takeFromSlot(inv: Inventory, slotId: string): ItemRef { const slot = getSlot(inv, slotId); if (!slot.item || slot.qty === 0) throw new Error(`Slot ${slotId} is empty`); diff --git a/tests/sim/inventory.test.ts b/tests/sim/inventory.test.ts index 2107023..ab6845a 100644 --- a/tests/sim/inventory.test.ts +++ b/tests/sim/inventory.test.ts @@ -1,7 +1,7 @@ import { describe, it, expect } from 'vitest'; import { addToBackroom, backroomQty, createInventory, getSlot, itemKey, parseItemKey, - shelfItems, SLOT_CAPACITY, stockSlot, takeFromSlot, totalQty, + shelfItems, SLOT_CAPACITY, stockSlot, takeFromSlot, totalQty, unstockSlot, } from '../../src/sim/inventory'; const tetrisNew = { gameId: 'tetris', condition: 'new' as const }; @@ -60,6 +60,29 @@ describe('inventory', () => { expect(() => takeFromSlot(inv, 'slot-0')).toThrow('Slot slot-0 is empty'); }); + it('moves items from a slot back to the backroom', () => { + const inv = createInventory(1); + addToBackroom(inv, tetrisNew, 4); + stockSlot(inv, 'slot-0', tetrisNew, 4); + expect(unstockSlot(inv, 'slot-0', 3)).toBe(3); + expect(getSlot(inv, 'slot-0').qty).toBe(1); + expect(backroomQty(inv, tetrisNew)).toBe(3); + }); + + it('caps unstocking to the slot quantity and clears the slot at 0', () => { + const inv = createInventory(1); + addToBackroom(inv, tetrisNew, 2); + stockSlot(inv, 'slot-0', tetrisNew, 2); + expect(unstockSlot(inv, 'slot-0', 10)).toBe(2); + expect(getSlot(inv, 'slot-0')).toEqual({ id: 'slot-0', item: null, qty: 0 }); + expect(backroomQty(inv, tetrisNew)).toBe(2); + }); + + it('returns 0 when unstocking an empty slot', () => { + const inv = createInventory(1); + expect(unstockSlot(inv, 'slot-0', 3)).toBe(0); + }); + it('throws on unknown slot', () => { expect(() => getSlot(createInventory(1), 'slot-9')).toThrow('Unknown slot: slot-9'); });