1   /**
2    * 
3    */
4   package org.melati.poem.test;
5   
6   import java.io.ByteArrayOutputStream;
7   import java.io.PrintStream;
8   import java.text.DateFormat;
9   import java.util.Enumeration;
10  
11  import org.melati.poem.AccessToken;
12  import org.melati.poem.CreationAccessPoemException;
13  import org.melati.poem.DeletePersistentAccessPoemException;
14  import org.melati.poem.DeletionIntegrityPoemException;
15  import org.melati.poem.DoubleCreatePoemException;
16  import org.melati.poem.Field;
17  import org.melati.poem.InvalidOperationOnFloatingPersistentPoemException;
18  import org.melati.poem.JdbcPersistent;
19  import org.melati.poem.NoSuchRowPoemException;
20  import org.melati.poem.Persistent;
21  import org.melati.poem.PoemThread;
22  import org.melati.poem.RowDisappearedPoemException;
23  import org.melati.poem.Setting;
24  import org.melati.poem.Table;
25  import org.melati.poem.TableCategory;
26  import org.melati.poem.TableInfo;
27  import org.melati.poem.User;
28  import org.melati.poem.WritePersistentAccessPoemException;
29  import org.melati.poem.PoemLocale;
30  
31  /**
32   * @author timp
33   * @since 27/11/2006
34   */
35  public class PersistentTest extends EverythingTestCase {
36  
37    /**
38     * Constructor for PersistentTest.
39     * @param name
40     */
41    public PersistentTest(String name) {
42      super(name);
43    }
44  
45    /**
46     * @see PoemTestCase#setUp()
47     */
48    protected void setUp()
49        throws Exception {
50      super.setUp();
51    }
52  
53    /**
54     * @see PoemTestCase#tearDown()
55     */
56    protected void tearDown()
57        throws Exception {
58      super.tearDown();
59    }
60  
61    /**
62     * 
63     * @see org.melati.poem.JdbcPersistent#invalidate()
64     */
65    public void testInvalidate() {
66      getDb().uncache();
67      JdbcPersistent p = (JdbcPersistent)getDb().getUserTable().newPersistent();
68      try {
69        p.invalidate();
70        fail("Should have blown up");
71      } catch (InvalidOperationOnFloatingPersistentPoemException e) {
72        e = null;
73      }
74      
75      // guestUser does not hit the database
76      int hits = getDb().getQueryCount();
77      int hits2 = getDb().getQueryCount();
78      getDb().getUserTable().guestUser();
79      getDb().getUserTable().guestUser();
80      int hits3 = getDb().getQueryCount();
81      getDb().uncache();
82      int hits4 = getDb().getQueryCount();
83      getDb().getUserTable().guestUser();
84      int hits5 = getDb().getQueryCount();
85      assertTrue(hits == hits2);
86      assertTrue(hits == hits3);
87      assertTrue(hits == hits4);
88      assertTrue(hits == hits5);
89      
90      // Count always increments queryCount
91      getDb().getUserTable().count();
92      int countHits1 = getDb().getQueryCount();
93      assertEquals(hits5 + 1, countHits1 );
94      getDb().getUserTable().count();
95      int countHits2 = getDb().getQueryCount();
96      //System.err.println(countHits2);
97      assertEquals(countHits1 + 1, countHits2);
98      
99      // FIXME Selection is cached but not invalidated 
100     // when table cache is invalidated
101     getDb().getUserTable().selection();
102     int selectionHits1 = getDb().getQueryCount();
103     getDb().getUserTable().selection();
104     int selectionHits2 = getDb().getQueryCount();
105     assertEquals(selectionHits1, selectionHits2);
106     getDb().uncache();
107     getDb().getUserTable().selection();
108     int selectionHits3 = getDb().getQueryCount();
109     assertEquals(selectionHits2 + 1, selectionHits3);
110     
111     getDb().getUserTable().getUserObject(0);
112     int getHits1 = getDb().getQueryCount();
113     //System.err.println(getHits1);
114     assertEquals(selectionHits3 + 1, getHits1);
115     getDb().uncache();
116     getDb().getUserTable().getUserObject(0);
117     int getHits2 = getDb().getQueryCount();
118     assertEquals(getHits1 + 1, getHits2);
119     
120     Persistent p2 = getDb().getUserTable().newPersistent();
121     p2.setCooked("name", "testuser");
122     p2.setCooked("login", "testuser");
123     p2.setCooked("password", "testuser");
124     p2.makePersistent();
125     int getHits3 = getDb().getQueryCount();
126     //System.err.println(getHits3);
127     assertEquals(getHits2 + 3, getHits3);
128     p2.delete();
129     PoemThread.commit();
130   }
131 
132 
133   /**
134    * @see org.melati.poem.Persistent#Persistent()
135    */
136   public void testPersistent() {
137 
138   }
139 
140   /**
141    * @see org.melati.poem.Persistent#Persistent(String, String)
142    */
143   public void testPersistentStringString() {
144     Persistent p = new JdbcPersistent("user", "0");
145     try {
146       p.makePersistent();
147       fail("Should have blown up");
148     } catch (DoubleCreatePoemException e) {
149       e = null;      
150     }
151     p = new JdbcPersistent(getDb().getUserTable(), new Integer(2));
152     try {
153       p.makePersistent();
154       fail("Should have blown up");
155     } catch (DoubleCreatePoemException e) {
156       e = null;      
157     }
158   }
159 
160   /**
161    * @see org.melati.poem.Persistent#Persistent(Table, Integer)
162    */
163   public void testPersistentTableInteger() {
164     Persistent p = new JdbcPersistent(getDb().getUserTable(), new Integer(0));
165     try {
166       p.makePersistent();
167       fail("Should have blown up");
168     } catch (DoubleCreatePoemException e) {
169       e = null;      
170     }
171     p = new JdbcPersistent(getDb().getUserTable(), new Integer(2));
172     try {
173       p.makePersistent();
174       fail("Should have blown up");
175     } catch (DoubleCreatePoemException e) {
176       e = null;      
177     }
178   }
179 
180   /**
181    * @see org.melati.poem.Persistent#setStatusNonexistent()
182    */
183   public void testSetStatusNonexistent() {
184 
185   }
186 
187   /**
188    * @see org.melati.poem.Persistent#setStatusExistent()
189    */
190   public void testSetStatusExistent() {
191 
192   }
193 
194   /**
195    * @see org.melati.poem.Persistent#statusNonexistent()
196    */
197   public void testStatusNonexistent() {
198 
199   }
200 
201   /**
202    * @see org.melati.poem.Persistent#statusExistent()
203    */
204   public void testStatusExistent() {
205 
206   }
207 
208   /**
209    * @see org.melati.poem.Persistent#makePersistent()
210    */
211   public void testMakePersistent() {
212 
213   }
214 
215 
216   /**
217    * @see org.melati.poem.Persistent#getTable()
218    */
219   public void testGetTable() {
220 
221   }
222 
223   /**
224    * @see org.melati.poem.Persistent#setTable(Table, Integer)
225    */
226   public void testSetTable() {
227 
228   }
229 
230   /**
231    * @see org.melati.poem.Persistent#getDatabase()
232    */
233   public void testGetDatabase() {
234     Persistent p = new JdbcPersistent(getDb().getUserTable(), new Integer(0));
235     assertEquals(p.getDatabase(), getDb());
236   }
237 
238   /**
239    * @see org.melati.poem.Persistent#troid()
240    */
241   public void testTroid() {
242     Persistent p = new JdbcPersistent();
243     assertNull(p.troid());
244     p = new JdbcPersistent(getDb().getUserTable(), new Integer(0));
245     assertEquals(p.troid(), new Integer(0));
246   }
247 
248   /**
249    * @see org.melati.poem.Persistent#getTroid()
250    */
251   public void testGetTroid() {
252     Persistent p = new JdbcPersistent();
253     assertNull(p.getTroid());
254     p = new JdbcPersistent(getDb().getUserTable(), new Integer(0));
255     assertEquals(p.getTroid(), new Integer(0));
256   }
257 
258   /**
259    * @see org.melati.poem.Persistent#existenceLock()
260    */
261   public void testExistenceLock() {
262     Persistent p = new JdbcPersistent();
263     p.existenceLock();
264     try {
265       p.delete();
266       fail("Should have blown up");
267     } catch (InvalidOperationOnFloatingPersistentPoemException e) {
268       e = null;
269     }
270        
271   }
272 
273 
274   /**
275    * @see org.melati.poem.Persistent#assertCanWrite(AccessToken)
276    */
277   public void testAssertCanWriteAccessToken() {
278     Persistent p = getDb().getUserTable().guestUser();
279     AccessToken g  = getDb().getUserTable().guestUser();
280     try {
281       p.assertCanWrite(g);
282       fail("Should have bombed");
283     } catch (WritePersistentAccessPoemException e) {
284       e = null;
285     }
286     AccessToken a  = getDb().getUserTable().administratorUser();
287     p.assertCanWrite(a);
288   }
289 
290   /**
291    * @see org.melati.poem.Persistent#assertCanWrite()
292    */
293   public void testAssertCanWrite() {
294     Persistent p = getDb().getUserTable().administratorUser();
295     AccessToken g  = getDb().getUserTable().guestUser();
296     p.assertCanWrite();
297     try {
298       PoemThread.setAccessToken(g);
299       p.assertCanWrite();
300       fail("Should have bombed");
301     } catch (WritePersistentAccessPoemException e) {
302       e = null;
303     }
304   }
305 
306   /**
307    * @see org.melati.poem.Persistent#assertCanDelete(AccessToken)
308    */
309   public void testAssertCanDeleteAccessToken() {
310     Persistent p = getDb().getUserTable().guestUser();
311     AccessToken g  = getDb().getUserTable().guestUser();
312     try {
313       p.assertCanDelete(g);
314       fail("Should have bombed");
315     } catch (DeletePersistentAccessPoemException e) {
316       e = null;
317     }
318     AccessToken a  = getDb().getUserTable().administratorUser();
319     p.assertCanDelete(a);
320   }
321 
322   /**
323    * @see org.melati.poem.Persistent#assertCanDelete()
324    */
325   public void testAssertCanDelete() {
326     Persistent p = getDb().getUserTable().administratorUser();
327     AccessToken g  = getDb().getUserTable().guestUser();
328     p.assertCanDelete();
329     try {
330       PoemThread.setAccessToken(g);
331       p.assertCanDelete();
332       fail("Should have bombed");
333     } catch (DeletePersistentAccessPoemException e) {
334       e = null;
335     }
336   }
337 
338   /**
339    * @see org.melati.poem.Persistent#assertCanCreate(AccessToken)
340    */
341   public void testAssertCanCreateAccessToken() {
342     Persistent p = getDb().getUserTable().guestUser();
343     AccessToken g  = getDb().getUserTable().guestUser();
344     try {
345       p.assertCanCreate(g);
346       fail("Should have bombed");
347     } catch (CreationAccessPoemException e) {
348       e = null;
349     }
350     AccessToken a  = getDb().getUserTable().administratorUser();
351     p.assertCanWrite(a);
352   }
353 
354   /**
355    * @see org.melati.poem.Persistent#assertCanCreate()
356    */
357   public void testAssertCanCreate() {
358     Persistent p = getDb().getUserTable().administratorUser();
359     AccessToken g  = getDb().getUserTable().guestUser();
360     p.assertCanCreate();
361     try {
362       PoemThread.setAccessToken(g);
363       p.assertCanCreate();
364       fail("Should have bombed");
365     } catch (CreationAccessPoemException e) {
366       e = null;
367     }
368   }
369 
370   /**
371    * @see org.melati.poem.Persistent#getRaw(String)
372    */
373   public void testGetRaw() {
374     Persistent p = getDb().getUserTable().administratorUser();
375     String name = (String)p.getRaw("name");
376     assertEquals("Melati database administrator", name);
377     Integer id = (Integer)p.getRaw("id");
378     assertEquals(new Integer(1), id);
379   }
380 
381   /**
382    * @see org.melati.poem.Persistent#getRawString(String)
383    */
384   public void testGetRawString() {
385     Persistent p = getDb().getUserTable().administratorUser();
386     String name = p.getRawString("name");
387     assertEquals("Melati database administrator", name);
388     String id = p.getRawString("id");
389     assertEquals("1", id);
390   }
391 
392   /**
393    * @see org.melati.poem.Persistent#setRaw(String, Object)
394    */
395   public void testSetRaw() {
396     Persistent p = getDb().getUserTable().administratorUser();
397     String name = p.getRawString("name");
398     assertEquals("Melati database administrator", name);
399     p.setRaw("name", "test");
400     String name2 = p.getRawString("name");
401     assertEquals("test", name2);
402     p.setRaw("name", name);
403     String name3 = p.getRawString("name");
404     assertEquals("Melati database administrator", name3);
405   }
406 
407   /**
408    * @see org.melati.poem.Persistent#setRawString(String, String)
409    */
410   public void testSetRawString() {
411     Persistent p = getDb().getUserTable().administratorUser();
412     String name = p.getRawString("name");
413     assertEquals("Melati database administrator", name);
414     p.setRawString("name", "test");
415     String name2 = p.getRawString("name");
416     assertEquals("test", name2);
417     p.setRawString("name", name);
418     String name3 = p.getRawString("name");
419     assertEquals("Melati database administrator", name3);
420   }
421 
422   /**
423    * @see org.melati.poem.Persistent#getCooked(String)
424    */
425   public void testGetCooked() {
426     Persistent p = getDb().getUserTable().administratorUser();
427     String name = (String)p.getCooked("name");
428     assertEquals("Melati database administrator", name);
429     p = getDb().getUserTable().getTableInfo();
430     TableCategory c = (TableCategory)p.getCooked("category");
431     assertEquals("tablecategory/0", c.toString());
432   }
433 
434   /**
435    * @see org.melati.poem.Persistent#getCookedString(String, PoemLocale, int)
436    */
437   public void testGetCookedString() {
438     Persistent p = getDb().getUserTable().administratorUser();
439     String name = p.getCookedString("name", PoemLocale.HERE, DateFormat.MEDIUM);
440     assertEquals("Melati database administrator", name);
441     Persistent p2 = getDb().getUserTable().getTableInfo();
442     String c = p2.getCookedString("category", PoemLocale.HERE, DateFormat.MEDIUM);
443     assertEquals("User", c);
444   }
445 
446   /**
447    * @see org.melati.poem.Persistent#setCooked(String, Object)
448    */
449   public void testSetCooked() {
450     Persistent p = getDb().getUserTable().administratorUser();
451     String name = p.getRawString("name");
452     assertEquals("Melati database administrator", name);
453     p.setCooked("name", "test");
454     String name2 = p.getRawString("name");
455     assertEquals("test", name2);
456     p.setCooked("name", name);
457     String name3 = p.getRawString("name");
458     assertEquals("Melati database administrator", name3);
459 
460     Persistent p2 = getDb().getUserTable().getTableInfo();
461     TableCategory c = (TableCategory)p2.getCooked("category");
462     TableCategory c2 = (TableCategory)getDb().getTableCategoryTable().newPersistent();
463     c2.setName("Test");
464     c2.makePersistent();
465     p2.setCooked("category",c2);
466     String cString = p2.getCookedString("category",PoemLocale.HERE, DateFormat.MEDIUM);
467     assertEquals("Test", cString);
468     p2.setCooked("category",c);
469     cString = p2.getCookedString("category",PoemLocale.HERE, DateFormat.MEDIUM);
470     assertEquals("User", cString);
471     c2.delete();
472   }
473 
474   /**
475    * @see org.melati.poem.Persistent#getField(String)
476    */
477   public void testGetField() {
478     Persistent p = getDb().getGroupMembershipTable().getObject(0);
479     Field f = p.getField("user");
480     assertEquals("user: Melati database administrator", f.toString());
481   }
482 
483   /**
484    * @see org.melati.poem.Persistent#fieldsOfColumns(Enumeration)
485    */
486   public void testFieldsOfColumns() {
487     Persistent p = getDb().getGroupMembershipTable().getObject(0);
488     Enumeration fields = p.fieldsOfColumns(p.getTable().columns());
489     Field f = (Field)fields.nextElement();
490     assertEquals("id: 0", f.toString());
491     f = (Field)fields.nextElement();
492     assertEquals("user: Melati database administrator", f.toString());
493     f = (Field)fields.nextElement();
494     assertEquals("group: Melati database administrators", f.toString());
495   }
496 
497   /**
498    * @see org.melati.poem.Persistent#getFields()
499    */
500   public void testGetFields() {
501     Persistent p = getDb().getGroupMembershipTable().getObject(0);
502     Enumeration fields = p.getFields();
503     Field f = (Field)fields.nextElement();
504     assertEquals("id: 0", f.toString());
505     f = (Field)fields.nextElement();
506     assertEquals("user: Melati database administrator", f.toString());
507     f = (Field)fields.nextElement();
508     assertEquals("group: Melati database administrators", f.toString());
509   }
510 
511   /**
512    * @see org.melati.poem.Persistent#getRecordDisplayFields()
513    */
514   public void testGetRecordDisplayFields() {
515     Persistent p = getDb().getGroupMembershipTable().getObject(0);
516     Enumeration fields = p.getRecordDisplayFields();
517     Field f = (Field)fields.nextElement();
518     assertEquals("user: Melati database administrator", f.toString());
519     f = (Field)fields.nextElement();
520     assertEquals("group: Melati database administrators", f.toString());
521   }
522 
523   /**
524    * @see org.melati.poem.Persistent#getDetailDisplayFields()
525    */
526   public void testGetDetailDisplayFields() {
527     Persistent p = getDb().getGroupMembershipTable().getObject(0);
528     Enumeration fields = p.getDetailDisplayFields();
529     Field f = (Field)fields.nextElement();
530     assertEquals("id: 0", f.toString());
531     f = (Field)fields.nextElement();
532     assertEquals("user: Melati database administrator", f.toString());
533     f = (Field)fields.nextElement();
534     assertEquals("group: Melati database administrators", f.toString());
535   }
536 
537   /**
538    * @see org.melati.poem.Persistent#getSummaryDisplayFields()
539    */
540   public void testGetSummaryDisplayFields() {
541     Persistent p = getDb().getGroupMembershipTable().getObject(0);
542     Enumeration fields = p.getSummaryDisplayFields();
543     Field f = (Field)fields.nextElement();
544     assertEquals("user: Melati database administrator", f.toString());
545     f = (Field)fields.nextElement();
546     assertEquals("group: Melati database administrators", f.toString());
547   }
548 
549   /**
550    * @see org.melati.poem.Persistent#getSearchCriterionFields()
551    */
552   public void testGetSearchCriterionFields() {
553     Persistent p = getDb().getGroupMembershipTable().getObject(0);
554     Enumeration fields = p.getSearchCriterionFields();
555     Field f = (Field)fields.nextElement();
556     assertEquals("id: 0", f.toString());
557     f = (Field)fields.nextElement();
558     assertEquals("user: Melati database administrator", f.toString());
559     f = (Field)fields.nextElement();
560     assertEquals("group: Melati database administrators", f.toString());
561   }
562 
563   /**
564    * @see org.melati.poem.test.ProtectedPersistentTest#testGetPrimaryDisplayField()
565    * @see org.melati.poem.Persistent#getPrimaryDisplayField()
566    */
567   public void testGetPrimaryDisplayField() {
568   }
569 
570   /**
571    * @see org.melati.poem.Persistent#delete(Map)
572    */
573   public void testDeleteMap() {
574     TableInfo ti = getDb().getUserTable().getTableInfo();
575     try { 
576       ti.delete();
577       fail("Should have bombed");
578     } catch (DeletionIntegrityPoemException e) { 
579       e = null;
580     }
581 
582   }
583 
584   /**
585    * @see org.melati.poem.Persistent#delete()
586    */
587   public void testDelete() {
588     Persistent p = getDb().getCapabilityTable().newPersistent();
589     try {
590       p.delete();
591       fail("Should have bombed");
592     } catch (InvalidOperationOnFloatingPersistentPoemException e) { 
593       e = null;
594     }
595     p.setCooked("name","testCapability");
596     p.makePersistent();
597     assertEquals("testCapability", p.getCooked("name"));
598     p.delete();
599     try { 
600       p.delete();
601       fail("Should have bombed");
602     } catch (RowDisappearedPoemException e) { 
603       e = null;
604     }
605     try {
606       getDb().getGroupTable().getObject(p.getTroid());
607       fail("Should have bombed");
608     } catch (NoSuchRowPoemException e) { 
609       e = null;
610     }
611     // To before we started
612     PoemThread.rollback();
613     try {
614       getDb().getGroupTable().getObject(p.getTroid());
615       fail("Should have bombed");
616     } catch (NoSuchRowPoemException e) { 
617       e = null;
618     }
619     p = getDb().getGroupTable().newPersistent();    
620     p.setCooked("name","testGroup");
621     p.makePersistent();
622     assertEquals("testGroup", p.getCooked("name"));
623     // Write to db
624     PoemThread.commit();
625     p.delete();
626     try { 
627       p.delete();
628       fail("Should have bombed");
629     } catch (RowDisappearedPoemException e) { 
630       e = null;
631     }
632     try {
633       getDb().getGroupTable().getObject(p.getTroid());
634       fail("Should have bombed");
635     } catch (NoSuchRowPoemException e) { 
636       e = null;
637     }
638     // Rollback so it should be there again
639     getDb().setLogCommits(true);
640     PoemThread.rollback(); 
641     getDb().setLogCommits(false);
642     getDb().getGroupTable().getObject(p.getTroid());
643     assertEquals("testGroup", p.getCooked("name"));
644     p.delete();
645     try { 
646       p.delete();
647       fail("Should have bombed");
648     } catch (RowDisappearedPoemException e) { 
649       e = null;
650     }
651     try {
652       getDb().getGroupTable().getObject(1);
653       fail("Should have bombed");
654     } catch (NoSuchRowPoemException e) { 
655       e = null;
656     }
657     // So the db state should be unchanged
658     getDb().setLogCommits(true);
659     PoemThread.commit();
660     getDb().setLogCommits(false);
661   }
662 
663   /**
664    * @see org.melati.poem.Persistent#delete_unsafe()
665    */
666   public void testDelete_unsafe() {
667     Persistent p = getDb().getGroupTable().newPersistent();
668     try {
669       p.delete_unsafe();
670       fail("Should have bombed");
671     } catch (InvalidOperationOnFloatingPersistentPoemException e) { 
672       e = null;
673     }
674     p.setCooked("name","test");
675     p.makePersistent();
676     // Hmm - not sure I am happy with this ordered dependency
677     assertEquals("test", p.getCooked("name"));
678     p.delete_unsafe();
679     try { 
680       p.delete_unsafe();
681     } catch (RowDisappearedPoemException e) { 
682       e = null;
683     }
684     try {
685       getDb().getGroupTable().getObject(2);
686       fail("Should have bombed");
687     } catch (NoSuchRowPoemException e) { 
688       e = null;
689     }
690 
691   }
692   
693 
694   /**
695    * @see org.melati.poem.Persistent#deleteAndCommit()
696    */
697   public void testDeleteAndCommit() {
698     Persistent p = getDb().getGroupTable().newPersistent();
699     try {
700       p.deleteAndCommit();
701       fail("Should have bombed");
702     } catch (InvalidOperationOnFloatingPersistentPoemException e) { 
703       e = null;
704     }
705     p.setCooked("name","test");
706     p.makePersistent();
707     assertEquals("test", p.getCooked("name"));
708     p.deleteAndCommit();
709     try { 
710       p.deleteAndCommit();
711     } catch (RowDisappearedPoemException e) { 
712       e = null;
713     }
714     try {
715       getDb().getGroupTable().getObject(3);
716       fail("Should have bombed");
717     } catch (NoSuchRowPoemException e) { 
718       e = null;
719     }
720   }
721 
722   /**
723    * @see org.melati.poem.Persistent#deleteAndCommit(Map)
724    */
725   public void testDeleteAndCommitMap() {
726     Persistent p = getDb().getGroupTable().newPersistent();
727     try {
728       p.deleteAndCommit(null);
729       fail("Should have bombed");
730     } catch (InvalidOperationOnFloatingPersistentPoemException e) { 
731       e = null;
732     }
733     p.setCooked("name","test");
734     p.makePersistent();
735     assertEquals("test", p.getCooked("name"));
736     Integer troid = p.getTroid();
737     p.deleteAndCommit(null);
738     try { 
739       p.deleteAndCommit(null);
740     } catch (RowDisappearedPoemException e) { 
741       e = null;
742     }
743     try {
744       getDb().getGroupTable().getObject(troid);
745       fail("Should have bombed");
746     } catch (NoSuchRowPoemException e) { 
747       e = null;
748     }
749 
750   }
751 
752   /**
753    * @see org.melati.poem.Persistent#duplicated()
754    */
755   public void testDuplicated() {
756     Persistent p = getDb().getGroupTable().getObject(0); 
757     Persistent p2 = p.duplicated();
758     assertFalse(p.equals(p2)); // p2 is floating
759     try {
760       p2.duplicated();
761       fail("Should have bombed");
762     } catch (InvalidOperationOnFloatingPersistentPoemException e) { 
763       e = null;
764     }
765   }
766 
767   /**
768    * @see org.melati.poem.Persistent#duplicatedFloating()
769    */
770   public void testDuplicatedFloating() {
771     Persistent p = getDb().getGroupTable().getObject(0); 
772     Persistent p2 = p.duplicatedFloating();
773     assertFalse(p.equals(p2)); 
774     Persistent p3 = p2.duplicatedFloating();
775     assertTrue(p2.equals(p3)); 
776   }
777 
778   /**
779    * @see org.melati.poem.Persistent#toString()
780    */
781   public void testToString() {
782     Persistent p = getDb().getGroupMembershipTable().getObject(0);
783     assertEquals("groupmembership/0", p.toString());
784   }
785 
786   /**
787    * @see org.melati.poem.Persistent#displayString(PoemLocale, int)
788    */
789   public void testDisplayStringPoemLocaleInt() {
790     Persistent p = getDb().getGroupTable().getObject(0);
791     assertEquals("Melati database administrators", 
792         p.displayString(PoemLocale.HERE, DateFormat.MEDIUM));
793   }
794 
795   /** 
796    * @see org.melati.poem.Persistent#displayString(PoemLocale)
797    */
798   public void testDisplayStringPoemLocale() {
799     Persistent p = getDb().getGroupTable().getObject(0);
800     assertEquals("Melati database administrators", 
801         p.displayString(PoemLocale.HERE));
802   }
803 
804   /**
805    * @see org.melati.poem.Persistent#displayString()
806    */
807   public void testDisplayString() {
808     Persistent p = getDb().getGroupTable().getObject(0);
809     assertEquals("Melati database administrators", 
810         p.displayString());    
811   }
812   
813   /**
814    * @see org.melati.poem.Persistent#hashCode()
815    */
816   public void testHashCode() {
817     Persistent p = getDb().getUserTable().guestUser();
818     assertEquals(3599307, p.hashCode());
819     try { 
820       p = getDb().getUserTable().newPersistent();
821       p.hashCode();
822       fail("Should have bombed");
823     } catch (InvalidOperationOnFloatingPersistentPoemException e) { 
824       e = null;
825     }
826   }
827   
828   /**
829    * @see org.melati.poem.Persistent#equals(Object)
830    */
831   public void testEqualsObject() {
832     Persistent p = getDb().getGroupTable().getObject(0);
833     assertTrue(p.equals(p));
834     Persistent p2 = getDb().getGroupTable().newPersistent();
835     assertTrue(p2.equals(p2));
836     assertFalse(p.equals(p2));
837     assertFalse(p.equals(null));
838     assertFalse(p.equals(new Integer(0)));
839     // Note that id != troid
840     // troid remains null
841     p2.setRaw("id", new Integer(0));
842     assertFalse(p.equals(p2));
843   }
844 
845   /**
846    * @see org.melati.poem.Persistent#dump()
847    */
848   public void testDump() {
849     Persistent p = new JdbcPersistent(getDb().getUserTable(), new Integer(0));
850     String d = null; 
851     try { 
852       d = p.dump();
853       fail("Should have blown up");
854     } catch (ClassCastException e) {
855       e = null;
856     }
857     assertNull(d);
858     
859     User u = (User)getDb().getUserTable().newPersistent();
860     d = u.dump();
861     assertTrue(d.startsWith("user/null"));
862     u = getDb().getUserTable().guestUser();
863     d = u.dump();
864     assertTrue(d.startsWith("user/0"));
865 
866 
867     
868     Setting stringSetting = getDb().getSettingTable().ensure("stringSetting","set","String","A set string setting");
869     ByteArrayOutputStream baos = new ByteArrayOutputStream();
870     PrintStream ps = new PrintStream(baos);
871     stringSetting.dump(ps);
872     //System.err.println(baos.toString().trim() + ":");
873     assertTrue(baos.toString().startsWith("setting/"));
874     stringSetting.delete();
875     
876   }
877   /**
878    * @see org.melati.poem.Persistent#dump(PrintStream)
879    */
880   public void testDumpPrintStream() {
881     ByteArrayOutputStream baos = new ByteArrayOutputStream();
882     PrintStream ps = new PrintStream(baos);
883     try { 
884       Persistent p = new JdbcPersistent(getDb().getUserTable(), new Integer(0));
885       p.dump(ps);
886       fail("Should have blown up");
887     } catch (ClassCastException e) {
888       e = null;
889     }
890     // Some gets written before blowing up
891     assertTrue(baos.toString().startsWith("user/0"));
892     
893     baos = new ByteArrayOutputStream();
894     ps = new PrintStream(baos);
895     User u = (User)getDb().getUserTable().newPersistent();
896     u.dump(ps);
897     assertTrue(baos.toString().startsWith("user/null"));
898     u = getDb().getUserTable().guestUser();
899     baos = new ByteArrayOutputStream();
900     ps = new PrintStream(baos);
901     u.dump(ps);
902     assertTrue(baos.toString().startsWith("user/0"));
903   
904   }
905 
906   /** 
907    * @see org.melati.poem.Persistent#postWrite()
908    */
909   public void testPostWrite() {
910     Persistent p = getDb().getUserTable().guestUser();
911     p.postWrite();
912   }
913 
914   /**
915    * @see org.melati.poem.Persistent#postInsert()
916    */
917   public void testPostInsert() {
918     Persistent p = getDb().getUserTable().guestUser();
919     p.postInsert();
920   }
921 
922   /**
923    * @see org.melati.poem.Persistent#postModify()
924    */
925   public void testPostModify() {
926     Persistent p = getDb().getUserTable().guestUser();
927     p.postModify();
928   }
929 
930   /**
931    * @see org.melati.poem.Persistent#preEdit()
932    */
933   public void testPreEdit() {
934     Persistent p = getDb().getUserTable().guestUser();
935     p.preEdit();
936   }
937 
938   /**
939    * @see org.melati.poem.Persistent#postEdit(boolean)
940    */
941   public void testPostEdit() {
942     Persistent p = getDb().getUserTable().guestUser();
943     p.postEdit(true);
944     p.postEdit(false);
945   }
946 
947 
948   /**
949    * Test the representation of an uninitialised Persistent.
950    */
951   public void testToStringNull() {
952     Persistent unit = new JdbcPersistent();
953     assertEquals("null/null", unit.toString());
954   }
955 
956   /**
957    * Test that two uninitialised Persistents are equal.
958    */
959   public void testEqualsNull() {
960     Persistent unitOne = new JdbcPersistent();
961     Persistent unitTwo = new JdbcPersistent();
962     assertTrue(unitOne.equals(unitTwo));
963   }
964 
965 }