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