1 /**
2  * Unit tests for nodelist.d
3  *
4  */
5 module nodelist_test;
6 
7 import ashd.core.node     : Node;
8 import ashd.core.nodelist : NodeList, SortFuncType;
9 
10 int main()
11 {
12     (new NodeListTests).addingNodeTriggersAddedSignal();
13     (new NodeListTests).removingNodeTriggersRemovedSignal();
14     (new NodeListTests).AllNodesAreCoveredDuringIteration();
15     (new NodeListTests).removingCurrentNodeDuringIterationIsValid();
16     (new NodeListTests).removingNextNodeDuringIterationIsValid();
17     (new NodeListTests).componentAddedSignalContainsCorrectParameters();
18     (new NodeListTests).componentRemovedSignalContainsCorrectParameters();
19     (new NodeListTests).nodesInitiallySortedInOrderOfAddition();
20     (new NodeListTests).swappingOnlyTwoNodesChangesTheirOrder();
21     (new NodeListTests).swappingAdjacentNodesChangesTheirPositions();
22     (new NodeListTests).swappingNonAdjacentNodesChangesTheirPositions();
23     (new NodeListTests).swappingEndNodesChangesTheirPositions();
24     (new NodeListTests).insertionSortCorrectlySortsSortedNodes();
25     (new NodeListTests).insertionSortCorrectlySortsReversedNodes();
26     (new NodeListTests).insertionSortCorrectlySortsMixedNodes();
27     (new NodeListTests).insertionSortRetainsTheOrderOfEquivalentNodes();
28     (new NodeListTests).mergeSortCorrectlySortsSortedNodes();
29     (new NodeListTests).mergeSortCorrectlySortsMixedNodes();
30     (new NodeListTests).mergeSortCorrectlySortsReversedNodes();
31 
32     return 0;
33 }
34 
35 class NodeListTests
36 {
37     NodeList mNodes;
38 
39     public this()
40     {
41         mNodes = new NodeList();
42     }
43 
44 
45     public void addingNodeTriggersAddedSignal()
46     {
47         MockNode node = new MockNode();
48 
49         bool bCalled = false;
50         class Watcher { void watch( Node n ) { bCalled = true; } }
51         Watcher testWatch = new Watcher();
52 
53         mNodes.nodeAdded.connect( &testWatch.watch );
54         mNodes.add( node );
55 
56         assert( bCalled == true );
57     }
58 
59     public void removingNodeTriggersRemovedSignal()
60     {
61         MockNode node = new MockNode();
62         mNodes.add( node );
63 
64         bool bCalled = false;
65         class Watcher { void watch( Node n ) { bCalled = true; } }
66         Watcher testWatch = new Watcher();
67 
68         mNodes.nodeRemoved.connect( &testWatch.watch );
69         mNodes.remove( node );
70 
71         assert( bCalled == true );
72     }
73 
74     public void AllNodesAreCoveredDuringIteration()
75     {
76         Node[] nodeArray;
77         foreach ( int i; 0..5 )
78         {
79             MockNode node = new MockNode();
80             nodeArray ~= node;
81             mNodes.add( node );
82         }
83 
84         for ( Node node = mNodes.head; node; node = node.next )
85         {
86             assert( nodeArray[0] == node );
87             nodeArray = nodeArray[1..$];
88         }
89         assert( nodeArray.length == 0 );
90     }
91 
92     public void removingCurrentNodeDuringIterationIsValid()
93     {
94         Node[] nodeArray;
95         foreach ( int i; 0..5 )
96         {
97             MockNode node = new MockNode();
98             nodeArray ~= node;
99             mNodes.add( node );
100         }
101        
102         int count;
103         for ( Node node = mNodes.head; node; node = node.next )
104         {
105             nodeArray = nodeArray[1..$];
106             if( ++count == 2 )
107             {
108                 mNodes.remove( node );
109             }
110         }
111         assert( nodeArray.length == 0 );
112     }
113 
114     public void removingNextNodeDuringIterationIsValid()
115     {
116         Node[] nodeArray;
117         foreach ( int i; 0..5 )
118         {
119             MockNode node = new MockNode();
120             nodeArray ~= node;
121             mNodes.add( node );
122         }
123         
124         int count;
125         for ( Node node = mNodes.head; node; node = node.next )
126         {
127             nodeArray = nodeArray[1..$];
128             if( ++count == 2 )
129             {
130                 mNodes.remove( node.next );
131             }
132         }
133         assert( nodeArray.length == 1 );
134     }
135 
136     public void componentAddedSignalContainsCorrectParameters()
137     {
138         Node tempNode = new MockNode();
139         class Watcher { void watch( Node n ) { assert( n is tempNode ); } }
140         Watcher testWatch = new Watcher();
141 
142         mNodes.nodeAdded.connect( &testWatch.watch );
143         mNodes.add( tempNode );
144     }
145 
146     public void componentRemovedSignalContainsCorrectParameters()
147     {
148         Node tempNode = new MockNode();
149         mNodes.add( tempNode );
150 
151         class Watcher { void watch( Node n ) { assert( n is tempNode ); } }
152         Watcher testWatch = new Watcher();
153 
154         mNodes.nodeRemoved.connect( &testWatch.watch );
155         mNodes.remove( tempNode );
156     }
157 
158     public void nodesInitiallySortedInOrderOfAddition()
159     {
160         MockNode node1 = new MockNode();
161         MockNode node2 = new MockNode();
162         MockNode node3 = new MockNode();
163         mNodes.add( node1 );
164         mNodes.add( node2 );
165         mNodes.add( node3 );
166 
167         Node[] nodes = mNodes.allNodes();
168         assert( nodes == [ node1, node2, node3 ] );
169     }
170  
171     public void swappingOnlyTwoNodesChangesTheirOrder()
172     {
173         MockNode node1 = new MockNode();
174         MockNode node2 = new MockNode();
175         mNodes.add( node1 );
176         mNodes.add( node2 );
177         mNodes.swap( node1, node2 );
178         Node[] nodes = mNodes.allNodes();
179         assert( nodes == [ node2, node1 ] );
180     }
181 
182     public void swappingAdjacentNodesChangesTheirPositions()
183     {
184         MockNode node1 = new MockNode();
185         MockNode node2 = new MockNode();
186         MockNode node3 = new MockNode();
187         MockNode node4 = new MockNode();
188         mNodes.add( node1 );
189         mNodes.add( node2 );
190         mNodes.add( node3 );
191         mNodes.add( node4 );
192         mNodes.swap( node2, node3 );
193         Node[] nodes = mNodes.allNodes();
194         assert( nodes == [ node1, node3, node2, node4 ] );
195     }
196 
197     public void swappingNonAdjacentNodesChangesTheirPositions()
198     {
199         MockNode node1 = new MockNode();
200         MockNode node2 = new MockNode();
201         MockNode node3 = new MockNode();
202         MockNode node4 = new MockNode();
203         MockNode node5 = new MockNode();
204         mNodes.add( node1 );
205         mNodes.add( node2 );
206         mNodes.add( node3 );
207         mNodes.add( node4 );
208         mNodes.add( node5 );
209         mNodes.swap( node2, node4 );
210         Node[] nodes = mNodes.allNodes();
211         assert( nodes == [ node1, node4, node3, node2, node5 ] );
212     }
213 
214     public void swappingEndNodesChangesTheirPositions()
215     {
216         MockNode node1 = new MockNode();
217         MockNode node2 = new MockNode();
218         MockNode node3 = new MockNode();
219         mNodes.add( node1 );
220         mNodes.add( node2 );
221         mNodes.add( node3 );
222 
223         mNodes.swap( node1, node3 );
224 
225         Node[] nodes = mNodes.allNodes();
226         assert( nodes == [ node3, node2, node1 ] );
227     }
228 
229     private double sortFunction( MockNode node1_a, MockNode node2_a )
230     {
231         return node1_a.mPos - node2_a.mPos;
232     }
233 
234     public void insertionSortCorrectlySortsSortedNodes()
235     {
236         MockNode node1 = new MockNode(1);
237         MockNode node2 = new MockNode(2);
238         MockNode node3 = new MockNode(3);
239         MockNode node4 = new MockNode(4);
240         mNodes.add( node1 );
241         mNodes.add( node2 );
242         mNodes.add( node3 );
243         mNodes.add( node4 );
244 
245         mNodes.insertionSort( cast(SortFuncType)&sortFunction );
246         Node[] nodes = mNodes.allNodes();
247         assert( nodes == [ node1, node2, node3, node4 ] );
248     }
249 
250     public void insertionSortCorrectlySortsReversedNodes()
251     {
252         MockNode node1 = new MockNode(1);
253         MockNode node2 = new MockNode(2);
254         MockNode node3 = new MockNode(3);
255         MockNode node4 = new MockNode(4);
256         mNodes.add( node4 );
257         mNodes.add( node3 );
258         mNodes.add( node2 );
259         mNodes.add( node1 );
260 
261         mNodes.insertionSort( cast(SortFuncType)&sortFunction );
262         Node[] nodes = mNodes.allNodes();
263         assert( nodes == [ node1, node2, node3, node4 ] );
264     }
265 
266     public void insertionSortCorrectlySortsMixedNodes()
267     {
268         MockNode node1 = new MockNode(1);
269         MockNode node2 = new MockNode(2);
270         MockNode node3 = new MockNode(3);
271         MockNode node4 = new MockNode(4);
272         MockNode node5 = new MockNode(5);
273         mNodes.add( node3 );
274         mNodes.add( node4 );
275         mNodes.add( node1 );
276         mNodes.add( node5 );
277         mNodes.add( node2 );
278 
279         mNodes.insertionSort( cast(SortFuncType)&sortFunction );
280         Node[] nodes = mNodes.allNodes();
281         assert( nodes == [ node1, node2, node3, node4, node5 ] );
282     }
283 
284     public void insertionSortRetainsTheOrderOfEquivalentNodes()
285     {
286         MockNode node1 = new MockNode(1);
287         MockNode node2 = new MockNode(1);
288         MockNode node3 = new MockNode(3);
289         MockNode node4 = new MockNode(4);
290         MockNode node5 = new MockNode(4);
291         mNodes.add( node3 );
292         mNodes.add( node4 );
293         mNodes.add( node1 );
294         mNodes.add( node5 );
295         mNodes.add( node2 );
296 
297         mNodes.insertionSort( cast(SortFuncType)&sortFunction );
298         Node[] nodes = mNodes.allNodes();
299         assert( nodes == [ node1, node2, node3, node4, node5 ] );
300     }
301 
302     public void mergeSortCorrectlySortsSortedNodes()
303     {
304         MockNode node1 = new MockNode(1);
305         MockNode node2 = new MockNode(2);
306         MockNode node3 = new MockNode(3);
307         MockNode node4 = new MockNode(4);
308         mNodes.add( node1 );
309         mNodes.add( node2 );
310         mNodes.add( node3 );
311         mNodes.add( node4 );
312 
313         mNodes.mergeSort( cast(SortFuncType)&sortFunction );
314         Node[] nodes = mNodes.allNodes();
315         assert( nodes == [ node1, node2, node3, node4 ] );
316     }
317  
318     public void mergeSortCorrectlySortsReversedNodes()
319     {
320         MockNode node1 = new MockNode(1);
321         MockNode node2 = new MockNode(2);
322         MockNode node3 = new MockNode(3);
323         MockNode node4 = new MockNode(4);
324         mNodes.add( node4 );
325         mNodes.add( node3 );
326         mNodes.add( node2 );
327         mNodes.add( node1 );
328 
329         mNodes.mergeSort( cast(SortFuncType)&sortFunction );
330         Node[] nodes = mNodes.allNodes();
331         assert( nodes == [ node1, node2, node3, node4 ] );
332 
333     }
334     
335     public void mergeSortCorrectlySortsMixedNodes()
336     {
337         MockNode node1 = new MockNode(1);
338         MockNode node2 = new MockNode(2);
339         MockNode node3 = new MockNode(3);
340         MockNode node4 = new MockNode(4);
341         MockNode node5 = new MockNode(5);
342         mNodes.add( node3 );
343         mNodes.add( node4 );
344         mNodes.add( node1 );
345         mNodes.add( node5 );
346         mNodes.add( node2 );
347 
348         mNodes.mergeSort( cast(SortFuncType)&sortFunction );
349         Node[] nodes = mNodes.allNodes();
350         assert( nodes == [ node1, node2, node3, node4, node5 ] );
351     }
352  
353 } // class NodeListTests
354 
355 
356 class MockNode: Node
357 {
358     public int mPos;
359   
360     this( int value_a = 0 )
361     {
362         mPos = value_a;
363     }
364 }
365 
366 
367 
368