CWIS Developer Documentation
PersistentDoublyLinkedList--Test.php
Go to the documentation of this file.
1 <?PHP
8 class PersistentDoublyLinkedList_Test extends PHPUnit\Framework\TestCase
9 {
13  static function setUpBeforeClass()
14  {
15  $DB = new Database();
16  $DB->Query("CREATE TABLE ListTestNoTypes ("
17  ."ItemId INT NOT NULL, "
18  ."PreviousItemId INT DEFAULT -1, "
19  ."NextItemId INT DEFAULT -1)");
20  $DB->Query("CREATE TABLE ListTest ("
21  ."ItemId INT NOT NULL, "
22  ."PreviousItemId INT DEFAULT -1, "
23  ."NextItemId INT DEFAULT -1, "
24  ."ItemType INT DEFAULT NULL, "
25  ."NextItemType INT DEFAULT NULL, "
26  ."PreviousItemType INT DEFAULT NULL)");
27  }
28 
32  static function tearDownAfterClass()
33  {
34  $DB = new Database();
35  $DB->Query("DROP TABLE ListTest");
36  $DB->Query("DROP TABLE ListTestNoTypes");
37  }
38 
42  function setUp()
43  {
44  static $DB;
45  if (!isset($DB))
46  {
47  $DB = new Database();
48  }
49 
50  $DB->Query("DELETE FROM ListTest");
51  $DB->Query("DELETE FROM ListTestNoTypes");
52 
53  $DB->Query(
54  "INSERT INTO ListTestNoTypes (ItemId) VALUES ".
55  implode(",", array_map(
56  function($x){ return "(".$x.")"; },
57  array(1,2,3,4,5))) );
58  $DB->Query(
59  "INSERT INTO ListTest (ItemId, ItemType) VALUES ".
60  implode(",", array_map(
61  function($x){ return "(".$x.",1)"; },
62  array(1,2,3,4,5))) );
63  }
64 
69  function testAppendNoTypes()
70  {
71  $MyList = new PersistentDoublyLinkedList(
72  "ListTestNoTypes", "ItemId");
73 
74  # list is initially empty
75  $this->CheckUntyped($MyList, array());
76 
77  try
78  {
79  $MyList->Append( 1, 1 );
80  # this should not succeed
81  $this->assertTrue(FALSE);
82  }
83  catch (Exception $e)
84  {
85  ; // empty on purpose
86  }
87 
88  # add a single element to it, we see that element
89  $MyList->Append( 1 );
90  $this->CheckUntyped( $MyList, array(1) );
91 
92  # attempt to add that element again, no change
93  $MyList->Append( 1 );
94  $this->CheckUntyped( $MyList, array(1) );
95 
96  # add a different element, it appears at the end
97  $MyList->Append( 2 );
98  $this->CheckUntyped( $MyList, array(1,2) );
99 
100  # attempt to repeat the addition, no change
101  $MyList->Append( 2 );
102  $this->CheckUntyped( $MyList, array(1,2) );
103 
104  # add the first element again, it should be moved to the end
105  $MyList->Append( 1 );
106  $this->CheckUntyped( $MyList, array(2,1) );
107 
108  # move the second element to the end
109  $MyList->Append( 2 );
110  $this->checkUntyped( $MyList, array(1,2) );
111 
112  # add a third element
113  $MyList->Append( 3 );
114  $this->CheckUntyped( $MyList, array(1,2,3) );
115 
116  # shuffle the first element to the end
117  $MyList->Append( 1 );
118  $this->CheckUntyped( $MyList, array(2,3,1) );
119 
120  # shuffle the middle element to the end
121  $MyList->Append( 3 );
122  $this->CheckUntyped( $MyList, array(2,1,3) );
123  }
124 
130  {
131  $MyList = new PersistentDoublyLinkedList(
132  "ListTestNoTypes", "ItemId");
133 
134  # list is initially empty
135  $this->CheckUntyped( $MyList, array() );
136 
137  # add a single element to it, we see that element
138  $MyList->Prepend( 1 );
139  $this->CheckUntyped( $MyList, array(1) );
140 
141  # attempt to add that element again, no change
142  $MyList->Prepend( 1 );
143  $this->CheckUntyped( $MyList, array(1) );
144 
145  # add a different element, it appears at the beginning
146  $MyList->Prepend( 2 );
147  $this->CheckUntyped( $MyList, array(2,1) );
148 
149  # attempt to repeat the addition, no change
150  $MyList->Prepend( 2 );
151  $this->CheckUntyped( $MyList, array(2,1) );
152 
153  # add the first element again, it should be moved to the beginning
154  $MyList->Prepend( 1 );
155  $this->CheckUntyped( $MyList, array(1,2) );
156 
157  # move the second element to the beginning
158  $MyList->Prepend( 2 );
159  $this->CheckUntyped( $MyList, array(2,1) );
160 
161  # add a third element
162  $MyList->Prepend( 3 );
163  $this->CheckUntyped( $MyList, array(3,2,1) );
164 
165  # shuffle the first element to the beginning
166  $MyList->Prepend( 1 );
167  $this->CheckUntyped( $MyList, array(1,3,2) );
168 
169  # shuffle the middle element to the beginning
170  $MyList->Prepend( 3 );
171  $this->CheckUntyped( $MyList, array(3,1,2) );
172  }
173 
179  {
180  $MyList = new PersistentDoublyLinkedList(
181  "ListTestNoTypes", "ItemId");
182 
183  # InsertBefore onto an emtpy list
184  $MyList->InsertBefore( 100, 2 );
185  $this->CheckUntyped( $MyList, array(2) );
186 
187  # InsertBefore w/ a nonexistent item
188  $MyList->InsertBefore( 100, 1 );
189  $this->CheckUntyped( $MyList, array(1,2) );
190 
191  # InsertBefore at the beginning
192  $MyList->InsertBefore(1, 3);
193  $this->CheckUntyped( $MyList, array(3,1,2) );
194 
195  # InsertBefore at the end
196  $MyList->InsertBefore(2, 4);
197  $this->CheckUntyped( $MyList, array(3,1,4,2) );
198 
199  # InsertBefore in the middle
200  $MyList->InsertBefore(4, 5);
201  $this->CheckUntyped( $MyList, array(3,1,5,4,2) );
202  }
203 
209  {
210  $MyList = new PersistentDoublyLinkedList(
211  "ListTestNoTypes", "ItemId");
212 
213  # InsertAfter onto an emtpy list
214  $MyList->InsertAfter( 100, 2 );
215  $this->CheckUntyped( $MyList, array(2) );
216 
217  # InsertAfter w/ a nonexistent item
218  $MyList->InsertAfter( 100, 1 );
219  $this->CheckUntyped( $MyList, array(2,1) );
220 
221  # InsertAfter at the beginning
222  $MyList->InsertAfter(2, 3);
223  $this->CheckUntyped($MyList, array(2,3,1) );
224 
225  # InsertAfter at the end
226  $MyList->InsertAfter(1, 4);
227  $this->CheckUntyped($MyList, array(2,3,1,4) );
228 
229  # InsertAfter in the middle
230  $MyList->InsertAfter(3, 5);
231  $this->CheckUntyped($MyList, array(2,3,5,1,4) );
232  }
233 
238  function testAppendTypes()
239  {
240  $MyList = new PersistentDoublyLinkedList(
241  "ListTest", "ItemId", NULL, "ItemType");
242 
243  # list is initially empty
244  $this->assertSame(
245  array(), $MyList->GetIds() );
246 
247  try
248  {
249  $MyList->Append( 1 );
250  # this should not succeed
251  $this->assertTrue(FALSE);
252  }
253  catch (Exception $e)
254  {
255  ; // empty on purpose
256  }
257 
258  # add a single element to it, we see that element
259  $MyList->Append( 1, 1 );
260  $this->CheckTypedList($MyList, array(1));
261 
262  # attempt to add that element again, no change
263  $MyList->Append( 1, 1 );
264  $this->CheckTypedList($MyList, array(1));
265 
266  # add a different element, it appears at the end
267  $MyList->Append( 2, 1 );
268  $this->CheckTypedList($MyList, array(1,2) );
269 
270  # attempt to repeat the addition, no change
271  $MyList->Append( 2, 1 );
272  $this->CheckTypedList($MyList, array(1,2) );
273 
274  # add the first element again, it should be moved to the end
275  $MyList->Append( 1, 1 );
276  $this->CheckTypedList($MyList, array(2,1) );
277 
278  # move the second element to the end
279  $MyList->Append( 2, 1 );
280  $this->CheckTypedList($MyList, array(1,2) );
281 
282  # add a third element
283  $MyList->Append( 3, 1 );
284  $this->CheckTypedList($MyList, array(1,2,3) );
285 
286  # shuffle the first element to the end
287  $MyList->Append( 1, 1 );
288  $this->CheckTypedList($MyList, array(2,3,1) );
289 
290  # shuffle the middle element to the end
291  $MyList->Append( 3, 1 );
292  $this->CheckTypedList($MyList, array(2,1,3) );
293  }
294 
299  function testPrependTypes()
300  {
301  $MyList = new PersistentDoublyLinkedList(
302  "ListTest", "ItemId", NULL, "ItemType");
303 
304  # list is initially empty
305  $this->assertSame(
306  array(), $MyList->GetIds() );
307 
308  # add a single element to it, we see that element
309  $MyList->Prepend( 1, 1 );
310  $this->CheckTypedList( $MyList, array(1) );
311 
312  # attempt to add that element again, no change
313  $MyList->Prepend( 1, 1 );
314  $this->CheckTypedList( $MyList, array(1) );
315 
316  # add a different element, it appears at the beginning
317  $MyList->Prepend( 2, 1 );
318  $this->CheckTypedList($MyList, array(2,1) );
319 
320  # attempt to repeat the addition, no change
321  $MyList->Prepend( 2, 1 );
322  $this->CheckTypedList($MyList, array(2,1) );
323 
324  # add the first element again, it should be moved to the beginning
325  $MyList->Prepend( 1, 1 );
326  $this->CheckTypedList($MyList, array(1,2) );
327 
328  # move the second element to the beginning
329  $MyList->Prepend( 2, 1 );
330  $this->CheckTypedList($MyList, array(2,1) );
331 
332  # add a third element
333  $MyList->Prepend( 3, 1 );
334  $this->CheckTypedList($MyList, array(3,2,1) );
335 
336  # shuffle the first element to the end
337  $MyList->Prepend( 1, 1 );
338  $this->CheckTypedList($MyList, array(1,3,2) );
339 
340  # shuffle the middle element to the end
341  $MyList->Prepend( 3, 1 );
342  $this->CheckTypedList($MyList, array(3,1,2) );
343  }
344 
350  {
351  $MyList = new PersistentDoublyLinkedList(
352  "ListTest", "ItemId", NULL, "ItemType");
353 
354  # InsertBefore onto an emtpy list
355  $MyList->InsertBefore( 100, 2, 1, 1 );
356  $this->CheckTypedList($MyList, array(2) );
357 
358  # InsertBefore w/ a nonexistent item
359  $MyList->InsertBefore( 100, 1, 1, 1);
360  $this->CheckTypedList($MyList, array(1,2) );
361 
362  # InsertBefore at the beginning
363  $MyList->InsertBefore(1, 3, 1, 1);
364  $this->CheckTypedList($MyList, array(3,1,2) );
365 
366  # InsertBefore at the end
367  $MyList->InsertBefore(2, 4, 1, 1);
368  $this->CheckTypedList($MyList, array(3,1,4,2) );
369 
370  # InsertBefore in the middle
371  $MyList->InsertBefore(4, 5, 1,1);
372  $this->CheckTypedList($MyList, array(3,1,5,4,2));
373  }
374 
380  {
381  $MyList = new PersistentDoublyLinkedList(
382  "ListTest", "ItemId", NULL, "ItemType");
383 
384  # InsertAfter onto an emtpy list
385  $MyList->InsertAfter( 100, 2, 1, 1);
386  $this->CheckTypedList($MyList, array(2) );
387 
388  # InsertAfter w/ a nonexistent item
389  $MyList->InsertAfter( 100, 1, 1, 1);
390  $this->CheckTypedList($MyList, array(2,1) );
391 
392  # InsertAfter at the beginning
393  $MyList->InsertAfter(2, 3, 1, 1);
394  $this->CheckTypedList($MyList, array(2,3,1) );
395 
396  # InsertAfter at the end
397  $MyList->InsertAfter(1, 4, 1, 1);
398  $this->CheckTypedList($MyList, array(2,3,1,4) );
399 
400  # InsertAfter in the middle
401  $MyList->InsertAfter(3, 5, 1, 1);
402  $this->CheckTypedList($MyList, array(2,3,5,1,4) );
403  }
404 
409  function testSqlCondition()
410  {
411  $MyList = new PersistentDoublyLinkedList(
412  "ListTestNoTypes", "ItemId");
413 
414  $this->assertSame(
415  $MyList->SqlCondition(), NULL);
416 
417  $MyList->SqlCondition("ItemId=1");
418  $this->assertSame(
419  $MyList->SqlCondition(), "ItemId=1");
420  }
421 
428  private function CheckUntyped($List, $Values)
429  {
430  $this->assertSame(
431  count($Values), $List->GetCount() );
432  $this->assertSame(
433  $Values, $List->GetIds() );
434  }
435 
442  private function CheckTypedList($List, $Values)
443  {
444  $Expected = array();
445  foreach ($Values as $Value)
446  {
447  $Expected["1:".$Value] = array("Type"=>1, "ID"=> $Value);
448  }
449 
450  $this->assertSame(
451  count($Values), $List->GetCount() );
452  $this->assertSame(
453  $Expected, $List->GetIds() );
454  }
455 }
testPrependTypes()
Create a typed list, test Prepend()ing to it.
Tests for the PersistentlyDoublyLinkedList.
SQL database abstraction object with smart query caching.
Definition: Database.php:22
testAppendTypes()
Create a typed list, test Append()ing to it.
testInsertAfterTypes()
Create a typed list, test InsertAfter() on it.
testSqlCondition()
Create an untyped list, verify that we can add an SqlCondition to it.
static setUpBeforeClass()
Create necessary database tables for testing the PDLL class.
testInsertBeforeTypes()
Create a typed list, test InsertBefore() on it.
testPrependNoTypes()
Create an untyped list, prepend elements to it.
setUp()
Prior to each test, ensure that tables are empty.
testInsertAfterNoTypes()
Create an untyped list, test InsertAfter on it.
testAppendNoTypes()
Create an untyped list, append elements to it.
Persistent doubly-linked-list data structure, with its data stored in a specified database table...
testInsertBeforeNoTypes()
Create an untyped list, test InsertBefore on it.
static tearDownAfterClass()
Destroy tables created for testing.