add # 新增开垦、升级土地功能

This commit is contained in:
2026-10-21 14:07:18 +08:00
parent e5bec1a2b6
commit 4a484bfde6
13 changed files with 709 additions and 33 deletions
+33 -1
View File
@@ -31,7 +31,7 @@ def snapshot(plots=None, **account):
values = dict(name="演示农场", point=500, vip_point=0, experience=0)
values.update(account)
return Snapshot(Account(**values), (), tuple(
plots if plots is not None else [Plot(i) for i in range(1, 4)]
plots if plots is not None else [Plot(i) for i in range(1, 7)]
))
@@ -42,6 +42,38 @@ class RenderTests(unittest.TestCase):
self.who = Identity("test", "local", "qq", "one")
self.plant = next(iter(Catalogue.bundled()))
def test_plot_ids_follow_positions_and_mark_owned_slots(self):
options = RenderOptions(width=1536, show_plot_ids=True)
scene = self.renderer.scene(self.who, snapshot(), 0)
canvas = Canvas.new((1536, 936), 'white')
with patch.object(canvas, 'text', wraps=canvas.text) as text:
self.renderer._plot_ids(canvas, scene, options)
self.assertEqual(
[call.args[1] for call in text.call_args_list[:30]],
[str(i) for i in range(1, 31)],
)
for slot, color in ((1, '#fff2ca'), (6, '#fff2ca'),
(7, '#d5e8bc'), (30, '#d5e8bc')):
pos = self.renderer.assets.metadata['positions'][slot-1]
x, y = round((pos['x']+117)/2), round((pos['y']+78)/2)
from PIL import ImageColor
self.assertEqual(canvas.image.getpixel((x-15, y))[:3],
ImageColor.getrgb(color))
def test_plot_id_image_has_separate_cache_from_normal_farm(self):
plain = self.renderer.render(self.who, snapshot(), 0)
options = RenderOptions(show_plot_ids=True)
numbered = self.renderer.render(self.who, snapshot(), 0, options)
self.assertFalse(numbered.cache_hit)
self.assertNotEqual(plain.content, numbered.content)
self.assertTrue(self.renderer.render(
self.who, snapshot(), 0, options,
).cache_hit)
self.assertEqual(
self.renderer.render(self.who, snapshot(), 0).content,
plain.content,
)
def test_canvas_alpha_crop_text_and_formats(self):
canvas = Canvas.new((100, 80), "white")
overlay = Image.new("RGBA", (20, 20), (255, 0, 0, 128))
+7 -4
View File
@@ -61,13 +61,16 @@ class TransactionTests(unittest.IsolatedAsyncioTestCase):
self.assertEqual(snapshot.account.point, 500)
self.assertEqual(snapshot.account.vip_point, 0)
self.assertEqual(snapshot.account.experience, 0)
self.assertEqual(len(snapshot.plots), 3)
self.assertEqual([p.slot for p in snapshot.plots], list(range(1, 7)))
self.assertTrue(all(p.plant is None for p in snapshot.plots))
repeated = await self.service.register(
self.identity, "另一个名称", "register-again",
)
self.assertFalse(repeated.data["created"])
self.assertEqual(repeated.data["account"]["point"], 500)
self.assertEqual(
(await self.service.snapshot(self.identity)).plots, snapshot.plots,
)
self.assertEqual(len(await self.store.ledger(self.identity)), 1)
async def test_scopes_are_independent(self):
@@ -158,13 +161,13 @@ class TransactionTests(unittest.IsolatedAsyncioTestCase):
self.assertEqual(result.data["account"]["vip_point"], 6)
async def test_sow_all_and_explicit_overflow(self):
await self.service.buy(self.identity, "萝卜", 5, "buy")
await self.service.buy(self.identity, "萝卜", 8, "buy")
before = await self.service.snapshot(self.identity)
with self.assertRaisesRegex(FarmError, "insufficient_empty_plots"):
await self.service.sow(self.identity, "萝卜", 4, "too-many")
await self.service.sow(self.identity, "萝卜", 7, "too-many")
self.assertEqual(await self.service.snapshot(self.identity), before)
result = await self.service.sow(self.identity, "萝卜", None, "all")
self.assertEqual(result.data["quantity"], 3)
self.assertEqual(result.data["quantity"], 6)
self.assertEqual(result.data["seeds"], 2)
async def test_maturity_boundary_and_multi_crop_lifecycle(self):
+38
View File
@@ -45,6 +45,44 @@ class ZhenxunRuntimeTests(unittest.IsolatedAsyncioTestCase):
**{**self.context, "message_id":message, **changes},
)
async def test_plot_ids_command_registration_hint_and_read_only(self):
from io import BytesIO
from PIL import Image
from unittest.mock import AsyncMock
self.assertEqual(self.module.COMMANDS['地块编号'], 'plot_ids')
self.assertIn('地块编号', await self.call('help'))
first = await self.call('register')
self.assertIn('6块土地', first)
self.assertIn('地块编号', first)
repeated = await self.call('register', message='again')
self.assertNotIn('已获得6块土地', repeated)
before = await self.runtime.service.snapshot(self.runtime_identity())
with patch.object(self.runtime.service, 'snapshot',
new=AsyncMock(return_value=before)) as query:
result = await self.call('plot_ids', message=None)
query.assert_awaited_once()
with Image.open(BytesIO(result)) as image:
self.assertEqual(image.width, 1024)
self.assertEqual(image.format, 'JPEG')
self.assertEqual(
await self.runtime.service.snapshot(self.runtime_identity()),
before,
)
self.assertIn('参数有误', await self.call('plot_ids', '1'))
self.assertIn('开通农场', await self.call('plot_ids', user_id='other'))
async def test_plot_ids_text_fallback_uses_actual_owned_slots(self):
await self.call('register')
rendering = self.runtime.rendering
self.runtime.rendering = None
try:
text = await self.call('plot_ids', message=None)
finally:
self.runtime.rendering = rendering
self.assertIn('已开垦(6块):1、2、3、4、5、6', text)
self.assertIn('待开垦(24块):7、8、9', text)
self.assertIn('农场详述', text)
async def test_original_commands_transactions_and_png(self):
self.assertNotIn("测试农场", self.module.COMMANDS)
self.assertIn("开通农场", self.module.COMMANDS)