View Javadoc

1   package org.apache.maven.doxia.module.confluence;
2   
3   /*
4    * Licensed to the Apache Software Foundation (ASF) under one
5    * or more contributor license agreements.  See the NOTICE file
6    * distributed with this work for additional information
7    * regarding copyright ownership.  The ASF licenses this file
8    * to you under the Apache License, Version 2.0 (the
9    * "License"); you may not use this file except in compliance
10   * with the License.  You may obtain a copy of the License at
11   *
12   *   http://www.apache.org/licenses/LICENSE-2.0
13   *
14   * Unless required by applicable law or agreed to in writing,
15   * software distributed under the License is distributed on an
16   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
17   * KIND, either express or implied.  See the License for the
18   * specific language governing permissions and limitations
19   * under the License.
20   */
21  
22  import java.io.FilterWriter;
23  import java.io.IOException;
24  import java.io.Reader;
25  import java.io.StringReader;
26  import java.io.StringWriter;
27  import java.io.Writer;
28  import java.util.Iterator;
29  
30  import org.apache.maven.doxia.parser.AbstractParserTest;
31  import org.apache.maven.doxia.parser.ParseException;
32  import org.apache.maven.doxia.parser.Parser;
33  import org.apache.maven.doxia.sink.Sink;
34  import org.apache.maven.doxia.sink.SinkEventAttributeSet;
35  import org.apache.maven.doxia.sink.SinkEventElement;
36  import org.apache.maven.doxia.sink.SinkEventTestingSink;
37  import org.apache.maven.doxia.sink.TextSink;
38  
39  import org.codehaus.plexus.util.IOUtil;
40  import org.codehaus.plexus.util.StringUtils;
41  
42  /**
43   * Test class for ConfluenceParser.
44   */
45  public class ConfluenceParserTest
46      extends AbstractParserTest
47  {
48      private ConfluenceParser parser;
49  
50      private StringWriter output;
51  
52      private Reader reader;
53  
54      private Writer writer;
55  
56      /** {@inheritDoc} */
57      protected void setUp()
58          throws Exception
59      {
60          super.setUp();
61  
62          parser = (ConfluenceParser) lookup( Parser.ROLE, "confluence" );
63  
64          output = null;
65          reader = null;
66          writer = null;
67      }
68  
69      /** {@inheritDoc} */
70      protected void tearDown()
71          throws Exception
72      {
73          IOUtil.close( output );
74          IOUtil.close( reader );
75          IOUtil.close( writer );
76  
77          super.tearDown();
78      }
79  
80      /** {@inheritDoc} */
81      protected Parser createParser()
82      {
83          return parser;
84      }
85  
86      /** {@inheritDoc} */
87      protected String outputExtension()
88      {
89          return "confluence";
90      }
91  
92      /** @throws Exception */
93      public void testMarkupTestPage()
94          throws Exception
95      {
96          String result = locateAndParseTestSourceFile( "test" );
97          assertContainsLines( result, "end:body" );
98      }
99  
100     /** @throws Exception */
101     public void testParagraphWithSimpleFormatting()
102         throws Exception
103     {
104         String result = locateAndParseTestSourceFile( "simple-paragraph" );
105 
106         assertContainsLines( result, "begin:bold\ntext: bold\n" );
107         assertContainsLines( result, "begin:italic\ntext: italic\n" );
108         assertContainsLines( result, "begin:monospaced\ntext: monospaced\n" );
109         assertContainsLines( result, "begin:link, name: http://jira.codehaus.org\ntext: http://jira.codehaus.org" );
110         assertContainsLines( result, "begin:link, name: http://jira.codehaus.org\ntext: JIRA\n" );
111         // four paragraphs in the input...
112         assertEquals( 5, result.split( "end:paragraph" ).length );
113     }
114 
115     /** @throws Exception */
116     public void testLineBreak()
117         throws Exception
118     {
119         String lineBreak = getLineBreakString();
120 
121         String result = locateAndParseTestSourceFile( "linebreak" );
122 
123         assertContainsLines( result, "Line\n" + lineBreak );
124         assertContainsLines( result, "with 2\n" + lineBreak );
125         assertContainsLines( result, "inline\n" + lineBreak );
126     }
127 
128     /** @throws Exception */
129     public void testEscapes()
130         throws Exception
131     {
132         String result = locateAndParseTestSourceFile( "escapes" );
133 
134         assertContainsLines( result, "asterisk *" );
135         assertContainsLines( result, "underline _" );
136         assertContainsLines( result, "asterisk *not bold*" );
137         assertContainsLines( result, "underline _not italic_" );
138         assertContainsLines( result, "normal character" );
139         assertContainsLines( result, "trailing slash\\\n" );
140     }
141 
142     /** @throws Exception */
143     public void testSectionTitles()
144         throws Exception
145     {
146         String result = locateAndParseTestSourceFile( "section" );
147 
148         for ( int i = 1; i <= 5; i++ )
149         {
150             assertContainsLines( "Could not locate section " + i + " title", result,
151                     "sectionTitle" + i + "\ntext: Section" + i );
152         }
153 
154         assertContainsLines( "Section title has leading space", result, "sectionTitle1\ntext: TitleWithLeadingSpace" );
155     }
156 
157     /** @throws Exception */
158     public void testNestedBulletList()
159         throws Exception
160     {
161         String result = locateAndParseTestSourceFile( "nested-list" );
162 
163         assertContainsLines( "Nested list not found", result,
164                 "begin:listItem\ntext: A top level list item\nbegin:list" );
165         // two lists in the input...
166         assertEquals( 3, result.split( "end:list\n" ).length );
167         // ...and 4 list items
168         assertEquals( 5, result.split( "end:listItem\n" ).length );
169     }
170 
171     /** @throws Exception */
172     public void testNestedHeterogenousList()
173         throws Exception
174     {
175     	String result = locateAndParseTestSourceFile( "nested-list-heterogenous" );
176 
177         // test heterogenous list
178         assertContainsLines( "Nested list not found", result, "begin:listItem\ntext: A top level list item\nbegin:numberedList" );
179 
180         // exactly one list and one numberedList
181         assertEquals( 2, result.split( "begin:list\n" ).length );
182         assertEquals( 2, result.split( "begin:numberedList" ).length );
183 
184         // ...and 4 list items
185         assertEquals( 5, result.split( "end:listItem\n" ).length );
186     }
187 
188     /** @throws Exception */
189     public void testListWithSimpleFormatting()
190         throws Exception
191     {
192         String result = locateAndParseTestSourceFile( "simple-list" );
193 
194         assertContainsLines( result, "begin:bold\ntext: bold\n" );
195         assertContainsLines( result, "begin:italic\ntext: italic\n" );
196         assertContainsLines( result, "begin:monospaced\ntext: monospaced\n" );
197         assertContainsLines( result, "begin:monospaced\ntext: some escaped monospaced \\\\unc\\path\n" );
198         assertContainsLines( result, "begin:link, name: http://jira.codehaus.org\ntext: http://jira.codehaus.org\n" );
199         assertContainsLines( result, "begin:link, name: http://jira.codehaus.org\ntext: JIRA\n" );
200         assertContainsLines( result, "begin:listItem\ntext: Item with no formatting\nend:listItem\n" );
201         assertContainsLines( result, "begin:listItem\ntext: One bullet\nend:listItem\n" );
202         assertContainsLines( result, "begin:listItem\ntext: A list item with more than one line\nend:listItem\n" );
203         // 3 lists in the input...
204         assertEquals( 4, result.split( "end:list\n" ).length );
205         // ...and 7 list items
206         assertEquals( 9, result.split( "end:listItem\n" ).length );
207     }
208 
209     /** @throws Exception */
210     public void testAnchor()
211         throws Exception
212     {
213         String result = locateAndParseTestSourceFile( "anchor" );
214 
215         assertContainsLines( result, "begin:paragraph\nbegin:anchor, name: start\nend:anchor" );
216         assertContainsLines( result, "begin:anchor, name: middle\nend:anchor" );
217         assertContainsLines( result, "begin:paragraph\ntext: Simple paragraph\nbegin:anchor, name: end\nend:anchor" );
218         // 3 anchors in the input...
219         assertEquals( 4, result.split( "end:anchor\n" ).length );
220     }
221 
222     /** @throws Exception */
223     public void testUnknownMacro()
224         throws Exception
225     {
226         String result = locateAndParseTestSourceFile( "unknown-macro" );
227 
228         assertContainsLines( result, "begin:paragraph\ntext: {unknown:start}" );
229     }
230 
231     /** @throws Exception */
232     public void testCodeMacro()
233         throws Exception
234     {
235         String result = locateAndParseTestSourceFile( "code" );
236 
237         assertContainsLines( result, "begin:verbatim, boxed: true\ntext: public class Cat {" );
238         // 5 paragraphs in the input...
239         assertEquals( 5, result.split( "end:paragraph\n" ).length );
240         // 3 verbatim in the input...
241         assertEquals( 3, result.split( "end:verbatim\n" ).length );
242     }
243 
244     /** @throws Exception */
245     public void testFigure()
246         throws Exception
247     {
248         Reader result = getTestReader( "figure" );
249 
250         SinkEventTestingSink sink = new SinkEventTestingSink();
251 
252         parser.parse( result, sink );
253 
254         Iterator<SinkEventElement> it = sink.getEventList().iterator();
255 
256         assertEquals( it, "head", "head_", "body", "paragraph" );
257         assertEquals( it.next(), "text", "Simple paragraph." );
258         assertEquals( it, "paragraph_", "figure" );
259         assertEquals( it.next(), "figureGraphics", "images/photo.jpg" );
260         assertEquals( it, "figure_", "paragraph" );
261         assertEquals( it.next(), "text", "Simple paragraph with attempted inline !image.jpg! (should fail)." );
262         assertEquals( it, "paragraph_", "figure" );
263         assertEquals( it.next(), "figureGraphics", "images/photo.jpg" );
264         assertEquals( it.next().getName(), "figureCaption" ); 
265         assertEquals( it.next(), "text", "With caption on same line" );
266         assertEquals( it, "figureCaption_", "figure_", "figure" );
267         assertEquals( it.next(), "figureGraphics", "images/linebreak.jpg" );
268         assertEquals( it.next().getName(), "figureCaption" );
269         assertEquals( it.next(), "text", "With caption underneath and linebreak" );
270         assertEquals( it, "figureCaption_", "figure_", "figure" );
271         assertEquals( it.next(), "figureGraphics", "images/nolinebreak.jpg" );
272         assertEquals( it.next().getName(), "figureCaption" );
273         assertEquals( it.next(), "text", "With caption underneath and no linebreak" );
274         assertEquals( it, "figureCaption_", "figure_", "figure" );
275         assertEquals( it.next(), "figureGraphics", "images/bold.jpg" );
276         assertEquals( it.next().getName(), "figureCaption" );
277         assertEquals( it.next(), "text", "With *bold* caption underneath" );
278         assertEquals( it, "figureCaption_", "figure_", "figure" );
279         assertEquals( it.next(), "figureGraphics", "image.gif" );
280         assertEquals( it, "figure_", "body_" );
281         assertFalse( it.hasNext() );
282     }
283 
284     /** @throws Exception */
285     public void testLink()
286         throws Exception
287     {
288         String result = locateAndParseTestSourceFile( "link" );
289 
290         assertContainsLines( result, "begin:link, name: middle.html\ntext: middle\nend:link" );
291         assertContainsLines( result, "begin:link, name: end.html\ntext: end\nend:link" );
292         assertContainsLines( result, "begin:link, name: link.html\ntext: alias\nend:link" );
293         assertContainsLines( result, "begin:link, name: link.html#anchor\ntext: link#anchor\nend:link" );
294         assertContainsLines( result, "begin:link, name: #simple\ntext: simple\nend:link" );
295         assertContainsLines( result, "begin:link, name: resource.pdf\ntext: resource.pdf\nend:link" );
296         assertContainsLines( result, "begin:link, name: resource.pdf\ntext: alias pdf\nend:link" );
297         assertContainsLines( result, "begin:link, name: http://link.to/page_with_underscore-and-dash\ntext: underscore_-dash\nend:link" );
298         // 5 paragraphs in the input...
299         assertEquals( 6, result.split( "end:paragraph\n" ).length );
300         // 8 links in the input...
301         assertEquals( 9, result.split( "end:link\n" ).length );
302     }
303 
304     /** @throws Exception */
305     public void testTableWithLinks()
306         throws Exception
307     {
308         String result = locateAndParseTestSourceFile( "table-link" );
309 
310         assertContainsLines( result, "begin:tableCell\nbegin:link, name: http://example.com/release.0.1.3/ex-win32-win32.x86.zip\ntext: Download\nend:link\n\n\nend:tableCell\n" );
311         assertContainsLines( result, "begin:tableCell\nbegin:link, name: http://example.com/release.0.1.2/ex-win32-win32.x86.zip\ntext: http://example.com/release.0.1.2/ex-win32-win32.x86.zip\nend:link\n\n\nend:tableCell\n" );
312 
313         // 3 links in the input
314         assertEquals( 4, result.split( "end:link\n" ).length );
315     }
316 
317     /** @throws Exception */
318     public void testParagraphWithList()
319         throws Exception
320     {
321         String result = locateAndParseTestSourceFile( "paragraph-list" );
322 
323         assertContainsLines( result, "begin:paragraph\ntext: A paragraph\nend:paragraph\n" );
324         assertContainsLines( result, "begin:listItem\ntext: A nested list item\nend:listItem\n" );
325         assertContainsLines( result, "begin:listItem\ntext: Another nested list item with two lines\nend:listItem\n" );
326         // 2 paragraphs in the input...
327         assertEquals( 3, result.split( "end:paragraph\n" ).length );
328         // 1 list in the input...
329         assertEquals( 2, result.split( "end:list\n" ).length );
330     }
331 
332     /** @throws Exception */
333     public void testParagraphWithFigure()
334         throws Exception
335     {
336         String result = locateAndParseTestSourceFile( "paragraph-figure" );
337 
338         assertContainsLines( result, "begin:paragraph\ntext: A paragraph\nend:paragraph\n" );
339         assertContainsLines( result, "begin:figure\nfigureGraphics, name: images/logo.png\nbegin:figureCaption\ntext: with a figure\nend:figureCaption" );
340         // 2 paragraphs in the input...
341         assertEquals( 3, result.split( "end:paragraph\n" ).length );
342         // 1 figure in the input...
343         assertEquals( 2, result.split( "end:figure\n" ).length );
344     }
345 
346     /** @throws Exception */
347     public void testParagraphWithHeader()
348         throws Exception
349     {
350         String result = locateAndParseTestSourceFile( "paragraph-header" );
351 
352         assertContainsLines( result, "begin:paragraph\ntext: A paragraph\nend:paragraph\n" );
353         assertContainsLines( result, "begin:section2\nbegin:sectionTitle2\ntext: A header\nend:sectionTitle2" );
354         // 3 paragraphs in the input...
355         assertEquals( 4, result.split( "end:paragraph\n" ).length );
356         // 1 header in the input...
357         assertEquals( 2, result.split( "end:sectionTitle2\n" ).length );
358     }
359 
360     /** @throws Exception */
361     public void testNestedFormats()
362         throws Exception
363     {
364         String result = locateAndParseTestSourceFile( "nested-format" );
365 
366         assertContainsLines( result, "begin:bold\nbegin:italic\ntext: bold italic\nend:italic" );
367         assertContainsLines( result, "begin:italic\nbegin:bold\ntext: italic bold\nend:bold" );
368         assertContainsLines( result, "begin:bold\nbegin:monospaced\ntext: bold monospaced\nend:monospaced" );
369         assertContainsLines( result, "text: A paragraph with \nbegin:bold\ntext: bold \nbegin:italic\ntext: italic\nend:italic" );
370         assertContainsLines( result, "begin:italic\ntext: italic \nbegin:bold\ntext: bold\nend:bold" );
371         assertContainsLines( result, "begin:bold\ntext: bold \nbegin:monospaced\ntext: monospaced\nend:monospaced" );
372         // 2 paragraphs in the input...
373         assertEquals( 3, result.split( "end:paragraph\n" ).length );
374         // 6 bolds in the input...
375         assertEquals( 7, result.split( "end:bold\n" ).length );
376         // 4 italics in the input...
377         assertEquals( 5, result.split( "end:italic\n" ).length );
378         // 2 monospaced in the input...
379         assertEquals( 3, result.split( "end:monospaced\n" ).length );
380     }
381 
382     /** @throws Exception */
383     public void testNoteInfoTipQuote()
384         throws Exception
385     {
386         String result = locateAndParseTestSourceFile( "note-tip-info" );
387 
388         assertContainsLines( result, "begin:definedTerm\ntext: Be Careful\nend:definedTerm\n" );
389         assertContainsLines( result, "begin:definition\ntext: The body of the note here..\nend:definition" );
390         assertContainsLines( result, "begin:definedTerm\ntext: Guess What?\nend:definedTerm\n" );
391         assertContainsLines( result, "begin:definition\ntext: The body of the tip here..\nend:definition" );
392         assertContainsLines( result, "begin:definedTerm\ntext: Some Info\nend:definedTerm\n" );
393         assertContainsLines( result, "begin:definition\ntext: The body of the info here..\nend:definition" );
394         assertContainsLines( result, "begin:definedTerm\ntext: Simon Says\nend:definedTerm\n" );
395         assertContainsLines( result, "begin:definition\ntext: The body of the \nbegin:bold\ntext: quote\nend:bold" );
396 
397         // 5 paragraphs in the input...
398         assertEquals( 6, result.split( "end:paragraph\n" ).length );
399         // 4 dinitionList in the input...
400         assertEquals( 5, result.split( "end:definitionList\n" ).length );
401     }
402 
403     /**
404      * DOXIA-247
405      *
406      * @throws ParseException if something goes wrong.
407      */
408     public void testEndBracket()
409         throws ParseException
410     {
411         String document = "Test"
412             + "\n\n* list1"
413             + "\n\n* list2"
414             + "\n\n* list2"
415             + "\n{pre}123{/pre}";
416 
417         output = new StringWriter();
418         Sink sink = new TextSink( output );
419 
420         /* parsing with additional space at end works */
421         createParser().parse( new StringReader( document + " " ), sink );
422         assertTrue( "generated document should have a size > 0", output.toString().length() > 0 );
423 
424         /* parsing with document ending in } should not fail */
425         try
426         {
427             createParser().parse( new StringReader( document ), sink );
428         }
429         catch ( Exception e )
430         {
431             e.printStackTrace();
432             fail( "parsing with document ending in } should not fail" );
433         }
434 
435         assertTrue( "generated document should have a size > 0", output.toString().length() > 0 );
436     }
437 
438     /**
439      * DOXIA-247
440      *
441      * @throws ParseException
442      */
443     public void testEndBracketInList()
444         throws ParseException
445     {
446         String document1 = "Test"
447             + "\n\n* list1"
448             + "\n\n* list2"
449             + "\n\n* list2{pre}123{/pre} "
450             + "\n123";
451 
452         String document2 = "Test"
453             + "\n\n* list1"
454             + "\n\n* list2"
455             + "\n\n* list2{pre}123{/pre}"
456             + "\n123";
457 
458         output = new StringWriter();
459         Sink sink = new TextSink( output );
460 
461         /* parsing with additional space at end of list item works */
462         createParser().parse( new StringReader( document1 ), sink );
463         assertTrue( "generated document should have a size > 0", output.toString().length() > 0 );
464 
465         /* parsing with end of list item ending in } should not fail */
466         try
467         {
468             createParser().parse( new StringReader( document2 ), sink );
469         }
470         catch ( Exception e )
471         {
472             e.printStackTrace();
473             fail( "parsing with end of list item ending in } should not fail" );
474         }
475 
476         assertTrue( "generated document should have a size > 0", output.toString().length() > 0 );
477     }
478 
479     public void testDoxia382SinkCannotBeReused()
480             throws ParseException
481     {
482         String document1 = "Test A"
483             + "\n\n* list1"
484             + "\n\n* list2"
485             + "\n\n* list2{pre}123{/pre} "
486             + "\n123";
487 
488         String document2 = "Test B"
489             + "\n\n* list1"
490             + "\n\n* list2"
491             + "\n\n* list2{pre}123{/pre}"
492             + "\n123";
493 
494         output = new StringWriter();
495         Sink sink = new TextSink( new FilterWriter( output )
496         {
497             public void close() throws IOException
498             {
499                 super.close();
500                 this.out = null;
501             }
502 
503             public void write( String str, int off, int len )
504                     throws IOException
505             {
506                 if ( out == null )
507                 {
508                     throw new IOException( "Writing to an already closed Writer" );
509                 }
510             }
511         });
512 
513         createParser().parse( new StringReader( document1 ), sink );
514         createParser().parse( new StringReader( document2 ), sink );
515     }
516     
517 
518     /**
519      * DOXIA-370
520      *
521      * @throws ParseException
522      */
523     public void testSeparatorInParagraph()
524         throws ParseException
525     {
526         String document = "Up\n---\nDown\n";
527 
528         output = new StringWriter();
529         Sink sink = new TextSink( output );
530 
531         /* parsing with separator in middle of paragraph */
532         createParser().parse( new StringReader( document ), sink );
533         assertTrue( "generated document should have a size > 0", output.toString().length() > 0 );
534 
535     }
536     
537     public void testListFollowedByMacro() throws Exception
538     {
539         // @todo FIX
540         // DOXIA-371
541         String document = "- This is a little test. \r\n" +
542                 "\r\n" + // with extra linebreak it succeeds, without it should too 
543         		"{code}\r\n" + 
544         		"    @Autowired\r\n" + 
545         		"    private DataSource dataSource;\r\n" + 
546         		"{code}\r\n"; 
547         output = new StringWriter();
548         SinkEventTestingSink sink = new SinkEventTestingSink();
549         createParser().parse( new StringReader( document ), sink );
550         
551         Iterator<SinkEventElement> it = sink.getEventList().iterator();
552         assertEquals("head", it.next().getName() );
553         assertEquals("head_", it.next().getName() );
554         assertEquals("body", it.next().getName() );
555         assertEquals("list", it.next().getName() );
556         assertEquals("listItem", it.next().getName() );
557         assertEquals( it.next(), "text", "This is a little test." );
558         assertEquals("listItem_", it.next().getName() );
559         assertEquals("list_", it.next().getName() );
560         assertEquals("verbatim", it.next().getName() );
561         assertEquals( it.next(), "text", "    @Autowired\n    private DataSource dataSource;\n" );
562         assertEquals("verbatim_", it.next().getName() );
563         assertEquals("body_", it.next().getName() );
564     }
565 
566 	public void testLinethrough() throws Exception {
567 		String document = "-Linethrough-";
568 		output = new StringWriter();
569 		SinkEventTestingSink sink = new SinkEventTestingSink();
570 		createParser().parse(new StringReader(document), sink);
571 
572 		Iterator<SinkEventElement> it = sink.getEventList().iterator();
573 		assertEquals(it, "head", "head_", "body", "paragraph");
574 		assertEquals(it.next(), "text", "Linethrough",
575 				new SinkEventAttributeSet("decoration", "line-through"));
576 		assertEquals(it, "paragraph_", "body_");
577 		assertFalse(it.hasNext());
578 	}
579 
580 	public void testUnderline() throws Exception {
581 		String document = "+Underline+";
582 		output = new StringWriter();
583 		SinkEventTestingSink sink = new SinkEventTestingSink();
584 		createParser().parse(new StringReader(document), sink);
585 
586 		Iterator<SinkEventElement> it = sink.getEventList().iterator();
587 		assertEquals(it, "head", "head_", "body", "paragraph");
588 		assertEquals(it.next(), "text", "Underline", new SinkEventAttributeSet(
589 				"decoration", "underline"));
590 		assertEquals(it, "paragraph_", "body_");
591 		assertFalse(it.hasNext());
592 	}
593 
594 	public void testSub() throws Exception {
595 		String document = "~Sub~";
596 		output = new StringWriter();
597 		SinkEventTestingSink sink = new SinkEventTestingSink();
598 		createParser().parse(new StringReader(document), sink);
599 
600 		Iterator<SinkEventElement> it = sink.getEventList().iterator();
601 		assertEquals(it, "head", "head_", "body", "paragraph");
602 		assertEquals(it.next(), "text", "Sub", new SinkEventAttributeSet(
603 				"valign", "sub"));
604 		assertEquals(it, "paragraph_", "body_");
605 		assertFalse(it.hasNext());
606 	}
607 
608 	public void testSup() throws Exception {
609 		String document = "^Sup^";
610 		output = new StringWriter();
611 		SinkEventTestingSink sink = new SinkEventTestingSink();
612 		createParser().parse(new StringReader(document), sink);
613 
614 		Iterator<SinkEventElement> it = sink.getEventList().iterator();
615 		assertEquals(it, "head", "head_", "body", "paragraph");
616 		assertEquals(it.next(), "text", "Sup", new SinkEventAttributeSet(
617 				"valign", "sup"));
618 		assertEquals(it, "paragraph_", "body_");
619 		assertFalse(it.hasNext());
620 	}
621 
622     private void assertContainsLines( String message, String result, String lines )
623     {
624         lines = StringUtils.replace( lines, "\n", EOL );
625         if ( message != null )
626         {
627             assertTrue( message, result.indexOf( lines ) != -1 );
628         }
629         else
630         {
631             assertTrue( result.indexOf( lines ) != -1 );
632         }
633     }
634 
635     private void assertContainsLines( String result, String lines )
636     {
637         this.assertContainsLines( null, result, lines );
638     }
639 
640     private String getLineBreakString()
641     {
642         StringWriter sw = new StringWriter();
643         Sink sink = new TextSink( sw );
644         sink.lineBreak();
645 
646         return sw.toString();
647     }
648 
649     private String locateAndParseTestSourceFile( String stem )
650         throws IOException, ParseException
651     {
652         output = new StringWriter();
653         reader = getTestReader( stem, outputExtension() );
654         writer = getTestWriter( stem, "txt" );
655 
656         Sink sink = new TextSink( output );
657         createParser().parse( reader, sink );
658 
659         // write to file
660         String expected = output.toString();
661         writer.write( expected );
662         writer.flush();
663         return expected;
664     }
665 
666 }