1   /*
2    * Copyright 2001-2004 The Apache Software Foundation.
3    * 
4    * Licensed under the Apache License, Version 2.0 (the "License");
5    * you may not use this file except in compliance with the License.
6    * You may obtain a copy of the License at
7    * 
8    *      http://www.apache.org/licenses/LICENSE-2.0
9    * 
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS,
12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   * See the License for the specific language governing permissions and
14   * limitations under the License.
15   */ 
16   
17  package org.apache.commons.betwixt;
18  
19  import java.io.ByteArrayOutputStream;
20  import java.io.PrintStream;
21  import java.io.StringWriter;
22  import java.util.ArrayList;
23  import java.util.Collection;
24  
25  import junit.framework.Test;
26  import junit.framework.TestSuite;
27  import junit.textui.TestRunner;
28  
29  import org.apache.commons.betwixt.io.BeanWriter;
30  import org.apache.commons.betwixt.io.CyclicReferenceException;
31  import org.apache.commons.betwixt.strategy.CapitalizeNameMapper;
32  import org.apache.commons.betwixt.strategy.HyphenatedNameMapper;
33  import org.apache.commons.logging.impl.SimpleLog;
34  
35  /*** Test harness for the BeanWriter
36    *
37    * @author <a href="mailto:jstrachan@apache.org">James Strachan</a>
38    * @author <a href="mailto:martin@mvdb.net">Martin van den Bemt</a>
39    * @version $Revision: 164896 $
40    */
41  public class TestBeanWriter extends AbstractTestCase {
42      
43      public static void main( String[] args ) {
44          TestRunner.run( suite() );
45      }
46      
47      public static Test suite() {
48          return new TestSuite(TestBeanWriter.class);
49      }
50      
51      public TestBeanWriter(String testName) {
52          super(testName);
53      }
54      
55      public void testBeanWriter() throws Exception {
56          Object bean = createBean();
57          
58          System.out.println( "Now trying pretty print" );
59          
60          BeanWriter writer = new BeanWriter();
61          writer.setWriteEmptyElements(true);
62          writer.enablePrettyPrint();
63          writer.write( bean );
64      }
65      
66      
67      public void testLooping() throws Exception {
68          StringWriter out = new StringWriter();
69          out.write("<?xml version='1.0'?>");
70          BeanWriter writer = new BeanWriter(out);
71          writer.setWriteEmptyElements( true );
72          
73          // logging for debugging jsut this method 
74  //        SimpleLog log = new SimpleLog("[testLooping:BeanWriter]");
75  //        log.setLevel(SimpleLog.LOG_LEVEL_TRACE);
76  //        writer.setLog(log);
77          
78  //        log = new SimpleLog("[testLooping:AbstractBeanWriter]");
79  //        log.setLevel(SimpleLog.LOG_LEVEL_TRACE);
80  //        writer.setAbstractBeanWriterLog(log);
81          
82  //        log = new SimpleLog("[testLooping]");
83  //        log.setLevel(SimpleLog.LOG_LEVEL_TRACE);
84          
85          writer.enablePrettyPrint();
86          writer.write( LoopBean.createNoLoopExampleBean() );    
87          
88          String xml ="<?xml version='1.0'?><LoopBean id='1'><name>Root</name><friend id='2'><name>level1</name>"
89                  + "<friend id='3'><name>level2</name><friend id='4'><name>level3</name><friend id='5'><name>level4</name>"
90                  + "<friend id='6'><name>level5</name></friend></friend></friend></friend></friend></LoopBean>";
91        
92        	String xmlOut = out.getBuffer().toString();
93          xmlAssertIsomorphicContent(
94                              "Test no loop",
95                              parseString(xmlOut),
96                              parseString(xml), 
97                              true);        
98          
99          out = new StringWriter();
100         out.write("<?xml version='1.0'?>");
101         writer = new BeanWriter(out);
102         writer.setWriteEmptyElements( true );
103         writer.write( LoopBean.createLoopExampleBean() );  
104         xml ="<?xml version='1.0'?><LoopBean id='1'><name>Root</name><friend id='2'><name>level1</name>"
105                 + "<friend id='3'><name>level2</name><friend id='4'><name>level3</name><friend id='5'><name>level4</name>"
106                 + "<friend id='6'><name>level5</name><friend idref='1'/></friend></friend></friend>"
107                 + "</friend></friend></LoopBean>";
108         xmlAssertIsomorphicContent(
109                             "Test loop",
110                             parseString(out.getBuffer().toString()),
111                             parseString(xml), 
112                             true);  
113         
114         // test not writing IDs
115 
116         
117 //        log.info("Writing LoopBean.createNoLoopExampleBean...");
118         
119         out = new StringWriter();
120         out.write("<?xml version='1.0'?>");
121         writer = new BeanWriter(out);
122         writer.setWriteEmptyElements( true );
123         writer.getBindingConfiguration().setMapIDs(false);
124         writer.write( LoopBean.createNoLoopExampleBean() );
125         xml ="<?xml version='1.0'?><LoopBean><name>Root</name><friend><name>level1</name><friend>"
126             + "<name>level2</name><friend><name>level3</name><friend><name>level4</name><friend>"
127             + "<name>level5</name></friend></friend>"
128             + "</friend></friend></friend></LoopBean>";
129                 
130         xmlAssertIsomorphicContent(	
131                             "Test no loop, no ids",
132                             parseString(out.getBuffer().toString()),
133                             parseString(xml), 
134                             true); 
135         
136 //        log.info("Writing LoopBean.createIdOnlyLoopExampleBean...");
137         
138         out = new StringWriter();
139         out.write("<?xml version='1.0'?>");
140         writer = new BeanWriter(out);
141         writer.setWriteEmptyElements( true );
142         writer.getBindingConfiguration().setMapIDs(false);
143         writer.write( LoopBean.createIdOnlyLoopExampleBean() );
144         xml = "<?xml version='1.0'?><LoopBean><name>Root</name><friend><name>level1</name>"
145             + "<friend><name>level2</name><friend><name>level3</name><friend><name>level4</name>"
146             + "<friend><name>level5</name><friend><name>Root</name></friend></friend>"
147             + "</friend></friend></friend></friend></LoopBean>";
148                 
149         xmlAssertIsomorphicContent(	
150                             "Test id only loop",
151                             parseString(out.getBuffer().toString()),
152                             parseString(xml), 
153                             true); 
154         
155         try {   
156 //            log.info("Writing LoopBean.createLoopExampleBean...")
157             out = new StringWriter();
158             out.write("<?xml version='1.0'?>");
159             writer = new BeanWriter(out);
160             writer.setWriteEmptyElements( true );
161             writer.getBindingConfiguration().setMapIDs(false);
162             writer.write( LoopBean.createLoopExampleBean() );   
163             fail("CyclicReferenceException not thrown!");
164             
165         } catch (CyclicReferenceException e) {
166             // everything's fine
167         }
168     }
169     
170     public void testEscaping() throws Exception {
171         //XXX find a way to automatically verify test
172         ByteArrayOutputStream out = new ByteArrayOutputStream();
173         BeanWriter writer = new BeanWriter(out);
174         writer.setWriteEmptyElements( true );
175 		writer.getBindingConfiguration().setMapIDs(false);
176         writer.enablePrettyPrint(); 
177         XMLIntrospector introspector = new XMLIntrospector();
178         introspector.getConfiguration().setAttributesForPrimitives(true);
179         writer.setXMLIntrospector(introspector);
180         writer.write(new LoopBean("Escape<LessThan"));
181         writer.write(new LoopBean("Escape>GreaterThan"));
182         writer.write(new LoopBean("Escape&amphersand"));
183         writer.write(new LoopBean("Escape'apostrophe"));
184         writer.write(new LoopBean("Escape\"Quote"));
185         
186         CustomerBean bean = new CustomerBean();
187         bean.setEmails( new String[] { 
188                                         "Escape<LessThan",
189                                         "Escape>GreaterThan",
190                                         "Escape&amphersand",
191                                         "Escape'apostrophe",
192                                         "Escape\"Quote"} );
193                                         
194         // The attribute value escaping needs test too..
195         bean.setName("Escape<LessThan");
196         AddressBean address = new AddressBean();
197         address.setCode("Escape>GreaterThan");
198         address.setCountry("Escape&amphersand");
199         address.setCity("Escape'apostrophe");
200         address.setStreet("Escape\"Quote");
201         bean.setAddress(address);
202         
203         writer.write(bean);
204         out.flush();
205         String result = "<?xml version='1.0'?><beans>" + out.toString() + "</beans>";
206         
207         // check for the elemant content..
208         assertTrue(result.indexOf("<email>Escape&lt;LessThan</email>") > -1 );
209         assertTrue(result.indexOf("<email>Escape&gt;GreaterThan</email>") > -1);
210         assertTrue(result.indexOf("<email>Escape&amp;amphersand</email>") != -1);
211         assertTrue(result.indexOf("<email>Escape'apostrophe</email>") != -1);
212         assertTrue(result.indexOf("<email>Escape\"Quote</email>") != -1);
213         // check for the attributes..
214         assertTrue(result.indexOf("name=\"Escape&lt;LessThan\"") > -1 );
215         assertTrue(result.indexOf("code=\"Escape&gt;GreaterThan\"") > -1);
216         assertTrue(result.indexOf("country=\"Escape&amp;amphersand\"") != -1);
217         assertTrue(result.indexOf("city=\"Escape&apos;apostrophe\"") != -1);
218         assertTrue(result.indexOf("street=\"Escape&quot;Quote\"") != -1);
219         
220         String xml="<?xml version='1.0'?><beans>  <LoopBean name='Escape&lt;LessThan'/>"
221             + "<LoopBean name='Escape&gt;GreaterThan'/><LoopBean name='Escape&amp;amphersand'/>"
222             + "<LoopBean name='Escape&apos;apostrophe'/><LoopBean name='Escape&quot;Quote'/>"
223             + "<CustomerBean name='Escape&lt;LessThan' >"
224             + "<projectMap/><projectNames/><emails><email>Escape&lt;LessThan</email>"
225             + "<email>Escape&gt;GreaterThan</email><email>Escape&amp;amphersand</email>"
226             + "<email>Escape'apostrophe</email><email>Escape\"Quote</email></emails>"
227             + "<locations/><projectURLs/>"
228             + "<address code='Escape&gt;GreaterThan' city='Escape&apos;apostrophe' "
229             + "country='Escape&amp;amphersand' street='Escape&quot;Quote'/>"
230             + "<numbers/></CustomerBean></beans>";
231             
232         xmlAssertIsomorphicContent(
233                             "Test escaping ",
234                             parseString(result),
235                             parseString(xml), 
236                             true);  
237     }
238     /***
239      * Testing valid endofline characters.
240      * It tests if there is a warning on System.err
241      */
242     public void testValidEndOfLine() throws Exception {
243         BeanWriter writer = new BeanWriter();
244         writer.setWriteEmptyElements(true);
245         
246         // store the system err
247         PrintStream errStream = System.err;
248         ByteArrayOutputStream warning = new ByteArrayOutputStream();
249         System.setErr(new PrintStream(warning));
250         
251         // force logging to go to System.err
252         writer.setLog( new SimpleLog( "test.betwixt" ) );
253         
254         
255         writer.setEndOfLine("X");
256         warning.flush();
257         assertTrue(warning.toString().startsWith("[WARN]"));
258         warning.reset();
259         writer.setEndOfLine("\tX");
260         warning.flush();
261         assertTrue(warning.toString().startsWith("[WARN]"));
262         warning.reset();
263         // now test a valid value..
264         writer.setEndOfLine(" ");
265         warning.flush();
266         assertTrue(warning.toString().equals(""));
267         warning.reset();
268         // set the System.err back again..
269         System.setErr(errStream);
270     }
271     
272     /*** Test simplest case for writing empty elements */
273     public void testSimpleWriteEmptyElements() throws Exception{
274         // use same bean for both tests
275         AddressBean bean = new AddressBean();
276         bean.setStreet("Pasture Lane");
277         bean.setCity("Bradford");
278         
279 //        SimpleLog log = new SimpleLog( "[SimpleEmpty:AbstractBeanWriter]" );
280 //        log.setLevel(SimpleLog.LOG_LEVEL_TRACE);
281         
282 //        SimpleLog baseLog = new SimpleLog( "[SimpleEmpty]" );
283 //        baseLog.setLevel(SimpleLog.LOG_LEVEL_TRACE);
284         
285         // test output when writing empty elements
286         StringWriter out = new StringWriter();
287         out.write("<?xml version='1.0'?>");
288         BeanWriter writer = new BeanWriter(out);
289         writer.setWriteEmptyElements(true);
290         writer.getBindingConfiguration().setMapIDs(false);
291         writer.write(bean);
292 //        baseLog.debug("SIMPLE EMPTY");
293 //        baseLog.debug(out.getBuffer().toString());
294         String xml = "<?xml version='1.0'?><AddressBean><street>Pasture Lane</street><city>Bradford</city>"
295                     + "<code/><country/></AddressBean>";
296 //        baseLog.debug(xml);
297 
298         xmlAssertIsomorphicContent(parseString(out.getBuffer().toString()),parseString(xml), true);
299         
300         // test output when not writing empty elements
301         out = new StringWriter();
302         out.write("<?xml version='1.0'?>");
303         writer = new BeanWriter(out);
304         writer.setWriteEmptyElements(false);
305         writer.getBindingConfiguration().setMapIDs(false);
306 //        writer.setAbstractBeanWriterLog(log);
307         writer.write(bean);
308         xml = "<?xml version='1.0'?><AddressBean><street>Pasture Lane</street><city>Bradford</city>"
309                     + "</AddressBean>";
310 //        baseLog.debug("SIMPLE NOT EMPTY");
311 //        baseLog.debug(out.getBuffer().toString());
312         xmlAssertIsomorphicContent(parseString(out.getBuffer().toString()),parseString(xml), true);
313     }
314 
315     
316     public void testArrayWrite() throws Exception {
317         ArrayBean bean = new ArrayBean("Rob");
318         bean.addHobby("Hacking open source software");
319         bean.addHobby("Playing cricket");
320         bean.addHobby("Watching rugby league");
321         bean.addHobby("Havin' it large");
322     
323         StringWriter out = new StringWriter();
324         out.write("<?xml version='1.0'?>");
325         BeanWriter writer = new BeanWriter(out);
326         writer.setWriteEmptyElements(true);
327         writer.getBindingConfiguration().setMapIDs(false);
328         writer.write(bean);
329         
330         String xml = "<?xml version='1.0'?><ArrayBean><name>Rob</name><hobbies>"
331          + "<hobby>Hacking open source software</hobby>" 
332          + "<hobby>Playing cricket</hobby>" 
333          + "<hobby>Watching rugby league</hobby>" 
334          + "<hobby>Havin' it large</hobby>"
335          +"</hobbies></ArrayBean>";
336         xmlAssertIsomorphicContent(
337                             parseString(out.getBuffer().toString()),
338                             parseString(xml), 
339                             true);
340                             
341         String [] array = {"This", "That", "The Other"};
342         out = new StringWriter();
343         out.write("<?xml version='1.0'?>");
344         writer = new BeanWriter(out);
345         writer.setWriteEmptyElements(true);
346         writer.getBindingConfiguration().setMapIDs(false);
347         writer.write(array);
348         
349         xml = "<?xml version='1.0'?><Array>"
350          + "<String>This</String>" 
351          + "<String>That</String>" 
352          + "<String>The Other</String>" 
353          +"</Array>";
354          
355         xmlAssertIsomorphicContent(
356                             parseString(out.getBuffer().toString()),
357                             parseString(xml), 
358                             true);
359     }
360     
361     
362     /*** Test nested case for writing empty elements */
363     public void testListedWriteEmptyElements() throws Exception {
364         ListOfNames names = new ListOfNames();
365         names.addName(new NameBean("Tom"));
366         names.addName(new NameBean("Dick"));
367         names.addName(new NameBean("Harry"));
368         names.addName(new NameBean(""));
369     
370         StringWriter out = new StringWriter();
371         out.write("<?xml version='1.0'?>");
372 
373         BeanWriter writer = new BeanWriter(out);
374         
375         //SimpleLog log = new SimpleLog("[testListedWriteEmptyElements:AbstractBeanWriter]");
376         //log.setLevel(SimpleLog.LOG_LEVEL_TRACE);
377         //writer.setAbstractBeanWriterLog(log);
378         
379         //log = new SimpleLog("[testListedWriteEmptyElements:XMLIntrospector]");
380         //log.setLevel(SimpleLog.LOG_LEVEL_TRACE);
381         //writer.getXMLIntrospector().setLog(log);
382         
383         //log = new SimpleLog("[testListedWriteEmptyElements:XMLIntrospectorHelper]");
384         //log.setLevel(SimpleLog.LOG_LEVEL_TRACE);
385         //XMLIntrospectorHelper.setLog(log);
386         
387         writer.setWriteEmptyElements(false);
388         writer.getXMLIntrospector().getConfiguration().setWrapCollectionsInElement(false);
389         writer.getBindingConfiguration().setMapIDs(false);
390         writer.write("Names", names);
391         
392         String xml = "<?xml version='1.0'?><Names>"
393          + "<name><name>Tom</name></name>" 
394          + "<name><name>Dick</name></name>" 
395          + "<name><name>Harry</name></name>" 
396          +"</Names>";
397          
398         xmlAssertIsomorphicContent(
399                             parseString(out.getBuffer().toString()),
400                             parseString(xml), 
401                             true);
402                             
403         out = new StringWriter();
404         out.write("<?xml version='1.0'?>");
405 
406         writer = new BeanWriter(out);
407         writer.setWriteEmptyElements(true);
408         writer.getXMLIntrospector().getConfiguration().setWrapCollectionsInElement(false);
409         writer.getBindingConfiguration().setMapIDs(false);
410         writer.write("Names", names);
411         
412         xml = "<?xml version='1.0'?><Names>"
413          + "<name><name>Tom</name></name>" 
414          + "<name><name>Dick</name></name>" 
415          + "<name><name>Harry</name></name>" 
416          + "<name><name/></name>"
417          +"</Names>";
418          
419         xmlAssertIsomorphicContent(
420                             parseString(out.getBuffer().toString()),
421                             parseString(xml), 
422                             true);
423                             
424         out = new StringWriter();
425         out.write("<?xml version='1.0'?>");
426 
427         writer = new BeanWriter(out);
428         writer.setWriteEmptyElements(true);
429         writer.getXMLIntrospector().getConfiguration().setWrapCollectionsInElement(true);
430         writer.getBindingConfiguration().setMapIDs(false);
431         writer.write("Names", names);
432         
433         xml = "<?xml version='1.0'?><Names><names>"
434          + "<name><name>Tom</name></name>" 
435          + "<name><name>Dick</name></name>" 
436          + "<name><name>Harry</name></name>" 
437          + "<name><name/></name></names>"
438          +"</Names>";
439          
440         xmlAssertIsomorphicContent(
441                             parseString(out.getBuffer().toString()),
442                             parseString(xml), 
443                             true);
444                             
445         out = new StringWriter();
446         out.write("<?xml version='1.0'?>");
447 
448         writer = new BeanWriter(out);
449         writer.setWriteEmptyElements(false);
450         writer.getXMLIntrospector().getConfiguration().setWrapCollectionsInElement(true);
451         writer.getBindingConfiguration().setMapIDs(false);
452         writer.write("Names", names);
453         
454         xml = "<?xml version='1.0'?><Names><names>"
455          + "<name><name>Tom</name></name>" 
456          + "<name><name>Dick</name></name>" 
457          + "<name><name>Harry</name></name>" 
458          + "</names>"
459          +"</Names>";
460          
461         xmlAssertIsomorphicContent(
462                             parseString(out.getBuffer().toString()),
463                             parseString(xml), 
464                             true);
465                             
466     }
467     
468     public void testWriteNameMapperStrategy() throws Exception {
469         ListOfNames names = new ListOfNames();
470         names.addName(new NameBean("Sid James"));
471         names.addName(new NameBean("Kenneth Williams"));
472         names.addName(new NameBean("Joan Simms"));
473         names.addName(new NameBean("Charles Hawtrey"));
474         
475         StringWriter out = new StringWriter();
476         out.write("<?xml version='1.0'?>");
477 
478         BeanWriter writer = new BeanWriter(out);
479         writer.setWriteEmptyElements(true);
480         writer.getXMLIntrospector().getConfiguration().setWrapCollectionsInElement(true);
481         writer.getBindingConfiguration().setMapIDs(false);
482         writer.write("CarryOn", names);
483         
484         String xml = "<?xml version='1.0'?><CarryOn><names>"
485          + "<name><name>Sid James</name></name>" 
486          + "<name><name>Kenneth Williams</name></name>" 
487          + "<name><name>Joan Simms</name></name>" 
488          + "<name><name>Charles Hawtrey</name></name>" 
489          + "</names>"
490          +"</CarryOn>";
491          
492         xmlAssertIsomorphicContent(
493                             parseString(out.getBuffer().toString()),
494                             parseString(xml), 
495                             true);
496                             
497         out = new StringWriter();
498         out.write("<?xml version='1.0'?>");
499 
500         writer = new BeanWriter(out);
501         writer.setWriteEmptyElements(true);
502         writer.getXMLIntrospector().getConfiguration().setWrapCollectionsInElement(true);
503         writer.getBindingConfiguration().setMapIDs(false);
504         writer.getXMLIntrospector().getConfiguration().setElementNameMapper(new CapitalizeNameMapper());
505         writer.write("CarryOn", names);
506         
507         xml = "<?xml version='1.0'?><CarryOn><Names>"
508          + "<Name><Name>Sid James</Name></Name>" 
509          + "<Name><Name>Kenneth Williams</Name></Name>" 
510          + "<Name><Name>Joan Simms</Name></Name>" 
511          + "<Name><Name>Charles Hawtrey</Name></Name>" 
512          + "</Names>"
513          +"</CarryOn>";
514          
515         xmlAssertIsomorphicContent(
516                             parseString(out.getBuffer().toString()),
517                             parseString(xml), 
518                             true);
519                             
520         ArrayList things = new ArrayList();
521         things.add(new NameBean("Sugar"));
522         things.add(new NameBean("Spice"));
523         things.add(new NameBean("All Things Nice"));
524         
525         NoAdderBean bean = new NoAdderBean();
526         bean.setThings(things);
527         
528         out = new StringWriter();
529         out.write("<?xml version='1.0'?>");
530         writer = new BeanWriter(out);
531         writer.setWriteEmptyElements(true);
532         writer.getXMLIntrospector().getConfiguration().setWrapCollectionsInElement(true);
533         writer.getBindingConfiguration().setMapIDs(false);
534         writer.write(bean);
535         
536         xml = "<?xml version='1.0'?><NoAdderBean><things>"
537          + "<NameBean><name>Sugar</name></NameBean>" 
538          + "<NameBean><name>Spice</name></NameBean>" 
539          + "<NameBean><name>All Things Nice</name></NameBean>" 
540          + "</things>"
541          +"</NoAdderBean>";
542          
543         xmlAssertIsomorphicContent(
544                             parseString(out.getBuffer().toString()),
545                             parseString(xml), 
546                             true);
547         
548         out = new StringWriter();
549         out.write("<?xml version='1.0'?>");
550         writer = new BeanWriter(out);
551         writer.setWriteEmptyElements(true);
552         writer.getXMLIntrospector().getConfiguration().setWrapCollectionsInElement(true);
553         writer.getBindingConfiguration().setMapIDs(false);
554         writer.getXMLIntrospector().getConfiguration().setElementNameMapper(new CapitalizeNameMapper());
555         writer.write(bean);
556         
557         xml = "<?xml version='1.0'?><NoAdderBean><Things>"
558          + "<NameBean><Name>Sugar</Name></NameBean>" 
559          + "<NameBean><Name>Spice</Name></NameBean>" 
560          + "<NameBean><Name>All Things Nice</Name></NameBean>" 
561          + "</Things>"
562          +"</NoAdderBean>";
563          
564         xmlAssertIsomorphicContent(
565                             parseString(out.getBuffer().toString()),
566                             parseString(xml), 
567                             true);
568                             
569         out = new StringWriter();
570         out.write("<?xml version='1.0'?>");
571         writer = new BeanWriter(out);
572         writer.setWriteEmptyElements(true);
573         writer.getXMLIntrospector().getConfiguration().setWrapCollectionsInElement(true);
574         writer.getBindingConfiguration().setMapIDs(false);
575         writer.getXMLIntrospector().getConfiguration().setElementNameMapper(new HyphenatedNameMapper(false));
576         writer.write(bean);
577         
578         xml = "<?xml version='1.0'?><no-adder-bean><things>"
579          + "<name-bean><name>Sugar</name></name-bean>" 
580          + "<name-bean><name>Spice</name></name-bean>" 
581          + "<name-bean><name>All Things Nice</name></name-bean>" 
582          + "</things>"
583          +"</no-adder-bean>";
584          
585         xmlAssertIsomorphicContent(
586                             parseString(out.getBuffer().toString()),
587                             parseString(xml), 
588                             true);
589     }
590     
591     public void testBeanWriterWorksWithAnAddMethodAndACollection() throws Exception {
592 
593         BeanWriter bw = new BeanWriter();
594         try {
595             bw.write(new BeanWithAddMethod());
596         } catch (IllegalArgumentException e) {
597             fail("BeanWriter fails when a method is just called add(<type>) and there is also a collection");
598         }
599     }
600     
601     // used in testBeanWriterWorksWithAnAddMethodAndACollection
602     public static class BeanWithAddMethod {
603         private Collection x;
604         public void add(Object x)
605         {
606             // do nothing
607         }
608 
609         public Collection getX() {
610             return x;
611         }
612 
613         public void setX(Collection x) {
614             this.x = x;
615         }        
616     }
617 }
618