~ubuntu-branches/ubuntu/quantal/xom/quantal

« back to all changes in this revision

Viewing changes to src/nu/xom/tests/SerializerTest.java

  • Committer: Bazaar Package Importer
  • Author(s): Varun Hiremath
  • Date: 2007-11-25 15:50:40 UTC
  • Revision ID: james.westby@ubuntu.com-20071125155040-r75ikcqf1vu0cei7
Tags: upstream-1.1
ImportĀ upstreamĀ versionĀ 1.1

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* Copyright 2002-2005 Elliotte Rusty Harold
 
2
   
 
3
   This library is free software; you can redistribute it and/or modify
 
4
   it under the terms of version 2.1 of the GNU Lesser General Public 
 
5
   License as published by the Free Software Foundation.
 
6
   
 
7
   This library is distributed in the hope that it will be useful,
 
8
   but WITHOUT ANY WARRANTY; without even the implied warranty of
 
9
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the 
 
10
   GNU Lesser General Public License for more details.
 
11
   
 
12
   You should have received a copy of the GNU Lesser General Public
 
13
   License along with this library; if not, write to the 
 
14
   Free Software Foundation, Inc., 59 Temple Place, Suite 330, 
 
15
   Boston, MA 02111-1307  USA
 
16
   
 
17
   You can contact Elliotte Rusty Harold by sending e-mail to
 
18
   elharo@metalab.unc.edu. Please include the word "XOM" in the
 
19
   subject line. The XOM home page is located at http://www.xom.nu/
 
20
*/
 
21
 
 
22
package nu.xom.tests;
 
23
 
 
24
import nu.xom.Elements;
 
25
import nu.xom.Namespace;
 
26
import nu.xom.Node;
 
27
import nu.xom.Serializer;
 
28
import nu.xom.Element;
 
29
import nu.xom.DocType;
 
30
import nu.xom.Document;
 
31
import nu.xom.Builder;
 
32
import nu.xom.Comment;
 
33
import nu.xom.ParsingException;
 
34
import nu.xom.ProcessingInstruction;
 
35
import nu.xom.Attribute;
 
36
import nu.xom.Text;
 
37
import nu.xom.UnavailableCharacterException;
 
38
import nu.xom.ValidityException;
 
39
import nu.xom.XMLException;
 
40
 
 
41
import java.io.ByteArrayInputStream;
 
42
import java.io.ByteArrayOutputStream;
 
43
import java.io.File;
 
44
import java.io.IOException;
 
45
import java.io.BufferedReader;
 
46
import java.io.InputStream;
 
47
import java.io.OutputStream;
 
48
import java.io.StringReader;
 
49
import java.io.UnsupportedEncodingException;
 
50
 
 
51
/**
 
52
 * <p>
 
53
 * Tests for <code>Serializer</code> functionality.
 
54
 * </p>
 
55
 * 
 
56
 * @author Elliotte Rusty Harold
 
57
 * @version 1.1b7
 
58
 *
 
59
 */
 
60
public class SerializerTest extends XOMTestCase {
 
61
 
 
62
    
 
63
    private Builder parser;
 
64
    private final static double version = Double.parseDouble(
 
65
      System.getProperty("java.version").substring(0,3)
 
66
    );
 
67
    Element root = new Element("root");
 
68
    Document doc = new Document(root);
 
69
    ByteArrayOutputStream out = new ByteArrayOutputStream();    
 
70
    
 
71
    
 
72
    public SerializerTest(String name) {
 
73
        super(name);
 
74
    }
 
75
 
 
76
    
 
77
    protected void setUp() {
 
78
       parser = new Builder();  
 
79
    }
 
80
    
 
81
 
 
82
    public void testNFC88592() throws IOException, ParsingException {
 
83
        
 
84
        String data = "Ā Ä„Ė˜ÅĀ¤Ä½ÅšĀ§ĀØŠŞŤŹĀ­Å½Å»Ā°Ä…Ė›Å‚Ā“ľśĖ‡ĀøŔşńÅŗĖÅ¾Å¼Å”ĆĆ‚Ä‚Ć„Ä¹Ä†Ć‡ÄŒĆ‰Ä˜Ć‹ÄšĆĆŽÄŽÄÅƒÅ‡Ć“Ć”ÅĆ–Ć—Å˜Å®ĆšÅ°ĆœĆÅ¢ĆŸÅ•Ć”Ć¢ÄƒĆ¤ÄŗÄ‡Ć§ÄĆ©Ä™Ć«Ä›Ć­Ć®ÄÄ‘Å„ÅˆĆ³Ć“Å‘Ć¶Ć·Å™ÅÆĆŗÅ±Ć¼Ć½Å£Ė™";
 
85
        Element root = new Element("a");
 
86
        root.appendChild(data);
 
87
        Document doc = new Document(root);
 
88
        
 
89
        // try with 8859-2 encoding on serializer
 
90
        Serializer serializer = new Serializer(out);
 
91
        serializer.setUnicodeNormalizationFormC(true);
 
92
        serializer.write(doc);
 
93
        serializer.flush();
 
94
        out.close();
 
95
        byte[] temp = out.toByteArray();
 
96
        Document roundTrip = parser.build(new ByteArrayInputStream(temp));
 
97
        
 
98
        assertEquals(data, roundTrip.getValue());
 
99
        
 
100
    }
 
101
    
 
102
    
 
103
    public void testMultipleCombiningCharactersWithNFC() 
 
104
      throws ParsingException, IOException {
 
105
    
 
106
        // LATIN CAPITAL LETTER D WITH DOT BELOW, COMBINING DOT ABOVE
 
107
        String input = "<a>&#x1E0A;&#x0323;</a>";
 
108
        // LATIN CAPITAL LETTER D WITH DOT ABOVE, COMBINING DOT BELOW
 
109
        String output = "<?xml version=\"1.0\" encoding=\"US-ASCII\"?>\r\n"
 
110
          + "<a>&#x1E0C;&#x307;</a>\r\n";  
 
111
            
 
112
        Document doc = parser.build(input, null);
 
113
        Serializer serializer = new Serializer(out, "US-ASCII");
 
114
        serializer.setUnicodeNormalizationFormC(true);
 
115
        serializer.write(doc);
 
116
        serializer.flush();
 
117
        String result = out.toString("US-ASCII");
 
118
        assertEquals(output, result);
 
119
            
 
120
    }
 
121
    
 
122
 
 
123
    public void testMultipleCombiningCharactersWithDifferentCombiningClassesNFC() 
 
124
      throws ParsingException, IOException {
 
125
    
 
126
        // LATIN SMALL LETTER A, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, 
 
127
        // MUSICAL SYMBOL COMBINING AUGMENTATION DOT, HEBREW ACCENT ZINOR, 
 
128
        // LATIN SMALL LETTER B
 
129
        String input = "<a>&#x0061;&#x0300;&#x05AE;&#x1D16D;&#x05AE;&#x0062;</a>";
 
130
        // There was a bug where 1D16D was not listed as a combining character
 
131
        String output = "<?xml version=\"1.0\" encoding=\"US-ASCII\"?>\r\n"
 
132
          + "<a>&#xE0;&#x1D16D;&#x5AE;&#x5AE;b</a>\r\n";  
 
133
            
 
134
        Document doc = parser.build(input, null);
 
135
        Serializer serializer = new Serializer(out, "US-ASCII");
 
136
        serializer.setUnicodeNormalizationFormC(true);
 
137
        serializer.write(doc);
 
138
        serializer.flush();
 
139
        String result = out.toString("US-ASCII");
 
140
        assertEquals(output, result);
 
141
            
 
142
    }
 
143
    
 
144
 
 
145
    public void testEWithCombiningMacron() 
 
146
      throws ParsingException, IOException {
 
147
    
 
148
        // LATIN CAPITAL LETTER E WITH COMBINING MACRON 
 
149
        String input = "<a>&#x45;&#x0304;</a>";
 
150
        String output = "<?xml version=\"1.0\" encoding=\"US-ASCII\"?>\r\n<a>&#x112;</a>\r\n";  
 
151
            
 
152
        Document doc = parser.build(input, null);
 
153
        Serializer serializer = new Serializer(out, "US-ASCII");
 
154
        serializer.setUnicodeNormalizationFormC(true);
 
155
        serializer.write(doc);
 
156
        serializer.flush();
 
157
        String result = out.toString("US-ASCII");
 
158
        assertEquals(output, result);
 
159
            
 
160
    }
 
161
 
 
162
    
 
163
    public void testEWithCombiningMacronAndGrave() 
 
164
      throws ParsingException, IOException {
 
165
    
 
166
        // LATIN CAPITAL LETTER E WITH COMBINING MACRON and grave
 
167
        String input = "<a>&#x0045;&#x0304;&#x0300;</a>";
 
168
        String output = "<?xml version=\"1.0\" encoding=\"US-ASCII\"?>\r\n<a>&#x1E14;</a>\r\n";  
 
169
            
 
170
        Document doc = parser.build(input, null);
 
171
        Serializer serializer = new Serializer(out, "US-ASCII");
 
172
        serializer.setUnicodeNormalizationFormC(true);
 
173
        serializer.write(doc);
 
174
        serializer.flush();
 
175
        String result = out.toString("US-ASCII");
 
176
        assertEquals(output, result);
 
177
            
 
178
    }
 
179
 
 
180
    
 
181
    public void testParenthesizedOjeon() 
 
182
      throws ParsingException, IOException {
 
183
    
 
184
        // (Initial consonant Medial Vowel Initial consonant Medial Vowel Final Consonant)
 
185
        String input = "<a>&#x0028;&#x110B;&#x1169;&#x110C;&#x1165;&#x11AB;&#x0029;</a>";
 
186
        String output = "<?xml version=\"1.0\" encoding=\"US-ASCII\"?>\r\n<a>(&#xC624;&#xC804;)</a>\r\n";  
 
187
            
 
188
        Document doc = parser.build(input, null);
 
189
        Serializer serializer = new Serializer(out, "US-ASCII");
 
190
        serializer.setUnicodeNormalizationFormC(true);
 
191
        serializer.write(doc);
 
192
        serializer.flush();
 
193
        String result = out.toString("US-ASCII");
 
194
        assertEquals(output, result);
 
195
            
 
196
    }
 
197
 
 
198
    
 
199
    public void testNonParenthesizedOjeon() 
 
200
      throws ParsingException, IOException {
 
201
    
 
202
        // Initial consonant Medial Vowel Initial consonant Medial Vowel Final Consonant
 
203
        String input = "<a>&#x110B;&#x1169;&#x110C;&#x1165;&#x11AB;</a>";
 
204
        String output = "<?xml version=\"1.0\" encoding=\"US-ASCII\"?>\r\n<a>&#xC624;&#xC804;</a>\r\n";  
 
205
            
 
206
        Document doc = parser.build(input, null);
 
207
        Serializer serializer = new Serializer(out, "US-ASCII");
 
208
        serializer.setUnicodeNormalizationFormC(true);
 
209
        serializer.write(doc);
 
210
        serializer.flush();
 
211
        String result = out.toString("US-ASCII");
 
212
        assertEquals(output, result);
 
213
            
 
214
    }
 
215
 
 
216
    
 
217
    public void testOjeon() 
 
218
      throws ParsingException, IOException {
 
219
    
 
220
        // (Initial consonant Medial Vowel Initial consonant Medial Vowel Final Consonant)
 
221
        String input = "<a>&#x110C;&#x1165;&#x11AB;</a>";
 
222
        String output = "<?xml version=\"1.0\" encoding=\"US-ASCII\"?>\r\n<a>&#xC804;</a>\r\n";  
 
223
            
 
224
        Document doc = parser.build(input, null);
 
225
        Serializer serializer = new Serializer(out, "US-ASCII");
 
226
        serializer.setUnicodeNormalizationFormC(true);
 
227
        serializer.write(doc);
 
228
        serializer.flush();
 
229
        String result = out.toString("US-ASCII");
 
230
        assertEquals(output, result);
 
231
            
 
232
    }
 
233
 
 
234
    
 
235
    public void testKannadaVowelSignOO() 
 
236
      throws ParsingException, IOException {
 
237
    
 
238
        String input = "<a>&#x0CC6;&#x0CC2;&#x0CD5;</a>";
 
239
        String output = "<?xml version=\"1.0\" encoding=\"US-ASCII\"?>\r\n<a>&#xCCB;</a>\r\n";  
 
240
            
 
241
        Document doc = parser.build(input, null);
 
242
        Serializer serializer = new Serializer(out, "US-ASCII");
 
243
        serializer.setUnicodeNormalizationFormC(true);
 
244
        serializer.write(doc);
 
245
        serializer.flush();
 
246
        String result = out.toString("US-ASCII");
 
247
        assertEquals(output, result);
 
248
            
 
249
    }
 
250
 
 
251
    
 
252
    public void testCDATASectionEndDelimiter() throws IOException {
 
253
 
 
254
        root.appendChild("]]>");    
 
255
        Serializer serializer = new Serializer(out, "UTF-8");
 
256
        serializer.setMaxLength(20);
 
257
        serializer.write(doc);
 
258
        String result = out.toString("UTF-8");
 
259
        assertTrue(result.indexOf("]]&gt;") > 0);
 
260
        
 
261
    }
 
262
 
 
263
    
 
264
    public void testXMLSpacePreserve() throws IOException {
 
265
 
 
266
        root.addAttribute(
 
267
          new Attribute(
 
268
            "xml:space", 
 
269
            "http://www.w3.org/XML/1998/namespace", 
 
270
            "preserve"));
 
271
        String value =  
 
272
          "This is a long sentence with plenty of opportunities for " +
 
273
          "breaking from beginning to end.";
 
274
        root.appendChild(value);    
 
275
        Serializer serializer = new Serializer(out, "UTF-8");
 
276
        serializer.setMaxLength(20);
 
277
        serializer.write(doc);
 
278
        String result = out.toString("UTF-8");
 
279
        assertTrue(result.indexOf(value) > 0); 
 
280
        
 
281
    }
 
282
 
 
283
    
 
284
    /**
 
285
     * <p>
 
286
     *   Check that the UTF-16LE encoding omits the byte-order mark.
 
287
     * </p>
 
288
     * 
 
289
     * @throws IOException
 
290
     */
 
291
    public void testUTF16LEBOM() throws IOException {
 
292
        
 
293
        if (version >= 1.3) { 
 
294
            // UTF-16LE only supported in 1.3 and later
 
295
            Serializer serializer = new Serializer(out, "UTF-16LE");
 
296
            serializer.write(doc);
 
297
            serializer.flush();
 
298
            out.flush();
 
299
            out.close();
 
300
            byte[] data = out.toByteArray();
 
301
            assertEquals('<', (char) data[0]);     
 
302
            assertEquals((byte) 0, data[1]);
 
303
        }
 
304
        
 
305
    }   
 
306
    
 
307
    
 
308
    /**
 
309
     * <p>
 
310
     *   Check that the UTF-16 encoding outputs a byte-order mark.
 
311
     * </p>
 
312
     * 
 
313
     * @throws IOException
 
314
     */
 
315
    public void testUTF16BOM() throws IOException {
 
316
 
 
317
        Serializer serializer = new Serializer(out, "UTF-16");
 
318
        serializer.write(doc);
 
319
        serializer.flush();
 
320
        out.flush();
 
321
        out.close();
 
322
        byte[] data = out.toByteArray();
 
323
        assertEquals((byte) 0xFE, data[0]);
 
324
        assertEquals((byte) 0xFF, data[1]);
 
325
        assertEquals((byte) 0, data[2]);
 
326
        assertEquals('<', (char) data[3]);     
 
327
 
 
328
    }
 
329
    
 
330
    
 
331
    /**
 
332
     * <p>
 
333
     *   Check that the UTF-16BE encoding omits the byte-order mark.
 
334
     * </p>
 
335
     * 
 
336
     * @throws IOException
 
337
     */
 
338
    public void testUTF16BEBOM() throws IOException {
 
339
 
 
340
        if (version >= 1.3) { 
 
341
            // UTF-16LE only supported in 1.3 and later
 
342
            Serializer serializer = new Serializer(out, "UTF-16BE");
 
343
            serializer.write(doc);
 
344
            serializer.flush();
 
345
            out.flush();
 
346
            out.close();
 
347
            byte[] data = out.toByteArray();
 
348
            assertEquals((byte) 0, data[0]);
 
349
            assertEquals('<', (char) data[1]);
 
350
        }
 
351
        
 
352
    }
 
353
 
 
354
    
 
355
    public void testXMLSpaceDefault() throws IOException {
 
356
 
 
357
        root.addAttribute(
 
358
          new Attribute(
 
359
            "xml:space", 
 
360
            "http://www.w3.org/XML/1998/namespace", 
 
361
            "preserve"));
 
362
        Element child1 = new Element("preserve");
 
363
        String value = 
 
364
          "This is a long sentence with plenty of opportunities for " +
 
365
          "breaking from beginning to end.";
 
366
        child1.appendChild(value);    
 
367
        Element child2 = new Element("default");
 
368
        root.appendChild(child1);
 
369
        root.appendChild(child2);
 
370
        child2.addAttribute(
 
371
          new Attribute(
 
372
            "xml:space", 
 
373
            "http://www.w3.org/XML/1998/namespace", 
 
374
            "default"));
 
375
        String value2 = 
 
376
            "This is another very long sentence with plenty" +
 
377
            " of opportunities for breaking from beginning to end.";
 
378
        child2.appendChild(value2);
 
379
 
 
380
        String value3 = 
 
381
          "This is still another very long sentence with plenty of " +
 
382
          "opportunities for breaking from beginning to end.";
 
383
        Element preserveAgain = new Element("test");
 
384
        preserveAgain.appendChild(value3);
 
385
        child2.appendChild(preserveAgain);
 
386
        preserveAgain.addAttribute(
 
387
          new Attribute(
 
388
            "xml:space", 
 
389
            "http://www.w3.org/XML/1998/namespace", 
 
390
            "preserve"));
 
391
 
 
392
 
 
393
        Serializer serializer = new Serializer(out, "UTF-8");
 
394
        serializer.setMaxLength(20);
 
395
        serializer.write(doc);
 
396
        String result = out.toString("UTF-8");
 
397
        assertTrue(result.indexOf(value) > 0);            
 
398
        assertTrue(result.indexOf(value3) > 0);            
 
399
        assertEquals(-1, result.indexOf(value2));      
 
400
        
 
401
    }
 
402
 
 
403
 
 
404
    public void testXMLSpacePreserveWithIndenting() 
 
405
      throws IOException {
 
406
 
 
407
        root.addAttribute(
 
408
          new Attribute(
 
409
            "xml:space", 
 
410
            "http://www.w3.org/XML/1998/namespace", 
 
411
            "preserve"));
 
412
        root.appendChild(new Element("sameline"));    
 
413
        ByteArrayOutputStream out = new ByteArrayOutputStream();
 
414
        Serializer serializer = new Serializer(out, "UTF-8");
 
415
        serializer.setIndent(4);
 
416
        serializer.write(doc);
 
417
        String result = out.toString("UTF-8");
 
418
        assertEquals("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\r\n"
 
419
          + "<root xml:space=\"preserve\"><sameline/></root>\r\n",
 
420
           result);  
 
421
        
 
422
    }
 
423
 
 
424
    
 
425
    public void testXMLSpaceUnspecifiedValueWithIndenting() 
 
426
      throws IOException {
 
427
        
 
428
        root.addAttribute(
 
429
          new Attribute(
 
430
            "xml:space", 
 
431
            "http://www.w3.org/XML/1998/namespace", 
 
432
            "undefined"));
 
433
        root.appendChild(new Element("sameline"));    
 
434
        Serializer serializer = new Serializer(out, "UTF-8");
 
435
        serializer.setIndent(4);
 
436
        serializer.write(doc);
 
437
        String result = out.toString("UTF-8");
 
438
        assertEquals("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\r\n"
 
439
          + "<root xml:space=\"undefined\">\r\n    <sameline/>\r\n</root>\r\n",
 
440
           result);   
 
441
        
 
442
    }
 
443
 
 
444
    
 
445
    public void testXMLSpaceDefaultWithIndenting() throws IOException {
 
446
        
 
447
        root.addAttribute(
 
448
          new Attribute(
 
449
            "xml:space", 
 
450
            "http://www.w3.org/XML/1998/namespace", 
 
451
            "preserve"));
 
452
        Element child = new Element("child");
 
453
        child.addAttribute(
 
454
          new Attribute(
 
455
            "xml:space", 
 
456
            "http://www.w3.org/XML/1998/namespace", 
 
457
            "default"));
 
458
        root.appendChild(child);    
 
459
        Serializer serializer = new Serializer(out, "UTF-8");
 
460
        serializer.setIndent(4);
 
461
        serializer.write(doc);
 
462
        String result = out.toString("UTF-8");
 
463
        assertEquals("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\r\n"
 
464
          + "<root xml:space=\"preserve\">" +
 
465
            "<child xml:space=\"default\"/></root>\r\n",
 
466
           result); 
 
467
        
 
468
    }
 
469
 
 
470
    
 
471
    public void testXMLSpaceDefaultWithIndentingAndGrandchildren() 
 
472
      throws IOException {
 
473
        
 
474
        root.addAttribute(
 
475
          new Attribute(
 
476
            "xml:space", 
 
477
            "http://www.w3.org/XML/1998/namespace", 
 
478
            "preserve"));
 
479
        Element child = new Element("child");
 
480
        child.addAttribute(
 
481
          new Attribute(
 
482
            "xml:space", 
 
483
            "http://www.w3.org/XML/1998/namespace", 
 
484
            "default"));
 
485
        root.appendChild(child);
 
486
        child.appendChild(new Element("differentLine"));    
 
487
        Serializer serializer = new Serializer(out, "UTF-8");
 
488
        serializer.setIndent(2);
 
489
        serializer.write(doc);
 
490
        String result = out.toString("UTF-8");
 
491
        assertEquals("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\r\n"
 
492
          + "<root xml:space=\"preserve\">" +
 
493
            "<child xml:space=\"default\">\r\n    <differentLine/>\r\n" +
 
494
            "  </child></root>\r\n",
 
495
           result); 
 
496
        
 
497
    }
 
498
 
 
499
 
 
500
    public void testDontSerializeXMLNamespace() throws IOException {
 
501
        
 
502
        Element root 
 
503
          = new Element("html", "http://www.w3.org/1999/xhtml");
 
504
        root.addAttribute(
 
505
          new Attribute(
 
506
            "xml:lang", "http://www.w3.org/XML/1998/namespace", "en"));
 
507
        Document doc = new Document(root);
 
508
        Serializer serializer = new Serializer(out, "UTF-8");
 
509
        serializer.write(doc);
 
510
        String result = out.toString("UTF-8");
 
511
        assertEquals(-1, result.indexOf("xmlns:xml"));
 
512
        assertTrue(result.indexOf("xml:lang=") > 1);
 
513
        
 
514
    }
 
515
    
 
516
    public void testDontSerializeNoNamespace() throws IOException { 
 
517
        
 
518
        Serializer serializer = new Serializer(out, "UTF-8");
 
519
        serializer.write(doc);
 
520
        String result = out.toString("UTF-8");
 
521
        assertEquals(-1, result.indexOf("xmlns="));
 
522
        
 
523
    }
 
524
    
 
525
    
 
526
    public void testDefaultNamespace() throws IOException { 
 
527
        
 
528
        Element root = new Element("root", "http://www.example.com");
 
529
        Document doc = new Document(root);
 
530
        Serializer serializer = new Serializer(out, "UTF-8");
 
531
        serializer.write(doc);
 
532
        String result = out.toString("UTF-8");
 
533
        assertTrue(result.indexOf("xmlns=") > 1);
 
534
        assertTrue(result.indexOf("http://www.example.com") > 1);
 
535
        
 
536
    }
 
537
    
 
538
    
 
539
    public void testEmptyElement() throws IOException {    
 
540
        
 
541
        Serializer serializer = new Serializer(out, "UTF-8");
 
542
        serializer.write(doc);
 
543
        String result = out.toString("UTF-8");
 
544
        assertEquals(
 
545
          "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\r\n<root/>\r\n",
 
546
          result
 
547
        );
 
548
        
 
549
    }
 
550
    
 
551
    
 
552
    public void testElementWithText() throws IOException { 
 
553
        
 
554
        String data = "   test   \n\n   \n  \n hello again";
 
555
        root.appendChild(data);
 
556
        Serializer serializer = new Serializer(out, "UTF-8");
 
557
        serializer.write(doc);
 
558
        String result = out.toString("UTF-8");
 
559
        
 
560
        assertEquals( 
 
561
          "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\r\n<root>"
 
562
          + data + "</root>\r\n",
 
563
          result);  
 
564
        
 
565
    }    
 
566
    
 
567
    
 
568
    public void testStaticElementWithText() 
 
569
      throws IOException {        
 
570
        
 
571
        String data = "   test   \n\n   \n  \n hello again";
 
572
        root.appendChild(data);
 
573
        Serializer serializer = new Serializer(out);
 
574
        serializer.write(doc);
 
575
        String result = out.toString("UTF-8");
 
576
        
 
577
        assertEquals( 
 
578
          "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\r\n<root>"
 
579
          + data + "</root>\r\n",
 
580
          result);    
 
581
        
 
582
    }    
 
583
    
 
584
    
 
585
    public void testElementWithTextAndCarriageReturns() 
 
586
      throws IOException { 
 
587
        
 
588
        String data = "   test   \r\n   \n  \r hello again";
 
589
        root.appendChild(data);
 
590
        Serializer serializer = new Serializer(out, "UTF-8");
 
591
        serializer.write(doc);
 
592
        String result = out.toString("UTF-8");
 
593
        
 
594
        assertEquals( 
 
595
          "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\r\n<root>"
 
596
          + "   test   &#x0D;\n   \n  &#x0D; hello again" 
 
597
          + "</root>\r\n",
 
598
          result);   
 
599
        
 
600
    }    
 
601
    
 
602
    
 
603
    private void serializeParseAndCompare(Document doc) 
 
604
      throws IOException, ParsingException {
 
605
        
 
606
        ByteArrayOutputStream out = new ByteArrayOutputStream();
 
607
        Serializer serializer = new Serializer(out, "UTF-8");
 
608
        serializer.write(doc);
 
609
        String result = out.toString("UTF-8");
 
610
        
 
611
        Document resultDoc = parser.build(result, null);
 
612
        XOMTestCase.assertEquals(doc, resultDoc);
 
613
           
 
614
        setOutputStreamSerializeParseAndCompare(doc); 
 
615
        
 
616
    }
 
617
 
 
618
    
 
619
    private void setOutputStreamSerializeParseAndCompare(Document doc) 
 
620
      throws IOException, ParsingException {
 
621
        
 
622
        Serializer serializer = new Serializer(out);
 
623
        serializer.write(doc);
 
624
        ByteArrayOutputStream out2 = new ByteArrayOutputStream();
 
625
        serializer.setOutputStream(out2);
 
626
        serializer.write(doc);
 
627
        String result = out2.toString("UTF-8");
 
628
        
 
629
        Document resultDoc = parser.build(result, null);
 
630
        XOMTestCase.assertEquals(doc, resultDoc); 
 
631
        
 
632
    }
 
633
    
 
634
    
 
635
    public void testComment() 
 
636
      throws IOException, ParsingException {
 
637
        
 
638
        String data = "  <>&amp;&entity; test   \n  hello again";
 
639
        root.appendChild(new Comment(data));
 
640
        serializeParseAndCompare(doc);
 
641
        
 
642
    }
 
643
    
 
644
    
 
645
    public void testProcessingInstruction() 
 
646
      throws IOException, ParsingException { 
 
647
        
 
648
        String data = "<>&amp;&entity; test   \n  hello again";
 
649
        root.appendChild(new ProcessingInstruction("target", data));
 
650
        serializeParseAndCompare(doc); 
 
651
        
 
652
    }
 
653
    
 
654
    public void testBasicElementWithText() 
 
655
      throws IOException, ParsingException {  
 
656
        
 
657
        String data = "   test   \n  hello again";
 
658
        root.appendChild(data);
 
659
        serializeParseAndCompare(doc); 
 
660
        
 
661
    }
 
662
    
 
663
    
 
664
    public void testAttributes() 
 
665
      throws IOException, ParsingException { 
 
666
        
 
667
        root.addAttribute(new Attribute("test", "sadlkhasdk"));
 
668
        String data = "   test   \n  hello again";
 
669
        root.appendChild(data);
 
670
        serializeParseAndCompare(doc);
 
671
        
 
672
        root.addAttribute(new Attribute("test2", "sadlkhasdk"));
 
673
        serializeParseAndCompare(doc);
 
674
 
 
675
        root.addAttribute(new Attribute("test3", " s adl  khasdk  "));
 
676
        serializeParseAndCompare(doc);
 
677
 
 
678
        root.addAttribute(new Attribute("xlink:type", 
 
679
          "http://www.w3.org/2001/xlink", " s adl  khasdk  "));
 
680
        serializeParseAndCompare(doc);
 
681
 
 
682
    }
 
683
 
 
684
    
 
685
    public void testChildElements() 
 
686
      throws IOException, ParsingException {  
 
687
     
 
688
        serializeParseAndCompare(doc);
 
689
 
 
690
        Element child1 = new Element("child");
 
691
        Element child2 = new Element("child");
 
692
        Element child3 = new Element("child");
 
693
        serializeParseAndCompare(doc);
 
694
        root.appendChild(child1);
 
695
        serializeParseAndCompare(doc);
 
696
        child1.appendChild(child2);
 
697
        serializeParseAndCompare(doc);
 
698
        root.appendChild(child3);
 
699
        serializeParseAndCompare(doc);
 
700
        child3.appendChild("some data");
 
701
        serializeParseAndCompare(doc);
 
702
        child2.appendChild("\nsome data with \n line breaks\n");
 
703
        serializeParseAndCompare(doc);
 
704
        root.insertChild("now let's have some mixed content", 0);        
 
705
        serializeParseAndCompare(doc);
 
706
 
 
707
        root.setNamespaceURI("http://www.example.org/");
 
708
        serializeParseAndCompare(doc);
 
709
        child1.setNamespaceURI("http://www.example.org/");
 
710
        serializeParseAndCompare(doc);
 
711
        child2.setNamespaceURI("http://www.example.org/");
 
712
        serializeParseAndCompare(doc);
 
713
        child3.setNamespaceURI("http://www.example.org/");
 
714
        serializeParseAndCompare(doc);
 
715
        child1.setNamespacePrefix("example");
 
716
        serializeParseAndCompare(doc);
 
717
        child2.setNamespacePrefix("perverse");
 
718
        serializeParseAndCompare(doc);    
 
719
        
 
720
    }
 
721
 
 
722
    
 
723
    public void testPrologAndEpilog() 
 
724
      throws IOException, ParsingException { 
 
725
        
 
726
        serializeParseAndCompare(doc);
 
727
 
 
728
        doc.insertChild(new Comment("Hello"), 0);
 
729
        serializeParseAndCompare(doc);    
 
730
        doc.insertChild(new DocType("root"), 0);
 
731
        serializeParseAndCompare(doc);    
 
732
        doc.insertChild(new ProcessingInstruction("test", "some data"), 
 
733
          0);
 
734
        serializeParseAndCompare(doc);    
 
735
        doc.insertChild(new Comment("Goodbye"), 0);
 
736
        serializeParseAndCompare(doc);    
 
737
        doc.insertChild(
 
738
          new ProcessingInstruction("goodbye", "some data"), 0);
 
739
        serializeParseAndCompare(doc);    
 
740
        doc.appendChild(new Comment("Hello"));
 
741
        serializeParseAndCompare(doc);    
 
742
        doc.appendChild(
 
743
          new ProcessingInstruction("test", "some data"));
 
744
        serializeParseAndCompare(doc);    
 
745
        
 
746
    }
 
747
    
 
748
    
 
749
    public void testChangeLineSeparator() throws IOException { 
 
750
        
 
751
        String breaks = 
 
752
          "This\nstring\rcontains\r\nseveral\r\rweird line breaks.";
 
753
        root.appendChild(breaks);
 
754
        root.addAttribute(new Attribute("test", breaks));
 
755
            
 
756
        Serializer serializer = new Serializer(out, "UTF-8");
 
757
        serializer.setLineSeparator("\n");
 
758
        serializer.write(doc);
 
759
        String result = out.toString("UTF-8");
 
760
        assertTrue(result.indexOf('\n') > 0);
 
761
        assertTrue(result + "**\n" + result.indexOf('\r'), 
 
762
          result.indexOf('\r') == -1);
 
763
 
 
764
        out = new ByteArrayOutputStream();
 
765
        serializer = new Serializer(out, "UTF-8");
 
766
        serializer.setLineSeparator("\r");
 
767
        serializer.write(doc);
 
768
        result = out.toString("UTF-8");
 
769
        assertTrue(result.indexOf('\r') > 0);
 
770
        assertTrue(result.indexOf('\n') == -1);
 
771
        
 
772
        out = new ByteArrayOutputStream();
 
773
        serializer = new Serializer(out, "UTF-8");
 
774
        serializer.setLineSeparator("\r\n");
 
775
        serializer.write(doc);
 
776
        result = out.toString("UTF-8");
 
777
        assertTrue(result.indexOf("\r\n") > 0);
 
778
        for (int i = 0; i < result.length(); i++) {
 
779
          int c = result.charAt(i);
 
780
          if (c == '\r') assertTrue(result.charAt(i+1) == '\n');    
 
781
        }     
 
782
        
 
783
    }
 
784
    
 
785
    
 
786
    public void testSettingOutputStreamDoesNotSetLineSeparator() 
 
787
      throws IOException { 
 
788
        
 
789
        root.appendChild("This\rstring");          
 
790
        Serializer serializer = new Serializer(System.out, "UTF-8");
 
791
        
 
792
        serializer.setOutputStream(out);
 
793
        
 
794
        serializer.write(doc);
 
795
        String result = out.toString("UTF-8");
 
796
        assertTrue(result.indexOf("This&#x0D;string") > 0);
 
797
        
 
798
    }
 
799
    
 
800
    
 
801
    public void testSettingOutputStreamDoesNotUnnecessarilyEscapeLineBreaks() 
 
802
      throws IOException { 
 
803
        
 
804
        root.appendChild("This\rstring");          
 
805
        Serializer serializer = new Serializer(System.out, "UTF-8");
 
806
        
 
807
        serializer.setOutputStream(out);
 
808
        serializer.setLineSeparator("\r\n");
 
809
        serializer.write(doc);
 
810
        String result = out.toString("UTF-8");
 
811
        assertTrue(result.indexOf("This\r\nstring") > 0);
 
812
        
 
813
    }
 
814
    
 
815
    
 
816
    public void testDontChangeLineSeparator() throws IOException { 
 
817
        
 
818
        String breaks 
 
819
          = "This\nstring\rcontains\r\rseveral\n\nweird line breaks.";
 
820
        String breaksHalfEscaped 
 
821
          = "This\nstring&#x0D;contains&#x0D;&#x0D;several" +
 
822
            "\n\nweird line breaks.";
 
823
        String breaksEscaped 
 
824
          = "This&#x0A;string&#x0D;contains&#x0D;&#x0D;several" +
 
825
            "&#x0A;&#x0A;weird line breaks.";
 
826
        root.appendChild(breaks);
 
827
            
 
828
        Serializer serializer = new Serializer(out, "UTF-8");
 
829
        serializer.write(doc);
 
830
        String result = out.toString("UTF-8");
 
831
        assertTrue(result.indexOf(breaksHalfEscaped) > 0);
 
832
 
 
833
        root = new Element("root");
 
834
        doc = new Document(root);
 
835
        root.addAttribute(new Attribute("test", breaks));
 
836
            
 
837
        out = new ByteArrayOutputStream();
 
838
        serializer = new Serializer(out, "UTF-8");
 
839
        serializer.write(doc);
 
840
        result = out.toString("UTF-8");
 
841
        assertTrue(result.indexOf(breaksEscaped) > 0);        
 
842
        
 
843
    }
 
844
 
 
845
    
 
846
    public void testPreserveBaseURI() throws IOException {        
 
847
 
 
848
        Serializer serializer = new Serializer(out, "UTF-8");
 
849
        serializer.setPreserveBaseURI(true);
 
850
        serializer.write(doc);
 
851
        String result = out.toString("UTF-8");
 
852
        assertTrue(result.indexOf("<root") > 1);
 
853
        doc.setBaseURI("http://www.example.com/index.xml");
 
854
        serializer.write(doc);
 
855
        result = out.toString("UTF-8");
 
856
        assertTrue(result.indexOf("<root ") > 1);
 
857
        assertTrue(result.indexOf("xml:base=") > 1);
 
858
        assertTrue(
 
859
          result.indexOf("http://www.example.com/index.xml") > 1
 
860
        );
 
861
        
 
862
    } 
 
863
 
 
864
    
 
865
    public void testPreserveBaseURIWithChildren() throws IOException {        
 
866
 
 
867
        String base = "http://www.example.com/index.xml";
 
868
        root.setBaseURI(base);
 
869
        Element child = new Element("child");
 
870
        child.setBaseURI(base);
 
871
        root.appendChild(child);
 
872
        Serializer serializer = new Serializer(out, "UTF-8");
 
873
        serializer.setPreserveBaseURI(true);
 
874
        serializer.write(doc);
 
875
        String result = out.toString("UTF-8");
 
876
        assertEquals("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\r\n"
 
877
          + "<root xml:base=\"" + base + "\"><child/></root>\r\n", result);
 
878
        
 
879
    } 
 
880
 
 
881
    
 
882
    public void testPreserveBaseURIDoesntOverrideXMLBase() 
 
883
      throws IOException { 
 
884
        
 
885
        root.addAttribute(new Attribute("xml:base", 
 
886
          "http://www.w3.org/XML/1998/namespace", 
 
887
          "http://www.cafeconleche.org/"));
 
888
        Serializer serializer = new Serializer(out, "UTF-8");
 
889
        serializer.setPreserveBaseURI(true);
 
890
        serializer.write(doc);
 
891
        String result = out.toString("UTF-8");
 
892
        assertTrue(result.indexOf("<root") > 1);
 
893
        doc.setBaseURI("http://www.example.com/index.xml");
 
894
        serializer.write(doc);
 
895
        result = out.toString("UTF-8");
 
896
        assertTrue(result.indexOf("<root ") > 1);
 
897
        assertTrue(result.indexOf("xml:base=") > 1);
 
898
        assertTrue(result.indexOf("http://www.cafeconleche.org/") > 1);
 
899
        assertEquals(-1, result.indexOf("http://www.example.com/index.xml"));
 
900
        
 
901
    } 
 
902
    
 
903
    
 
904
    public void testSetLineSeparator() {
 
905
        
 
906
        Serializer serializer = new Serializer(System.out);
 
907
        
 
908
        serializer.setLineSeparator("\r");
 
909
        assertEquals("\r", serializer.getLineSeparator());
 
910
        serializer.setLineSeparator("\n");
 
911
        assertEquals("\n", serializer.getLineSeparator());
 
912
        serializer.setLineSeparator("\r\n");
 
913
        assertEquals("\r\n", serializer.getLineSeparator());
 
914
        
 
915
        try {
 
916
            serializer.setLineSeparator("r");
 
917
            fail("Allowed illegal separator character");
 
918
        }
 
919
        catch (IllegalArgumentException success) {
 
920
            assertNotNull(success.getMessage());
 
921
        }
 
922
        
 
923
        try {
 
924
            serializer.setLineSeparator("n");
 
925
            fail("Allowed illegal separator character");
 
926
        }
 
927
        catch (IllegalArgumentException success) {
 
928
            assertNotNull(success.getMessage());
 
929
        }
 
930
        
 
931
        try {
 
932
            serializer.setLineSeparator(" ");
 
933
            fail("Allowed illegal separator character");
 
934
        }
 
935
        catch (IllegalArgumentException success) {
 
936
            assertNotNull(success.getMessage());
 
937
        }
 
938
        
 
939
        try {
 
940
            serializer.setLineSeparator("rn");
 
941
            fail("Allowed illegal separator character");
 
942
        }
 
943
        catch (IllegalArgumentException success) {
 
944
            assertNotNull(success.getMessage());
 
945
        }
 
946
        
 
947
        try {
 
948
            serializer.setLineSeparator("<");
 
949
            fail("Allowed illegal separator character");
 
950
        }
 
951
        catch (IllegalArgumentException success) {
 
952
            assertNotNull(success.getMessage());
 
953
        }
 
954
        
 
955
        try {
 
956
            serializer.setLineSeparator("\u0085");
 
957
            fail("Allowed NEL separator character");
 
958
        }
 
959
        catch (IllegalArgumentException success) {
 
960
            assertNotNull(success.getMessage());
 
961
        }
 
962
        
 
963
    }
 
964
 
 
965
      
 
966
    public void testLowerLimitOfUnicodeInCharacterData() 
 
967
      throws IOException {   
 
968
        
 
969
        root.appendChild("\uD800\uDC00");
 
970
        Serializer serializer = new Serializer(out, "ISO-8859-1");
 
971
        serializer.write(doc);
 
972
        String result = out.toString("ISO-8859-1");
 
973
        assertTrue(result, result.indexOf("&#x10000;") > 12);
 
974
        
 
975
    }
 
976
    
 
977
    
 
978
    public void testUpperLimitOfUnicodeInCharacterData() 
 
979
      throws IOException {  
 
980
        
 
981
        root.appendChild("\uDBFF\uDFFD");
 
982
        Serializer serializer = new Serializer(out, "ISO-8859-1");
 
983
        serializer.write(doc);
 
984
        String result = out.toString("ISO-8859-1");
 
985
        assertTrue(result, result.indexOf("&#x10FFFD;") > 12);
 
986
        
 
987
    }
 
988
      
 
989
    
 
990
    public void testSerializePlane1CharacterInAttributeValue() 
 
991
      throws IOException {        
 
992
        
 
993
        root.addAttribute(new Attribute("test", "\uD834\uDD1E"));
 
994
        Serializer serializer = new Serializer(out, "ISO-8859-1");
 
995
        serializer.write(doc);
 
996
        String result = out.toString("ISO-8859-1");
 
997
        assertTrue(result, result.indexOf("&#x1D11E;") > 12);
 
998
        
 
999
    }
 
1000
    
 
1001
    public void testSerializePlane1CharacterInCharacterData() 
 
1002
      throws IOException {   
 
1003
        
 
1004
        root.appendChild("\uD834\uDD1E");
 
1005
        Serializer serializer = new Serializer(out, "ISO-8859-1");
 
1006
        serializer.write(doc);
 
1007
        String result = out.toString("ISO-8859-1");
 
1008
        assertTrue(result, result.indexOf("&#x1D11E;") > 12);
 
1009
        
 
1010
    }
 
1011
    
 
1012
    
 
1013
    public void testSurrogatePairCountsAsOneCharacterForColumnCount() 
 
1014
      throws IOException {   
 
1015
        
 
1016
        Element root = new Element("r");
 
1017
        root.appendChild("\uD834\uDD1E");
 
1018
        Document doc = new Document(root);
 
1019
        Serializer serializer = new ColumnSerializer(out);
 
1020
        serializer.write(doc);
 
1021
        
 
1022
    }
 
1023
    
 
1024
    
 
1025
    private static class ColumnSerializer extends Serializer {
 
1026
     
 
1027
        
 
1028
        ColumnSerializer(OutputStream out) {
 
1029
            super(out);
 
1030
        }
 
1031
        
 
1032
        
 
1033
        public void write(Document doc) throws IOException {
 
1034
            
 
1035
            for (int i = 0; i < doc.getChildCount(); i++) {
 
1036
                writeChild(doc.getChild(i)); 
 
1037
            }       
 
1038
            super.flush();
 
1039
            assertEquals(8, super.getColumnNumber());
 
1040
            
 
1041
        }   
 
1042
 
 
1043
        
 
1044
    }
 
1045
    
 
1046
    
 
1047
    public void testEscapeAttributeValue() throws IOException {   
 
1048
        
 
1049
        root.addAttribute(new Attribute("test", "\u0110"));
 
1050
        Serializer serializer = new Serializer(out, "ISO-8859-1");
 
1051
        serializer.write(doc);
 
1052
        String result = out.toString("ISO-8859-1");
 
1053
        assertTrue(result, result.indexOf("&#x110;") > 5);
 
1054
        
 
1055
    }   
 
1056
 
 
1057
    
 
1058
    public void testLineFeedInAttributeValueWithDefaultOptions() 
 
1059
      throws IOException, ParsingException {   
 
1060
        
 
1061
        root.addAttribute(new Attribute("test", "\n"));
 
1062
        Serializer serializer = new Serializer(out, "ISO-8859-1");
 
1063
        serializer.write(doc);
 
1064
        out.close();
 
1065
        InputStream in = new ByteArrayInputStream(out.toByteArray());
 
1066
        Document reparsed = parser.build(in);
 
1067
        assertEquals(doc, reparsed);
 
1068
        
 
1069
    }
 
1070
    
 
1071
    
 
1072
    public void testCarriageReturnInAttributeValueWithDefaultOptions()
 
1073
      throws IOException, ParsingException {  
 
1074
        
 
1075
        root.addAttribute(new Attribute("test", "\r"));
 
1076
        Serializer serializer = new Serializer(out, "ISO-8859-1");
 
1077
        serializer.write(doc);
 
1078
        out.close();
 
1079
        InputStream in = new ByteArrayInputStream(out.toByteArray());
 
1080
        Document reparsed = parser.build(in);
 
1081
        assertEquals(doc, reparsed);
 
1082
        
 
1083
    }
 
1084
    
 
1085
    
 
1086
    public void testCarriageReturnInTextWithDefaultOptions() 
 
1087
      throws IOException, ParsingException { 
 
1088
        
 
1089
        root.appendChild("\r");
 
1090
        Serializer serializer = new Serializer(out, "ISO-8859-1");
 
1091
        serializer.write(doc);
 
1092
        out.close();
 
1093
        InputStream in = new ByteArrayInputStream(out.toByteArray());
 
1094
        Document reparsed = parser.build(in);
 
1095
        assertEquals(doc, reparsed);
 
1096
        
 
1097
    }
 
1098
    
 
1099
    
 
1100
    public void testTabInAttributeValueWithDefaultOptions() 
 
1101
      throws IOException, ParsingException { 
 
1102
        
 
1103
        root.addAttribute(new Attribute("test", "\t"));
 
1104
        Serializer serializer = new Serializer(out, "ISO-8859-1");
 
1105
        serializer.write(doc);
 
1106
        out.close();
 
1107
        InputStream in = new ByteArrayInputStream(out.toByteArray());
 
1108
        Document reparsed = parser.build(in);
 
1109
        assertEquals(doc, reparsed);
 
1110
        
 
1111
    }
 
1112
    
 
1113
    
 
1114
    /**
 
1115
     * <p>
 
1116
     *   Test that tabs in attribute values are escaped even when
 
1117
     *   a line separator is set.
 
1118
     * </p>
 
1119
     */
 
1120
    public void testTabInAttributeValueWithLineSeparator() 
 
1121
      throws IOException, ParsingException {   
 
1122
        
 
1123
        root.addAttribute(new Attribute("test", "\t"));
 
1124
        Serializer serializer = new Serializer(out, "ISO-8859-1");
 
1125
        serializer.setLineSeparator("\r");
 
1126
        serializer.write(doc);
 
1127
        out.close();
 
1128
        InputStream in = new ByteArrayInputStream(out.toByteArray());
 
1129
        Document reparsed = parser.build(in);
 
1130
        assertEquals(doc, reparsed);
 
1131
        
 
1132
    }
 
1133
    
 
1134
    
 
1135
    
 
1136
    /**
 
1137
     * <p>
 
1138
     *   Test that tabs in attribute values are not escaped when 
 
1139
     *   indenting.
 
1140
     * </p>
 
1141
     */
 
1142
    public void testTabInAttributeValueWithIndenting() 
 
1143
      throws IOException, ParsingException { 
 
1144
      
 
1145
        root.addAttribute(new Attribute("test", "\t"));
 
1146
        Serializer serializer = new Serializer(out, "ISO-8859-1");
 
1147
        serializer.setIndent(2);
 
1148
        serializer.write(doc);
 
1149
        out.close();
 
1150
        InputStream in = new ByteArrayInputStream(out.toByteArray());
 
1151
        Document reparsed = parser.build(in);
 
1152
        String result = reparsed.getRootElement().getAttributeValue("test");
 
1153
        assertEquals("Tab not normalized to space", " ", result);
 
1154
        
 
1155
    }
 
1156
 
 
1157
    
 
1158
    public void testCRLFInAttributeValueWithLineSeparatorCR() 
 
1159
      throws IOException, ParsingException {   
 
1160
        
 
1161
        root.addAttribute(new Attribute("test", "\r\n"));
 
1162
        Serializer serializer = new Serializer(out, "ISO-8859-1");
 
1163
        serializer.setLineSeparator("\r");
 
1164
        serializer.write(doc);
 
1165
        out.close();
 
1166
        InputStream in = new ByteArrayInputStream(out.toByteArray());
 
1167
        Document reparsed = parser.build(in);
 
1168
        String result = reparsed.getRootElement().getAttributeValue("test");
 
1169
        assertEquals("\r", result);
 
1170
        
 
1171
    }
 
1172
    
 
1173
    
 
1174
    public void testCRLFInAttributeValueWithLineSeparatorLF() 
 
1175
      throws IOException, ParsingException {  
 
1176
        
 
1177
        root.addAttribute(new Attribute("test", "\r\n"));
 
1178
        Serializer serializer = new Serializer(out, "ISO-8859-1");
 
1179
        serializer.setLineSeparator("\n");
 
1180
        serializer.write(doc);
 
1181
        out.close();
 
1182
        InputStream in = new ByteArrayInputStream(out.toByteArray());
 
1183
        Document reparsed = parser.build(in);
 
1184
        String result = reparsed.getRootElement().getAttributeValue("test");
 
1185
        assertEquals("\n", result);
 
1186
        
 
1187
    }
 
1188
    
 
1189
    public void testLFInAttributeValueWithLineSeparatorCRLF() 
 
1190
      throws IOException, ParsingException {  
 
1191
        
 
1192
        root.addAttribute(new Attribute("test", "\n"));
 
1193
        Serializer serializer = new Serializer(out, "ISO-8859-1");
 
1194
        serializer.setLineSeparator("\r\n");
 
1195
        serializer.write(doc);
 
1196
        out.close();
 
1197
        InputStream in = new ByteArrayInputStream(out.toByteArray());
 
1198
        Document reparsed = parser.build(in);
 
1199
        String result = reparsed.getRootElement().getAttributeValue("test");
 
1200
        assertEquals("\r\n", result);
 
1201
        
 
1202
    }
 
1203
 
 
1204
    
 
1205
    public void testNotEscapeLinefeedInTextContent() 
 
1206
      throws IOException { 
 
1207
 
 
1208
        root.appendChild("\r\n");
 
1209
        Serializer serializer = new Serializer(out, "ISO-8859-1");
 
1210
        serializer.write(doc);
 
1211
        out.close();
 
1212
        String result = new String(out.toByteArray(), "ISO-8859-1");
 
1213
        assertEquals(
 
1214
          "<?xml version=\"1.0\" encoding=\"ISO-8859-1\"?>\r\n<root>&#x0D;\n</root>\r\n", 
 
1215
          result
 
1216
        );
 
1217
        
 
1218
    }
 
1219
    
 
1220
    
 
1221
    public void testCRLFInAttributeValue() 
 
1222
      throws IOException, ParsingException {  
 
1223
 
 
1224
        root.addAttribute(new Attribute("test", "a\r\na"));
 
1225
        Serializer serializer = new Serializer(out, "ISO-8859-1");
 
1226
        serializer.write(doc);
 
1227
        out.close();
 
1228
        InputStream in = new ByteArrayInputStream(out.toByteArray());
 
1229
        Document reparsed = parser.build(in);
 
1230
        String result = reparsed.getRootElement().getAttributeValue("test");
 
1231
        assertEquals("CRLF not escaped", "a\r\na", result);
 
1232
        
 
1233
    }
 
1234
    
 
1235
    
 
1236
    public void testPunctuationInAttributeValueNonUnicode() 
 
1237
      throws IOException, ParsingException {  
 
1238
 
 
1239
        root.addAttribute(new Attribute("test", "$()*+,="));
 
1240
        Serializer serializer = new Serializer(out, "ISO-8859-1");
 
1241
        serializer.write(doc);
 
1242
        out.close();
 
1243
        InputStream in = new ByteArrayInputStream(out.toByteArray());
 
1244
        Document reparsed = parser.build(in);
 
1245
        String result = reparsed.getRootElement().getAttributeValue("test");
 
1246
        assertEquals("$()*+,=", result);
 
1247
        
 
1248
    }
 
1249
    
 
1250
    
 
1251
    public void testCRLFInAttributeValueWithIndenting() 
 
1252
      throws IOException, ParsingException {  
 
1253
 
 
1254
        root.addAttribute(new Attribute("test", "\r\n"));
 
1255
        Serializer serializer = new Serializer(out, "ISO-8859-1");
 
1256
        serializer.setIndent(2);
 
1257
        serializer.write(doc);
 
1258
        out.close();
 
1259
        InputStream in = new ByteArrayInputStream(out.toByteArray());
 
1260
        Document reparsed = parser.build(in);
 
1261
        String result = reparsed.getRootElement().getAttributeValue("test");
 
1262
        assertEquals("CRLF unnecessarily escaped", -1, result.indexOf('\r'));
 
1263
        // Need to figure out the serializer should indent this 
 
1264
        // and write a unit test for that too.
 
1265
        
 
1266
    }
 
1267
    
 
1268
    
 
1269
    public void testCRLFInAttributeValueWithMaxLength() 
 
1270
      throws IOException, ParsingException { 
 
1271
 
 
1272
        root.addAttribute(new Attribute("test", "\r\n"));
 
1273
 
 
1274
        Serializer serializer = new Serializer(out, "ISO-8859-1");
 
1275
        serializer.setMaxLength(64);
 
1276
        serializer.write(doc);
 
1277
        out.close();
 
1278
        InputStream in = new ByteArrayInputStream(out.toByteArray());
 
1279
        Document reparsed = parser.build(in);
 
1280
        String result = reparsed.getRootElement().getAttributeValue("test");
 
1281
        assertEquals("CRLF unnecessarily escaped", " ", result);
 
1282
        
 
1283
    }
 
1284
 
 
1285
    
 
1286
    public void testCRInTextValueWithLineSeparator() 
 
1287
      throws IOException, ParsingException {
 
1288
 
 
1289
        root.appendChild("\r");
 
1290
        Serializer serializer = new Serializer(out, "ISO-8859-1");
 
1291
        serializer.setLineSeparator("\n");
 
1292
        serializer.write(doc);
 
1293
        out.close();
 
1294
        InputStream in = new ByteArrayInputStream(out.toByteArray());
 
1295
        Document reparsed = parser.build(in);
 
1296
        String result = reparsed.getValue();
 
1297
        assertEquals("\n", result);
 
1298
        
 
1299
    } 
 
1300
    
 
1301
    
 
1302
    public void testCRLFInTextValueWithLineSeparator() 
 
1303
      throws IOException, ParsingException {   
 
1304
        
 
1305
        root.appendChild("test \r\n test");
 
1306
        Serializer serializer = new Serializer(out, "ISO-8859-1");
 
1307
        serializer.setLineSeparator("\n");
 
1308
        serializer.write(doc);
 
1309
        out.close();
 
1310
        InputStream in = new ByteArrayInputStream(out.toByteArray());
 
1311
        Document reparsed = parser.build(in);
 
1312
        String result = reparsed.getValue();
 
1313
        assertEquals("test \n test", result);
 
1314
        
 
1315
    } 
 
1316
    
 
1317
    
 
1318
    public void testCRInTextWithIndenting() 
 
1319
      throws IOException, ParsingException {  
 
1320
        
 
1321
        root.appendChild("\r");
 
1322
        Serializer serializer = new Serializer(out, "ISO-8859-1");
 
1323
        serializer.setIndent(2);
 
1324
        serializer.write(doc);
 
1325
        out.close();
 
1326
        InputStream in = new ByteArrayInputStream(out.toByteArray());
 
1327
        Document reparsed = parser.build(in);
 
1328
        String result = reparsed.getValue();
 
1329
        assertEquals("Carriage return unnecessarily escaped", 
 
1330
          -1, result.indexOf('\r'));
 
1331
        
 
1332
        // really need to think about what the serializer should output here
 
1333
        // and write a test case for that; this is not ideal output
 
1334
        
 
1335
    }
 
1336
    
 
1337
    
 
1338
    public void testCRInTextWithMaxLength() 
 
1339
      throws IOException, ParsingException {        
 
1340
 
 
1341
        root.appendChild("\r");
 
1342
        Serializer serializer = new Serializer(out, "ISO-8859-1");
 
1343
        serializer.setMaxLength(64);
 
1344
        serializer.write(doc);
 
1345
        out.close();
 
1346
        InputStream in = new ByteArrayInputStream(out.toByteArray());
 
1347
        Document reparsed = parser.build(in);
 
1348
        String result = reparsed.getValue();
 
1349
        assertEquals("Carriage return unnecessarily escaped", "\n", result);
 
1350
        
 
1351
    }
 
1352
    
 
1353
    
 
1354
    public void testTabInAttributeValueWithMaxLength() 
 
1355
      throws IOException, ParsingException {  
 
1356
        
 
1357
        root.addAttribute(new Attribute("test", "\t"));
 
1358
        Serializer serializer = new Serializer(out, "ISO-8859-1");
 
1359
        serializer.setMaxLength(64);
 
1360
        serializer.write(doc);
 
1361
        out.close();
 
1362
        InputStream in = new ByteArrayInputStream(out.toByteArray());
 
1363
        Document reparsed = parser.build(in);
 
1364
        String result = reparsed.getRootElement().getAttributeValue("test");
 
1365
        assertEquals("Tab not normalized to space", " ", result);
 
1366
        
 
1367
    }
 
1368
 
 
1369
    
 
1370
    /**
 
1371
     * <p>
 
1372
     *   Test that tabs in attribute values are escaped when 
 
1373
     *   max length is set to 0
 
1374
     * </p>
 
1375
     */
 
1376
    public void testTabInAttributeValueWithZeroMaxLength() 
 
1377
      throws IOException, ParsingException {  
 
1378
 
 
1379
        root.addAttribute(new Attribute("test", "\t"));
 
1380
        Serializer serializer = new Serializer(out, "ISO-8859-1");
 
1381
        serializer.setMaxLength(0);
 
1382
        serializer.write(doc);
 
1383
        out.close();
 
1384
        InputStream in = new ByteArrayInputStream(out.toByteArray());
 
1385
        Document reparsed = parser.build(in);
 
1386
        String result = reparsed.getRootElement().getAttributeValue("test");
 
1387
        assertEquals("Tab not normalized to space", "\t", result);
 
1388
        
 
1389
    }
 
1390
    
 
1391
 
 
1392
    public void testSetMaxLength() {
 
1393
        Serializer serializer = new Serializer(System.out);
 
1394
        
 
1395
        serializer.setMaxLength(72);
 
1396
        assertEquals(72, serializer.getMaxLength());
 
1397
        serializer.setMaxLength(720);
 
1398
        assertEquals(720, serializer.getMaxLength());
 
1399
        serializer.setMaxLength(1);
 
1400
        assertEquals(1, serializer.getMaxLength());
 
1401
        serializer.setMaxLength(0);
 
1402
        assertEquals(0, serializer.getMaxLength());
 
1403
        serializer.setMaxLength(-1);
 
1404
        assertEquals(0, serializer.getMaxLength());
 
1405
        
 
1406
    }
 
1407
 
 
1408
    
 
1409
    public void testSetIndent() {
 
1410
        
 
1411
        Serializer serializer = new Serializer(System.out);
 
1412
        serializer.setIndent(72);
 
1413
        assertEquals(72, serializer.getIndent());
 
1414
        serializer.setIndent(720);
 
1415
        assertEquals(720, serializer.getIndent());
 
1416
        serializer.setIndent(1);
 
1417
        assertEquals(1, serializer.getIndent());
 
1418
        serializer.setIndent(0);
 
1419
        assertEquals(0, serializer.getIndent());
 
1420
        try {
 
1421
            serializer.setIndent(-1);
 
1422
            fail("Allowed negative indent");
 
1423
        }
 
1424
        catch (IllegalArgumentException success) {
 
1425
            assertNotNull(success.getMessage());
 
1426
        }
 
1427
        
 
1428
    }
 
1429
 
 
1430
    
 
1431
    public void testReallyBigIndent() throws ValidityException, ParsingException, IOException {
 
1432
        
 
1433
        ByteArrayOutputStream out = new ByteArrayOutputStream();
 
1434
        Serializer serializer = new Serializer(out);
 
1435
        serializer.setIndent(100);
 
1436
        StringBuffer spaces = new StringBuffer(400);
 
1437
        for (int i = 0; i < 400; i++) spaces.append(' ');
 
1438
        String _400 = spaces.toString();
 
1439
        String _300 = spaces.substring(0, 300);
 
1440
        String _200 = spaces.substring(0, 200);
 
1441
        String _100 = spaces.substring(0, 100);
 
1442
        
 
1443
        String original ="<a><b><c><d><e>Hello</e></d></c></b></a>";
 
1444
        Document doc = parser.build(original, null);
 
1445
        serializer.write(doc);
 
1446
        String expected ="<?xml version=\"1.0\" encoding=\"UTF-8\"?>\r\n<a>\r\n"
 
1447
          + _100 + "<b>\r\n" + _200 + "<c>\r\n" + _300 + "<d>\r\n" + _400
 
1448
          + "<e>Hello</e>\r\n" + _300 + "</d>\r\n" + _200 + "</c>\r\n"
 
1449
          + _100 + "</b>\r\n</a>\r\n";
 
1450
        String result = new String(out.toByteArray(), "UTF-8");
 
1451
        assertEquals(expected, result);
 
1452
        
 
1453
    }
 
1454
 
 
1455
    
 
1456
    public void testLineLength() throws IOException {
 
1457
          
 
1458
        int length = 40;        
 
1459
        String data = "This is a really long string that does not "
 
1460
         + "contain any line breaks.  However, there is lots of " 
 
1461
         + "white space so there shouldn't be any trouble wrapping it"
 
1462
         + " into 40 characters or less per line. ";
 
1463
        root.appendChild(data);
 
1464
        Serializer serializer = new Serializer(out, "UTF-8");
 
1465
        serializer.setMaxLength(length);
 
1466
        serializer.write(doc);
 
1467
        String result = out.toString("UTF-8");
 
1468
        
 
1469
        BufferedReader reader 
 
1470
          = new BufferedReader(new StringReader(result)); 
 
1471
        for (String line = reader.readLine(); 
 
1472
             line != null;
 
1473
             line = reader.readLine()) {
 
1474
            assertTrue(line.length() + ": " + line, 
 
1475
              line.length() <= length);    
 
1476
        }
 
1477
        
 
1478
    }
 
1479
 
 
1480
    
 
1481
    public void testLineLengthWithSetOutputStream() 
 
1482
      throws IOException {
 
1483
          
 
1484
        int length = 40;        
 
1485
        String data = "This is a really long string that does not "
 
1486
         + "contain any line breaks.  However, there is lots of " 
 
1487
         + "white space so there shouldn't be any trouble wrapping it"
 
1488
         + " into 40 characters or less per line. ";
 
1489
        root.appendChild(data);
 
1490
        Serializer serializer = new Serializer(new ByteArrayOutputStream(), "UTF-8");
 
1491
        serializer.setMaxLength(length);
 
1492
        serializer.write(doc);
 
1493
        serializer.setOutputStream(out);
 
1494
        serializer.write(doc);
 
1495
        String result = out.toString("UTF-8");
 
1496
        
 
1497
        BufferedReader reader 
 
1498
          = new BufferedReader(new StringReader(result)); 
 
1499
        for (String line = reader.readLine(); 
 
1500
             line != null;
 
1501
             line = reader.readLine()) {
 
1502
            assertTrue(line.length() + ": " + line, 
 
1503
              line.length() <= length);    
 
1504
        }
 
1505
        
 
1506
    }   
 
1507
    
 
1508
    
 
1509
    public void testPrettyXML() throws IOException {
 
1510
        
 
1511
        Element items = new Element("itemSet");
 
1512
        items.appendChild(new Element("item1"));
 
1513
        items.appendChild(new Element("item2"));
 
1514
        Document doc = new Document(items);
 
1515
        Serializer serializer = new Serializer(out);
 
1516
        serializer.setIndent(4);
 
1517
        serializer.write(doc);
 
1518
        serializer.flush();
 
1519
        out.close();
 
1520
        String result = new String(out.toByteArray(), "UTF-8");
 
1521
        assertEquals(
 
1522
          "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\r\n"
 
1523
          + "<itemSet>\r\n    <item1/>\r\n    <item2/>\r\n"
 
1524
          + "</itemSet>\r\n", 
 
1525
          result
 
1526
        );
 
1527
        
 
1528
    }
 
1529
 
 
1530
    
 
1531
    public void testIndentAndBreakBeforeComment() throws IOException {
 
1532
        
 
1533
        Element items = new Element("itemSet");
 
1534
        items.appendChild(new Comment("item1"));
 
1535
        Document doc = new Document(items);
 
1536
        Serializer serializer = new Serializer(out);
 
1537
        serializer.setIndent(4);
 
1538
        serializer.write(doc);
 
1539
        serializer.flush();
 
1540
        out.close();
 
1541
        String result = new String(out.toByteArray(), "UTF-8");
 
1542
        assertEquals(
 
1543
          "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\r\n"
 
1544
          + "<itemSet>\r\n    <!--item1-->\r\n"
 
1545
          + "</itemSet>\r\n", 
 
1546
          result
 
1547
        );
 
1548
        
 
1549
    }
 
1550
    
 
1551
    
 
1552
    public void testOnlyXMLSpaceCountsAsBoundaryWhiteSpace() 
 
1553
      throws IOException {
 
1554
        
 
1555
        String emSpace = "\u2003";
 
1556
        Element items = new Element("itemSet");
 
1557
        items.appendChild(emSpace);
 
1558
        items.appendChild(new Element("a"));
 
1559
 
 
1560
        Document doc = new Document(items);
 
1561
        Serializer serializer = new Serializer(out);
 
1562
        serializer.setIndent(4);
 
1563
        serializer.write(doc);
 
1564
        serializer.flush();
 
1565
        out.close();
 
1566
        String result = new String(out.toByteArray(), "UTF-8");
 
1567
        assertEquals(
 
1568
          "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\r\n"
 
1569
          + "<itemSet>\u2003\r\n    <a/>\r\n</itemSet>\r\n", 
 
1570
          result
 
1571
        );
 
1572
        
 
1573
    }
 
1574
    
 
1575
    
 
1576
    public void testWhiteSpaceBetweenCommentsIsBoundaryWhiteSpace() 
 
1577
      throws IOException {
 
1578
        
 
1579
        Element items = new Element("itemSet");
 
1580
        items.appendChild(new Comment("item1"));
 
1581
        items.appendChild("      \r\n              ");
 
1582
        items.appendChild(new Comment("item2"));
 
1583
        Document doc = new Document(items);
 
1584
        Serializer serializer = new Serializer(out);
 
1585
        serializer.setIndent(4);
 
1586
        serializer.write(doc);
 
1587
        serializer.flush();
 
1588
        out.close();
 
1589
        String result = new String(out.toByteArray(), "UTF-8");
 
1590
        assertEquals(
 
1591
          "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\r\n"
 
1592
          + "<itemSet>\r\n    <!--item1-->\r\n    <!--item2-->\r\n"
 
1593
          + "</itemSet>\r\n", 
 
1594
          result
 
1595
        );
 
1596
        
 
1597
    }
 
1598
    
 
1599
    
 
1600
    public void testWhiteSpaceBeforeCommentIsBoundaryWhiteSpace() 
 
1601
      throws IOException {
 
1602
        
 
1603
        Element items = new Element("itemSet");
 
1604
        items.appendChild("      \r\n              ");
 
1605
        items.appendChild(new Comment("item1"));
 
1606
        items.appendChild(new Comment("item2"));
 
1607
        Document doc = new Document(items);
 
1608
        Serializer serializer = new Serializer(out);
 
1609
        serializer.setIndent(4);
 
1610
        serializer.write(doc);
 
1611
        serializer.flush();
 
1612
        out.close();
 
1613
        String result = new String(out.toByteArray(), "UTF-8");
 
1614
        assertEquals(
 
1615
          "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\r\n"
 
1616
          + "<itemSet>\r\n    <!--item1-->\r\n    <!--item2-->\r\n"
 
1617
          + "</itemSet>\r\n", 
 
1618
          result
 
1619
        );
 
1620
        
 
1621
    }
 
1622
    
 
1623
    
 
1624
    public void testWhiteSpaceAfterCommentsIsBoundaryWhiteSpace() 
 
1625
      throws IOException {
 
1626
        
 
1627
        Element items = new Element("itemSet");
 
1628
        items.appendChild(new Comment("item1"));
 
1629
        items.appendChild(new Comment("item2"));
 
1630
        items.appendChild("      \r\n              ");
 
1631
        Document doc = new Document(items);
 
1632
        Serializer serializer = new Serializer(out);
 
1633
        serializer.setIndent(4);
 
1634
        serializer.write(doc);
 
1635
        serializer.flush();
 
1636
        out.close();
 
1637
        String result = new String(out.toByteArray(), "UTF-8");
 
1638
        assertEquals(
 
1639
          "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\r\n"
 
1640
          + "<itemSet>\r\n    <!--item1-->\r\n    <!--item2-->\r\n"
 
1641
          + "</itemSet>\r\n", 
 
1642
          result
 
1643
        );
 
1644
        
 
1645
    }
 
1646
    
 
1647
    
 
1648
    public void testIndentAndBreakBeforeProcessingInstruction() 
 
1649
      throws IOException {
 
1650
        
 
1651
        Element items = new Element("itemSet");
 
1652
        items.appendChild(new ProcessingInstruction("target", "value"));
 
1653
        Document doc = new Document(items);
 
1654
        Serializer serializer = new Serializer(out);
 
1655
        serializer.setIndent(4);
 
1656
        serializer.write(doc);
 
1657
        serializer.flush();
 
1658
        out.close();
 
1659
        String result = new String(out.toByteArray(), "UTF-8");
 
1660
        assertEquals(
 
1661
          "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\r\n"
 
1662
          + "<itemSet>\r\n    <?target value?>\r\n"
 
1663
          + "</itemSet>\r\n", 
 
1664
          result
 
1665
        );
 
1666
        
 
1667
    }
 
1668
    
 
1669
    
 
1670
    public void testDontBreakLineInElementWithSimpleContent() 
 
1671
      throws IOException {
 
1672
        
 
1673
        Element items = new Element("itemSet");
 
1674
        Element item1 = new Element("item1");
 
1675
        items.appendChild(item1);
 
1676
        item1.appendChild("content");
 
1677
        Document doc = new Document(items);
 
1678
        Serializer serializer = new Serializer(out);
 
1679
        serializer.setIndent(4);
 
1680
        serializer.write(doc);
 
1681
        serializer.flush();
 
1682
        out.close();
 
1683
        String result = new String(out.toByteArray(), "UTF-8");
 
1684
        assertEquals(
 
1685
          "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\r\n"
 
1686
          + "<itemSet>\r\n    <item1>content</item1>\r\n"
 
1687
          + "</itemSet>\r\n", 
 
1688
          result
 
1689
        );
 
1690
        
 
1691
    }
 
1692
    
 
1693
    
 
1694
    public void testPrettyXMLWithSetOutputStream() throws IOException {
 
1695
        
 
1696
        Element items = new Element("itemSet");
 
1697
        items.appendChild(new Element("item1"));
 
1698
        items.appendChild(new Element("item2"));
 
1699
        Document doc = new Document(items);
 
1700
        Serializer serializer = new Serializer(new ByteArrayOutputStream());
 
1701
        serializer.setIndent(4);
 
1702
        serializer.setLineSeparator("\n");
 
1703
        serializer.write(doc);
 
1704
        serializer.setOutputStream(out);
 
1705
        serializer.write(doc);
 
1706
        serializer.flush();
 
1707
        out.close();
 
1708
        String result = new String(out.toByteArray(), "UTF-8");
 
1709
        assertEquals(
 
1710
          "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
 
1711
          + "<itemSet>\n    <item1/>\n    <item2/>\n"
 
1712
          + "</itemSet>\n", 
 
1713
          result
 
1714
        );
 
1715
        
 
1716
    }
 
1717
    
 
1718
    
 
1719
    public void testAmpersandAndLessThanInText() throws IOException {
 
1720
        
 
1721
        root.appendChild("data<data&data");
 
1722
        Serializer serializer = new Serializer(out);
 
1723
        serializer.write(doc);
 
1724
        serializer.flush();
 
1725
        out.close();
 
1726
        String result = new String(out.toByteArray(), "UTF-8");
 
1727
        assertEquals(
 
1728
          "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\r\n"
 
1729
          + "<root>data&lt;data&amp;data"
 
1730
          + "</root>\r\n", 
 
1731
          result
 
1732
        );
 
1733
        
 
1734
    }
 
1735
 
 
1736
    
 
1737
    public void testAmpersandAndAngleBracketsInAttributeValue() 
 
1738
      throws IOException {
 
1739
        
 
1740
        root.addAttribute(new Attribute("b", "data<data>data&"));
 
1741
        Serializer serializer = new Serializer(out);
 
1742
        serializer.write(doc);
 
1743
        serializer.flush();
 
1744
        out.close();
 
1745
        String result = new String(out.toByteArray(), "UTF-8");
 
1746
        assertEquals(
 
1747
          "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\r\n"
 
1748
          + "<root b=\"data&lt;data&gt;data&amp;\"/>\r\n", 
 
1749
          result
 
1750
        );
 
1751
        
 
1752
    }
 
1753
    
 
1754
    
 
1755
    public void testSetNFC() {
 
1756
        
 
1757
        Serializer serializer = new Serializer(System.out);
 
1758
        assertFalse(serializer.getUnicodeNormalizationFormC());
 
1759
        serializer.setUnicodeNormalizationFormC(true);
 
1760
        assertTrue(serializer.getUnicodeNormalizationFormC());
 
1761
        
 
1762
    }
 
1763
 
 
1764
    
 
1765
    public void testNFCInElementContent() throws IOException {
 
1766
        
 
1767
        Element root = new Element("a");
 
1768
        root.appendChild("c\u0327"); // c with combining cedilla
 
1769
        Document doc = new Document(root);
 
1770
        Serializer serializer = new Serializer(out);
 
1771
        serializer.setUnicodeNormalizationFormC(true);
 
1772
        serializer.write(doc);
 
1773
        serializer.flush();
 
1774
        out.close();
 
1775
        String result = new String(out.toByteArray(), "UTF-8");
 
1776
        assertEquals(
 
1777
          "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\r\n"
 
1778
          + "<a>\u00E7</a>\r\n", 
 
1779
          result
 
1780
        ); 
 
1781
        
 
1782
    }
 
1783
 
 
1784
    
 
1785
    public void testNFCInConsecutiveTextNodes() throws IOException {
 
1786
        
 
1787
        Element root = new Element("a");
 
1788
        root.appendChild("c"); 
 
1789
        root.appendChild("\u0327"); // combining cedilla
 
1790
        Document doc = new Document(root);
 
1791
        Serializer serializer = new Serializer(out);
 
1792
        serializer.setUnicodeNormalizationFormC(true);
 
1793
        serializer.write(doc);
 
1794
        serializer.flush();
 
1795
        out.close();
 
1796
        String result = new String(out.toByteArray(), "UTF-8");
 
1797
        assertEquals(
 
1798
          "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\r\n"
 
1799
          + "<a>\u00E7</a>\r\n", 
 
1800
          result
 
1801
        ); 
 
1802
        
 
1803
    }
 
1804
 
 
1805
    
 
1806
    public void testNoNFCByDefault() throws IOException {
 
1807
        
 
1808
        Element root = new Element("c\u0327");
 
1809
        root.appendChild("c\u0327"); // c with combining cedilla
 
1810
        Document doc = new Document(root);
 
1811
        Serializer serializer = new Serializer(out);
 
1812
        serializer.write(doc);
 
1813
        serializer.flush();
 
1814
        out.close();
 
1815
        String result = new String(out.toByteArray(), "UTF-8");
 
1816
        assertEquals(
 
1817
          "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\r\n"
 
1818
          + "<c\u0327>c\u0327</c\u0327>\r\n", 
 
1819
          result
 
1820
        );  
 
1821
        
 
1822
    }
 
1823
 
 
1824
 
 
1825
    public void testUnicodeNFCTestSuite() 
 
1826
      throws ParsingException, IOException {
 
1827
        
 
1828
        Builder builder = new Builder();
 
1829
        Document doc = builder.build("data/nfctests.xml");
 
1830
        Elements tests = doc.getRootElement().getChildElements("test");
 
1831
        int size = tests.size();
 
1832
        for (int i = 0; i < size; i++) {
 
1833
            // System.out.println(i);
 
1834
            Element test = tests.get(i);
 
1835
            test.detach();
 
1836
            Document testdoc = new Document(test);
 
1837
            ByteArrayOutputStream out = new ByteArrayOutputStream();
 
1838
            Serializer serializer = new Serializer(out);
 
1839
            serializer.setUnicodeNormalizationFormC(true);
 
1840
            serializer.write(testdoc);
 
1841
            serializer.flush();
 
1842
            String result = new String(out.toByteArray(), "UTF-8");
 
1843
            Document resultDoc = builder.build(result, null);
 
1844
            Element root = resultDoc.getRootElement();
 
1845
            String c1 = root.getAttributeValue("c1");
 
1846
            String c2 = root.getAttributeValue("c2");
 
1847
            String c3 = root.getAttributeValue("c3");
 
1848
            String c4 = root.getAttributeValue("c4");
 
1849
            String c5 = root.getAttributeValue("c5");
 
1850
            /* String v1 = root.getAttributeValue("v1");
 
1851
            String v2 = root.getAttributeValue("v2");
 
1852
            String v3 = root.getAttributeValue("v3");
 
1853
            String v4 = root.getAttributeValue("v4");
 
1854
            String v5 = root.getAttributeValue("v5"); */
 
1855
            
 
1856
            assertEquals(root.getValue(), c1, c2);
 
1857
            assertEquals(c2, c3);
 
1858
            // I'm not sure the v's are correct past the BMP
 
1859
            //assertEquals(root.getValue(), c1, v1);
 
1860
            // assertEquals(c1, v2);
 
1861
            // assertEquals(c1, v3);
 
1862
            
 
1863
            assertEquals(c4, c5);
 
1864
            // assertEquals(c4, v4);
 
1865
            // assertEquals(c4, v5);
 
1866
            
 
1867
        }
 
1868
        
 
1869
    }
 
1870
 
 
1871
    
 
1872
    public void testNFCInAttribute() throws IOException {
 
1873
        
 
1874
        root.addAttribute(new Attribute("c\u0327", "c\u0327")); // c with combining cedilla
 
1875
        Serializer serializer = new Serializer(out);
 
1876
        serializer.setUnicodeNormalizationFormC(true);
 
1877
        serializer.write(doc);
 
1878
        serializer.flush();
 
1879
        out.close();
 
1880
        String result = new String(out.toByteArray(), "UTF-8");
 
1881
        assertEquals(
 
1882
          "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\r\n"
 
1883
          + "<root \u00E7=\"\u00E7\"/>\r\n", 
 
1884
          result
 
1885
        );  
 
1886
        
 
1887
    }
 
1888
 
 
1889
    
 
1890
    public void testNFCInElementName() throws IOException {
 
1891
        
 
1892
        Element root = new Element("c\u0327"); // c with combining cedilla
 
1893
        Document doc = new Document(root);
 
1894
        Serializer serializer = new Serializer(out);
 
1895
        serializer.setUnicodeNormalizationFormC(true);
 
1896
        serializer.write(doc);
 
1897
        serializer.flush();
 
1898
        out.close();
 
1899
        String result = new String(out.toByteArray(), "UTF-8");
 
1900
        assertEquals(
 
1901
          "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\r\n"
 
1902
          + "<\u00E7/>\r\n", 
 
1903
          result
 
1904
        );   
 
1905
        
 
1906
    }
 
1907
 
 
1908
    
 
1909
    public void testNFCInComment() throws IOException {
 
1910
        
 
1911
        Element root = new Element("a"); 
 
1912
        Document doc = new Document(root);
 
1913
        doc.insertChild(new Comment("c\u0327hat"), 0); // c with combining cedilla
 
1914
        Serializer serializer = new Serializer(out);
 
1915
        serializer.setUnicodeNormalizationFormC(true);
 
1916
        serializer.write(doc);
 
1917
        serializer.flush();
 
1918
        out.close();
 
1919
        String result = new String(out.toByteArray(), "UTF-8");
 
1920
        assertEquals(
 
1921
          "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\r\n"
 
1922
          + "<!--\u00E7hat-->\r\n"
 
1923
          + "<a/>\r\n", 
 
1924
          result
 
1925
        );   
 
1926
        
 
1927
    }
 
1928
 
 
1929
    
 
1930
    public void testNFCInProcessingInstruction() throws IOException {
 
1931
        
 
1932
        doc.appendChild(new ProcessingInstruction("c\u0327hat", "c\u0327hat"));
 
1933
        Serializer serializer = new Serializer(out);
 
1934
        serializer.setUnicodeNormalizationFormC(true);
 
1935
        serializer.write(doc);
 
1936
        serializer.flush();
 
1937
        out.close();
 
1938
        String result = new String(out.toByteArray(), "UTF-8");
 
1939
        assertEquals(
 
1940
          "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\r\n"
 
1941
          + "<root/>\r\n"
 
1942
          + "<?\u00E7hat \u00E7hat?>\r\n",
 
1943
          result
 
1944
        );   
 
1945
        
 
1946
    }
 
1947
 
 
1948
    
 
1949
    public void testNFCInElementContentWithNonUnicodeEncoding() 
 
1950
      throws IOException {
 
1951
        
 
1952
        root.appendChild("c\u0327"); // c with combining cedilla
 
1953
        Serializer serializer = new Serializer(out, "ISO-8859-5");
 
1954
        serializer.setUnicodeNormalizationFormC(true);
 
1955
        serializer.write(doc);
 
1956
        serializer.flush();
 
1957
        out.close();
 
1958
        String result = new String(out.toByteArray(), "ISO-8859-5");
 
1959
        assertEquals(
 
1960
          "<?xml version=\"1.0\" encoding=\"ISO-8859-5\"?>\r\n"
 
1961
          + "<root>&#xE7;</root>\r\n", 
 
1962
          result
 
1963
        );    
 
1964
        
 
1965
    }
 
1966
 
 
1967
    
 
1968
    public void testNFCFollowingEntityReference() 
 
1969
      throws IOException {
 
1970
        
 
1971
        root.appendChild("<\u0338"); // < followed by not
 
1972
        Serializer serializer = new Serializer(out);
 
1973
        serializer.setUnicodeNormalizationFormC(true);
 
1974
        serializer.write(doc);
 
1975
        serializer.flush();
 
1976
        out.close();
 
1977
        String result = new String(out.toByteArray(), "UTF-8");
 
1978
        assertEquals(
 
1979
          "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\r\n"
 
1980
          + "<root>\u226E</root>\r\n", 
 
1981
          result
 
1982
        );    
 
1983
        
 
1984
    }
 
1985
 
 
1986
    
 
1987
    public void testNFCWithSetOutputStream() 
 
1988
      throws IOException {
 
1989
        
 
1990
        root.appendChild("c\u0327"); // c with combining cedilla
 
1991
        Serializer serializer = new Serializer(new ByteArrayOutputStream(), "ISO-8859-5");
 
1992
        serializer.setUnicodeNormalizationFormC(true);
 
1993
        serializer.write(doc);
 
1994
        serializer.setOutputStream(out);
 
1995
        serializer.write(doc);          
 
1996
        serializer.flush();
 
1997
        out.close();
 
1998
        String result = new String(out.toByteArray(), "ISO-8859-5");
 
1999
        assertEquals(
 
2000
          "<?xml version=\"1.0\" encoding=\"ISO-8859-5\"?>\r\n"
 
2001
          + "<root>&#xE7;</root>\r\n", 
 
2002
          result
 
2003
        );      
 
2004
        
 
2005
    }
 
2006
    
 
2007
    
 
2008
    public void testNFCWithKoreanCharacter() 
 
2009
      throws IOException {
 
2010
        
 
2011
        root.appendChild("\u1111\u1171\u11B6"); // see p. 88 of Unicode 4.0 book
 
2012
        Serializer serializer = new Serializer(new ByteArrayOutputStream());
 
2013
        serializer.setUnicodeNormalizationFormC(true);
 
2014
        serializer.write(doc);
 
2015
        serializer.setOutputStream(out);
 
2016
        serializer.write(doc);          
 
2017
        serializer.flush();
 
2018
        out.close();
 
2019
        String result = new String(out.toByteArray(), "UTF-8");
 
2020
        assertEquals(
 
2021
          "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\r\n"
 
2022
          + "<root>\uD4DB</root>\r\n", 
 
2023
          result
 
2024
        );      
 
2025
        
 
2026
    }
 
2027
    
 
2028
    
 
2029
    public void testNullOutputStream() {
 
2030
        
 
2031
        try {
 
2032
            new Serializer(null);
 
2033
            fail("Allowed null output stream");   
 
2034
        }   
 
2035
        catch (NullPointerException success) {
 
2036
            assertNotNull(success.getMessage());   
 
2037
        }
 
2038
        
 
2039
    }
 
2040
 
 
2041
    
 
2042
    public void testNullOutputStreamWithEncoding() 
 
2043
      throws UnsupportedEncodingException {
 
2044
        
 
2045
        try {
 
2046
            new Serializer(null, "UTF-8");
 
2047
            fail("Allowed null output stream");   
 
2048
        }   
 
2049
        catch (NullPointerException success) {
 
2050
            assertNotNull(success.getMessage());   
 
2051
        }
 
2052
        
 
2053
    }
 
2054
 
 
2055
    
 
2056
    public void testNullEncoding() 
 
2057
      throws UnsupportedEncodingException {
 
2058
        
 
2059
        try {
 
2060
            new Serializer(System.out, null);
 
2061
            fail("Allowed null encoding");   
 
2062
        }   
 
2063
        catch (NullPointerException success) {
 
2064
            assertNotNull(success.getMessage());   
 
2065
        }
 
2066
        
 
2067
    }
 
2068
 
 
2069
    
 
2070
    // make sure null pointer exception doesn't cause any output
 
2071
    public void testNullDocument() throws IOException {
 
2072
        
 
2073
        Serializer serializer = new Serializer(out, "UTF-16");
 
2074
        try {
 
2075
            serializer.write(null);  
 
2076
            fail("Wrote null document"); 
 
2077
        }   
 
2078
        catch (NullPointerException success) {
 
2079
            // success   
 
2080
        }
 
2081
        byte[] result = out.toByteArray();
 
2082
        assertEquals(0, result.length);
 
2083
        
 
2084
    }
 
2085
 
 
2086
    
 
2087
    public void testGetEncoding() 
 
2088
      throws UnsupportedEncodingException {
 
2089
        
 
2090
        Serializer serializer = new Serializer(System.out, "ISO-8859-1");
 
2091
        assertEquals("ISO-8859-1", serializer.getEncoding());
 
2092
        
 
2093
    }
 
2094
 
 
2095
    
 
2096
    public void testGetPreserveBaseURI() 
 
2097
      throws UnsupportedEncodingException {
 
2098
        
 
2099
        Serializer serializer = new Serializer(System.out, "ISO-8859-1");
 
2100
        assertFalse(serializer.getPreserveBaseURI());
 
2101
        serializer.setPreserveBaseURI(true);
 
2102
        assertTrue(serializer.getPreserveBaseURI());
 
2103
        serializer.setPreserveBaseURI(false);
 
2104
        assertFalse(serializer.getPreserveBaseURI());
 
2105
        
 
2106
    }
 
2107
 
 
2108
 
 
2109
    public void testSerializeDocTypeWithSystemID() 
 
2110
      throws IOException {
 
2111
        
 
2112
        Serializer serializer = new Serializer(out);
 
2113
        Document doc = new Document(new Element("a"));
 
2114
        doc.setDocType(new DocType("b", "example.dtd"));
 
2115
        serializer.write(doc);
 
2116
        String result = out.toString("UTF-8");
 
2117
        assertTrue(result.endsWith("<a/>\r\n"));
 
2118
        assertTrue(result.indexOf("<!DOCTYPE b SYSTEM \"example.dtd\">") > 0);  
 
2119
        
 
2120
    }
 
2121
 
 
2122
    
 
2123
    public void testSerializeDocTypeWithPublicAndSystemID() 
 
2124
      throws IOException {
 
2125
        
 
2126
        Serializer serializer = new Serializer(out);
 
2127
        Document doc = new Document(new Element("a"));
 
2128
        doc.setDocType(new DocType("b", 
 
2129
          "-//W3C//DTD XHTML 1.0 Transitional//EN", "example.dtd"));
 
2130
        serializer.write(doc);
 
2131
        String result = out.toString("UTF-8");
 
2132
        assertTrue(result.endsWith("<a/>\r\n"));
 
2133
        assertTrue(result.indexOf(
 
2134
          "<!DOCTYPE b PUBLIC \"-//W3C//DTD XHTML 1.0 Transitional//EN\" \"example.dtd\">") > 0); 
 
2135
        
 
2136
    }
 
2137
 
 
2138
    
 
2139
    public void testSerializeXMLNamespaceDeclaration() 
 
2140
      throws ParsingException, IOException {
 
2141
        
 
2142
        Serializer serializer = new Serializer(out);
 
2143
        Element root = new Element("root");
 
2144
        root.addNamespaceDeclaration("xml", Namespace.XML_NAMESPACE);
 
2145
        Document doc = new Document(root);
 
2146
        serializer.write(doc);
 
2147
        String result = out.toString("UTF-8");
 
2148
        assertTrue(result.endsWith("<root/>\r\n"));  
 
2149
        
 
2150
    }
 
2151
 
 
2152
    
 
2153
    public void testSerializeDocTypeWithInternalDTDSubset() 
 
2154
      throws ParsingException, IOException {
 
2155
        
 
2156
        Serializer serializer = new Serializer(out);
 
2157
        String data = "<!DOCTYPE root [ <!ELEMENT root EMPTY> ]><test/>";   
 
2158
        Builder builder = new Builder();
 
2159
        Document doc = builder.build(data, "http://www.example.com");
 
2160
        serializer.write(doc);
 
2161
        String result = out.toString("UTF-8");
 
2162
        assertTrue(result.endsWith("<test/>\r\n"));
 
2163
        assertTrue(result.indexOf("<!DOCTYPE root [\r\n") > 0);         
 
2164
        assertTrue(result.indexOf("\r\n]>\r\n") > 0);         
 
2165
        assertTrue(result.indexOf("<!ELEMENT root EMPTY>\r\n") > 0);  
 
2166
        
 
2167
    }
 
2168
 
 
2169
    
 
2170
    public void testSerializeInternalDTDSubsetContainingUnavailableCharacter() 
 
2171
      throws ParsingException, IOException {
 
2172
        
 
2173
        Serializer serializer = new Serializer(out, "US-ASCII");
 
2174
        String data = "<!DOCTYPE root ["
 
2175
          + "<!ELEMENT root EMPTY> " 
 
2176
          + "<!ATTLIST root attr CDATA 'cafĆ© creme'> "
 
2177
          + "]><test/>";   
 
2178
        Builder builder = new Builder();
 
2179
        Document doc = builder.build(data, "http://www.example.com");
 
2180
        try {
 
2181
            serializer.write(doc);
 
2182
            fail("How'd you serialize Ć© in ASCII?");
 
2183
        }
 
2184
        catch (UnavailableCharacterException success) {
 
2185
            assertTrue(success.getMessage().indexOf("Ć© (&#xE9;)") > 1);
 
2186
        }
 
2187
        
 
2188
    }
 
2189
 
 
2190
    
 
2191
    public void testLineBreaksInInternalDTDSubset() 
 
2192
      throws ParsingException, IOException {
 
2193
        
 
2194
        Serializer serializer = new Serializer(out);
 
2195
        serializer.setLineSeparator("\r");
 
2196
        String data = "<!DOCTYPE root [ <!ELEMENT root EMPTY> <!ELEMENT data EMPTY> ]><test/>";   
 
2197
        Builder builder = new Builder();
 
2198
        Document doc = builder.build(data, "http://www.example.com");
 
2199
        serializer.write(doc);
 
2200
        String result = out.toString("UTF-8");
 
2201
        assertTrue(result.endsWith("<test/>\r"));
 
2202
        assertTrue(result.indexOf("<!DOCTYPE root [\r") > 0);         
 
2203
        assertTrue(result.indexOf("\r]>\r") > 0);         
 
2204
        assertTrue(result.indexOf("<!ELEMENT root EMPTY>\r") > 0);  
 
2205
        assertTrue(result.indexOf("<!ELEMENT data EMPTY>\r") > 0);  
 
2206
        assertEquals(-1, result.indexOf("<!ELEMENT data EMPTY>\r\n"));  
 
2207
        assertEquals(-1, result.indexOf("<!ELEMENT root EMPTY>\r\n"));  
 
2208
        assertEquals(-1, result.indexOf("<!ELEMENT data EMPTY>\r\r"));  
 
2209
        assertEquals(-1, result.indexOf("<!ELEMENT root EMPTY>\r\r"));  
 
2210
        assertEquals(-1, result.indexOf('\n'));  
 
2211
        
 
2212
    }
 
2213
 
 
2214
    
 
2215
    public void testSerializeQuoteInAttributeValue() 
 
2216
      throws IOException {
 
2217
        
 
2218
        Serializer serializer = new Serializer(out);
 
2219
        root.addAttribute(new Attribute("name", "\""));
 
2220
        serializer.write(doc);
 
2221
        String result = out.toString("UTF-8");
 
2222
        assertTrue(result.endsWith("<root name=\"&quot;\"/>\r\n"));
 
2223
        
 
2224
    }
 
2225
 
 
2226
    
 
2227
    public void testSerializeUnavailableCharacterInMarkup() 
 
2228
      throws IOException {
 
2229
        
 
2230
        Serializer serializer = new Serializer(out, "ISO-8859-1");
 
2231
        Element root = new Element("\u0419");
 
2232
        Document doc = new Document(root);
 
2233
        try {
 
2234
            serializer.write(doc);
 
2235
            fail("Wrote bad character: " + out.toString("ISO-8859-1"));
 
2236
        }
 
2237
        catch (UnavailableCharacterException success) {
 
2238
            assertNotNull(success.getMessage()); 
 
2239
            assertEquals('\u0419', success.getCharacter());
 
2240
            assertEquals("ISO-8859-1", success.getEncoding());
 
2241
        }  
 
2242
        
 
2243
    }
 
2244
 
 
2245
    
 
2246
    public void testTurnLineFeedInAttributeValueIntoSpaceWhenIndenting() 
 
2247
      throws IOException {
 
2248
        
 
2249
        Element root = new Element("a");
 
2250
        root.appendChild("c"); 
 
2251
        root.addAttribute(new Attribute("name", "value1\nvalue2")); 
 
2252
        Document doc = new Document(root);
 
2253
        Serializer serializer = new Serializer(out);
 
2254
        serializer.setMaxLength(245);
 
2255
        serializer.setIndent(4);
 
2256
        serializer.write(doc);
 
2257
        serializer.flush();
 
2258
        out.close();
 
2259
        String result = new String(out.toByteArray(), "UTF-8");
 
2260
        assertEquals(
 
2261
          "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\r\n"
 
2262
          + "<a name=\"value1 value2\">c</a>\r\n", 
 
2263
          result
 
2264
        );      
 
2265
        
 
2266
    }
 
2267
 
 
2268
    
 
2269
    public void testConflictBetweenMaxLengthAndIndent() 
 
2270
      throws IOException {
 
2271
        
 
2272
        Element root = new Element("a");
 
2273
        Element b = new Element("b");
 
2274
        Element c = new Element("c");
 
2275
        Element d = new Element("d");
 
2276
        b.appendChild(c);
 
2277
        root.appendChild(b); 
 
2278
        c.appendChild(d);
 
2279
        d.appendChild("data");
 
2280
        Document doc = new Document(root);
 
2281
        Serializer serializer = new Serializer(out);
 
2282
        serializer.setMaxLength(16);
 
2283
        serializer.setIndent(4);
 
2284
        serializer.write(doc);
 
2285
        serializer.flush();
 
2286
        out.close();
 
2287
        String result = new String(out.toByteArray(), "UTF-8");
 
2288
        assertEquals(
 
2289
          "<?xml version=\"1.0\"\r\nencoding=\"UTF-8\"?>\r\n"
 
2290
          + "<a>\r\n    <b>\r\n        <c>\r\n        <d>data</d>\r\n        </c>\r\n    </b>\r\n</a>\r\n", 
 
2291
          result
 
2292
        );  
 
2293
        
 
2294
    }
 
2295
 
 
2296
    
 
2297
    public void testWriteChild() throws IOException {
 
2298
                  
 
2299
        ExposingSerializer serializer = new ExposingSerializer(out, "UTF-8");
 
2300
        try {
 
2301
            serializer.writeChild(doc);
 
2302
            fail("writeChild wrote a document");
 
2303
        }
 
2304
        catch (XMLException success) {
 
2305
            assertNotNull(success.getMessage());
 
2306
        }
 
2307
        try {
 
2308
            serializer.writeChild(new Attribute("name", "value"));
 
2309
            fail("writeChild wrote an attribute");
 
2310
        }
 
2311
        catch (XMLException success) {
 
2312
            assertNotNull(success.getMessage());
 
2313
        }
 
2314
       
 
2315
    }
 
2316
    
 
2317
    
 
2318
    // just so we can test protected methods
 
2319
    private static class ExposingSerializer extends Serializer {
 
2320
        
 
2321
        ExposingSerializer(OutputStream out, String encoding) 
 
2322
          throws UnsupportedEncodingException {
 
2323
            super(out, encoding);   
 
2324
        }
 
2325
        
 
2326
        public void writeChild(Node node) throws IOException {
 
2327
            super.writeChild(node);
 
2328
        }
 
2329
        
 
2330
        public void exposedWriteRaw(String text) throws IOException {
 
2331
            writeRaw(text);
 
2332
        }
 
2333
        
 
2334
        public void exposedWriteEscaped(String text) throws IOException {
 
2335
            writeEscaped(text);
 
2336
        }
 
2337
        
 
2338
        public void exposedWriteAttributeValue(String text) throws IOException {
 
2339
            writeAttributeValue(text);
 
2340
        }
 
2341
        
 
2342
        public int exposeGetColumnNumber() {
 
2343
            return super.getColumnNumber();
 
2344
        }
 
2345
        
 
2346
    }
 
2347
 
 
2348
    
 
2349
    private static class ElementSerializer extends Serializer {
 
2350
        
 
2351
        ElementSerializer(OutputStream out, String encoding) 
 
2352
          throws UnsupportedEncodingException {
 
2353
            super(out, encoding);   
 
2354
        }
 
2355
        
 
2356
        protected void write(Element element) throws IOException {
 
2357
            super.write(element);
 
2358
        }
 
2359
        
 
2360
    }
 
2361
 
 
2362
    
 
2363
    private static class TextSerializer extends Serializer {
 
2364
        
 
2365
        TextSerializer(OutputStream out) {
 
2366
            super(out);   
 
2367
        }
 
2368
        
 
2369
        protected void write(Text text) throws IOException {
 
2370
            super.write(text);
 
2371
        }
 
2372
        
 
2373
    }
 
2374
    
 
2375
    
 
2376
    public void testWriteParentlessTextNode() throws IOException {
 
2377
     
 
2378
        Text t = new Text("Hello");
 
2379
        ByteArrayOutputStream out = new ByteArrayOutputStream();
 
2380
        TextSerializer serializer = new TextSerializer(out);
 
2381
        serializer.write(t);
 
2382
        serializer.flush();
 
2383
        byte[] result = out.toByteArray();
 
2384
        String s = new String(result, "UTF-8");
 
2385
        assertEquals(s, t.getValue());
 
2386
        
 
2387
    }
 
2388
 
 
2389
    
 
2390
    public void testWriteParentlessTextNodeWhileIndenting() throws IOException {
 
2391
     
 
2392
        Text t = new Text("Hello");
 
2393
        ByteArrayOutputStream out = new ByteArrayOutputStream();
 
2394
        TextSerializer serializer = new TextSerializer(out);
 
2395
        serializer.setIndent(2);
 
2396
        serializer.write(t);
 
2397
        serializer.flush();
 
2398
        byte[] result = out.toByteArray();
 
2399
        String s = new String(result, "UTF-8");
 
2400
        assertEquals(s, t.getValue());
 
2401
        
 
2402
    }
 
2403
 
 
2404
    
 
2405
    public void testWriteWhiteSpaceOnlyTextNodeWhileIndenting() throws IOException {
 
2406
     
 
2407
        Text t = new Text("  \r\n  ");
 
2408
        ByteArrayOutputStream out = new ByteArrayOutputStream();
 
2409
        TextSerializer serializer = new TextSerializer(out);
 
2410
        serializer.setIndent(2);
 
2411
        serializer.write(t);
 
2412
        serializer.flush();
 
2413
        byte[] result = out.toByteArray();
 
2414
        assertEquals(0, result.length);
 
2415
        
 
2416
    }
 
2417
 
 
2418
    
 
2419
    public void testWriteRaw() throws IOException {
 
2420
 
 
2421
        ExposingSerializer serializer = new ExposingSerializer(out, "UTF-8");
 
2422
        serializer.exposedWriteRaw("<>&\"'");
 
2423
        assertEquals(5, serializer.exposeGetColumnNumber()); 
 
2424
        serializer.flush();
 
2425
        String result = out.toString("UTF-8");
 
2426
        assertEquals("<>&\"'", result);
 
2427
        
 
2428
    }    
 
2429
 
 
2430
    
 
2431
    public void testWriteParentlessElementInANamespace() throws IOException {
 
2432
 
 
2433
        ElementSerializer serializer = new ElementSerializer(out, "UTF-8");
 
2434
        Element element = new Element("a", "http://www.example.org");
 
2435
        serializer.write(element); 
 
2436
        serializer.flush();
 
2437
        String result = out.toString("UTF-8");
 
2438
        assertEquals("<a xmlns=\"http://www.example.org\"/>", result);
 
2439
        
 
2440
    }    
 
2441
 
 
2442
    
 
2443
    public void testWriteEscaped() throws IOException {
 
2444
 
 
2445
        ExposingSerializer serializer = new ExposingSerializer(out, "UTF-8");
 
2446
        serializer.exposedWriteEscaped("<>&\"'");
 
2447
        assertEquals(15, serializer.exposeGetColumnNumber());   
 
2448
        serializer.flush();
 
2449
        byte[] data = out.toByteArray();
 
2450
        String result = new String(data, "UTF-8");
 
2451
        assertEquals("&lt;&gt;&amp;\"'", result);
 
2452
        
 
2453
    }    
 
2454
 
 
2455
    
 
2456
    public void testWriteAttributeValue() throws IOException {
 
2457
 
 
2458
        ExposingSerializer serializer = new ExposingSerializer(out, "UTF-8");
 
2459
        serializer.exposedWriteAttributeValue("<>&\"'");
 
2460
        assertEquals(20, serializer.exposeGetColumnNumber());   
 
2461
        serializer.flush();
 
2462
        String result = out.toString("UTF-8");
 
2463
        assertEquals("&lt;&gt;&amp;&quot;'", result);
 
2464
        
 
2465
    }    
 
2466
    
 
2467
    
 
2468
    // This test case reproduces a bug that
 
2469
    // showed up while working on SAX conformance testing.
 
2470
    public void testElementsThatOnlyContainsAnEmptyTextNodeShouldBeOutputWithAnEmptyElementTag() 
 
2471
      throws IOException {
 
2472
        
 
2473
        Element child = new Element("b");
 
2474
        child.appendChild("");
 
2475
        root.appendChild(child);
 
2476
        
 
2477
        Serializer serializer = new Serializer(out);
 
2478
        serializer.write(doc);
 
2479
           
 
2480
        serializer.flush();
 
2481
        String result = out.toString("UTF-8");
 
2482
        assertEquals("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\r\n" +
 
2483
          "<root><b/></root>\r\n", result); 
 
2484
        
 
2485
    }
 
2486
    
 
2487
    
 
2488
    // This test case reproduces a bug that
 
2489
    // showed up while working on SAX conformance testing.
 
2490
    public void testElementsThatOnlyContainEmptyTextNodesShouldBeOutputWithAnEmptyElementTag() 
 
2491
      throws IOException {
 
2492
        
 
2493
        Element root = new Element("a");
 
2494
        Element child = new Element("b");
 
2495
        child.appendChild("");
 
2496
        child.appendChild("");
 
2497
        child.appendChild("");
 
2498
        root.appendChild(child);
 
2499
        
 
2500
        Document doc = new Document(root);
 
2501
        
 
2502
        Serializer serializer = new Serializer(out);
 
2503
        serializer.write(doc);
 
2504
           
 
2505
        serializer.flush();
 
2506
        String result = out.toString("UTF-8");
 
2507
        assertEquals("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\r\n" +
 
2508
          "<a><b/></a>\r\n", result);
 
2509
        
 
2510
    }
 
2511
 
 
2512
    
 
2513
    // This test case reproduces a bug that
 
2514
    // showed up while working on SAX conformance testing.
 
2515
    public void testElementsThatOnlyContainASingleSpaceShouldNotBeSplitWhileIndenting() 
 
2516
      throws IOException {
 
2517
        
 
2518
        Element root = new Element("a");
 
2519
        Element child = new Element("b");
 
2520
        child.appendChild(" ");
 
2521
        root.appendChild(child);
 
2522
        
 
2523
        Document doc = new Document(root);
 
2524
        
 
2525
        Serializer serializer = new Serializer(out);
 
2526
        serializer.setIndent(4);
 
2527
        serializer.write(doc);
 
2528
           
 
2529
        serializer.flush();
 
2530
        String result = out.toString("UTF-8");
 
2531
        assertEquals("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\r\n" +
 
2532
          "<a>\r\n    <b> </b>\r\n</a>\r\n", result);
 
2533
 
 
2534
    }
 
2535
    
 
2536
    
 
2537
    public void testElementsThatOnlyContainTextNodesWithBoundaryWhiteSpaceShouldNotBeSplitWhileIndenting() 
 
2538
      throws IOException {
 
2539
        
 
2540
        Element root = new Element("a");
 
2541
        Element child = new Element("b");
 
2542
        child.appendChild(" ");
 
2543
        child.appendChild(" ");
 
2544
        root.appendChild(child);
 
2545
        
 
2546
        Document doc = new Document(root);
 
2547
        
 
2548
        Serializer serializer = new Serializer(out);
 
2549
        serializer.setIndent(4);
 
2550
        serializer.write(doc);
 
2551
           
 
2552
        serializer.flush();
 
2553
        String result = out.toString("UTF-8");
 
2554
        assertEquals("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\r\n" +
 
2555
          "<a>\r\n    <b> </b>\r\n</a>\r\n", result);
 
2556
 
 
2557
    }
 
2558
    
 
2559
    
 
2560
    public void testElementsThatOnlyContainASingleLinefeedShouldNotBeSplitWhileIndenting() 
 
2561
      throws IOException {
 
2562
        
 
2563
        Element root = new Element("a");
 
2564
        Element child = new Element("b");
 
2565
        child.appendChild("\n");
 
2566
        root.appendChild(child);
 
2567
        
 
2568
        Document doc = new Document(root);
 
2569
        
 
2570
        Serializer serializer = new Serializer(out);
 
2571
        serializer.setIndent(4);
 
2572
        serializer.write(doc);
 
2573
           
 
2574
        serializer.flush();
 
2575
        String result = out.toString("UTF-8");
 
2576
        assertEquals("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\r\n" +
 
2577
          "<a>\r\n    <b> </b>\r\n</a>\r\n", result);
 
2578
 
 
2579
    }
 
2580
    
 
2581
    
 
2582
    public void testEndTagsOfElementsWithContentGoOnSeparateLine() 
 
2583
      throws ParsingException, IOException {
 
2584
      
 
2585
        Serializer serializer = new Serializer(out, "ISO-8859-1");
 
2586
        serializer.setIndent(4);
 
2587
        serializer.setPreserveBaseURI(true);
 
2588
        serializer.flush();
 
2589
    
 
2590
        File f = new File("data");
 
2591
        f = new File(f, "prettyxml.xml");
 
2592
        Builder builder = new Builder();
 
2593
        Document doc = builder.build(f);
 
2594
        serializer.write(doc);
 
2595
        String result = out.toString("UTF-8");
 
2596
        assertTrue(result.endsWith("\r\n</html>\r\n"));
 
2597
      
 
2598
    }
 
2599
 
 
2600
    
 
2601
    public void testDontDoubleBreak() 
 
2602
      throws ParsingException, IOException {
 
2603
      
 
2604
        Serializer serializer = new Serializer(out, "ISO-8859-1");
 
2605
        serializer.setIndent(4);
 
2606
        serializer.setMaxLength(64);
 
2607
 
 
2608
        File f = new File("data");
 
2609
        f = new File(f, "prettytest.xml");
 
2610
        Builder builder = new Builder();
 
2611
        Document doc = builder.build(f);
 
2612
        serializer.write(doc);
 
2613
        String result = out.toString("UTF-8");
 
2614
        assertEquals("<?xml version=\"1.0\" encoding=\"ISO-8859-1\"?>\r\n" +
 
2615
          "<html a=\"AReallyLongNameWithNoOpportunitiesToBreakToPutUsPastTheMaxLineLengthAndForceABreak\">\r\n" +    
 
2616
          "    <head> </head>\r\n" + 
 
2617
          "</html>\r\n", result);
 
2618
      
 
2619
    }
 
2620
 
 
2621
    
 
2622
}