22Test the advanced schedulers.
33'''
44
5- import unittest
5+ from unittest import TestCase
6+ from unittest .mock import patch
67from mesa import Model , Agent
7- from mesa .time import StagedActivation
8+ from mesa .time import BaseScheduler , StagedActivation , RandomActivation , SimultaneousActivation
89
10+ RANDOM = 'random'
11+ STAGED = 'staged'
12+ SIMULTANEOUS = 'simultaneous'
913
10- class MockStagedAgent (Agent ):
14+
15+ class MockAgent (Agent ):
1116 '''
1217 Minimalistic agent for testing purposes.
1318 '''
@@ -21,24 +26,49 @@ def stage_one(self, model):
2126 def stage_two (self , model ):
2227 model .log .append (self .unique_id + "_2" )
2328
29+ def advance (self , model ):
30+ pass
31+
2432
2533class MockModel (Model ):
2634
27- def __init__ (self , shuffle ):
35+ def __init__ (self , shuffle = False , activation = STAGED ):
36+ '''
37+ Creates a Model instance with a schedule
38+
39+ Args:
40+ shuffle (Bool): whether or not to instantiate a scheduler with
41+ shuffling.
42+ This option is only used for StagedActivation schedulers.
43+
44+ activation (str): which kind of scheduler to use.
45+ 'random' will create a RandomActivation scheduler.
46+ 'staged' will create a StagedActivation scheduler.
47+ The default scheduler is a BaseScheduler.
48+ '''
2849 self .log = []
29- model_stages = ["stage_one" , "stage_two" ]
30- self .schedule = StagedActivation (self , model_stages , shuffle = shuffle )
50+
51+ # Make scheduler
52+ if activation == STAGED :
53+ model_stages = ["stage_one" , "stage_two" ]
54+ self .schedule = StagedActivation (self , model_stages , shuffle = shuffle )
55+ elif activation == RANDOM :
56+ self .schedule = RandomActivation (self )
57+ elif activation == SIMULTANEOUS :
58+ self .schedule = SimultaneousActivation (self )
59+ else :
60+ self .schedule = BaseScheduler (self )
3161
3262 # Make agents
3363 for name in ["A" , "B" ]:
34- agent = MockStagedAgent (name )
64+ agent = MockAgent (name )
3565 self .schedule .add (agent )
3666
3767 def step (self ):
3868 self .schedule .step ()
3969
4070
41- class TestStagedActivation (unittest . TestCase ):
71+ class TestStagedActivation (TestCase ):
4272 '''
4373 Test the staged activation.
4474 '''
@@ -49,17 +79,89 @@ def test_no_shuffle(self):
4979 '''
5080 Testing staged activation without shuffling.
5181 '''
52- model = MockModel (False )
82+ model = MockModel (shuffle = False )
5383 model .step ()
5484 assert model .log == self .expected_output
5585
5686 def test_shuffle (self ):
5787 '''
5888 Test staged activation with shuffling
5989 '''
60- model = MockModel (True )
90+ model = MockModel (shuffle = True )
6191 model .step ()
6292 for output in self .expected_output [:2 ]:
6393 assert output in model .log [:2 ]
6494 for output in self .expected_output [2 :]:
6595 assert output in model .log [2 :]
96+
97+ def test_shuffle_shuffles_agents (self ):
98+ model = MockModel (shuffle = True )
99+ with patch ('mesa.time.random.shuffle' ) as mock_shuffle :
100+ assert mock_shuffle .call_count == 0
101+ model .step ()
102+ assert mock_shuffle .call_count == 1
103+
104+ def test_remove (self ):
105+ '''
106+ Test staged activation can remove an agent
107+ '''
108+ model = MockModel (shuffle = True )
109+ agent = model .schedule .agents [0 ]
110+ model .schedule .remove (model .schedule .agents [0 ])
111+ assert agent not in model .schedule .agents
112+
113+
114+ class TestRandomActivation (TestCase ):
115+ '''
116+ Test the random activation.
117+ '''
118+
119+ def test_random_activation_step_shuffles (self ):
120+ '''
121+ Test the random activation step
122+ '''
123+ model = MockModel (activation = RANDOM )
124+ with patch ('mesa.time.random.shuffle' ) as mock_shuffle :
125+ model .schedule .step ()
126+ assert mock_shuffle .call_count == 1
127+
128+ def test_random_activation_step_increments_step_and_time_counts (self ):
129+ '''
130+ Test the random activation step increments step and time counts
131+ '''
132+ model = MockModel (activation = RANDOM )
133+ assert model .schedule .steps == 0
134+ assert model .schedule .time == 0
135+ model .schedule .step ()
136+ assert model .schedule .steps == 1
137+ assert model .schedule .time == 1
138+
139+ def test_random_activation_step_steps_each_agent (self ):
140+ '''
141+ Test the random activation step causes each agent to step
142+ '''
143+
144+ with patch ('test_time.MockAgent.step' ) as mock_agent_step :
145+ model = MockModel (activation = RANDOM )
146+ model .step ()
147+ # one step for each of 2 agents
148+ assert mock_agent_step .call_count == 2
149+
150+
151+ class TestSimultaneousActivation (TestCase ):
152+ '''
153+ Test the simultaneous activation.
154+ '''
155+
156+ def test_simultaneous_activation_step_steps_and_advances_each_agent (self ):
157+ '''
158+ Test the simultaneous activation step causes each agent to step
159+ '''
160+
161+ with patch ('test_time.MockAgent.step' ) as mock_agent_step ,\
162+ patch ('test_time.MockAgent.advance' ) as mock_agent_advance :
163+ model = MockModel (activation = SIMULTANEOUS )
164+ model .step ()
165+ # one step for each of 2 agents
166+ assert mock_agent_step .call_count == 2
167+ assert mock_agent_advance .call_count == 2
0 commit comments