Source code: com/RuntimeCollective/webapps/test/LazyEBListTest.java
1 /* $Header: /home/CVS/rjp/src/com/RuntimeCollective/webapps/test/LazyEBListTest.java,v 1.5 2003/09/30 15:13:19 joe Exp $
2 * $Revision: 1.5 $
3 * $Date: 2003/09/30 15:13:19 $
4 *
5 * ====================================================================
6 *
7 * Josephine : http://www.runtime-collective.com/josephine/index.html
8 *
9 * Copyright (C) 2003 Runtime Collective
10 *
11 * This product includes software developed by the
12 * Apache Software Foundation (http://www.apache.org/).
13 *
14 * This library is free software; you can redistribute it and/or
15 * modify it under the terms of the GNU Lesser General Public
16 * License as published by the Free Software Foundation; either
17 * version 2.1 of the License, or (at your option) any later version.
18 *
19 * This library is distributed in the hope that it will be useful,
20 * but WITHOUT ANY WARRANTY; without even the implied warranty of
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
22 * Lesser General Public License for more details.
23 *
24 * You should have received a copy of the GNU Lesser General Public
25 * License along with this library; if not, write to the Free Software
26 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
27 *
28 */
29
30 package com.RuntimeCollective.webapps.test;
31
32 import com.RuntimeCollective.webapps.bean.Address;
33 import com.RuntimeCollective.webapps.bean.User;
34 import com.RuntimeCollective.webapps.bean.SimpleUser;
35 import com.RuntimeCollective.webapps.bean.TrackedUser;
36 import com.RuntimeCollective.webapps.bean.SimpleTrackedUser;
37 import com.RuntimeCollective.webapps.bean.EntityBean;
38
39 import com.RuntimeCollective.webapps.EntityBeanStore;
40 import com.RuntimeCollective.webapps.Cache;
41 import com.RuntimeCollective.webapps.RuntimeParameters;
42 import com.RuntimeCollective.webapps.RuntimeDataSource;
43 import com.RuntimeCollective.webapps.EntityBeanStoreHandler;
44 import com.RuntimeCollective.webapps.LazyEBList;
45
46 import junit.framework.*;
47 import junit.textui.TestRunner;
48
49 import java.util.*;
50 import java.sql.SQLException;
51 import java.sql.Connection;
52
53 import org.apache.log4j.*;
54 import org.apache.log4j.xml.*;
55 import org.apache.log4j.net.*;
56
57 /**
58 * Tests correct behaviour on all methods of LazyEBList.
59 * <p>
60 * These tests could be extended to check that the LazyEBList
61 * fails correctly when given bad input.
62 */
63 public class LazyEBListTest extends WebappsTestCase {
64
65 public LazyEBListTest(String name) {
66 super(name);
67 }
68
69 protected void setUp() {
70 resetBeanRegister();
71
72 registerBeanClass(Address.class.getName());
73 registerBeanClass(User.class.getName());
74 registerBeanClass(SimpleUser.class.getName());
75 registerBeanClass(TrackedUser.class.getName());
76 registerBeanClass(SimpleTrackedUser.class.getName());
77
78 registerCustomBeans();
79 super.setUp();
80
81 ivSetup();
82 }
83
84 protected void tearDown() {
85 ivTearDown();
86 }
87
88 protected EntityBeanStore ebs;
89 protected Cache cache;
90 protected List ids;
91
92 protected void ivSetup() {
93 try {
94 ebs = RuntimeParameters.getStore();
95 cache = getCacheForEB();
96 ids = getEBList();
97 } catch (SQLException e) {
98 System.out.println("Failed: "+e);
99 }
100 }
101
102 protected void ivTearDown() {
103 ebs = null;
104 cache = null;
105 ids = null;
106 }
107
108
109 protected void registerCustomBeans() {
110 // none
111 }
112
113 /**
114 * Get a List of EntityBean Integer ids to play with (Users, by convention)
115 */
116 protected List getEBList() throws SQLException {
117 return RuntimeParameters.getStore().getAllIdsAsList(User.class.getName());
118 }
119
120 /**
121 * Classname of the EntityBeans returned by getEBList.
122 */
123 protected String ebClassName = User.class.getName();
124
125
126 /**
127 * Get the EBS cache for the EBs we're playing with (Users, by convention)
128 */
129 protected Cache getCacheForEB() throws SQLException {
130 return RuntimeParameters.getStore().getBeanCache(User.class.getName());
131 }
132
133 /**
134 * Returns true iff the cache is empty
135 */
136 public void checkEmptyCache() {
137 assertEquals("Cache contains instantiated EntityBeans!", 0, cache.getNoObjects());
138 }
139
140 /**
141 * Get the LazyList, clearing the cache before
142 */
143 protected List getLazyList() {
144 cache.clear();
145 List lazyList = ebs.getAsLazyList(ebClassName, ids);
146 checkEmptyCache();
147 return lazyList;
148 }
149
150
151
152
153
154
155
156 // ------- The tests -----------------------
157
158
159 public void testEBSize() {
160 assertTrue("We need at least two EntityBeans to work with!", ids.size() >= 2);
161 }
162
163
164 public void testSize() {
165
166 List lazyList = getLazyList();
167
168 // Correct size, without instantiation?
169 assertEquals("Unequal sizes!", ids.size(), lazyList.size());
170 }
171
172
173 public void testIsEmpty() {
174
175 List lazyList = getLazyList();
176
177 // This assumes "clear" works!
178 lazyList.clear();
179 assertEquals("List should be empty after a clear", lazyList.size(), 0);
180 checkEmptyCache();
181
182 }
183
184
185 public void testContains() {
186
187 List lazyList = getLazyList();
188
189 // Contains all the right users, without instantiating more than necessary?
190 for (int i=0; i < ids.size(); i++) {
191 int id = ((Integer)ids.get(i)).intValue();
192 EntityBean eb = ebs.get(EntityBean.class.getName(), id);
193
194 // check that the cache only contains the objects we've had to load
195 int numInCache = cache.getNoObjects();
196
197 assertTrue("The lazy-list must contain every EB selected", lazyList.contains(eb));
198
199 // check that the cache still only contains the objects we've had to load
200 assertEquals("The contains method puts more objects in the cache", numInCache, cache.getNoObjects());
201 }
202
203 }
204
205
206 public void testToArray() {
207
208 List lazyList = getLazyList();
209
210 // Arrays: now this, sadly, does require instantiating everything
211 Object[] objArray = lazyList.toArray();
212 assertEquals("The arrays should be the same size", objArray.length, ids.size());
213 for (int j=0; j < objArray.length; j++) {
214 assertTrue("All objects in the entity bean should be of type EntityBean", objArray[j] instanceof EntityBean);
215 EntityBean eb = (EntityBean)objArray[j];
216 assertEquals("The ids of the returned beans should match up with the ID list", eb.getId(), ((Integer)ids.get(j)).intValue());
217 }
218 cache.clear();
219
220 // An array that's too small
221 EntityBean[] ebArray = new EntityBean[ids.size()-1];
222 assertTrue("too small: The array should be an instance of EntityBean[]", ebArray instanceof EntityBean[]);
223 ebArray = (EntityBean[]) lazyList.toArray(ebArray);
224 assertEquals("too small: The arrays should be the same size", ebArray.length, ids.size());
225 for (int j=0; j < ebArray.length; j++) {
226 assertTrue("too small: All objects in the array should be of type EntityBean", ebArray[j] instanceof EntityBean);
227 EntityBean eb = (EntityBean)ebArray[j];
228 assertEquals("too small: The ids of the returned beans should match up with the ID list", eb.getId(), ((Integer)ids.get(j)).intValue());
229 }
230 cache.clear();
231
232 // An array that's too big
233 int tooBig = 1;
234 ebArray = new EntityBean[ids.size()+tooBig];
235 assertTrue("too big: The array should be an instance of EntityBean[]", ebArray instanceof EntityBean[]);
236 ebArray = (EntityBean[]) lazyList.toArray(ebArray);
237 assertEquals("too big: The last element of the array should be null", ebArray[ebArray.length-1], null);
238 for (int j=0; j < ebArray.length-tooBig; j++) {
239 assertTrue("too big: All objects in the array should be of type EntityBean", ebArray[j] instanceof EntityBean);
240 EntityBean eb = (EntityBean)ebArray[j];
241 assertEquals("too big: The ids of the returned beans should match up with the ID list", eb.getId(), ((Integer)ids.get(j)).intValue());
242 }
243 cache.clear();
244
245 }
246
247 public void testRemoveByObject() {
248
249 List lazyList = getLazyList();
250
251 // Remove each element in the list, checking the cache each time
252 Integer[] idsCopy = (Integer[]) ids.toArray(new Integer[ids.size()]);
253 for (int k=0; k < idsCopy.length; k++) {
254
255 int id = ((Integer)idsCopy[k]).intValue();
256 EntityBean eb = ebs.get(EntityBean.class.getName(), id);
257
258 // check that the cache only contains the objects we've had to load
259 int numInCache = cache.getNoObjects();
260 int size = lazyList.size();
261
262 assertTrue("It should have contained the specified element", lazyList.remove(eb));
263
264 // check that the cache still only contains the objects we've had to load
265 assertEquals("The contains method puts more objects in the cache", numInCache, cache.getNoObjects());
266 assertEquals("The size of the list should have decreased by one", lazyList.size(), size-1 );
267 }
268 assertEquals("The lazyList should now be empty", lazyList.size(), 0);
269 cache.clear();
270
271 }
272
273 public void testRemoveById() {
274
275
276 List lazyList = getLazyList();
277
278 // Remove each element in the list, checking the cache each time
279 Integer[] idsCopy = (Integer[]) ids.toArray(new Integer[ids.size()]);
280 for (int k=0; k < idsCopy.length; k++) {
281
282 // check that the cache only contains the objects we've had to load
283 int numInCache = cache.getNoObjects();
284 int size = lazyList.size();
285
286 EntityBean eb = (EntityBean)lazyList.remove(0);
287 assertTrue("Wrong object returned by remove(int)", eb.getId() == idsCopy[k].intValue());
288
289 // check that the cache hasn't grown by more than one
290 assertTrue("The contains method puts more than one object in the cache", cache.getNoObjects() <= numInCache+1);
291 assertEquals("The size of the list should have decreased by one", lazyList.size(), size-1 );
292 }
293
294 assertEquals("The lazyList should now be empty", lazyList.size(), 0);
295 cache.clear();
296
297 }
298
299
300 public void testRemoveAll() {
301
302 List lazyList = getLazyList();
303
304 Object[] objArray = lazyList.toArray();
305 List allEBs = Arrays.asList(objArray);
306 cache.clear();
307
308 // Remove all test
309 assertTrue("The lazy list should change when removing all the elements", lazyList.removeAll(allEBs));
310 assertEquals("The lazy list should be empty after removing all the elements", lazyList.size(), 0);
311 checkEmptyCache();
312
313 assertTrue("An empty lazy list should not change when removing all the elements", !lazyList.removeAll(allEBs));
314
315 }
316
317
318
319
320 public void testIterator() {
321
322 List lazyList = getLazyList();
323
324 Iterator it = lazyList.iterator();
325 int i=0;
326 while (it.hasNext()) {
327
328 int numInCache = cache.getNoObjects();
329
330 EntityBean eb = (EntityBean)it.next();
331
332 assertEquals("EntityBeans should come out in order", eb.getId(), ((Integer)ids.get(i)).intValue());
333
334 // check that the cache hasn't grown by more than one
335 assertTrue("The iterator puts more than one object in the cache", cache.getNoObjects() <= numInCache+1);
336
337 i++;
338 }
339
340 assertEquals("Iterator should be the same size as the id array", i, ids.size());
341
342 }
343
344
345 public void testContainsAll() {
346
347 List lazyList = getLazyList();
348
349 ArrayList firstTwo = new ArrayList();
350 for (int i=0; i<2; i++) {
351 firstTwo.add(ebs.get(EntityBean.class.getName(), ((Integer)ids.get(i)).intValue()));
352 }
353
354 int numInCache = cache.getNoObjects();
355 assertTrue("The lazy list should include the first two elements.", lazyList.containsAll(firstTwo));
356 assertEquals("The cache should not contain more objects", numInCache, cache.getNoObjects());
357
358 }
359
360
361 public void testAddAll() {
362
363 List lazyList = getLazyList();
364
365 Object[] objArray = lazyList.toArray();
366 List allEBs = Arrays.asList(objArray);
367
368 // wipe the list
369 lazyList.clear();
370
371 assertTrue("Adding all should have changed the list!", lazyList.addAll(allEBs));
372
373 ArrayList blank = new ArrayList();
374 assertTrue("Adding blank list should not have changed the list!", !lazyList.addAll(blank));
375
376 }
377
378
379 public void testRetainAll() {
380
381 List lazyList = getLazyList();
382
383
384 Object[] objArray = lazyList.toArray();
385 List allEBs = Arrays.asList(objArray);
386
387 assertTrue("Retaining all should not have changed the list!", !lazyList.retainAll(allEBs));
388
389 ArrayList blank = new ArrayList();
390 assertTrue("Retaining none should have changed the list!", lazyList.retainAll(blank));
391
392 }
393
394
395 public void testClear() {
396
397 List lazyList = getLazyList();
398
399 int size = lazyList.size();
400 lazyList.clear();
401 assertTrue("List should be empty after being cleared", lazyList.size()==0);
402 assertTrue("List should be register as being empty after being cleared", lazyList.isEmpty());
403 checkEmptyCache();
404
405 try {
406 lazyList.get(0);
407 fail("Getting element 0 of an empty list shouldn't work");
408 } catch (IndexOutOfBoundsException e) {
409 }
410 }
411
412
413 public void testEquals() {
414
415 List lazyList = getLazyList();
416
417 ArrayList allEBs = new ArrayList();
418 for (int i=0; i<ids.size(); i++) {
419 allEBs.add(ebs.get(EntityBean.class.getName(), ((Integer)ids.get(i)).intValue()));
420 }
421
422 assertTrue("Lists should be equal", lazyList.equals(allEBs));
423
424 allEBs.remove(0);
425 assertTrue("Lists are no longer", !lazyList.equals(allEBs));
426 }
427
428 /*
429 * This test will continue to fail, until LazyEBList's hashCode() method
430 * is fixed.<p>
431 *
432 * See LazyEBList.hashCode's javadoc for more information.
433 */
434 public void testHashCode() {
435
436 List lazyList = getLazyList();
437
438 ArrayList allEBs = new ArrayList();
439 for (int i=0; i<ids.size(); i++) {
440 allEBs.add(ebs.get(EntityBean.class.getName(), ((Integer)ids.get(i)).intValue()));
441 }
442
443 // Commenting out until hashCode is fixed.
444 //assertEquals("Hashcodes for equal lists should be equal", lazyList.hashCode(), allEBs.hashCode());
445
446 }
447
448
449 public void testGet() {
450
451 List lazyList = getLazyList();
452
453 // Gets all the right users, without instantiating more than necessary?
454 for (int i=0; i < ids.size(); i++) {
455 int id = ((Integer)ids.get(i)).intValue();
456
457 // check that the cache only contains the objects we've had to load
458 int numInCache = cache.getNoObjects();
459
460 EntityBean eb = (EntityBean)lazyList.get(i);
461
462 assertEquals("EntityBean id does not match", eb.getId(), id);
463
464 // check that the cache hasn't grown by more than one
465 assertTrue("The contains method puts more than one object in the cache", cache.getNoObjects() <= numInCache+1);
466 }
467
468
469
470 }
471
472
473 public void testSet() {
474
475 List lazyList = getLazyList();
476
477 // Objects at 0 and 1
478 EntityBean eb0 = (EntityBean) lazyList.get(0);
479 EntityBean eb1 = (EntityBean) lazyList.get(1);
480
481 // Put 1 into 0
482 int numInCache = cache.getNoObjects();
483 EntityBean returned = (EntityBean)lazyList.set(0, eb1);
484 assertEquals("Should have returned EB0", returned, eb0);
485
486 EntityBean eb0after = (EntityBean) lazyList.get(0);
487 EntityBean eb1after = (EntityBean) lazyList.get(1);
488 assertEquals("Position 0 should be eb1 after set", eb0after, eb1);
489 assertEquals("Position 1 should be eb1 after set", eb0after, eb1);
490
491 // check that the cache hasn't grown by more than one
492 assertTrue("The contains method puts more than one object in the cache", cache.getNoObjects() <= numInCache+1);
493 }
494
495
496 public void testAdd() {
497
498 List lazyList = getLazyList();
499
500 EntityBean eb0 = (EntityBean) lazyList.get(0);
501 int numInCache = cache.getNoObjects();
502 int size = lazyList.size();
503
504 // add the first object again
505 assertTrue("Adding an object should return true by definition", lazyList.add(eb0));
506
507 EntityBean last = (EntityBean)lazyList.get(lazyList.size()-1);
508 assertEquals("The last object in the list should be the one we've just added", last, eb0);
509
510 assertEquals("The list should have grown in size by 1", size+1, lazyList.size());
511
512 // check that the cache still only contains the objects we've had to load
513 assertEquals("The contains method puts more objects in the cache", numInCache, cache.getNoObjects());
514
515 }
516
517
518
519 public void testAddWithPosition() {
520
521 List lazyList = getLazyList();
522
523 EntityBean eb0 = (EntityBean) lazyList.get(0);
524 EntityBean eb1 = (EntityBean) lazyList.get(1);
525 int numInCache = cache.getNoObjects();
526 int size = lazyList.size();
527
528 // add the first object again, at position 1
529 lazyList.add(1, eb0);
530
531 EntityBean eb1after = (EntityBean)lazyList.get(1);
532 EntityBean eb2after = (EntityBean)lazyList.get(2);
533
534 assertEquals("The second object in the list should be the one we've just added", eb1after, eb0);
535 assertEquals("The third object in the list should be the one that WAS at the position we just added at", eb2after, eb1);
536
537 assertEquals("The list should have grown in size by 1", size+1, lazyList.size());
538
539 // check that the cache still only contains the objects we've had to load
540 assertEquals("The contains method puts more objects in the cache", numInCache, cache.getNoObjects());
541
542
543 }
544
545
546 public void testIndexOf() {
547
548 List lazyList = getLazyList();
549
550 for (int i=0; i < ids.size(); i++) {
551 Integer id = (Integer)ids.get(i);
552
553 EntityBean eb = (EntityBean)ebs.get(EntityBean.class.getName(), id.intValue());
554
555 int numInCache = cache.getNoObjects();
556
557 int idIndexOf = ids.indexOf(id);
558 int llIdIndexOf = lazyList.indexOf(eb);
559
560 assertEquals("Different indexes", idIndexOf, llIdIndexOf);
561
562 // check that the cache hasn't grown by more than one
563 assertTrue("The contains method puts more than one object in the cache", cache.getNoObjects() <= numInCache+1);
564 }
565 }
566
567
568 public void testLastIndexOf() {
569
570 List lazyList = getLazyList();
571
572 for (int i=0; i < ids.size(); i++) {
573 Integer id = (Integer)ids.get(i);
574
575 EntityBean eb = (EntityBean)ebs.get(EntityBean.class.getName(), id.intValue());
576
577 int numInCache = cache.getNoObjects();
578
579 int idIndexOf = ids.lastIndexOf(id);
580 int llIdIndexOf = lazyList.lastIndexOf(eb);
581
582 System.out.println("LASTINDEX: id="+id+", idIndexOf="+idIndexOf+", llIdIndexOf="+llIdIndexOf);
583
584 assertEquals("Different indexes: "+id, idIndexOf, llIdIndexOf);
585
586 // check that the cache hasn't grown by more than one
587 assertTrue("The contains method puts more than one object in the cache", cache.getNoObjects() <= numInCache+1);
588 }
589 }
590
591
592
593 public void testListIterator() {
594
595 List lazyList = getLazyList();
596
597 ListIterator it = lazyList.listIterator();
598 int i=0;
599 while (it.hasNext()) {
600
601 int numInCache = cache.getNoObjects();
602
603 EntityBean eb = (EntityBean)it.next();
604
605 assertEquals("EntityBeans should come out in order", eb.getId(), ((Integer)ids.get(i)).intValue());
606
607 // check that the cache hasn't grown by more than one
608 assertTrue("The iterator puts more than one object in the cache", cache.getNoObjects() <= numInCache+1);
609
610 i++;
611 }
612
613 assertEquals("ListIterator should be the same size as the id array", i, ids.size());
614
615 }
616
617
618
619
620 public void testSubList() {
621
622 List lazyList = getLazyList();
623
624 int idOriginalSize = ids.size();
625
626 // We will clear a range from the second element of the list to the second-to-last
627 // i.e. from 1 to size()-1
628 List subList = lazyList.subList(1, lazyList.size()-1);
629
630 assertEquals("Should be the size of the id list minus the first and last elements", subList.size(), idOriginalSize-2);
631 for (int i=0; i < subList.size(); i++) {
632 EntityBean eb = (EntityBean)subList.get(i);
633 assertEquals("IDs of the EBs should match up with the id list", eb.getId(), ((Integer)ids.get(i+1)).intValue());
634 }
635 }
636
637
638
639
640 public void testSubListClear() {
641
642 List lazyList = getLazyList();
643
644 int idOriginalSize = ids.size();
645
646 int firstElementId = ((Integer)ids.get(0)).intValue();
647 int lastElementId = ((Integer)ids.get(idOriginalSize-1)).intValue();
648
649 // We will clear a range from the second element of the list to the second-to-last
650 // i.e. from 1 to size()-1
651 System.out.println("Cache size before sublist: "+cache.getNoObjects());
652 List subList = lazyList.subList(1, lazyList.size()-1);
653 System.out.println("Cache size after sublist: "+cache.getNoObjects());
654
655 assertEquals("Should be the size of the id list minus the first and last elements", subList.size(), idOriginalSize-2);
656
657 // clear the range
658 System.out.println("Cache size before clear: "+cache.getNoObjects());
659 subList.clear();
660 System.out.println("Cache size after clear: "+cache.getNoObjects());
661
662 assertEquals("The size of the cleared list should be just 2", lazyList.size(), 2);
663
664 // No beans should have got instantiated yet
665 checkEmptyCache();
666
667 assertEquals("First element should be first element from ids", ((EntityBean)lazyList.get(0)).getId(), firstElementId);
668 assertEquals("Second (last) element should be last element from ids", ((EntityBean)lazyList.get(1)).getId(), lastElementId);
669 }
670
671
672
673
674
675 public static void main(String args[]) {
676 junit.textui.TestRunner.run(LazyEBListTest.class);
677 }
678
679 }
680