155 lines
6.2 KiB
Python
155 lines
6.2 KiB
Python
import unittest
|
|
from unittest.mock import patch
|
|
from munch import Munch
|
|
|
|
from mosfet.commands import Commands
|
|
from mosfet.protocol.managers import EntityManager, WorldState
|
|
from mosfet.world import World
|
|
|
|
|
|
class SignReadingTests(unittest.TestCase):
|
|
def test_world_decodes_front_and_back_sign_components(self):
|
|
chunks = Munch(block_entities={
|
|
(2, 64, 3): {
|
|
'type': 7,
|
|
'data': {
|
|
'front_text': {'messages': [
|
|
'{"text":"Hello","extra":[{"text":" world"}]}',
|
|
'{"text":"line two"}', '', ''],
|
|
},
|
|
'back_text': {'messages': [
|
|
'{"text":"back"}', '', '', ''],
|
|
},
|
|
},
|
|
},
|
|
})
|
|
signs = World(Munch(chunks=chunks)).find_signs((0, 64, 0), 10)
|
|
|
|
self.assertEqual(signs, [
|
|
{'position': (2, 64, 3), 'side': 'front',
|
|
'lines': ('Hello world', 'line two', '', '')},
|
|
{'position': (2, 64, 3), 'side': 'back',
|
|
'lines': ('back', '', '', '')},
|
|
])
|
|
|
|
def test_block_entity_update_is_cached_for_sign_search(self):
|
|
chunks = WorldState()
|
|
manager = object.__new__(EntityManager)
|
|
manager.g = Munch(chunks=chunks)
|
|
manager.handle_block_entity_data(Munch(
|
|
location=Munch(x=4, y=65, z=-2),
|
|
block_entity_type=7,
|
|
data={'front_text': {'messages': ['{"text":"Farm"}', '', '', '']}},
|
|
))
|
|
|
|
signs = World(Munch(chunks=chunks)).find_signs((4, 65, -2), 1)
|
|
self.assertEqual(signs[0]['lines'], ('Farm', '', '', ''))
|
|
|
|
def test_group_and_individual_sign_addresses(self):
|
|
group_world = World(Munch(chunks=Munch(block_entities={
|
|
(0, 64, 0): {'data': {'front_text': {'messages': [
|
|
'mosfet', 'stay within25', 'square', '',
|
|
]}}},
|
|
}), pos=(0, 64, 0)))
|
|
for bot_name in ('mosfet1', 'mosfet2', 'mosfet3'):
|
|
self.assertEqual([p['shape'] for p in
|
|
group_world.sign_policies(bot_name)], ['square'])
|
|
self.assertEqual(group_world.sign_policies('mosfet4'), [])
|
|
|
|
individual_world = World(Munch(chunks=Munch(block_entities={
|
|
(1, 64, 0): {'data': {'front_text': {'messages': [
|
|
'mosfet2', 'stay within 10 circle', '', '',
|
|
]}}},
|
|
}), pos=(1, 64, 0)))
|
|
self.assertEqual([p['shape'] for p in
|
|
individual_world.sign_policies('mosfet2')], ['circle'])
|
|
self.assertEqual(individual_world.sign_policies('mosfet1'), [])
|
|
|
|
def test_nearest_sign_policy_overrides_farther_matching_sign(self):
|
|
chunks = Munch(block_entities={
|
|
(-138, 71, -268): {'data': {'front_text': {'messages': [
|
|
'mosfet1', 'stay within 25 square', '', '',
|
|
]}}},
|
|
(-158, 71, -248): {'data': {'front_text': {'messages': [
|
|
'mosfet1', 'stay within 6 squares', '', '',
|
|
]}}},
|
|
})
|
|
world = World(Munch(chunks=chunks, pos=(-158, 71, -248)))
|
|
self.assertEqual(world.sign_policies('mosfet1'), [{
|
|
'position': (-158, 71, -248), 'distance': 6,
|
|
'shape': 'square', 'side': 'front',
|
|
}])
|
|
|
|
def test_work_paths_obey_sign_boundary_but_cache_paths_do_not(self):
|
|
sign_data = {'front_text': {'messages': [
|
|
'mosfet1', 'stay within 25 square', '', '',
|
|
]}}
|
|
chunks = Munch(block_entities={(0, 64, 0): {'data': sign_data}})
|
|
work_machine = object()
|
|
cache_machine = object()
|
|
job = Munch(active_machine=work_machine,
|
|
cache_items_states=cache_machine)
|
|
world = World(Munch(chunks=chunks, job=job, name='mosfet1',
|
|
pos=(0, 64, 0)))
|
|
|
|
class FixedPathfinder:
|
|
@staticmethod
|
|
def astar(_start, _place):
|
|
return [(0, 64, 0), (20, 64, 0), (30, 64, 0)]
|
|
|
|
with patch('mosfet.world.path.Pathfinder', return_value=FixedPathfinder()):
|
|
self.assertIsNone(world.path_to_place((0, 64, 0), (30, 64, 0)))
|
|
job.active_machine = cache_machine
|
|
self.assertEqual(world.path_to_place(
|
|
(0, 64, 0), (30, 64, 0)),
|
|
[(0, 64, 0), (20, 64, 0), (30, 64, 0)])
|
|
|
|
policy = {'position': (0, 64, 0), 'distance': 25, 'shape': 'square'}
|
|
self.assertTrue(World._path_allowed_by_sign(
|
|
[(30, 64, 0), (27, 64, 0), (24, 64, 0)], policy))
|
|
self.assertFalse(World._path_allowed_by_sign(
|
|
[(30, 64, 0), (32, 64, 0), (24, 64, 0)], policy))
|
|
|
|
six_square = {'position': (-158, 71, -248),
|
|
'distance': 6, 'shape': 'square'}
|
|
six_circle = dict(six_square, shape='circle')
|
|
crop = (-162, 68, -247)
|
|
self.assertEqual(World._sign_policy_distance(crop, six_square), 4)
|
|
self.assertAlmostEqual(World._sign_policy_distance(crop, six_circle),
|
|
(17 ** 0.5))
|
|
|
|
four_square = {'position': (0, 64, 0),
|
|
'distance': 4, 'shape': 'square'}
|
|
self.assertEqual(World._sign_policy_distance((4, 70, 4), four_square), 4)
|
|
self.assertTrue(World._inside_sign_policy((4, 70, 4), four_square))
|
|
self.assertFalse(World._inside_sign_policy((5, 64, 4), four_square))
|
|
same_xz_far_y = (-158, -20, -248)
|
|
self.assertEqual(
|
|
World._sign_policy_distance(same_xz_far_y, six_square), 0)
|
|
|
|
def test_signs_command_replies_with_nearby_text(self):
|
|
class FakeChat:
|
|
def __init__(self):
|
|
self.sent = []
|
|
|
|
def set_handler(self, handler):
|
|
self.handler = handler
|
|
|
|
def send(self, message):
|
|
self.sent.append(message)
|
|
|
|
chat = FakeChat()
|
|
world = Munch(find_signs=lambda _position, _distance: [{
|
|
'position': (1, 64, 2), 'side': 'front',
|
|
'lines': ('Hello', 'world', '', ''),
|
|
}])
|
|
commands = Commands(Munch(
|
|
name='mosfet1', chat=chat, world=world, pos=(0.5, 64.0, 0.5)))
|
|
commands.handle_chat(('CHAT', 'tester', 'tester: !signs'))
|
|
|
|
self.assertEqual(chat.sent, ['front (1, 64, 2): Hello | world'])
|
|
|
|
|
|
if __name__ == '__main__':
|
|
unittest.main()
|