- `stone-furnace` 배치 후 자동으로 `coal`과 `iron-ore`/`copper-ore`를 투입하여 제련이 시작되도록 보정하는 기능 추가 - `insert_to_entity` 호출 전에 `can_insert` 여부를 확인하여 아이템 증발 위험을 줄이는 로직 개선 - `README.md`에 새로운 기능 설명 추가 - `tests/test_furnace_bootstrap.py` 및 `tests/test_insert_to_entity.py`에 대한 단위 테스트 추가
92 lines
3.0 KiB
Python
92 lines
3.0 KiB
Python
import unittest
|
|
|
|
|
|
from action_executor import ActionExecutor
|
|
|
|
|
|
class _FakeRCON:
|
|
pass
|
|
|
|
|
|
class TestFurnaceBootstrap(unittest.TestCase):
|
|
def test_auto_bootstrap_calls_insert_in_expected_order(self):
|
|
"""
|
|
stone-furnace 배치 직후:
|
|
- 먼저 coal(연료)을 넣고
|
|
- 그 다음 ore(iron-ore 우선)을 넣어 제련이 시작되어야 한다.
|
|
"""
|
|
ex = ActionExecutor(_FakeRCON())
|
|
|
|
def fake_get_item_count(item: str) -> int:
|
|
return {
|
|
"coal": 20,
|
|
"iron-ore": 50,
|
|
"copper-ore": 0,
|
|
}.get(item, 0)
|
|
|
|
ex._get_item_count = fake_get_item_count # type: ignore[attr-defined]
|
|
|
|
calls: list[tuple[int, int, str, int]] = []
|
|
|
|
def fake_insert(x: int, y: int, item: str = "coal", count: int = 50):
|
|
calls.append((x, y, item, count))
|
|
return True, "OK"
|
|
|
|
ex.insert_to_entity = fake_insert # type: ignore[assignment]
|
|
|
|
# NOTE: 아직 구현 전이므로 이 테스트는 현재 실패해야 한다(TDD RED).
|
|
ex._auto_bootstrap_furnace(
|
|
furnace_name="stone-furnace",
|
|
x=-91,
|
|
y=-68,
|
|
reason="iron-ore(50) 제련 시작",
|
|
)
|
|
|
|
self.assertEqual(calls[0][2], "coal")
|
|
self.assertEqual(calls[0][3], 20) # min(50, coal=20)
|
|
|
|
self.assertEqual(calls[1][2], "iron-ore")
|
|
self.assertEqual(calls[1][3], 50) # min(50, iron-ore=50)
|
|
self.assertEqual(len(calls), 2)
|
|
|
|
def test_execute_triggers_bootstrap_after_successful_place_entity(self):
|
|
ex = ActionExecutor(_FakeRCON())
|
|
|
|
# place_entity를 성공으로 고정(좌표는 message에서 파싱한다고 가정)
|
|
def fake_place_entity(name: str, x: int, y: int, direction: str = "north"):
|
|
return True, "stone-furnace 배치 (-91, -68)"
|
|
|
|
ex.place_entity = fake_place_entity # type: ignore[assignment]
|
|
|
|
called: list[dict] = []
|
|
|
|
def fake_auto_bootstrap(*, furnace_name: str, x: int, y: int, reason: str = ""):
|
|
called.append({
|
|
"furnace_name": furnace_name,
|
|
"x": x,
|
|
"y": y,
|
|
"reason": reason,
|
|
})
|
|
return True, "mock_bootstrap_ok"
|
|
|
|
# NOTE: 아직 구현 전이므로 이 테스트는 현재 실패해야 한다(TDD RED).
|
|
ex._auto_bootstrap_furnace = fake_auto_bootstrap # type: ignore[attr-defined]
|
|
|
|
ok, msg = ex.execute({
|
|
"action": "place_entity",
|
|
"reason": "현재 인벤토리에 iron-ore(50)가 있어 제련 시작",
|
|
"params": {
|
|
"name": "stone-furnace",
|
|
"x": -91,
|
|
"y": -68,
|
|
"direction": "north",
|
|
},
|
|
})
|
|
|
|
self.assertTrue(ok, msg)
|
|
self.assertEqual(len(called), 1)
|
|
self.assertEqual(called[0]["furnace_name"], "stone-furnace")
|
|
self.assertEqual(called[0]["x"], -91)
|
|
self.assertEqual(called[0]["y"], -68)
|
|
|