1603 lines
41 KiB
Python
1603 lines
41 KiB
Python
"""
|
|
|
|
Tests for the XYZgrid system.
|
|
|
|
"""
|
|
from random import randint
|
|
from unittest import mock
|
|
|
|
from django.test import TestCase
|
|
from evennia.utils.test_resources import BaseEvenniaCommandTest, BaseEvenniaTest
|
|
from parameterized import parameterized
|
|
|
|
from . import commands, xymap, xymap_legend, xyzgrid, xyzroom
|
|
|
|
MAP1 = """
|
|
|
|
+ 0 1 2
|
|
|
|
1 #-#
|
|
| |
|
|
0 #-#
|
|
|
|
+ 0 1 2
|
|
|
|
"""
|
|
|
|
MAP1_DISPLAY = """
|
|
#-#
|
|
| |
|
|
#-#
|
|
""".strip()
|
|
|
|
|
|
MAP2 = """
|
|
|
|
+ 0 1 2 3 4 5
|
|
|
|
5 #-#-#-#-#
|
|
| |
|
|
4 #---#
|
|
| |
|
|
3 # | #-#
|
|
| | |
|
|
2 #-#-#-#---#
|
|
| |
|
|
1 #-#-#---#-#
|
|
| |
|
|
0 #-#-#-#
|
|
|
|
+ 0 1 2 3 4 5
|
|
|
|
"""
|
|
|
|
MAP2_DISPLAY = """
|
|
#-#-#-#-#
|
|
| |
|
|
#---#
|
|
| |
|
|
# | #-#
|
|
| | |
|
|
#-#-#-#---#
|
|
| |
|
|
#-#-#---#-#
|
|
| |
|
|
#-#-#-#
|
|
""".strip()
|
|
|
|
MAP3 = r"""
|
|
|
|
+ 0 1 2 3 4 5
|
|
|
|
5 #-#---# #
|
|
| / \ /
|
|
4 # / #
|
|
|/ |
|
|
3 # #
|
|
|\ / \
|
|
2 # #-# #
|
|
|/ \ /
|
|
1 # #
|
|
/ \ |
|
|
0 # #---#-#
|
|
|
|
+ 0 1 2 3 4 5
|
|
|
|
"""
|
|
|
|
MAP3_DISPLAY = r"""
|
|
#-#---# #
|
|
| / \ /
|
|
# / #
|
|
|/ |
|
|
# #
|
|
|\ / \
|
|
# #-# #
|
|
|/ \ /
|
|
# #
|
|
/ \ |
|
|
# #---#-#
|
|
""".strip()
|
|
|
|
MAP4 = r"""
|
|
|
|
+ 0 1 2 3 4
|
|
|
|
4 #-# #---#
|
|
x /
|
|
3 #-#-#
|
|
|x x|
|
|
2 #-#-#-#
|
|
| | |
|
|
1 #-+-#-+-#
|
|
| |
|
|
0 #---#
|
|
|
|
+ 0 1 2 3 4
|
|
|
|
"""
|
|
|
|
MAP4_DISPLAY = r"""
|
|
#-# #---#
|
|
x /
|
|
#-#-#
|
|
|x x|
|
|
#-#-#-#
|
|
| | |
|
|
#-+-#-+-#
|
|
| |
|
|
#---#
|
|
""".strip()
|
|
|
|
MAP5 = r"""
|
|
|
|
+ 0 1 2
|
|
|
|
2 #-#
|
|
| |
|
|
1 #>#
|
|
|
|
0 #>#
|
|
|
|
+ 0 1 2
|
|
|
|
"""
|
|
|
|
MAP5_DISPLAY = r"""
|
|
#-#
|
|
| |
|
|
#>#
|
|
|
|
#>#
|
|
""".strip()
|
|
|
|
MAP6 = r"""
|
|
|
|
+ 0 1 2 3 4
|
|
|
|
4 #-#-#-#
|
|
^ |
|
|
3 | #>#
|
|
| | |
|
|
2 #-#-#-#
|
|
^ v
|
|
1 #---#-#
|
|
| | |
|
|
0 #-#>#-#<#
|
|
|
|
+ 0 1 2 3 4
|
|
|
|
"""
|
|
|
|
MAP6_DISPLAY = r"""
|
|
#-#-#-#
|
|
^ |
|
|
| #>#
|
|
| | |
|
|
#-#-#-#
|
|
^ v
|
|
#---#-#
|
|
| | |
|
|
#-#>#-#<#
|
|
""".strip()
|
|
|
|
|
|
MAP7 = r"""
|
|
+ 0 1 2
|
|
|
|
2 #-#
|
|
|
|
|
1 #-o-#
|
|
|
|
|
0 #-#
|
|
|
|
+ 0 1 2
|
|
|
|
"""
|
|
|
|
MAP7_DISPLAY = r"""
|
|
#-#
|
|
|
|
|
#-o-#
|
|
|
|
|
#-#
|
|
""".strip()
|
|
|
|
|
|
MAP8 = r"""
|
|
+ 0 1 2 3 4 5
|
|
|
|
4 #-#-o o o-o
|
|
| \|/| | |
|
|
3 #-o-o-# o-#
|
|
| /|\ |
|
|
2 o-o-#-# o
|
|
| | /
|
|
1 #-o-#-o-#
|
|
| /
|
|
0 #---#-o
|
|
|
|
+ 0 1 2 3 4 5
|
|
|
|
"""
|
|
|
|
MAP8_DISPLAY = r"""
|
|
#-#-o o o-o
|
|
| \|/| | |
|
|
#-o-o-# o-#
|
|
| /|\ |
|
|
o-o-#-# o
|
|
| | /
|
|
#-o-#-o-#
|
|
| /
|
|
#---#-o
|
|
""".strip()
|
|
|
|
|
|
MAP9 = r"""
|
|
+ 0 1 2 3
|
|
|
|
3 #-#-#-#
|
|
d d d
|
|
2 | | |
|
|
u u u
|
|
1 #-# #-#
|
|
u d
|
|
0 #d# #u#
|
|
|
|
+ 0 1 2 3
|
|
|
|
"""
|
|
|
|
MAP9_DISPLAY = r"""
|
|
#-#-#-#
|
|
d d d
|
|
| | |
|
|
u u u
|
|
#-# #-#
|
|
u d
|
|
#d# #u#
|
|
""".strip()
|
|
|
|
|
|
MAP10 = r"""
|
|
|
|
+ 0 1 2 3
|
|
|
|
4 #---#-#
|
|
b |
|
|
3 #i#---#
|
|
|/|
|
|
2 # #-I-#
|
|
|
|
|
1 #-#b#-#
|
|
| | b
|
|
0 #b#-#-#
|
|
|
|
+ 0 1 2 3
|
|
|
|
"""
|
|
|
|
# note that I,i,b are invisible
|
|
MAP10_DISPLAY = r"""
|
|
#---#-#
|
|
/ |
|
|
#-#---#
|
|
|/|
|
|
# #-#-#
|
|
|
|
|
#-#-#-#
|
|
| | |
|
|
#-#-#-#
|
|
""".strip()
|
|
|
|
|
|
MAP11 = r"""
|
|
|
|
+ 0 1 2 3
|
|
|
|
2 #-#
|
|
\
|
|
1 t t
|
|
\
|
|
0 #-#
|
|
|
|
+ 0 1 2 3
|
|
|
|
"""
|
|
|
|
|
|
MAP11_DISPLAY = r"""
|
|
#-#
|
|
\
|
|
|
|
\
|
|
#-#
|
|
""".strip()
|
|
|
|
MAP12a = r"""
|
|
|
|
+ 0 1
|
|
|
|
1 #-T
|
|
|
|
|
0 #-#
|
|
|
|
+ 0 1
|
|
|
|
"""
|
|
|
|
|
|
MAP12b = r"""
|
|
|
|
+ 0 1
|
|
|
|
1 #-#
|
|
|
|
|
0 T-#
|
|
|
|
+ 0 1
|
|
|
|
"""
|
|
|
|
MAP13a = r"""
|
|
|
|
+ 0 1
|
|
|
|
1 #-#
|
|
|
|
|
0 #
|
|
|
|
+ 0 1
|
|
|
|
"""
|
|
|
|
MAP13b = r"""
|
|
|
|
+ 0 1
|
|
|
|
1 #
|
|
|
|
0
|
|
|
|
+ 0 1
|
|
|
|
"""
|
|
|
|
MAP13c = r"""
|
|
|
|
+ 0 1
|
|
|
|
1 #
|
|
|
|
0
|
|
|
|
+ 0 1
|
|
|
|
"""
|
|
|
|
MAP13d = r"""
|
|
|
|
+ 0 1
|
|
|
|
1 #-#
|
|
|
|
|
0 #
|
|
|
|
+ 0 1
|
|
|
|
"""
|
|
|
|
|
|
class _MapTest(BaseEvenniaTest):
|
|
"""
|
|
Parent for map tests
|
|
|
|
"""
|
|
|
|
map_data = {"map": MAP1, "zcoord": "map1"}
|
|
map_display = MAP1_DISPLAY
|
|
|
|
def setUp(self):
|
|
"""Set up grid and map"""
|
|
super().setUp()
|
|
self.grid, err = xyzgrid.XYZGrid.create("testgrid")
|
|
self.grid.add_maps(self.map_data)
|
|
self.map = self.grid.get_map(self.map_data["zcoord"])
|
|
|
|
# output to console
|
|
# def _log(msg):
|
|
# print(msg)
|
|
# self.grid.log = _log
|
|
|
|
def tearDown(self):
|
|
self.grid.delete()
|
|
xyzroom.XYZRoom.objects.all().delete()
|
|
xyzroom.XYZExit.objects.all().delete()
|
|
|
|
|
|
class TestMap1(_MapTest):
|
|
"""
|
|
Test the Map class with a simple 4-node map
|
|
|
|
"""
|
|
|
|
def test_str_output(self):
|
|
"""Check the display_map"""
|
|
self.assertEqual(str(self.map).replace("||", "|").strip(), MAP1_DISPLAY)
|
|
|
|
def test_node_from_coord(self):
|
|
node = self.map.get_node_from_coord((1, 1))
|
|
self.assertEqual(node.X, 1)
|
|
self.assertEqual(node.x, 2)
|
|
self.assertEqual(node.X, 1)
|
|
self.assertEqual(node.y, 2)
|
|
|
|
def test_get_shortest_path(self):
|
|
directions, path = self.map.get_shortest_path((0, 0), (1, 1))
|
|
self.assertEqual(directions, ["e", "n"])
|
|
self.assertEqual(
|
|
[str(node) for node in path],
|
|
[
|
|
str(self.map.node_index_map[0]),
|
|
"<LinkNode '-' XY=(0.5,0)>",
|
|
str(self.map.node_index_map[1]),
|
|
"<LinkNode '|' XY=(1,0.5)>",
|
|
str(self.map.node_index_map[3]),
|
|
],
|
|
)
|
|
|
|
@parameterized.expand(
|
|
[
|
|
((0, 0), "| \n#-", [["|", " "], ["#", "-"]]),
|
|
((1, 0), " |\n-#", [[" ", "|"], ["-", "#"]]),
|
|
((0, 1), "#-\n| ", [["#", "-"], ["|", " "]]),
|
|
((1, 1), "-#\n |", [["-", "#"], [" ", "|"]]),
|
|
]
|
|
)
|
|
def test_get_visual_range__scan(self, coord, expectstr, expectlst):
|
|
"""
|
|
Test displaying a part of the map around a central point.
|
|
|
|
"""
|
|
mapstr = self.map.get_visual_range(coord, dist=1, mode="scan", character=None)
|
|
maplst = self.map.get_visual_range(
|
|
coord, dist=1, mode="scan", return_str=False, character=None
|
|
)
|
|
maplst = [[part.replace("||", "|") for part in partlst] for partlst in maplst]
|
|
self.assertEqual(expectstr, mapstr.replace("||", "|"))
|
|
self.assertEqual(expectlst, maplst[::-1])
|
|
|
|
@parameterized.expand(
|
|
[
|
|
((0, 0), "| \n@-", [["|", " "], ["@", "-"]]),
|
|
((1, 0), " |\n-@", [[" ", "|"], ["-", "@"]]),
|
|
((0, 1), "@-\n| ", [["@", "-"], ["|", " "]]),
|
|
((1, 1), "-@\n |", [["-", "@"], [" ", "|"]]),
|
|
]
|
|
)
|
|
def test_get_visual_range__scan__character(self, coord, expectstr, expectlst):
|
|
"""
|
|
Test displaying a part of the map around a central point, showing the
|
|
character @-symbol in that spot.
|
|
|
|
"""
|
|
mapstr = self.map.get_visual_range(coord, dist=1, mode="scan", character="@")
|
|
maplst = self.map.get_visual_range(
|
|
coord, dist=1, mode="scan", return_str=False, character="@"
|
|
)
|
|
maplst = [[part.replace("||", "|") for part in partlst] for partlst in maplst]
|
|
self.assertEqual(expectstr, mapstr.replace("||", "|"))
|
|
self.assertEqual(expectlst, maplst[::-1]) # flip y-axis for print
|
|
|
|
@parameterized.expand(
|
|
[
|
|
((0, 0), 1, "# \n| \n@-#"),
|
|
((0, 1), 1, "@-#\n| \n# "),
|
|
((1, 0), 1, " #\n |\n#-@"),
|
|
((1, 1), 1, "#-@\n |\n #"),
|
|
((0, 0), 2, "#-#\n| |\n@-#"),
|
|
]
|
|
)
|
|
def test_get_visual_range__nodes__character(self, coord, dist, expected):
|
|
"""
|
|
Get sub-part of map with node-mode.
|
|
|
|
"""
|
|
mapstr = self.map.get_visual_range(coord, dist=dist, mode="nodes", character="@")
|
|
self.assertEqual(expected, mapstr.replace("||", "|"))
|
|
|
|
def test_spawn(self):
|
|
"""
|
|
Spawn the map into actual objects.
|
|
|
|
"""
|
|
self.grid.spawn()
|
|
self.assertEqual(xyzroom.XYZRoom.objects.all().count(), 4)
|
|
self.assertEqual(xyzroom.XYZExit.objects.all().count(), 8)
|
|
|
|
|
|
class TestMap2(_MapTest):
|
|
"""
|
|
Test with Map2 - a bigger map with multi-step links
|
|
|
|
"""
|
|
|
|
map_data = {"map": MAP2, "zcoord": "map2"}
|
|
map_display = MAP2_DISPLAY
|
|
|
|
def test_str_output(self):
|
|
"""Check the display_map"""
|
|
# strip the leftover spaces on the right to better
|
|
# work with text editor stripping this automatically ...
|
|
stripped_map = "\n".join(line.rstrip() for line in str(self.map).split("\n"))
|
|
self.assertEqual(stripped_map.replace("||", "|"), MAP2_DISPLAY)
|
|
|
|
def test_node_from_coord(self):
|
|
for mapnode in self.map.node_index_map.values():
|
|
node = self.map.get_node_from_coord((mapnode.X, mapnode.Y))
|
|
self.assertEqual(node, mapnode)
|
|
self.assertEqual(node.x // 2, node.X)
|
|
self.assertEqual(node.y // 2, node.Y)
|
|
|
|
@parameterized.expand(
|
|
[
|
|
((1, 0), (4, 0), ("e", "e", "e")), # straight path
|
|
((1, 0), (5, 1), ("n", "e", "e", "e")), # shortcut over long link
|
|
((2, 2), (2, 5), ("n", "n")), # shortcut over long link (vertical)
|
|
((4, 4), (0, 5), ("w", "n", "w", "w")), # shortcut over long link (vertical)
|
|
((4, 0), (0, 5), ("n", "w", "n", "n", "n", "w", "w")), # across entire grid
|
|
((4, 0), (0, 5), ("n", "w", "n", "n", "n", "w", "w")), # across entire grid
|
|
((5, 3), (0, 3), ("s", "w", "w", "w", "w", "n")), # down and back
|
|
]
|
|
)
|
|
def test_shortest_path(self, startcoord, endcoord, expected_directions):
|
|
"""
|
|
Test shortest-path calculations throughout the grid.
|
|
|
|
"""
|
|
directions, _ = self.map.get_shortest_path(startcoord, endcoord)
|
|
self.assertEqual(expected_directions, tuple(directions))
|
|
|
|
@parameterized.expand(
|
|
[
|
|
((1, 0), "#-#-#-#\n| | \n#-#-#--\n | \n @-#-#"),
|
|
(
|
|
(2, 2),
|
|
(
|
|
" #---#\n | |\n# | #\n| | \n#-#-@-#--\n| "
|
|
"| \n#-#-#---#\n | |\n #-#-#-#"
|
|
),
|
|
),
|
|
((4, 5), "#-#-@ \n| | \n#---# \n| | \n| #-#"),
|
|
((5, 2), "--# \n | \n #-#\n |\n#---@\n \n--#-#\n | \n#-# "),
|
|
]
|
|
)
|
|
def test_get_visual_range__scan__character(self, coord, expected):
|
|
"""
|
|
Test showing smaller part of grid, showing @-character in the middle.
|
|
|
|
"""
|
|
mapstr = self.map.get_visual_range(coord, dist=4, mode="scan", character="@")
|
|
self.assertEqual(expected, mapstr.replace("||", "|"))
|
|
|
|
def test_extended_path_tracking__horizontal(self):
|
|
"""
|
|
Crossing multi-gridpoint links should be tracked properly.
|
|
|
|
"""
|
|
node = self.map.get_node_from_coord((4, 1))
|
|
self.assertEqual(
|
|
{
|
|
direction: [step.symbol for step in steps]
|
|
for direction, steps in node.xy_steps_to_node.items()
|
|
},
|
|
{"e": ["-"], "s": ["|"], "w": ["-", "-", "-"]},
|
|
)
|
|
|
|
def test_extended_path_tracking__vertical(self):
|
|
"""
|
|
Testing multi-gridpoint links in the vertical direction.
|
|
|
|
"""
|
|
node = self.map.get_node_from_coord((2, 2))
|
|
self.assertEqual(
|
|
{
|
|
direction: [step.symbol for step in steps]
|
|
for direction, steps in node.xy_steps_to_node.items()
|
|
},
|
|
{"n": ["|", "|", "|"], "e": ["-"], "s": ["|"], "w": ["-"]},
|
|
)
|
|
|
|
@parameterized.expand(
|
|
[
|
|
((0, 0), 2, None, "@"), # outside of any known node
|
|
((4, 5), 0, None, "@"), # 0 distance
|
|
((1, 0), 2, None, "#-#-# \n | \n @-#-#"),
|
|
((0, 5), 1, None, "@-#"),
|
|
(
|
|
(0, 5),
|
|
4,
|
|
None,
|
|
"@-#-#-#-#\n | \n #---#\n | \n | \n | \n # ",
|
|
),
|
|
((5, 1), 3, None, " # \n | \n#-#---#-@\n | \n #-# "),
|
|
(
|
|
(2, 2),
|
|
2,
|
|
None,
|
|
(
|
|
" # \n | \n #---# \n | \n | \n | \n"
|
|
"#-#-@-#---#\n | \n #-#---# "
|
|
),
|
|
),
|
|
((2, 2), 2, (5, 5), " | \n | \n#-@-#\n | \n#-#--"), # limit display size
|
|
((2, 2), 4, (3, 3), " | \n-@-\n | "),
|
|
((2, 2), 4, (1, 1), "@"),
|
|
]
|
|
)
|
|
def test_get_visual_range__nodes__character(self, coord, dist, max_size, expected):
|
|
"""
|
|
Get sub-part of map with node-mode.
|
|
|
|
"""
|
|
mapstr = self.map.get_visual_range(
|
|
coord, dist=dist, mode="nodes", character="@", max_size=max_size
|
|
)
|
|
self.assertEqual(expected, mapstr.replace("||", "|"))
|
|
|
|
def test_spawn(self):
|
|
"""
|
|
Spawn the map into actual objects.
|
|
|
|
"""
|
|
self.grid.spawn()
|
|
self.assertEqual(xyzroom.XYZRoom.objects.all().count(), 24)
|
|
self.assertEqual(xyzroom.XYZExit.objects.all().count(), 54)
|
|
|
|
|
|
class TestMap3(_MapTest):
|
|
"""
|
|
Test Map3 - Map with diagonal links
|
|
|
|
"""
|
|
|
|
map_data = {"map": MAP3, "zcoord": "map3"}
|
|
map_display = MAP3_DISPLAY
|
|
|
|
def test_str_output(self):
|
|
"""Check the display_map"""
|
|
stripped_map = "\n".join(line.rstrip() for line in str(self.map).split("\n"))
|
|
self.assertEqual(MAP3_DISPLAY, stripped_map.replace("||", "|"))
|
|
|
|
@parameterized.expand(
|
|
[
|
|
((0, 0), (1, 0), ()), # no node at (1, 0)!
|
|
((2, 0), (5, 0), ("e", "e")), # straight path
|
|
((0, 0), (1, 1), ("ne",)),
|
|
((4, 1), (4, 3), ("nw", "ne")),
|
|
((4, 1), (4, 3), ("nw", "ne")),
|
|
((2, 2), (3, 5), ("nw", "ne")),
|
|
((2, 2), (1, 5), ("nw", "n", "n")),
|
|
((5, 5), (0, 0), ("sw", "s", "sw", "w", "sw", "sw")),
|
|
((5, 5), (0, 0), ("sw", "s", "sw", "w", "sw", "sw")),
|
|
((5, 2), (1, 2), ("sw", "nw", "w", "nw", "s")),
|
|
((4, 1), (1, 1), ("s", "w", "nw")),
|
|
]
|
|
)
|
|
def test_shortest_path(self, startcoord, endcoord, expected_directions):
|
|
"""
|
|
Test shortest-path calculations throughout the grid.
|
|
|
|
"""
|
|
directions, _ = self.map.get_shortest_path(startcoord, endcoord)
|
|
self.assertEqual(expected_directions, tuple(directions))
|
|
|
|
@parameterized.expand(
|
|
[
|
|
(
|
|
(2, 2),
|
|
2,
|
|
None,
|
|
(
|
|
" # \n / \n # / \n |/ \n # #\n |\\ / \n # @-# \n"
|
|
" |/ \\ \n # #\n / \\ \n# # "
|
|
),
|
|
),
|
|
((5, 2), 2, None, " # \n | \n # \n / \\ \n# @\n \\ / \n # \n | \n # "),
|
|
]
|
|
)
|
|
def test_get_visual_range__nodes__character(self, coord, dist, max_size, expected):
|
|
"""
|
|
Get sub-part of map with node-mode.
|
|
|
|
"""
|
|
mapstr = self.map.get_visual_range(
|
|
coord, dist=dist, mode="nodes", character="@", max_size=max_size
|
|
)
|
|
self.assertEqual(expected, mapstr.replace("||", "|"))
|
|
|
|
def test_spawn(self):
|
|
"""
|
|
Spawn the map into actual objects.
|
|
|
|
"""
|
|
self.grid.spawn()
|
|
self.assertEqual(xyzroom.XYZRoom.objects.all().count(), 18)
|
|
self.assertEqual(xyzroom.XYZExit.objects.all().count(), 44)
|
|
|
|
|
|
class TestMap4(_MapTest):
|
|
"""
|
|
Test Map4 - Map with + and x crossing links
|
|
|
|
"""
|
|
|
|
map_data = {"map": MAP4, "zcoord": "map4"}
|
|
map_display = MAP4_DISPLAY
|
|
|
|
def test_str_output(self):
|
|
"""Check the display_map"""
|
|
stripped_map = "\n".join(line.rstrip() for line in str(self.map).split("\n"))
|
|
self.assertEqual(MAP4_DISPLAY, stripped_map.replace("||", "|"))
|
|
|
|
@parameterized.expand(
|
|
[
|
|
((1, 0), (1, 2), ("n",)), # cross + vertically
|
|
((0, 1), (2, 1), ("e",)), # cross + horizontally
|
|
((4, 1), (1, 0), ("w", "w", "n", "e", "s")),
|
|
((1, 2), (2, 3), ("ne",)), # cross x
|
|
((1, 2), (2, 3), ("ne",)),
|
|
((2, 2), (0, 4), ("w", "ne", "nw", "w")),
|
|
]
|
|
)
|
|
def test_shortest_path(self, startcoord, endcoord, expected_directions):
|
|
"""
|
|
Test shortest-path calculations throughout the grid.
|
|
|
|
"""
|
|
directions, _ = self.map.get_shortest_path(startcoord, endcoord)
|
|
self.assertEqual(expected_directions, tuple(directions))
|
|
|
|
def test_spawn(self):
|
|
"""
|
|
Spawn the map into actual objects.
|
|
|
|
"""
|
|
self.grid.spawn()
|
|
self.assertEqual(xyzroom.XYZRoom.objects.all().count(), 16)
|
|
self.assertEqual(xyzroom.XYZExit.objects.all().count(), 44)
|
|
|
|
|
|
class TestMap5(_MapTest):
|
|
"""
|
|
Test Map5 - Small map with one-way links
|
|
|
|
"""
|
|
|
|
map_data = {"map": MAP5, "zcoord": "map5"}
|
|
map_display = MAP5_DISPLAY
|
|
|
|
def test_str_output(self):
|
|
"""Check the display_map"""
|
|
stripped_map = "\n".join(line.rstrip() for line in str(self.map).split("\n"))
|
|
self.assertEqual(MAP5_DISPLAY, stripped_map.replace("||", "|"))
|
|
|
|
@parameterized.expand(
|
|
[
|
|
((0, 0), (1, 0), ("e",)), # cross one-way
|
|
((1, 0), (0, 0), ()), # blocked
|
|
((0, 1), (1, 1), ("e",)), # should still take shortest
|
|
((1, 1), (0, 1), ("n", "w", "s")), # take long way around
|
|
]
|
|
)
|
|
def test_shortest_path(self, startcoord, endcoord, expected_directions):
|
|
"""
|
|
Test shortest-path calculations throughout the grid.
|
|
|
|
"""
|
|
directions, _ = self.map.get_shortest_path(startcoord, endcoord)
|
|
self.assertEqual(expected_directions, tuple(directions))
|
|
|
|
def test_spawn(self):
|
|
"""
|
|
Spawn the map into actual objects.
|
|
|
|
"""
|
|
self.grid.spawn()
|
|
self.assertEqual(xyzroom.XYZRoom.objects.all().count(), 6)
|
|
self.assertEqual(xyzroom.XYZExit.objects.all().count(), 8)
|
|
|
|
|
|
class TestMap6(_MapTest):
|
|
"""
|
|
Test Map6 - Bigger map with one-way links in different directions
|
|
|
|
"""
|
|
|
|
map_data = {"map": MAP6, "zcoord": "map6"}
|
|
map_display = MAP6_DISPLAY
|
|
|
|
def test_str_output(self):
|
|
"""Check the display_map"""
|
|
stripped_map = "\n".join(line.rstrip() for line in str(self.map).split("\n"))
|
|
self.assertEqual(MAP6_DISPLAY, stripped_map.replace("||", "|"))
|
|
|
|
@parameterized.expand(
|
|
[
|
|
((0, 0), (2, 0), ("e", "e")), # cross one-way
|
|
((2, 0), (0, 0), ("e", "n", "w", "s", "w")), # blocked, long way around
|
|
((4, 0), (3, 0), ("w",)),
|
|
((3, 0), (4, 0), ("n", "e", "s")),
|
|
((1, 1), (1, 2), ("n",)),
|
|
((1, 2), (1, 1), ("e", "e", "s", "w")),
|
|
((3, 1), (1, 4), ("w", "n", "n")),
|
|
((0, 4), (0, 0), ("e", "e", "e", "s", "s", "s", "w", "s", "w")),
|
|
]
|
|
)
|
|
def test_shortest_path(self, startcoord, endcoord, expected_directions):
|
|
"""
|
|
Test shortest-path calculations throughout the grid.
|
|
|
|
"""
|
|
directions, _ = self.map.get_shortest_path(startcoord, endcoord)
|
|
self.assertEqual(expected_directions, tuple(directions))
|
|
|
|
def test_spawn(self):
|
|
"""
|
|
Spawn the map into actual objects.
|
|
|
|
"""
|
|
self.grid.spawn()
|
|
self.assertEqual(xyzroom.XYZRoom.objects.all().count(), 18)
|
|
self.assertEqual(xyzroom.XYZExit.objects.all().count(), 38)
|
|
|
|
|
|
class TestMap7(_MapTest):
|
|
"""
|
|
Test Map7 - Small test of dynamic link node
|
|
|
|
"""
|
|
|
|
map_data = {"map": MAP7, "zcoord": "map7"}
|
|
map_display = MAP7_DISPLAY
|
|
|
|
def test_str_output(self):
|
|
"""Check the display_map"""
|
|
stripped_map = "\n".join(line.rstrip() for line in str(self.map).split("\n"))
|
|
self.assertEqual(MAP7_DISPLAY, stripped_map.replace("||", "|"))
|
|
|
|
@parameterized.expand(
|
|
[
|
|
((1, 0), (1, 2), ("n",)),
|
|
((1, 2), (1, 0), ("s",)),
|
|
((0, 1), (2, 1), ("e",)),
|
|
((2, 1), (0, 1), ("w",)),
|
|
]
|
|
)
|
|
def test_shortest_path(self, startcoord, endcoord, expected_directions):
|
|
"""
|
|
test shortest-path calculations throughout the grid.
|
|
|
|
"""
|
|
directions, _ = self.map.get_shortest_path(startcoord, endcoord)
|
|
self.assertEqual(expected_directions, tuple(directions))
|
|
|
|
def test_spawn(self):
|
|
"""
|
|
Spawn the map into actual objects.
|
|
|
|
"""
|
|
self.grid.spawn()
|
|
self.assertEqual(xyzroom.XYZRoom.objects.all().count(), 6)
|
|
self.assertEqual(xyzroom.XYZExit.objects.all().count(), 8)
|
|
|
|
|
|
class TestMap8(_MapTest):
|
|
"""
|
|
Test Map8 - Small test of dynamic link node
|
|
|
|
"""
|
|
|
|
map_data = {"map": MAP8, "zcoord": "map8"}
|
|
map_display = MAP8_DISPLAY
|
|
|
|
def test_str_output(self):
|
|
"""Check the display_map"""
|
|
stripped_map = "\n".join(line.rstrip() for line in str(self.map).split("\n"))
|
|
self.assertEqual(MAP8_DISPLAY, stripped_map.replace("||", "|"))
|
|
|
|
@parameterized.expand(
|
|
[
|
|
((2, 0), (2, 2), ("n",)),
|
|
((0, 0), (5, 3), ("e", "e")),
|
|
((5, 1), (0, 3), ("w", "w", "n", "w")),
|
|
((1, 1), (2, 2), ("n", "w", "s")),
|
|
((5, 3), (5, 3), ()),
|
|
((5, 3), (0, 4), ("s", "n", "w", "n")),
|
|
((1, 4), (3, 3), ("e", "w", "e")),
|
|
]
|
|
)
|
|
def test_shortest_path(self, startcoord, endcoord, expected_directions):
|
|
"""
|
|
test shortest-path calculations throughout the grid.
|
|
|
|
"""
|
|
directions, _ = self.map.get_shortest_path(startcoord, endcoord)
|
|
self.assertEqual(expected_directions, tuple(directions))
|
|
|
|
@parameterized.expand(
|
|
[
|
|
(
|
|
(2, 2),
|
|
1,
|
|
None,
|
|
" #-o \n | \n# o \n| | \no-o-@-#\n | \n o \n | \n # ",
|
|
),
|
|
]
|
|
)
|
|
def test_get_visual_range__nodes__character(self, coord, dist, max_size, expected):
|
|
"""
|
|
Get sub-part of map with node-mode.
|
|
|
|
"""
|
|
mapstr = self.map.get_visual_range(
|
|
coord, dist=dist, mode="nodes", character="@", max_size=max_size
|
|
)
|
|
self.assertEqual(expected, mapstr.replace("||", "|"))
|
|
|
|
@parameterized.expand(
|
|
[
|
|
(
|
|
(2, 2),
|
|
(3, 2),
|
|
1,
|
|
None,
|
|
" #-o \n | \n# o \n| | \no-o-@..\n | \n o \n | \n # ",
|
|
),
|
|
(
|
|
(2, 2),
|
|
(5, 3),
|
|
1,
|
|
None,
|
|
" #-o \n | \n# o \n| | \no-o-@-#\n . \n . \n . \n ...",
|
|
),
|
|
(
|
|
(2, 2),
|
|
(5, 3),
|
|
2,
|
|
None,
|
|
(
|
|
"#-#-o \n| \\| \n#-o-o-# .\n| |\\ .\no-o-@-"
|
|
"# .\n . . \n . . \n . . \n#---... "
|
|
),
|
|
),
|
|
((5, 3), (2, 2), 2, (13, 7), " o-o\n | |\n o-@\n .\n. .\n. . "),
|
|
(
|
|
(5, 3),
|
|
(1, 1),
|
|
2,
|
|
None,
|
|
(
|
|
" o-o\n | |\n o-@\n. .\n..... "
|
|
".\n . . \n . . \n . . \n#---... "
|
|
),
|
|
),
|
|
]
|
|
)
|
|
def test_get_visual_range_with_path(self, coord, target, dist, max_size, expected):
|
|
"""
|
|
Get visual range with a path-to-target marked.
|
|
|
|
"""
|
|
mapstr = self.map.get_visual_range(
|
|
coord,
|
|
dist=dist,
|
|
mode="nodes",
|
|
target=target,
|
|
target_path_style=".",
|
|
character="@",
|
|
max_size=max_size,
|
|
)
|
|
self.assertEqual(expected, mapstr.replace("||", "|"))
|
|
|
|
def test_spawn(self):
|
|
"""
|
|
Spawn the map into actual objects.
|
|
|
|
"""
|
|
self.grid.spawn()
|
|
self.assertEqual(xyzroom.XYZRoom.objects.all().count(), 12)
|
|
self.assertEqual(xyzroom.XYZExit.objects.all().count(), 28)
|
|
|
|
|
|
class TestMap9(_MapTest):
|
|
"""
|
|
Test Map9 - a map with up/down links.
|
|
|
|
"""
|
|
|
|
map_data = {"map": MAP9, "zcoord": "map9"}
|
|
map_display = MAP9_DISPLAY
|
|
|
|
def test_str_output(self):
|
|
"""Check the display_map"""
|
|
stripped_map = "\n".join(line.rstrip() for line in str(self.map).split("\n"))
|
|
self.assertEqual(MAP9_DISPLAY, stripped_map.replace("||", "|"))
|
|
|
|
@parameterized.expand(
|
|
[
|
|
((0, 0), (0, 1), ("u",)),
|
|
((0, 0), (1, 0), ("d",)),
|
|
((1, 0), (2, 1), ("d", "u", "e", "u", "e", "d")),
|
|
((2, 1), (0, 1), ("u", "w", "d", "w")),
|
|
]
|
|
)
|
|
def test_shortest_path(self, startcoord, endcoord, expected_directions):
|
|
"""
|
|
test shortest-path calculations throughout the grid.
|
|
|
|
"""
|
|
directions, _ = self.map.get_shortest_path(startcoord, endcoord)
|
|
self.assertEqual(expected_directions, tuple(directions))
|
|
|
|
def test_spawn(self):
|
|
"""
|
|
Spawn the map into actual objects.
|
|
|
|
"""
|
|
self.grid.spawn()
|
|
self.assertEqual(xyzroom.XYZRoom.objects.all().count(), 12)
|
|
self.assertEqual(xyzroom.XYZExit.objects.all().count(), 24)
|
|
|
|
|
|
class TestMap10(_MapTest):
|
|
"""
|
|
Test Map10 - a map with blocked- and interrupt links/nodes. These are
|
|
'invisible' nodes and won't show up in the map display.
|
|
|
|
"""
|
|
|
|
map_data = {"map": MAP10, "zcoord": "map10"}
|
|
map_display = MAP10_DISPLAY
|
|
|
|
def test_str_output(self):
|
|
"""Check the display_map"""
|
|
stripped_map = "\n".join(line.rstrip() for line in str(self.map).split("\n"))
|
|
self.assertEqual(MAP10_DISPLAY, stripped_map.replace("||", "|"))
|
|
|
|
# interrupts are only relevant to the auto-stepper
|
|
@parameterized.expand(
|
|
[
|
|
((0, 0), (1, 0), ("n", "e", "s")),
|
|
((3, 0), (3, 1), ()), # the blockage hinders this
|
|
((1, 3), (0, 4), ("e", "n", "w", "w")),
|
|
((0, 1), (3, 2), ("e", "n", "e", "e")),
|
|
((0, 1), (0, 3), ("e", "n", "n", "w")),
|
|
((1, 3), (0, 3), ("w",)),
|
|
((3, 2), (2, 2), ("w",)),
|
|
((3, 2), (1, 2), ("w", "w")),
|
|
((3, 3), (0, 3), ("w", "w")),
|
|
((2, 2), (3, 2), ("e",)),
|
|
]
|
|
)
|
|
def test_shortest_path(self, startcoord, endcoord, expected_directions):
|
|
"""
|
|
test shortest-path calculations throughout the grid.
|
|
|
|
"""
|
|
directions, _ = self.map.get_shortest_path(startcoord, endcoord)
|
|
self.assertEqual(expected_directions, tuple(directions))
|
|
|
|
@parameterized.expand(
|
|
[
|
|
((2, 2), (3, 2), ("e",), ((2, 2), (2.5, 2), (3, 2))),
|
|
(
|
|
(3, 3),
|
|
(0, 3),
|
|
("w", "w"),
|
|
((3, 3), (2.5, 3.0), (2.0, 3.0), (1.5, 3.0), (1, 3), (0.5, 3), (0, 3)),
|
|
),
|
|
]
|
|
)
|
|
def test_paths(self, startcoord, endcoord, expected_directions, expected_path):
|
|
"""
|
|
Test path locations.
|
|
|
|
"""
|
|
directions, path = self.map.get_shortest_path(startcoord, endcoord)
|
|
self.assertEqual(expected_directions, tuple(directions))
|
|
strpositions = [(step.X, step.Y) for step in path]
|
|
self.assertEqual(expected_path, tuple(strpositions))
|
|
|
|
def test_spawn(self):
|
|
"""
|
|
Spawn the map into actual objects.
|
|
|
|
"""
|
|
self.grid.spawn()
|
|
self.assertEqual(xyzroom.XYZRoom.objects.all().count(), 18)
|
|
self.assertEqual(xyzroom.XYZExit.objects.all().count(), 42)
|
|
|
|
|
|
class TestMap11(_MapTest):
|
|
"""
|
|
Test Map11 - a map teleporter links.
|
|
|
|
"""
|
|
|
|
map_data = {"map": MAP11, "zcoord": "map11"}
|
|
map_display = MAP11_DISPLAY
|
|
|
|
def test_str_output(self):
|
|
"""Check the display_map"""
|
|
stripped_map = "\n".join(line.rstrip() for line in str(self.map).split("\n"))
|
|
self.assertEqual(MAP11_DISPLAY, stripped_map.replace("||", "|"))
|
|
|
|
@parameterized.expand(
|
|
[
|
|
((2, 0), (1, 2), ("e", "nw", "e")),
|
|
((1, 2), (2, 0), ("w", "se", "w")),
|
|
]
|
|
)
|
|
def test_shortest_path(self, startcoord, endcoord, expected_directions):
|
|
"""
|
|
test shortest-path calculations throughout the grid.
|
|
|
|
"""
|
|
directions, _ = self.map.get_shortest_path(startcoord, endcoord)
|
|
self.assertEqual(expected_directions, tuple(directions))
|
|
|
|
@parameterized.expand(
|
|
[
|
|
(
|
|
(3, 0),
|
|
(0, 2),
|
|
("nw",),
|
|
((3, 0), (2.5, 0.5), (2.0, 1.0), (1.0, 1.0), (0.5, 1.5), (0, 2)),
|
|
),
|
|
(
|
|
(0, 2),
|
|
(3, 0),
|
|
("se",),
|
|
((0, 2), (0.5, 1.5), (1.0, 1.0), (2.0, 1.0), (2.5, 0.5), (3, 0)),
|
|
),
|
|
]
|
|
)
|
|
def test_paths(self, startcoord, endcoord, expected_directions, expected_path):
|
|
"""
|
|
Test path locations.
|
|
|
|
"""
|
|
directions, path = self.map.get_shortest_path(startcoord, endcoord)
|
|
self.assertEqual(expected_directions, tuple(directions))
|
|
strpositions = [(step.X, step.Y) for step in path]
|
|
self.assertEqual(expected_path, tuple(strpositions))
|
|
|
|
@parameterized.expand(
|
|
[
|
|
((2, 0), (1, 2), 3, None, "... \n . \n . . \n . \n @.."),
|
|
((1, 2), (2, 0), 3, None, "..@ \n . \n . . \n . \n ..."),
|
|
]
|
|
)
|
|
def test_get_visual_range_with_path(self, coord, target, dist, max_size, expected):
|
|
"""
|
|
Get visual range with a path-to-target marked.
|
|
|
|
"""
|
|
mapstr = self.map.get_visual_range(
|
|
coord,
|
|
dist=dist,
|
|
mode="nodes",
|
|
target=target,
|
|
target_path_style=".",
|
|
character="@",
|
|
max_size=max_size,
|
|
)
|
|
|
|
self.assertEqual(expected, mapstr)
|
|
|
|
def test_spawn(self):
|
|
"""
|
|
Spawn the map into actual objects.
|
|
|
|
"""
|
|
self.grid.spawn()
|
|
self.assertEqual(xyzroom.XYZRoom.objects.all().count(), 4)
|
|
self.assertEqual(xyzroom.XYZExit.objects.all().count(), 6)
|
|
|
|
|
|
class TestMapStressTest(TestCase):
|
|
"""
|
|
Performance test of map patfinder and visualizer.
|
|
|
|
#-#-#-#-#....
|
|
|x|x|x|x|
|
|
#-#-#-#-#
|
|
|x|x|x|x|
|
|
#-#-#-#-#
|
|
|x|x|x|x|
|
|
#-#-#-#-#
|
|
...
|
|
|
|
This should be a good stress-testing scenario because most each internal node has a maxiumum
|
|
number of connections and options to consider.
|
|
|
|
"""
|
|
|
|
def _get_grid(self, Xsize, Ysize):
|
|
edge = f"+ {' ' * Xsize * 2}"
|
|
l1 = f"\n {'#-' * Xsize}#"
|
|
l2 = f"\n {'|x' * Xsize}|"
|
|
|
|
return f"{edge}\n{(l1 + l2) * Ysize}{l1}\n\n{edge}"
|
|
|
|
@parameterized.expand(
|
|
[
|
|
((10, 10), 0.03),
|
|
((100, 100), 5),
|
|
]
|
|
)
|
|
def test_grid_creation(self, gridsize, max_time):
|
|
"""
|
|
Test of grid-creataion performance for Nx, Ny grid.
|
|
|
|
"""
|
|
# import cProfile
|
|
Xmax, Ymax = gridsize
|
|
grid = self._get_grid(Xmax, Ymax)
|
|
mapobj = xymap.XYMap({"map": grid}, Z="testmap")
|
|
# t0 = time()
|
|
mapobj.parse()
|
|
# cProfile.runctx('mapobj.parse()', globals(), locals())
|
|
# t1 = time()
|
|
# if (t1 - t0 > max_time):
|
|
# print(f"Map creation of ({Xmax}x{Ymax}) grid slower "
|
|
# f"than expected {max_time}s.")
|
|
|
|
@parameterized.expand(
|
|
[
|
|
((10, 10), 10**-3),
|
|
((20, 20), 10**-3),
|
|
]
|
|
)
|
|
def test_grid_pathfind(self, gridsize, max_time):
|
|
"""
|
|
Test pathfinding performance for Nx, Ny grid.
|
|
|
|
"""
|
|
Xmax, Ymax = gridsize
|
|
grid = self._get_grid(Xmax, Ymax)
|
|
mapobj = xymap.XYMap({"map": grid}, Z="testmap")
|
|
mapobj.parse()
|
|
|
|
# t0 = time()
|
|
mapobj.calculate_path_matrix()
|
|
# t1 = time()
|
|
# print(f"pathfinder matrix for grid {Xmax}x{Ymax}: {t1 - t0}s")
|
|
|
|
# get the maximum distance and 9 other random points in the grid
|
|
start_end_points = [((0, 0), (Xmax - 1, Ymax - 1))]
|
|
for _ in range(9):
|
|
start_end_points.append(
|
|
((randint(0, Xmax), randint(0, Ymax)), (randint(0, Xmax), randint(0, Ymax)))
|
|
)
|
|
|
|
# t0 = time()
|
|
for startcoord, endcoord in start_end_points:
|
|
mapobj.get_shortest_path(startcoord, endcoord)
|
|
# t1 = time()
|
|
# if (t1 - t0) / 10 > max_time:
|
|
# print(f"Pathfinding for ({Xmax}x{Ymax}) grid slower "
|
|
# f"than expected {max_time}s.")
|
|
|
|
@parameterized.expand(
|
|
[
|
|
((10, 10), 4, 0.01),
|
|
((20, 20), 4, 0.01),
|
|
]
|
|
)
|
|
def test_grid_visibility(self, gridsize, dist, max_time):
|
|
"""
|
|
Test grid visualization performance for Nx, Ny grid for
|
|
different visibility distances.
|
|
|
|
"""
|
|
Xmax, Ymax = gridsize
|
|
grid = self._get_grid(Xmax, Ymax)
|
|
mapobj = xymap.XYMap({"map": grid}, Z="testmap")
|
|
mapobj.parse()
|
|
|
|
# t0 = time()
|
|
mapobj.calculate_path_matrix()
|
|
# t1 = time()
|
|
# print(f"pathfinder matrix for grid {Xmax}x{Ymax}: {t1 - t0}s")
|
|
|
|
# get random center points in grid and a range of targets to visualize the
|
|
# path to
|
|
start_end_points = [((0, 0), (Xmax - 1, Ymax - 1))] # include max distance
|
|
for _ in range(9):
|
|
start_end_points.append(
|
|
((randint(0, Xmax), randint(0, Ymax)), (randint(0, Xmax), randint(0, Ymax)))
|
|
)
|
|
|
|
# t0 = time()
|
|
for coord, target in start_end_points:
|
|
mapobj.get_visual_range(coord, dist=dist, mode="nodes", character="@", target=target)
|
|
# t1 = time()
|
|
# if (t1 - t0) / 10 > max_time:
|
|
# print(f"Visual Range calculation for ({Xmax}x{Ymax}) grid "
|
|
# f"slower than expected {max_time}s.")
|
|
|
|
|
|
class TestXYZGrid(BaseEvenniaTest):
|
|
"""
|
|
Test base grid class with a single map, including spawning objects.
|
|
|
|
"""
|
|
|
|
zcoord = "map1"
|
|
|
|
def setUp(self):
|
|
self.grid, err = xyzgrid.XYZGrid.create("testgrid")
|
|
|
|
self.map_data1 = {"map": MAP1, "zcoord": self.zcoord}
|
|
|
|
self.grid.add_maps(self.map_data1)
|
|
|
|
def tearDown(self):
|
|
self.grid.delete()
|
|
|
|
def test_str_output(self):
|
|
"""Check the display_map"""
|
|
xymap = self.grid.get_map(self.zcoord)
|
|
stripped_map = "\n".join(line.rstrip() for line in str(xymap).split("\n"))
|
|
self.assertEqual(MAP1_DISPLAY, stripped_map.replace("||", "|"))
|
|
|
|
def test_spawn(self):
|
|
"""Spawn objects for the grid"""
|
|
self.grid.spawn()
|
|
# import sys
|
|
# sys.stderr.write("\nrooms: " + repr(xyzroom.XYZRoom.objects.all()))
|
|
# sys.stderr.write("\n\nexits: " + repr(xyzroom.XYZExit.objects.all()) + "\n")
|
|
|
|
self.assertEqual(xyzroom.XYZRoom.objects.all().count(), 4)
|
|
self.assertEqual(xyzroom.XYZExit.objects.all().count(), 8)
|
|
|
|
|
|
# map transitions
|
|
class Map12aTransition(xymap_legend.TransitionMapNode):
|
|
symbol = "T"
|
|
target_map_xyz = (1, 0, "map12b")
|
|
|
|
|
|
class Map12bTransition(xymap_legend.TransitionMapNode):
|
|
symbol = "T"
|
|
target_map_xyz = (0, 1, "map12a")
|
|
|
|
|
|
class TestXYZGridTransition(BaseEvenniaTest):
|
|
"""
|
|
Test the XYZGrid class and transitions between maps.
|
|
|
|
"""
|
|
|
|
def setUp(self):
|
|
super().setUp()
|
|
self.grid, err = xyzgrid.XYZGrid.create("testgrid")
|
|
|
|
self.map_data12a = {"map": MAP12a, "zcoord": "map12a", "legend": {"T": Map12aTransition}}
|
|
self.map_data12b = {"map": MAP12b, "zcoord": "map12b", "legend": {"T": Map12bTransition}}
|
|
|
|
self.grid.add_maps(self.map_data12a, self.map_data12b)
|
|
|
|
def tearDown(self):
|
|
self.grid.delete()
|
|
|
|
@parameterized.expand(
|
|
[
|
|
((1, 0), (1, 1), ("w", "n", "e")),
|
|
((1, 1), (1, 0), ("w", "s", "e")),
|
|
]
|
|
)
|
|
def test_shortest_path(self, startcoord, endcoord, expected_directions):
|
|
"""
|
|
test shortest-path calculations throughout the grid.
|
|
|
|
"""
|
|
directions, _ = self.grid.get_map("map12a").get_shortest_path(startcoord, endcoord)
|
|
self.assertEqual(expected_directions, tuple(directions))
|
|
|
|
def test_spawn(self):
|
|
"""
|
|
Spawn the two maps into actual objects.
|
|
|
|
"""
|
|
self.grid.spawn()
|
|
|
|
self.assertEqual(xyzroom.XYZRoom.objects.all().count(), 6)
|
|
self.assertEqual(xyzroom.XYZExit.objects.all().count(), 10)
|
|
|
|
room1 = xyzroom.XYZRoom.objects.get_xyz(xyz=(0, 1, "map12a"))
|
|
room2 = xyzroom.XYZRoom.objects.get_xyz(xyz=(1, 0, "map12b"))
|
|
east_exit = [exi for exi in room1.exits if exi.db_key == "east"][0]
|
|
west_exit = [exi for exi in room2.exits if exi.db_key == "west"][0]
|
|
|
|
# make sure exits traverse the maps
|
|
self.assertEqual(east_exit.db_destination, room2)
|
|
self.assertEqual(west_exit.db_destination, room1)
|
|
|
|
|
|
class TestBuildExampleGrid(BaseEvenniaTest):
|
|
"""
|
|
Test building the map-example (this takes about 30s)
|
|
|
|
"""
|
|
|
|
def setUp(self):
|
|
# build and populate grid
|
|
super().setUp()
|
|
self.grid, err = xyzgrid.XYZGrid.create("testgrid")
|
|
|
|
# def _log(msg):
|
|
# print(msg)
|
|
# self.grid.log = _log
|
|
|
|
def tearDown(self):
|
|
self.grid.delete()
|
|
|
|
def test_build(self):
|
|
"""
|
|
Build the map example.
|
|
|
|
"""
|
|
mapdatas = self.grid.maps_from_module("evennia.contrib.grid.xyzgrid.example")
|
|
self.assertEqual(len(mapdatas), 2)
|
|
|
|
self.grid.add_maps(*mapdatas)
|
|
self.grid.spawn()
|
|
|
|
# testing
|
|
room1a = xyzroom.XYZRoom.objects.get_xyz(xyz=(3, 0, "the large tree"))
|
|
room1b = xyzroom.XYZRoom.objects.get_xyz(xyz=(10, 8, "the large tree"))
|
|
room2a = xyzroom.XYZRoom.objects.get_xyz(xyz=(1, 0, "the small cave"))
|
|
room2b = xyzroom.XYZRoom.objects.get_xyz(xyz=(1, 3, "the small cave"))
|
|
|
|
self.assertEqual(room1a.key, "Dungeon Entrance")
|
|
self.assertTrue(room1a.db.desc.startswith("To the east"))
|
|
self.assertEqual(room1b.key, "A gorgeous view")
|
|
self.assertTrue(room1b.db.desc.startswith("The view from here is breathtaking,"))
|
|
self.assertEqual(room2a.key, "The entrance")
|
|
self.assertTrue(room2a.db.desc.startswith("This is the entrance to"))
|
|
self.assertEqual(room2b.key, "North-west corner of the atrium")
|
|
self.assertTrue(room2b.db.desc.startswith("Sunlight sifts down"))
|
|
|
|
|
|
mock_room_callbacks = mock.MagicMock()
|
|
mock_exit_callbacks = mock.MagicMock()
|
|
|
|
|
|
class TestXyzRoom(xyzroom.XYZRoom):
|
|
def at_object_creation(self):
|
|
mock_room_callbacks.at_object_creation()
|
|
|
|
|
|
class TestXyzExit(xyzroom.XYZExit):
|
|
def at_object_creation(self):
|
|
mock_exit_callbacks.at_object_creation()
|
|
|
|
|
|
MAP_DATA = {
|
|
"map": """
|
|
|
|
+ 0 1
|
|
|
|
0 #-#
|
|
|
|
+ 0 1
|
|
|
|
""",
|
|
"zcoord": "map1",
|
|
"prototypes": {
|
|
("*", "*"): {
|
|
"key": "room",
|
|
"desc": "A room.",
|
|
"prototype_parent": "xyz_room",
|
|
},
|
|
("*", "*", "*"): {
|
|
"desc": "A passage.",
|
|
"prototype_parent": "xyz_exit",
|
|
},
|
|
},
|
|
"options": {
|
|
"map_visual_range": 1,
|
|
"map_mode": "scan",
|
|
},
|
|
}
|
|
|
|
|
|
class TestCallbacks(BaseEvenniaTest):
|
|
def setUp(self):
|
|
super().setUp()
|
|
mock_room_callbacks.reset_mock()
|
|
mock_exit_callbacks.reset_mock()
|
|
|
|
def setup_grid(self, map_data):
|
|
self.grid, err = xyzgrid.XYZGrid.create("testgrid")
|
|
|
|
def _log(msg):
|
|
print(msg)
|
|
|
|
self.grid.log = _log
|
|
|
|
self.map_data = map_data
|
|
self.grid.add_maps(map_data)
|
|
|
|
def tearDown(self):
|
|
super().tearDown()
|
|
self.grid.delete()
|
|
|
|
def test_typeclassed_xyzroom_and_xyzexit_with_at_object_creation_are_called(self):
|
|
map_data = dict(MAP_DATA)
|
|
for prototype_key, prototype_value in map_data["prototypes"].items():
|
|
if len(prototype_key) == 2:
|
|
prototype_value["typeclass"] = "evennia.contrib.grid.xyzgrid.tests.TestXyzRoom"
|
|
if len(prototype_key) == 3:
|
|
prototype_value["typeclass"] = "evennia.contrib.grid.xyzgrid.tests.TestXyzExit"
|
|
self.setup_grid(map_data)
|
|
|
|
self.grid.spawn()
|
|
|
|
# Two rooms and 2 exits, Each one should have gotten one `at_object_creation` callback.
|
|
self.assertEqual(
|
|
mock_room_callbacks.at_object_creation.mock_calls, [mock.call(), mock.call()]
|
|
)
|
|
self.assertEqual(
|
|
mock_exit_callbacks.at_object_creation.mock_calls, [mock.call(), mock.call()]
|
|
)
|
|
|
|
|
|
class TestFlyDiveCommand(BaseEvenniaCommandTest):
|
|
def setUp(self):
|
|
super().setUp()
|
|
|
|
self.grid, err = xyzgrid.XYZGrid.create("testgrid")
|
|
|
|
self.map_data13a = {"map": MAP13a, "zcoord": -2}
|
|
self.map_data13b = {"map": MAP13b, "zcoord": -1}
|
|
self.map_data13c = {"map": MAP13c, "zcoord": 0}
|
|
self.map_data13d = {"map": MAP13d, "zcoord": 1} # not contiguous
|
|
|
|
self.grid.add_maps(self.map_data13a, self.map_data13b, self.map_data13c, self.map_data13d)
|
|
self.grid.spawn()
|
|
|
|
def tearDown(self):
|
|
self.grid.delete()
|
|
|
|
@parameterized.expand(
|
|
[
|
|
# startcoord, cmd, succeed?, endcoord
|
|
((0, 0, -2), "fly", False, (0, 0, -2)),
|
|
((1, 1, -2), "fly", True, (1, 1, -1)),
|
|
((1, 1, -1), "fly", True, (1, 1, 0)),
|
|
((1, 1, 0), "fly", True, (1, 1, 1)),
|
|
((1, 1, 1), "fly", False, (1, 1, 1)),
|
|
((0, 0, 1), "fly", False, (0, 0, 1)),
|
|
((0, 0, 1), "dive", False, (0, 0, 1)),
|
|
((1, 1, 1), "dive", True, (1, 1, 0)),
|
|
((1, 1, 0), "dive", True, (1, 1, -1)),
|
|
((1, 1, -1), "dive", True, (1, 1, -2)),
|
|
((1, 1, -2), "dive", False, (1, 1, -2)),
|
|
]
|
|
)
|
|
def test_fly_and_dive(self, startcoord, cmdstring, success, endcoord):
|
|
"""
|
|
Test flying up and down and seeing if it works at different locations.
|
|
|
|
"""
|
|
start_room = xyzgrid.XYZRoom.objects.get_xyz(xyz=startcoord)
|
|
self.char1.move_to(start_room)
|
|
|
|
self.call(commands.CmdFlyAndDive(), "", "You" if success else "Can't", cmdstring=cmdstring)
|
|
|
|
self.assertEqual(self.char1.location.xyz, endcoord)
|