1 /**
2  * Unit tests for system.d
3  *
4  */
5 module system_test;
6 
7 import ashd.core.engine   : Engine;
8 import ashd.core.iengine  : IEngine;
9 import ashd.core.system   : System;
10 
11 
12 import std.datetime  : dur, Duration, SysTime;
13 
14 
15 int main()
16 {
17     (new SystemTests).systemsGetterReturnsAllTheSystems();
18     (new SystemTests).addSystemCallsAddToEngine();
19     (new SystemTests).removeSystemCallsRemovedFromEngine();
20     (new SystemTests).engineCallsUpdateOnSystems();
21     (new SystemTests).defaultPriorityIsZero();
22     (new SystemTests).canSetPriorityWhenAddingSystem();
23     (new SystemTests).systemsUpdatedInPriorityOrderIfSameAsAddOrder();
24     (new SystemTests).systemsUpdatedInPriorityOrderIfReverseOfAddOrder();
25     (new SystemTests).systemsUpdatedInPriorityOrderIfPrioritiesAreNegative();
26     (new SystemTests).updatingIsFalseBeforeUpdate();
27     (new SystemTests).updatingIsTrueDuringUpdate();
28     (new SystemTests).updatingIsFalseAfterUpdate();
29     (new SystemTests).completeSignalIsDispatchedAfterUpdate();
30     (new SystemTests).getSystemReturnsTheSystem();
31     (new SystemTests).getSystemReturnsNullIfNoSuchSystem();
32     (new SystemTests).removeAllSystemsDoesWhatItSays();
33     (new SystemTests).removeSystemAndAddItAgainDontCauseInvalidLinkedList();
34 
35     return 0;
36 }
37 
38 class SystemTests
39 {
40     Engine mEngine;
41 
42     bool mAddedCallbackCalled;
43     bool mRemovedCallbackCalled;
44     bool mUpdatedCallbackCalled;
45     bool mUpdateCompleteCallbackCalled;
46 
47     void delegate(System sys_a, string action_a, IEngine engine_a) mCallbackType1;
48     void delegate(System sys_a, string action_a, Duration time_a)  mCallbackType2;
49 
50     public this()
51     {
52         mEngine = new Engine();
53     }
54 
55     public void systemsGetterReturnsAllTheSystems()
56     {
57         MockSystem system1 = new MockSystem( this );
58         mEngine.addSystem( system1, 1 );
59         MockSystem system2 = new MockSystem( this );
60         mEngine.addSystem( system2, 1 );
61         assert( mEngine.systems.length == 2 );
62         bool[System] tmp;
63         foreach ( sys; mEngine.systems )
64             tmp[sys] = true;
65         assert( system1 in tmp );
66         assert( system2 in tmp );
67     }
68 
69     public void addSystemCallsAddToEngine()
70     {
71         mAddedCallbackCalled = false;
72         MockSystem system = new MockSystem( this );
73         mCallbackType1 = &this.addedCallbackMethod;
74         mEngine.addSystem( system, 0 );
75         assert( mAddedCallbackCalled == true );
76     }
77 
78     private void addedCallbackMethod( System sys_a, string action_a, IEngine engine_a )
79     {
80         mAddedCallbackCalled = true;
81         assert( action_a == "added" );
82         assert( engine_a is mEngine );
83     }
84 
85     public void removeSystemCallsRemovedFromEngine()
86     {
87         mRemovedCallbackCalled = false;
88         MockSystem system = new MockSystem( this );
89         mEngine.addSystem( system, 0 );
90         mCallbackType1 = &this.removedCallbackMethod;
91         mEngine.removeSystem( system );
92         assert( mRemovedCallbackCalled == true );
93     }
94 
95     private void removedCallbackMethod( System sys_a, string action_a, IEngine engine_a )
96     {
97         mRemovedCallbackCalled = true;
98         assert( action_a == "removed" );
99         assert( engine_a is mEngine );
100     }
101 
102     public void engineCallsUpdateOnSystems()
103     {
104         mUpdatedCallbackCalled = false;
105         MockSystem system = new MockSystem( this );
106         mEngine.addSystem( system, 0 );
107         mCallbackType2 = &this.updateCallbackMethod;
108         mEngine.update( dur!"seconds"(3) );
109         assert( mUpdatedCallbackCalled == true );
110     }
111     private void updateCallbackMethod( System system_a, string action_a, Duration time_a )
112     {
113         mUpdatedCallbackCalled = true;
114         assert( action_a == "update" );
115         assert( time_a == dur!"seconds"(3) );
116     }
117 
118     public void defaultPriorityIsZero()
119     {
120         MockSystem system = new MockSystem( this );
121         assert( system.priority == 0 );
122     }
123 
124     public void canSetPriorityWhenAddingSystem()
125     {
126         MockSystem system = new MockSystem( this );
127         mEngine.addSystem( system, 10 );
128         assert( system.priority == 10 );
129     }
130 
131     MockSystem tmpSys1, tmpSys2;
132     public void systemsUpdatedInPriorityOrderIfSameAsAddOrder()
133     {
134         mUpdatedCallbackCalled = false;
135         tmpSys1 = new MockSystem( this );
136         mEngine.addSystem( tmpSys1, 10 );
137         tmpSys2 = new MockSystem( this );
138         mEngine.addSystem( tmpSys2, 20 );
139         mCallbackType2 = &this.updateCallbackMethod1;
140         mEngine.update( dur!"seconds"(3) );
141         assert( mUpdatedCallbackCalled == true );
142     }
143 
144     private void updateCallbackMethod1( System system_a, string action_a, Duration time_a )
145     {
146         assert( system_a is tmpSys1 );
147         mCallbackType2 = &this.updateCallbackMethod2;
148     }
149 
150     private void updateCallbackMethod2( System system_a, string action_a, Duration time_a )
151     {
152         mUpdatedCallbackCalled = true;
153         assert( system_a is tmpSys2 );
154     }
155 
156     public void systemsUpdatedInPriorityOrderIfReverseOfAddOrder()
157     {
158         mUpdatedCallbackCalled = false;
159         tmpSys2 = new MockSystem( this );
160         mEngine.addSystem( tmpSys2, 20 );
161         tmpSys1 = new MockSystem( this );
162         mEngine.addSystem( tmpSys1, 10 );
163         mCallbackType2 = &this.updateCallbackMethod1;
164         mEngine.update( dur!"seconds"(3) );
165         assert( mUpdatedCallbackCalled == true );
166     }
167 
168     public void systemsUpdatedInPriorityOrderIfPrioritiesAreNegative()
169     {
170         tmpSys2 = new MockSystem( this );
171         mEngine.addSystem( tmpSys2, 20 );
172         tmpSys1 = new MockSystem( this );
173         mEngine.addSystem( tmpSys1, -20 );
174         mCallbackType2 = &this.updateCallbackMethod1;
175         mEngine.update( dur!"seconds"(3) );
176     }
177 
178     public void updatingIsFalseBeforeUpdate()
179     {
180         assert( mEngine.updating == false );
181     }
182 
183     public void updatingIsTrueDuringUpdate()
184     {
185         MockSystem system = new MockSystem( this );
186         mEngine.addSystem( system, 0 );
187         mCallbackType2 = &this.assertUpdatingIsTrue;
188         mEngine.update( dur!"seconds"(3) );
189     }
190 
191     private void assertUpdatingIsTrue( System system_a, string action_a, Duration time_a )
192     {
193         assert( mEngine.updating == true );
194     }
195 
196     public void updatingIsFalseAfterUpdate()
197     {
198         mEngine.update( dur!"seconds"(3) );
199         assert( mEngine.updating == false );
200     }
201 
202     public void completeSignalIsDispatchedAfterUpdate()
203     {
204         mUpdateCompleteCallbackCalled = false;
205         MockSystem system = new MockSystem( this );
206         mEngine.addSystem( system, 0 );
207         mCallbackType2 = &this.listensForUpdateComplete;
208         mEngine.update( dur!"seconds"(3) );
209         assert( mUpdatedCallbackCalled == true );
210         assert( mUpdateCompleteCallbackCalled == true );
211     }
212 
213     private void listensForUpdateComplete( System system_a, string action_a, Duration time_a )
214     {
215         mUpdatedCallbackCalled = true;
216         class Watcher { void watch() { mUpdateCompleteCallbackCalled = true; } }
217         Watcher testWatch = new Watcher();
218         mEngine.updateComplete.connect( &testWatch.watch );
219     }
220 
221     public void getSystemReturnsTheSystem()
222     {
223         MockSystem system1 = new MockSystem( this );
224         mEngine.addSystem( system1, 0 );
225         MockSystem2 system2 = new MockSystem2;
226         mEngine.addSystem( system2, 0 );
227         assert( mEngine.getSystem!MockSystem() is system1 );
228     }
229 
230     public void getSystemReturnsNullIfNoSuchSystem()
231     {
232         MockSystem2 system2 = new MockSystem2;
233         mEngine.addSystem( system2, 0 );
234         assert( mEngine.getSystem!MockSystem() is null );
235     }
236 
237     public void removeAllSystemsDoesWhatItSays()
238     {
239         MockSystem system1 = new MockSystem( this );
240         mEngine.addSystem( system1, 0 );
241         MockSystem2 system2 = new MockSystem2;
242         mEngine.addSystem( system2, 0 );
243         mEngine.removeAllSystems();
244         assert( mEngine.getSystem!MockSystem() is null );
245         assert( mEngine.getSystem!MockSystem2() is null );
246     }
247 
248     public void removeSystemAndAddItAgainDontCauseInvalidLinkedList()
249     {
250         auto systemB  = new MockSystem2();
251         auto systemC  = new MockSystem2();
252         mEngine.addSystem( systemB, 0 );
253         mEngine.addSystem( systemC, 0 );
254         mEngine.removeSystem( systemB );
255         mEngine.addSystem( systemB, 0 );
256         assert( systemC.previous is null );
257         assert( systemB.next is null );
258     }
259  
260 
261 }
262 
263 
264 class MockSystem: System
265 {
266     private SystemTests mTests;
267 
268     public this( SystemTests tests_a )
269     {
270         this.mTests = tests_a;
271     }
272 
273     override public void addToEngine( IEngine engine_a )
274     {
275         if( mTests.mCallbackType1 != null )
276             mTests.mCallbackType1( this, "added", engine_a );
277     }
278 
279     override public void removeFromEngine( IEngine engine_a )
280     {
281         if( mTests.mCallbackType1 != null )
282             mTests.mCallbackType1( this, "removed", engine_a );
283     }
284 
285     override public void update( Duration time_a )
286     {
287         if( mTests.mCallbackType2 != null )
288             mTests.mCallbackType2( this, "update", time_a );
289     }
290     
291 }
292 
293 class MockSystem2: System
294 {
295    
296 }
297