Mesa 1.1.0__py3-none-any.whl → 1.2.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of Mesa might be problematic. Click here for more details.
- {Mesa-1.1.0.dist-info → Mesa-1.2.0.dist-info}/LICENSE +1 -1
- {Mesa-1.1.0.dist-info → Mesa-1.2.0.dist-info}/METADATA +15 -14
- {Mesa-1.1.0.dist-info → Mesa-1.2.0.dist-info}/RECORD +41 -41
- {Mesa-1.1.0.dist-info → Mesa-1.2.0.dist-info}/WHEEL +1 -1
- mesa/__init__.py +8 -9
- mesa/agent.py +2 -3
- mesa/batchrunner.py +19 -28
- mesa/datacollection.py +15 -28
- mesa/main.py +4 -4
- mesa/model.py +2 -6
- mesa/space.py +379 -286
- mesa/time.py +21 -22
- mesa/visualization/ModularVisualization.py +11 -9
- mesa/visualization/TextVisualization.py +0 -3
- mesa/visualization/UserParam.py +8 -11
- mesa/visualization/__init__.py +0 -1
- mesa/visualization/modules/BarChartVisualization.py +7 -8
- mesa/visualization/modules/CanvasGridVisualization.py +1 -3
- mesa/visualization/modules/ChartVisualization.py +2 -3
- mesa/visualization/modules/HexGridVisualization.py +1 -3
- mesa/visualization/modules/NetworkVisualization.py +1 -2
- mesa/visualization/modules/PieChartVisualization.py +2 -6
- mesa/visualization/templates/js/GridDraw.js +6 -10
- mesa/visualization/templates/js/HexDraw.js +5 -9
- mesa/visualization/templates/js/InteractionHandler.js +0 -2
- tests/test_batchrunner.py +3 -4
- tests/test_batchrunnerMP.py +4 -4
- tests/test_datacollector.py +2 -2
- tests/test_examples.py +8 -5
- tests/test_grid.py +104 -37
- tests/test_import_namespace.py +0 -1
- tests/test_lifespan.py +4 -3
- tests/test_main.py +5 -1
- tests/test_scaffold.py +2 -1
- tests/test_space.py +13 -20
- tests/test_time.py +44 -14
- tests/test_tornado.py +4 -2
- tests/test_usersettableparam.py +4 -3
- tests/test_visualization.py +4 -8
- {Mesa-1.1.0.dist-info → Mesa-1.2.0.dist-info}/entry_points.txt +0 -0
- {Mesa-1.1.0.dist-info → Mesa-1.2.0.dist-info}/top_level.txt +0 -0
tests/test_examples.py
CHANGED
|
@@ -1,14 +1,17 @@
|
|
|
1
|
-
import sys
|
|
2
|
-
import os.path
|
|
3
|
-
import unittest
|
|
4
1
|
import contextlib
|
|
5
2
|
import importlib
|
|
3
|
+
import os.path
|
|
4
|
+
import sys
|
|
5
|
+
import unittest
|
|
6
6
|
|
|
7
7
|
|
|
8
8
|
def classcase(name):
|
|
9
9
|
return "".join(x.capitalize() for x in name.replace("-", "_").split("_"))
|
|
10
10
|
|
|
11
11
|
|
|
12
|
+
@unittest.skip(
|
|
13
|
+
"Skipping TextExamples, because examples folder was moved. More discussion needed."
|
|
14
|
+
)
|
|
12
15
|
class TestExamples(unittest.TestCase):
|
|
13
16
|
"""
|
|
14
17
|
Test examples' models. This creates a model object and iterates it through
|
|
@@ -59,7 +62,7 @@ class TestExamples(unittest.TestCase):
|
|
|
59
62
|
f"{example.replace('-', '_')}.server"
|
|
60
63
|
)
|
|
61
64
|
server.server.render_model()
|
|
62
|
-
|
|
63
|
-
model =
|
|
65
|
+
model_class = getattr(mod, classcase(example))
|
|
66
|
+
model = model_class()
|
|
64
67
|
for _ in range(10):
|
|
65
68
|
model.step()
|
tests/test_grid.py
CHANGED
|
@@ -3,7 +3,9 @@ Test the Grid objects.
|
|
|
3
3
|
"""
|
|
4
4
|
import random
|
|
5
5
|
import unittest
|
|
6
|
-
from
|
|
6
|
+
from unittest.mock import Mock, patch
|
|
7
|
+
|
|
8
|
+
from mesa.space import HexGrid, MultiGrid, SingleGrid
|
|
7
9
|
|
|
8
10
|
# Initial agent positions for testing
|
|
9
11
|
#
|
|
@@ -14,7 +16,7 @@ from mesa.space import Grid, SingleGrid, MultiGrid, HexGrid
|
|
|
14
16
|
# 1 0 1
|
|
15
17
|
# 0 0 1
|
|
16
18
|
# -------------------
|
|
17
|
-
TEST_GRID = [[0, 1, 0, 1, 0], [0, 0, 1, 1, 0], [1, 1, 0, 0, 0]]
|
|
19
|
+
TEST_GRID = [[0, 1, 0, 1, 0, 0], [0, 0, 1, 1, 0, 1], [1, 1, 0, 0, 0, 1]]
|
|
18
20
|
|
|
19
21
|
|
|
20
22
|
class MockAgent:
|
|
@@ -28,9 +30,9 @@ class MockAgent:
|
|
|
28
30
|
self.pos = pos
|
|
29
31
|
|
|
30
32
|
|
|
31
|
-
class
|
|
33
|
+
class TestSingleGrid(unittest.TestCase):
|
|
32
34
|
"""
|
|
33
|
-
Testing a non-toroidal
|
|
35
|
+
Testing a non-toroidal singlegrid.
|
|
34
36
|
"""
|
|
35
37
|
|
|
36
38
|
torus = False
|
|
@@ -39,9 +41,10 @@ class TestBaseGrid(unittest.TestCase):
|
|
|
39
41
|
"""
|
|
40
42
|
Create a test non-toroidal grid and populate it with Mock Agents
|
|
41
43
|
"""
|
|
44
|
+
# The height needs to be even to test the edge case described in PR #1517
|
|
45
|
+
height = 6 # height of grid
|
|
42
46
|
width = 3 # width of grid
|
|
43
|
-
|
|
44
|
-
self.grid = Grid(width, height, self.torus)
|
|
47
|
+
self.grid = SingleGrid(width, height, self.torus)
|
|
45
48
|
self.agents = []
|
|
46
49
|
counter = 0
|
|
47
50
|
for x in range(width):
|
|
@@ -108,10 +111,10 @@ class TestBaseGrid(unittest.TestCase):
|
|
|
108
111
|
assert len(neighborhood) == 8
|
|
109
112
|
|
|
110
113
|
neighborhood = self.grid.get_neighborhood((1, 4), moore=False)
|
|
111
|
-
assert len(neighborhood) ==
|
|
114
|
+
assert len(neighborhood) == 4
|
|
112
115
|
|
|
113
116
|
neighborhood = self.grid.get_neighborhood((1, 4), moore=True)
|
|
114
|
-
assert len(neighborhood) ==
|
|
117
|
+
assert len(neighborhood) == 8
|
|
115
118
|
|
|
116
119
|
neighborhood = self.grid.get_neighborhood((0, 0), moore=False)
|
|
117
120
|
assert len(neighborhood) == 2
|
|
@@ -126,7 +129,7 @@ class TestBaseGrid(unittest.TestCase):
|
|
|
126
129
|
assert len(neighbors) == 3
|
|
127
130
|
|
|
128
131
|
neighbors = self.grid.get_neighbors((1, 3), moore=False, radius=2)
|
|
129
|
-
assert len(neighbors) ==
|
|
132
|
+
assert len(neighbors) == 3
|
|
130
133
|
|
|
131
134
|
def test_coord_iter(self):
|
|
132
135
|
ci = self.grid.coord_iter()
|
|
@@ -147,8 +150,8 @@ class TestBaseGrid(unittest.TestCase):
|
|
|
147
150
|
def test_agent_move(self):
|
|
148
151
|
# get the agent at [0, 1]
|
|
149
152
|
agent = self.agents[0]
|
|
150
|
-
self.grid.move_agent(agent, (1,
|
|
151
|
-
assert agent.pos == (1,
|
|
153
|
+
self.grid.move_agent(agent, (1, 0))
|
|
154
|
+
assert agent.pos == (1, 0)
|
|
152
155
|
# move it off the torus and check for the exception
|
|
153
156
|
if not self.torus:
|
|
154
157
|
with self.assertRaises(Exception):
|
|
@@ -156,22 +159,51 @@ class TestBaseGrid(unittest.TestCase):
|
|
|
156
159
|
with self.assertRaises(Exception):
|
|
157
160
|
self.grid.move_agent(agent, [1, self.grid.height + 1])
|
|
158
161
|
else:
|
|
159
|
-
self.grid.move_agent(agent, [
|
|
160
|
-
assert agent.pos == (self.grid.
|
|
161
|
-
self.grid.move_agent(agent, [1, self.grid.height
|
|
162
|
-
assert agent.pos == (1,
|
|
162
|
+
self.grid.move_agent(agent, [0, -1])
|
|
163
|
+
assert agent.pos == (0, self.grid.height - 1)
|
|
164
|
+
self.grid.move_agent(agent, [1, self.grid.height])
|
|
165
|
+
assert agent.pos == (1, 0)
|
|
163
166
|
|
|
164
167
|
def test_agent_remove(self):
|
|
165
168
|
agent = self.agents[0]
|
|
166
169
|
x, y = agent.pos
|
|
167
170
|
self.grid.remove_agent(agent)
|
|
168
171
|
assert agent.pos is None
|
|
169
|
-
assert self.grid
|
|
172
|
+
assert self.grid[x][y] is None
|
|
173
|
+
|
|
174
|
+
def test_swap_pos(self):
|
|
175
|
+
# Swap agents positions
|
|
176
|
+
agent_a, agent_b = list(filter(None, self.grid))[:2]
|
|
177
|
+
pos_a = agent_a.pos
|
|
178
|
+
pos_b = agent_b.pos
|
|
179
|
+
|
|
180
|
+
self.grid.swap_pos(agent_a, agent_b)
|
|
181
|
+
|
|
182
|
+
assert agent_a.pos == pos_b
|
|
183
|
+
assert agent_b.pos == pos_a
|
|
184
|
+
assert self.grid[pos_a] == agent_b
|
|
185
|
+
assert self.grid[pos_b] == agent_a
|
|
186
|
+
|
|
187
|
+
# Swap the same agents
|
|
188
|
+
self.grid.swap_pos(agent_a, agent_a)
|
|
189
|
+
|
|
190
|
+
assert agent_a.pos == pos_b
|
|
191
|
+
assert self.grid[pos_b] == agent_a
|
|
192
|
+
|
|
193
|
+
# Raise for agents not on the grid
|
|
194
|
+
self.grid.remove_agent(agent_a)
|
|
195
|
+
self.grid.remove_agent(agent_b)
|
|
170
196
|
|
|
197
|
+
id_a = agent_a.unique_id
|
|
198
|
+
id_b = agent_b.unique_id
|
|
199
|
+
e_message = f"<Agent id: {id_a}>, <Agent id: {id_b}> - not on the grid"
|
|
200
|
+
with self.assertRaisesRegex(Exception, e_message):
|
|
201
|
+
self.grid.swap_pos(agent_a, agent_b)
|
|
171
202
|
|
|
172
|
-
|
|
203
|
+
|
|
204
|
+
class TestSingleGridTorus(TestSingleGrid):
|
|
173
205
|
"""
|
|
174
|
-
Testing the toroidal
|
|
206
|
+
Testing the toroidal singlegrid.
|
|
175
207
|
"""
|
|
176
208
|
|
|
177
209
|
torus = True
|
|
@@ -190,25 +222,30 @@ class TestBaseGridTorus(TestBaseGrid):
|
|
|
190
222
|
neighborhood = self.grid.get_neighborhood((0, 0), moore=False)
|
|
191
223
|
assert len(neighborhood) == 4
|
|
192
224
|
|
|
225
|
+
# here we test the edge case described in PR #1517 using a radius
|
|
226
|
+
# measuring half of the grid height
|
|
227
|
+
neighborhood = self.grid.get_neighborhood((0, 0), moore=True, radius=3)
|
|
228
|
+
assert len(neighborhood) == 17
|
|
229
|
+
|
|
230
|
+
neighborhood = self.grid.get_neighborhood((1, 1), moore=False, radius=3)
|
|
231
|
+
assert len(neighborhood) == 15
|
|
232
|
+
|
|
193
233
|
neighbors = self.grid.get_neighbors((1, 4), moore=False)
|
|
194
|
-
assert len(neighbors) ==
|
|
234
|
+
assert len(neighbors) == 2
|
|
195
235
|
|
|
196
236
|
neighbors = self.grid.get_neighbors((1, 4), moore=True)
|
|
197
|
-
assert len(neighbors) ==
|
|
237
|
+
assert len(neighbors) == 4
|
|
198
238
|
|
|
199
239
|
neighbors = self.grid.get_neighbors((1, 1), moore=False, include_center=True)
|
|
200
240
|
assert len(neighbors) == 3
|
|
201
241
|
|
|
202
242
|
neighbors = self.grid.get_neighbors((1, 3), moore=False, radius=2)
|
|
203
|
-
assert len(neighbors) ==
|
|
243
|
+
assert len(neighbors) == 3
|
|
204
244
|
|
|
205
245
|
|
|
206
|
-
class
|
|
246
|
+
class TestSingleGridEnforcement(unittest.TestCase):
|
|
207
247
|
"""
|
|
208
|
-
Test the SingleGrid
|
|
209
|
-
|
|
210
|
-
Since it inherits from Grid, all the functionality tested above should
|
|
211
|
-
work here too. Instead, this tests the enforcement.
|
|
248
|
+
Test the enforcement in SingleGrid.
|
|
212
249
|
"""
|
|
213
250
|
|
|
214
251
|
def setUp(self):
|
|
@@ -231,7 +268,27 @@ class TestSingleGrid(unittest.TestCase):
|
|
|
231
268
|
self.grid.place_agent(a, (x, y))
|
|
232
269
|
self.num_agents = len(self.agents)
|
|
233
270
|
|
|
234
|
-
|
|
271
|
+
@patch.object(MockAgent, "model", create=True)
|
|
272
|
+
def test_position_agent(self, mock_model):
|
|
273
|
+
a = MockAgent(100, None)
|
|
274
|
+
with self.assertRaises(Exception) as exc_info:
|
|
275
|
+
self.grid.position_agent(a, (1, 1))
|
|
276
|
+
expected = (
|
|
277
|
+
"x must be an integer or a string 'random'."
|
|
278
|
+
" Actual type: <class 'tuple'>. Actual value: (1, 1)."
|
|
279
|
+
)
|
|
280
|
+
assert str(exc_info.exception) == expected
|
|
281
|
+
with self.assertRaises(Exception) as exc_info:
|
|
282
|
+
self.grid.position_agent(a, "(1, 1)")
|
|
283
|
+
expected = (
|
|
284
|
+
"x must be an integer or a string 'random'."
|
|
285
|
+
" Actual type: <class 'str'>. Actual value: (1, 1)."
|
|
286
|
+
)
|
|
287
|
+
assert str(exc_info.exception) == expected
|
|
288
|
+
self.grid.position_agent(a, "random")
|
|
289
|
+
|
|
290
|
+
@patch.object(MockAgent, "model", create=True)
|
|
291
|
+
def test_enforcement(self, mock_model):
|
|
235
292
|
"""
|
|
236
293
|
Test the SingleGrid empty count and enforcement.
|
|
237
294
|
"""
|
|
@@ -239,17 +296,16 @@ class TestSingleGrid(unittest.TestCase):
|
|
|
239
296
|
assert len(self.grid.empties) == 9
|
|
240
297
|
a = MockAgent(100, None)
|
|
241
298
|
with self.assertRaises(Exception):
|
|
242
|
-
self.grid.
|
|
299
|
+
self.grid.place_agent(a, (0, 1))
|
|
243
300
|
|
|
244
301
|
# Place the agent in an empty cell
|
|
302
|
+
mock_model.schedule.get_agent_count = Mock(side_effect=lambda: len(self.agents))
|
|
245
303
|
self.grid.position_agent(a)
|
|
246
304
|
self.num_agents += 1
|
|
247
305
|
# Test whether after placing, the empty cells are reduced by 1
|
|
248
306
|
assert a.pos not in self.grid.empties
|
|
249
307
|
assert len(self.grid.empties) == 8
|
|
250
|
-
for
|
|
251
|
-
# Since the agents and the grid are not associated with a model, we
|
|
252
|
-
# must explicitly tell move_to_empty the number of agents.
|
|
308
|
+
for _i in range(10):
|
|
253
309
|
self.grid.move_to_empty(a, num_agents=self.num_agents)
|
|
254
310
|
assert len(self.grid.empties) == 8
|
|
255
311
|
|
|
@@ -299,7 +355,7 @@ class TestMultiGrid(unittest.TestCase):
|
|
|
299
355
|
counter = 0
|
|
300
356
|
for x in range(width):
|
|
301
357
|
for y in range(height):
|
|
302
|
-
for
|
|
358
|
+
for _i in range(TEST_MULTIGRID[x][y]):
|
|
303
359
|
counter += 1
|
|
304
360
|
# Create and place the mock agent
|
|
305
361
|
a = MockAgent(counter, None)
|
|
@@ -343,7 +399,7 @@ class TestMultiGrid(unittest.TestCase):
|
|
|
343
399
|
|
|
344
400
|
class TestHexGrid(unittest.TestCase):
|
|
345
401
|
"""
|
|
346
|
-
Testing a hexagonal
|
|
402
|
+
Testing a hexagonal singlegrid.
|
|
347
403
|
"""
|
|
348
404
|
|
|
349
405
|
def setUp(self):
|
|
@@ -391,10 +447,14 @@ class TestHexGrid(unittest.TestCase):
|
|
|
391
447
|
neighborhood = self.grid.get_neighborhood((1, 1), include_center=True)
|
|
392
448
|
assert len(neighborhood) == 7
|
|
393
449
|
|
|
450
|
+
neighborhood = self.grid.get_neighborhood((0, 0), radius=4)
|
|
451
|
+
assert len(neighborhood) == 13
|
|
452
|
+
assert sum(x + y for x, y in neighborhood) == 39
|
|
394
453
|
|
|
395
|
-
|
|
454
|
+
|
|
455
|
+
class TestHexGridTorus(TestSingleGrid):
|
|
396
456
|
"""
|
|
397
|
-
Testing a hexagonal toroidal
|
|
457
|
+
Testing a hexagonal toroidal singlegrid.
|
|
398
458
|
"""
|
|
399
459
|
|
|
400
460
|
torus = True
|
|
@@ -435,12 +495,19 @@ class TestHexGridTorus(TestBaseGrid):
|
|
|
435
495
|
neighborhood = self.grid.get_neighborhood((2, 4))
|
|
436
496
|
assert len(neighborhood) == 6
|
|
437
497
|
|
|
498
|
+
neighborhood = self.grid.get_neighborhood((1, 1), include_center=True, radius=2)
|
|
499
|
+
assert len(neighborhood) == 13
|
|
500
|
+
|
|
501
|
+
neighborhood = self.grid.get_neighborhood((0, 0), radius=4)
|
|
502
|
+
assert len(neighborhood) == 14
|
|
503
|
+
assert sum(x + y for x, y in neighborhood) == 45
|
|
504
|
+
|
|
438
505
|
|
|
439
506
|
class TestIndexing:
|
|
440
507
|
# Create a grid where the content of each coordinate is a tuple of its coordinates
|
|
441
|
-
grid =
|
|
508
|
+
grid = SingleGrid(3, 5, True)
|
|
442
509
|
for _, x, y in grid.coord_iter():
|
|
443
|
-
grid.
|
|
510
|
+
grid._grid[x][y] = (x, y)
|
|
444
511
|
|
|
445
512
|
def test_int(self):
|
|
446
513
|
assert self.grid[0][0] == (0, 0)
|
tests/test_import_namespace.py
CHANGED
tests/test_lifespan.py
CHANGED
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
import unittest
|
|
2
2
|
|
|
3
|
-
from mesa.time import RandomActivation
|
|
4
|
-
from mesa.datacollection import DataCollector
|
|
5
|
-
from mesa import Model, Agent
|
|
6
3
|
import numpy as np
|
|
7
4
|
|
|
5
|
+
from mesa import Agent, Model
|
|
6
|
+
from mesa.datacollection import DataCollector
|
|
7
|
+
from mesa.time import RandomActivation
|
|
8
|
+
|
|
8
9
|
|
|
9
10
|
class LifeTimeModel(Model):
|
|
10
11
|
"""Simple model for running models with a finite life"""
|
tests/test_main.py
CHANGED
|
@@ -2,6 +2,7 @@ import os
|
|
|
2
2
|
import sys
|
|
3
3
|
import unittest
|
|
4
4
|
from unittest.mock import patch
|
|
5
|
+
|
|
5
6
|
from click.testing import CliRunner
|
|
6
7
|
|
|
7
8
|
from mesa.main import cli
|
|
@@ -19,8 +20,11 @@ class TestCli(unittest.TestCase):
|
|
|
19
20
|
def tearDown(self):
|
|
20
21
|
sys.path[:] = self.old_sys_path
|
|
21
22
|
|
|
23
|
+
@unittest.skip(
|
|
24
|
+
"Skipping test_run, because examples folder was moved. More discussion needed."
|
|
25
|
+
)
|
|
22
26
|
def test_run(self):
|
|
23
|
-
with patch("mesa.visualization.ModularServer") as ModularServer:
|
|
27
|
+
with patch("mesa.visualization.ModularServer") as ModularServer: # noqa: N806
|
|
24
28
|
example_dir = os.path.abspath(
|
|
25
29
|
os.path.join(os.path.dirname(__file__), "../examples/wolf_sheep")
|
|
26
30
|
)
|
tests/test_scaffold.py
CHANGED
tests/test_space.py
CHANGED
|
@@ -4,12 +4,9 @@ import networkx as nx
|
|
|
4
4
|
import numpy as np
|
|
5
5
|
import pytest
|
|
6
6
|
|
|
7
|
-
from mesa.space import ContinuousSpace
|
|
8
|
-
from mesa.space import SingleGrid
|
|
9
|
-
from mesa.space import NetworkGrid
|
|
7
|
+
from mesa.space import ContinuousSpace, NetworkGrid, SingleGrid
|
|
10
8
|
from tests.test_grid import MockAgent
|
|
11
9
|
|
|
12
|
-
|
|
13
10
|
TEST_AGENTS = [(-20, -20), (-20, -20.05), (65, 18)]
|
|
14
11
|
TEST_AGENTS_GRID = [(1, 1), (10, 0), (10, 10)]
|
|
15
12
|
TEST_AGENTS_NETWORK_SINGLE = [0, 1, 5]
|
|
@@ -302,10 +299,10 @@ class TestSingleGrid(unittest.TestCase):
|
|
|
302
299
|
for i, pos in enumerate(TEST_AGENTS_GRID):
|
|
303
300
|
a = self.agents[i]
|
|
304
301
|
assert a.pos == pos
|
|
305
|
-
assert self.space
|
|
302
|
+
assert self.space[pos[0]][pos[1]] == a
|
|
306
303
|
self.space.remove_agent(a)
|
|
307
304
|
assert a.pos is None
|
|
308
|
-
assert self.space
|
|
305
|
+
assert self.space[pos[0]][pos[1]] is None
|
|
309
306
|
|
|
310
307
|
def test_empty_cells(self):
|
|
311
308
|
if self.space.exists_empty_cells():
|
|
@@ -325,12 +322,12 @@ class TestSingleGrid(unittest.TestCase):
|
|
|
325
322
|
_agent = self.agents[agent_number]
|
|
326
323
|
|
|
327
324
|
assert _agent.pos == initial_pos
|
|
328
|
-
assert self.space
|
|
329
|
-
assert self.space
|
|
325
|
+
assert self.space[initial_pos[0]][initial_pos[1]] == _agent
|
|
326
|
+
assert self.space[final_pos[0]][final_pos[1]] is None
|
|
330
327
|
self.space.move_agent(_agent, final_pos)
|
|
331
328
|
assert _agent.pos == final_pos
|
|
332
|
-
assert self.space
|
|
333
|
-
assert self.space
|
|
329
|
+
assert self.space[initial_pos[0]][initial_pos[1]] is None
|
|
330
|
+
assert self.space[final_pos[0]][final_pos[1]] == _agent
|
|
334
331
|
|
|
335
332
|
|
|
336
333
|
class TestSingleNetworkGrid(unittest.TestCase):
|
|
@@ -340,7 +337,7 @@ class TestSingleNetworkGrid(unittest.TestCase):
|
|
|
340
337
|
"""
|
|
341
338
|
Create a test network grid and populate with Mock Agents.
|
|
342
339
|
"""
|
|
343
|
-
G = nx.
|
|
340
|
+
G = nx.cycle_graph(TestSingleNetworkGrid.GRAPH_SIZE) # noqa: N806
|
|
344
341
|
self.space = NetworkGrid(G)
|
|
345
342
|
self.agents = []
|
|
346
343
|
for i, pos in enumerate(TEST_AGENTS_NETWORK_SINGLE):
|
|
@@ -357,14 +354,10 @@ class TestSingleNetworkGrid(unittest.TestCase):
|
|
|
357
354
|
assert a.pos == pos
|
|
358
355
|
|
|
359
356
|
def test_get_neighbors(self):
|
|
360
|
-
assert (
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
)
|
|
364
|
-
assert (
|
|
365
|
-
len(self.space.get_neighbors(0, include_center=False))
|
|
366
|
-
== TestSingleNetworkGrid.GRAPH_SIZE - 1
|
|
367
|
-
)
|
|
357
|
+
assert len(self.space.get_neighbors(0, include_center=True)) == 3
|
|
358
|
+
assert len(self.space.get_neighbors(0, include_center=False)) == 2
|
|
359
|
+
assert len(self.space.get_neighbors(2, include_center=True, radius=3)) == 7
|
|
360
|
+
assert len(self.space.get_neighbors(2, include_center=False, radius=3)) == 6
|
|
368
361
|
|
|
369
362
|
def test_move_agent(self):
|
|
370
363
|
initial_pos = 1
|
|
@@ -415,7 +408,7 @@ class TestMultipleNetworkGrid(unittest.TestCase):
|
|
|
415
408
|
"""
|
|
416
409
|
Create a test network grid and populate with Mock Agents.
|
|
417
410
|
"""
|
|
418
|
-
G = nx.complete_graph(TestMultipleNetworkGrid.GRAPH_SIZE)
|
|
411
|
+
G = nx.complete_graph(TestMultipleNetworkGrid.GRAPH_SIZE) # noqa: N806
|
|
419
412
|
self.space = NetworkGrid(G)
|
|
420
413
|
self.agents = []
|
|
421
414
|
for i, pos in enumerate(TEST_AGENTS_NETWORK_MULTIPLE):
|
tests/test_time.py
CHANGED
|
@@ -4,13 +4,14 @@ Test the advanced schedulers.
|
|
|
4
4
|
|
|
5
5
|
import unittest
|
|
6
6
|
from unittest import TestCase, mock
|
|
7
|
-
|
|
7
|
+
|
|
8
|
+
from mesa import Agent, Model
|
|
8
9
|
from mesa.time import (
|
|
9
10
|
BaseScheduler,
|
|
10
|
-
StagedActivation,
|
|
11
11
|
RandomActivation,
|
|
12
|
-
SimultaneousActivation,
|
|
13
12
|
RandomActivationByType,
|
|
13
|
+
SimultaneousActivation,
|
|
14
|
+
StagedActivation,
|
|
14
15
|
)
|
|
15
16
|
|
|
16
17
|
RANDOM = "random"
|
|
@@ -29,7 +30,15 @@ class MockAgent(Agent):
|
|
|
29
30
|
self.steps = 0
|
|
30
31
|
self.advances = 0
|
|
31
32
|
|
|
33
|
+
def kill_other_agent(self):
|
|
34
|
+
for agent in self.model.schedule.agents:
|
|
35
|
+
if agent is not self:
|
|
36
|
+
self.model.schedule.remove(agent)
|
|
37
|
+
break
|
|
38
|
+
|
|
32
39
|
def stage_one(self):
|
|
40
|
+
if self.model.enable_kill_other_agent:
|
|
41
|
+
self.kill_other_agent()
|
|
33
42
|
self.model.log.append(self.unique_id + "_1")
|
|
34
43
|
|
|
35
44
|
def stage_two(self):
|
|
@@ -39,11 +48,14 @@ class MockAgent(Agent):
|
|
|
39
48
|
self.advances += 1
|
|
40
49
|
|
|
41
50
|
def step(self):
|
|
51
|
+
if self.model.enable_kill_other_agent:
|
|
52
|
+
self.kill_other_agent()
|
|
42
53
|
self.steps += 1
|
|
54
|
+
self.model.log.append(self.unique_id)
|
|
43
55
|
|
|
44
56
|
|
|
45
57
|
class MockModel(Model):
|
|
46
|
-
def __init__(self, shuffle=False, activation=STAGED):
|
|
58
|
+
def __init__(self, shuffle=False, activation=STAGED, enable_kill_other_agent=False):
|
|
47
59
|
"""
|
|
48
60
|
Creates a Model instance with a schedule
|
|
49
61
|
|
|
@@ -59,6 +71,7 @@ class MockModel(Model):
|
|
|
59
71
|
The default scheduler is a BaseScheduler.
|
|
60
72
|
"""
|
|
61
73
|
self.log = []
|
|
74
|
+
self.enable_kill_other_agent = enable_kill_other_agent
|
|
62
75
|
|
|
63
76
|
# Make scheduler
|
|
64
77
|
if activation == STAGED:
|
|
@@ -91,7 +104,7 @@ class TestStagedActivation(TestCase):
|
|
|
91
104
|
|
|
92
105
|
def test_no_shuffle(self):
|
|
93
106
|
"""
|
|
94
|
-
Testing staged activation without shuffling.
|
|
107
|
+
Testing the staged activation without shuffling.
|
|
95
108
|
"""
|
|
96
109
|
model = MockModel(shuffle=False)
|
|
97
110
|
model.step()
|
|
@@ -100,7 +113,7 @@ class TestStagedActivation(TestCase):
|
|
|
100
113
|
|
|
101
114
|
def test_shuffle(self):
|
|
102
115
|
"""
|
|
103
|
-
Test staged activation with shuffling
|
|
116
|
+
Test the staged activation with shuffling
|
|
104
117
|
"""
|
|
105
118
|
model = MockModel(shuffle=True)
|
|
106
119
|
model.step()
|
|
@@ -118,7 +131,7 @@ class TestStagedActivation(TestCase):
|
|
|
118
131
|
|
|
119
132
|
def test_remove(self):
|
|
120
133
|
"""
|
|
121
|
-
Test staged activation can remove an agent
|
|
134
|
+
Test the staged activation can remove an agent
|
|
122
135
|
"""
|
|
123
136
|
model = MockModel(shuffle=True)
|
|
124
137
|
agent_keys = list(model.schedule._agents.keys())
|
|
@@ -126,6 +139,15 @@ class TestStagedActivation(TestCase):
|
|
|
126
139
|
model.schedule.remove(agent)
|
|
127
140
|
assert agent not in model.schedule.agents
|
|
128
141
|
|
|
142
|
+
def test_intrastep_remove(self):
|
|
143
|
+
"""
|
|
144
|
+
Test the staged activation can remove an agent in a
|
|
145
|
+
step of another agent so that the one removed doesn't step.
|
|
146
|
+
"""
|
|
147
|
+
model = MockModel(shuffle=True, enable_kill_other_agent=True)
|
|
148
|
+
model.step()
|
|
149
|
+
assert len(model.log) == 2
|
|
150
|
+
|
|
129
151
|
def test_add_existing_agent(self):
|
|
130
152
|
model = MockModel()
|
|
131
153
|
agent = model.schedule.agents[0]
|
|
@@ -162,12 +184,20 @@ class TestRandomActivation(TestCase):
|
|
|
162
184
|
"""
|
|
163
185
|
Test the random activation step causes each agent to step
|
|
164
186
|
"""
|
|
165
|
-
|
|
166
187
|
model = MockModel(activation=RANDOM)
|
|
167
188
|
model.step()
|
|
168
189
|
agent_steps = [i.steps for i in model.schedule.agents]
|
|
169
190
|
# one step for each of 2 agents
|
|
170
|
-
assert all(
|
|
191
|
+
assert all(x == 1 for x in agent_steps)
|
|
192
|
+
|
|
193
|
+
def test_intrastep_remove(self):
|
|
194
|
+
"""
|
|
195
|
+
Test the random activation can remove an agent in a
|
|
196
|
+
step of another agent so that the one removed doesn't step.
|
|
197
|
+
"""
|
|
198
|
+
model = MockModel(activation=RANDOM, enable_kill_other_agent=True)
|
|
199
|
+
model.step()
|
|
200
|
+
assert len(model.log) == 1
|
|
171
201
|
|
|
172
202
|
|
|
173
203
|
class TestSimultaneousActivation(TestCase):
|
|
@@ -184,8 +214,8 @@ class TestSimultaneousActivation(TestCase):
|
|
|
184
214
|
# one step for each of 2 agents
|
|
185
215
|
agent_steps = [i.steps for i in model.schedule.agents]
|
|
186
216
|
agent_advances = [i.advances for i in model.schedule.agents]
|
|
187
|
-
assert all(
|
|
188
|
-
assert all(
|
|
217
|
+
assert all(x == 1 for x in agent_steps)
|
|
218
|
+
assert all(x == 1 for x in agent_advances)
|
|
189
219
|
|
|
190
220
|
|
|
191
221
|
class TestRandomActivationByType(TestCase):
|
|
@@ -224,7 +254,7 @@ class TestRandomActivationByType(TestCase):
|
|
|
224
254
|
model.step()
|
|
225
255
|
agent_steps = [i.steps for i in model.schedule.agents]
|
|
226
256
|
# one step for each of 2 agents
|
|
227
|
-
assert all(
|
|
257
|
+
assert all(x == 1 for x in agent_steps)
|
|
228
258
|
|
|
229
259
|
def test_add_non_unique_ids(self):
|
|
230
260
|
"""
|
|
@@ -233,8 +263,8 @@ class TestRandomActivationByType(TestCase):
|
|
|
233
263
|
RandomActivationByType.
|
|
234
264
|
"""
|
|
235
265
|
model = MockModel(activation=RANDOM_BY_TYPE)
|
|
236
|
-
a = MockAgent(0,
|
|
237
|
-
b = MockAgent(0,
|
|
266
|
+
a = MockAgent(0, model)
|
|
267
|
+
b = MockAgent(0, model)
|
|
238
268
|
model.schedule.add(a)
|
|
239
269
|
with self.assertRaises(Exception):
|
|
240
270
|
model.schedule.add(b)
|
tests/test_tornado.py
CHANGED
|
@@ -1,8 +1,10 @@
|
|
|
1
|
-
|
|
1
|
+
import json
|
|
2
|
+
|
|
2
3
|
import tornado
|
|
4
|
+
from tornado.testing import AsyncHTTPTestCase
|
|
5
|
+
|
|
3
6
|
from mesa import Model
|
|
4
7
|
from mesa.visualization.ModularVisualization import ModularServer
|
|
5
|
-
import json
|
|
6
8
|
|
|
7
9
|
|
|
8
10
|
class TestServer(AsyncHTTPTestCase):
|
tests/test_usersettableparam.py
CHANGED
tests/test_visualization.py
CHANGED
|
@@ -1,13 +1,12 @@
|
|
|
1
|
-
from unittest import TestCase
|
|
2
1
|
from collections import defaultdict
|
|
2
|
+
from unittest import TestCase
|
|
3
3
|
|
|
4
4
|
from mesa.model import Model
|
|
5
|
-
from mesa.space import
|
|
5
|
+
from mesa.space import MultiGrid
|
|
6
6
|
from mesa.time import SimultaneousActivation
|
|
7
7
|
from mesa.visualization.ModularVisualization import ModularServer
|
|
8
8
|
from mesa.visualization.modules import CanvasGrid, TextElement
|
|
9
9
|
from mesa.visualization.UserParam import UserSettableParameter
|
|
10
|
-
|
|
11
10
|
from tests.test_batchrunner import MockAgent
|
|
12
11
|
|
|
13
12
|
|
|
@@ -15,15 +14,14 @@ class MockModel(Model):
|
|
|
15
14
|
"""Test model for testing"""
|
|
16
15
|
|
|
17
16
|
def __init__(self, width, height, key1=103, key2=104):
|
|
18
|
-
|
|
19
17
|
self.width = width
|
|
20
18
|
self.height = height
|
|
21
19
|
self.key1 = (key1,)
|
|
22
20
|
self.key2 = key2
|
|
23
21
|
self.schedule = SimultaneousActivation(self)
|
|
24
|
-
self.grid =
|
|
22
|
+
self.grid = MultiGrid(width, height, torus=True)
|
|
25
23
|
|
|
26
|
-
for
|
|
24
|
+
for _c, x, y in self.grid.coord_iter():
|
|
27
25
|
a = MockAgent(x + y * 100, self, x * y * 3)
|
|
28
26
|
self.grid.place_agent(a, (x, y))
|
|
29
27
|
self.schedule.add(a)
|
|
@@ -48,7 +46,6 @@ class TestModularServer(TestCase):
|
|
|
48
46
|
}
|
|
49
47
|
|
|
50
48
|
def setUp(self):
|
|
51
|
-
|
|
52
49
|
self.user_params = {
|
|
53
50
|
"width": 1,
|
|
54
51
|
"height": 1,
|
|
@@ -68,7 +65,6 @@ class TestModularServer(TestCase):
|
|
|
68
65
|
)
|
|
69
66
|
|
|
70
67
|
def test_canvas_render_model_state(self):
|
|
71
|
-
|
|
72
68
|
test_portrayal = self.portrayal(None)
|
|
73
69
|
test_grid_state = defaultdict(list)
|
|
74
70
|
test_grid_state[test_portrayal["Layer"]].append(test_portrayal)
|
|
File without changes
|
|
File without changes
|