'use strict'; const test = require('node:test'); const assert = require('node:assert'); const { fillTemplate } = require('../src/bot/botManager'); const { AutoEater, findFoodSlot } = require('../src/bot/autoEat'); const { DurabilityGuard, CHECK_INTERVAL_MS } = require('../src/bot/durabilityGuard'); const { defaultConfig } = require('../src/config/expansionConfig'); const { FakeBot } = require('./helpers/fakeBot'); test('fillTemplate 替换密码占位符', () => { assert.strictEqual(fillTemplate('login {password}', 'abc123'), 'login abc123'); assert.strictEqual(fillTemplate('register {password} {password}', 'p'), 'register p p'); assert.strictEqual(fillTemplate('login', 'abc'), 'login', '无占位符时原样返回'); }); test('findFoodSlot 找到背包中的食物', () => { const bot = new FakeBot({ slots: [ { name: 'diamond_sword' }, { name: 'cooked_beef' }, { name: 'apple' } ] }); assert.strictEqual(findFoodSlot(bot), 1); }); test('findFoodSlot 没有食物时返回 -1', () => { const bot = new FakeBot({ slots: [{ name: 'diamond_sword' }, { name: 'stone' }] }); assert.strictEqual(findFoodSlot(bot), -1); }); test('自动进食:饥饿低于阈值时开始进食', async () => { const bot = new FakeBot({ slots: [{ name: 'cooked_beef' }] }); bot.food = 10; const config = defaultConfig(); const eater = new AutoEater(bot, config, null, null); const busy = eater.tick(); assert.strictEqual(busy, true); await new Promise((resolve) => setImmediate(resolve)); assert.strictEqual(bot.food, 20, '进食后饥饿值应回满'); assert.strictEqual(eater.eating, false, '进食完成后应复位'); }); test('自动进食:饥饿充足时不做任何事', () => { const bot = new FakeBot({ slots: [{ name: 'cooked_beef' }] }); bot.food = 20; const eater = new AutoEater(bot, defaultConfig(), null, null); assert.strictEqual(eater.tick(), false); assert.strictEqual(eater.eating, false); }); test('自动进食:背包没有食物时保持非占用状态', () => { const bot = new FakeBot({ slots: [{ name: 'stone' }] }); bot.food = 5; const eater = new AutoEater(bot, defaultConfig(), null, null); assert.strictEqual(eater.tick(), false); assert.strictEqual(eater.eating, false); }); test('自动进食:autoEat 关闭时完全跳过', () => { const bot = new FakeBot({ slots: [{ name: 'cooked_beef' }] }); bot.food = 5; const config = defaultConfig(); config.autoEat = false; const eater = new AutoEater(bot, config, null, null); assert.strictEqual(eater.tick(), false); }); test('自动进食:进食前松开移动键(防 NoSlow)', async () => { const bot = new FakeBot({ slots: [{ name: 'cooked_beef' }] }); bot.food = 10; const controls = {}; const grim = { setControlState(control, state) { controls[control] = state; }, setLook() {} }; const config = defaultConfig(); const eater = new AutoEater(bot, config, null, grim); eater.tick(); await new Promise((resolve) => setImmediate(resolve)); for (const control of ['forward', 'back', 'left', 'right', 'sprint', 'jump']) { assert.strictEqual(controls[control], false, control + ' 应被松开'); } }); test('耐久保护:按间隔节流检查', () => { const bot = new FakeBot({ slots: [] }); bot.heldItem = { name: 'diamond_sword', maxDurability: 1561, durabilityUsed: 1500 }; const guard = new DurabilityGuard(bot, defaultConfig(), null); const first = guard.check(1000000); assert.ok(first, '首次检查应立即生效'); assert.strictEqual(guard.check(1000000 + CHECK_INTERVAL_MS - 1), null, '间隔内不再检查'); assert.ok(guard.check(1000000 + CHECK_INTERVAL_MS), '超过间隔后再次检查'); }); test('耐久保护:关闭时永远返回 null', () => { const bot = new FakeBot({ slots: [] }); bot.heldItem = { name: 'diamond_sword', maxDurability: 1561, durabilityUsed: 1561 }; const config = defaultConfig(); config.durabilityGuard = false; const guard = new DurabilityGuard(bot, config, null); assert.strictEqual(guard.check(1000), null); }); test('耐久保护:reset 后立即重新检查', () => { const bot = new FakeBot({ slots: [] }); bot.heldItem = { name: 'diamond_sword', maxDurability: 1561, durabilityUsed: 1500 }; const guard = new DurabilityGuard(bot, defaultConfig(), null); guard.check(1000000); guard.reset(); assert.ok(guard.check(1000000), 'reset 后应可立即再次检查'); });