Mesa 1.1.1__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.1.dist-info → Mesa-1.2.0.dist-info}/LICENSE +1 -1
- {Mesa-1.1.1.dist-info → Mesa-1.2.0.dist-info}/METADATA +14 -12
- {Mesa-1.1.1.dist-info → Mesa-1.2.0.dist-info}/RECORD +41 -41
- {Mesa-1.1.1.dist-info → Mesa-1.2.0.dist-info}/WHEEL +1 -1
- mesa/__init__.py +8 -9
- mesa/agent.py +2 -3
- mesa/batchrunner.py +16 -23
- mesa/datacollection.py +15 -28
- mesa/main.py +4 -4
- mesa/model.py +2 -6
- mesa/space.py +298 -225
- mesa/time.py +25 -24
- mesa/visualization/ModularVisualization.py +5 -8
- 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 +5 -9
- 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 +89 -36
- 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.1.dist-info → Mesa-1.2.0.dist-info}/entry_points.txt +0 -0
- {Mesa-1.1.1.dist-info → Mesa-1.2.0.dist-info}/top_level.txt +0 -0
tests/test_grid.py
CHANGED
|
@@ -3,8 +3,9 @@ Test the Grid objects.
|
|
|
3
3
|
"""
|
|
4
4
|
import random
|
|
5
5
|
import unittest
|
|
6
|
-
from unittest.mock import
|
|
7
|
-
|
|
6
|
+
from unittest.mock import Mock, patch
|
|
7
|
+
|
|
8
|
+
from mesa.space import HexGrid, MultiGrid, SingleGrid
|
|
8
9
|
|
|
9
10
|
# Initial agent positions for testing
|
|
10
11
|
#
|
|
@@ -15,7 +16,7 @@ from mesa.space import Grid, SingleGrid, MultiGrid, HexGrid
|
|
|
15
16
|
# 1 0 1
|
|
16
17
|
# 0 0 1
|
|
17
18
|
# -------------------
|
|
18
|
-
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]]
|
|
19
20
|
|
|
20
21
|
|
|
21
22
|
class MockAgent:
|
|
@@ -29,9 +30,9 @@ class MockAgent:
|
|
|
29
30
|
self.pos = pos
|
|
30
31
|
|
|
31
32
|
|
|
32
|
-
class
|
|
33
|
+
class TestSingleGrid(unittest.TestCase):
|
|
33
34
|
"""
|
|
34
|
-
Testing a non-toroidal
|
|
35
|
+
Testing a non-toroidal singlegrid.
|
|
35
36
|
"""
|
|
36
37
|
|
|
37
38
|
torus = False
|
|
@@ -40,9 +41,10 @@ class TestBaseGrid(unittest.TestCase):
|
|
|
40
41
|
"""
|
|
41
42
|
Create a test non-toroidal grid and populate it with Mock Agents
|
|
42
43
|
"""
|
|
44
|
+
# The height needs to be even to test the edge case described in PR #1517
|
|
45
|
+
height = 6 # height of grid
|
|
43
46
|
width = 3 # width of grid
|
|
44
|
-
|
|
45
|
-
self.grid = Grid(width, height, self.torus)
|
|
47
|
+
self.grid = SingleGrid(width, height, self.torus)
|
|
46
48
|
self.agents = []
|
|
47
49
|
counter = 0
|
|
48
50
|
for x in range(width):
|
|
@@ -109,10 +111,10 @@ class TestBaseGrid(unittest.TestCase):
|
|
|
109
111
|
assert len(neighborhood) == 8
|
|
110
112
|
|
|
111
113
|
neighborhood = self.grid.get_neighborhood((1, 4), moore=False)
|
|
112
|
-
assert len(neighborhood) ==
|
|
114
|
+
assert len(neighborhood) == 4
|
|
113
115
|
|
|
114
116
|
neighborhood = self.grid.get_neighborhood((1, 4), moore=True)
|
|
115
|
-
assert len(neighborhood) ==
|
|
117
|
+
assert len(neighborhood) == 8
|
|
116
118
|
|
|
117
119
|
neighborhood = self.grid.get_neighborhood((0, 0), moore=False)
|
|
118
120
|
assert len(neighborhood) == 2
|
|
@@ -127,7 +129,7 @@ class TestBaseGrid(unittest.TestCase):
|
|
|
127
129
|
assert len(neighbors) == 3
|
|
128
130
|
|
|
129
131
|
neighbors = self.grid.get_neighbors((1, 3), moore=False, radius=2)
|
|
130
|
-
assert len(neighbors) ==
|
|
132
|
+
assert len(neighbors) == 3
|
|
131
133
|
|
|
132
134
|
def test_coord_iter(self):
|
|
133
135
|
ci = self.grid.coord_iter()
|
|
@@ -148,8 +150,8 @@ class TestBaseGrid(unittest.TestCase):
|
|
|
148
150
|
def test_agent_move(self):
|
|
149
151
|
# get the agent at [0, 1]
|
|
150
152
|
agent = self.agents[0]
|
|
151
|
-
self.grid.move_agent(agent, (1,
|
|
152
|
-
assert agent.pos == (1,
|
|
153
|
+
self.grid.move_agent(agent, (1, 0))
|
|
154
|
+
assert agent.pos == (1, 0)
|
|
153
155
|
# move it off the torus and check for the exception
|
|
154
156
|
if not self.torus:
|
|
155
157
|
with self.assertRaises(Exception):
|
|
@@ -157,22 +159,51 @@ class TestBaseGrid(unittest.TestCase):
|
|
|
157
159
|
with self.assertRaises(Exception):
|
|
158
160
|
self.grid.move_agent(agent, [1, self.grid.height + 1])
|
|
159
161
|
else:
|
|
160
|
-
self.grid.move_agent(agent, [
|
|
161
|
-
assert agent.pos == (self.grid.
|
|
162
|
-
self.grid.move_agent(agent, [1, self.grid.height
|
|
163
|
-
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)
|
|
164
166
|
|
|
165
167
|
def test_agent_remove(self):
|
|
166
168
|
agent = self.agents[0]
|
|
167
169
|
x, y = agent.pos
|
|
168
170
|
self.grid.remove_agent(agent)
|
|
169
171
|
assert agent.pos is None
|
|
170
|
-
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
|
|
171
192
|
|
|
193
|
+
# Raise for agents not on the grid
|
|
194
|
+
self.grid.remove_agent(agent_a)
|
|
195
|
+
self.grid.remove_agent(agent_b)
|
|
172
196
|
|
|
173
|
-
|
|
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)
|
|
202
|
+
|
|
203
|
+
|
|
204
|
+
class TestSingleGridTorus(TestSingleGrid):
|
|
174
205
|
"""
|
|
175
|
-
Testing the toroidal
|
|
206
|
+
Testing the toroidal singlegrid.
|
|
176
207
|
"""
|
|
177
208
|
|
|
178
209
|
torus = True
|
|
@@ -191,25 +222,30 @@ class TestBaseGridTorus(TestBaseGrid):
|
|
|
191
222
|
neighborhood = self.grid.get_neighborhood((0, 0), moore=False)
|
|
192
223
|
assert len(neighborhood) == 4
|
|
193
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
|
+
|
|
194
233
|
neighbors = self.grid.get_neighbors((1, 4), moore=False)
|
|
195
|
-
assert len(neighbors) ==
|
|
234
|
+
assert len(neighbors) == 2
|
|
196
235
|
|
|
197
236
|
neighbors = self.grid.get_neighbors((1, 4), moore=True)
|
|
198
|
-
assert len(neighbors) ==
|
|
237
|
+
assert len(neighbors) == 4
|
|
199
238
|
|
|
200
239
|
neighbors = self.grid.get_neighbors((1, 1), moore=False, include_center=True)
|
|
201
240
|
assert len(neighbors) == 3
|
|
202
241
|
|
|
203
242
|
neighbors = self.grid.get_neighbors((1, 3), moore=False, radius=2)
|
|
204
|
-
assert len(neighbors) ==
|
|
243
|
+
assert len(neighbors) == 3
|
|
205
244
|
|
|
206
245
|
|
|
207
|
-
class
|
|
246
|
+
class TestSingleGridEnforcement(unittest.TestCase):
|
|
208
247
|
"""
|
|
209
|
-
Test the SingleGrid
|
|
210
|
-
|
|
211
|
-
Since it inherits from Grid, all the functionality tested above should
|
|
212
|
-
work here too. Instead, this tests the enforcement.
|
|
248
|
+
Test the enforcement in SingleGrid.
|
|
213
249
|
"""
|
|
214
250
|
|
|
215
251
|
def setUp(self):
|
|
@@ -232,6 +268,25 @@ class TestSingleGrid(unittest.TestCase):
|
|
|
232
268
|
self.grid.place_agent(a, (x, y))
|
|
233
269
|
self.num_agents = len(self.agents)
|
|
234
270
|
|
|
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
|
+
|
|
235
290
|
@patch.object(MockAgent, "model", create=True)
|
|
236
291
|
def test_enforcement(self, mock_model):
|
|
237
292
|
"""
|
|
@@ -250,9 +305,7 @@ class TestSingleGrid(unittest.TestCase):
|
|
|
250
305
|
# Test whether after placing, the empty cells are reduced by 1
|
|
251
306
|
assert a.pos not in self.grid.empties
|
|
252
307
|
assert len(self.grid.empties) == 8
|
|
253
|
-
for
|
|
254
|
-
# Since the agents and the grid are not associated with a model, we
|
|
255
|
-
# must explicitly tell move_to_empty the number of agents.
|
|
308
|
+
for _i in range(10):
|
|
256
309
|
self.grid.move_to_empty(a, num_agents=self.num_agents)
|
|
257
310
|
assert len(self.grid.empties) == 8
|
|
258
311
|
|
|
@@ -302,7 +355,7 @@ class TestMultiGrid(unittest.TestCase):
|
|
|
302
355
|
counter = 0
|
|
303
356
|
for x in range(width):
|
|
304
357
|
for y in range(height):
|
|
305
|
-
for
|
|
358
|
+
for _i in range(TEST_MULTIGRID[x][y]):
|
|
306
359
|
counter += 1
|
|
307
360
|
# Create and place the mock agent
|
|
308
361
|
a = MockAgent(counter, None)
|
|
@@ -346,7 +399,7 @@ class TestMultiGrid(unittest.TestCase):
|
|
|
346
399
|
|
|
347
400
|
class TestHexGrid(unittest.TestCase):
|
|
348
401
|
"""
|
|
349
|
-
Testing a hexagonal
|
|
402
|
+
Testing a hexagonal singlegrid.
|
|
350
403
|
"""
|
|
351
404
|
|
|
352
405
|
def setUp(self):
|
|
@@ -399,9 +452,9 @@ class TestHexGrid(unittest.TestCase):
|
|
|
399
452
|
assert sum(x + y for x, y in neighborhood) == 39
|
|
400
453
|
|
|
401
454
|
|
|
402
|
-
class TestHexGridTorus(
|
|
455
|
+
class TestHexGridTorus(TestSingleGrid):
|
|
403
456
|
"""
|
|
404
|
-
Testing a hexagonal toroidal
|
|
457
|
+
Testing a hexagonal toroidal singlegrid.
|
|
405
458
|
"""
|
|
406
459
|
|
|
407
460
|
torus = True
|
|
@@ -452,9 +505,9 @@ class TestHexGridTorus(TestBaseGrid):
|
|
|
452
505
|
|
|
453
506
|
class TestIndexing:
|
|
454
507
|
# Create a grid where the content of each coordinate is a tuple of its coordinates
|
|
455
|
-
grid =
|
|
508
|
+
grid = SingleGrid(3, 5, True)
|
|
456
509
|
for _, x, y in grid.coord_iter():
|
|
457
|
-
grid.
|
|
510
|
+
grid._grid[x][y] = (x, y)
|
|
458
511
|
|
|
459
512
|
def test_int(self):
|
|
460
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
|