001package org.apache.maven.doxia.sink;
002
003/*
004 * Licensed to the Apache Software Foundation (ASF) under one
005 * or more contributor license agreements.  See the NOTICE file
006 * distributed with this work for additional information
007 * regarding copyright ownership.  The ASF licenses this file
008 * to you under the Apache License, Version 2.0 (the
009 * "License"); you may not use this file except in compliance
010 * with the License.  You may obtain a copy of the License at
011 *
012 *   http://www.apache.org/licenses/LICENSE-2.0
013 *
014 * Unless required by applicable law or agreed to in writing,
015 * software distributed under the License is distributed on an
016 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
017 * KIND, either express or implied.  See the License for the
018 * specific language governing permissions and limitations
019 * under the License.
020 */
021
022import java.io.CharArrayWriter;
023import java.io.IOException;
024import java.io.Writer;
025
026import org.apache.maven.doxia.AbstractModuleTest;
027import org.apache.maven.doxia.logging.PlexusLoggerWrapper;
028import org.codehaus.plexus.util.IOUtil;
029import org.custommonkey.xmlunit.Diff;
030import org.custommonkey.xmlunit.XMLUnit;
031
032/**
033 * Abstract base class to test sinks.
034 *
035 * @version $Id$
036 * @since 1.0
037 */
038public abstract class AbstractSinkTest
039    extends AbstractModuleTest
040{
041    private final CharArrayWriter testWriter = new CharArrayWriter();
042    private Sink sink;
043
044    /**
045     * Resets the writer and creates a new sink with it.
046     *
047     * {@inheritDoc}
048     *
049     * @throws java.lang.Exception if something goes wrong.
050     */
051    @Override
052    protected void setUp()
053        throws Exception
054    {
055        super.setUp();
056
057        testWriter.reset();
058        sink = createSink( testWriter );
059        sink.enableLogging( new PlexusLoggerWrapper( getContainer().getLogger() ) );
060    }
061
062    /**
063     * Ability to wrap the xmlFragment with a roottag and namespaces, when required
064     * 
065     * @param xmlFragment
066     * @return valid XML
067     */
068    protected String wrapXml( String xmlFragment )
069    {
070        return xmlFragment;
071    }
072
073    // ---------------------------------------------------------------------
074    // Common test cases
075    // ----------------------------------------------------------------------
076
077    /**
078     * Tests that the current sink is able to render the common test document. If the sink is an Xml sink defined
079     * by {@link #isXmlSink()}, it uses an Xml Writer defined by {@link #getXmlTestWriter(String)}. If not, it uses
080     * the Writer defined by {@link #getTestWriter(String)}.
081     *
082     * @see SinkTestDocument
083     * @throws IOException If the target test document could not be generated.
084     * @see #isXmlSink()
085     * @see #getTestWriter(String)
086     * @see #getXmlTestWriter(String)
087     */
088    public final void testTestDocument() throws IOException
089    {
090        Writer writer = ( isXmlSink() ? getXmlTestWriter( "testDocument" ) : getTestWriter( "testDocument" ) );
091        Sink testSink = createSink( writer );
092
093        try
094        {
095            SinkTestDocument.generate( testSink );
096        }
097        finally
098        {
099            testSink.close();
100            IOUtil.close( writer );
101        }
102    }
103
104    /**
105     * Checks that the sequence <code>[title(), text( title ), title_()]</code>,
106     * invoked on the current sink, produces the same result as
107     * {@link #getTitleBlock getTitleBlock}( title ).
108     */
109    public void testTitle()
110    {
111        String title = "Grodek";
112        sink.title();
113        sink.text( title );
114        sink.title_();
115        sink.flush();
116        sink.close();
117
118        String actual = testWriter.toString();
119        String expected = getTitleBlock( title );
120
121        assertEquals( "Wrong title!", expected, actual );
122    }
123
124    /**
125     * Checks that the sequence <code>[author(), text( author ), author_()]
126     * </code>, invoked on the current sink, produces the same result as
127     * {@link #getAuthorBlock getAuthorBlock}( author ).
128     */
129    public void testAuthor()
130    {
131        String author = "Georg_Trakl";
132        sink.author();
133        sink.text( author );
134        sink.author_();
135        sink.flush();
136        sink.close();
137
138        String actual = testWriter.toString();
139        String expected = getAuthorBlock( author );
140
141        assertEquals( "Wrong author!", expected, actual );
142    }
143
144    /**
145     * Checks that the sequence <code>[date(), text( date ), date_()]</code>,
146     * invoked on the current sink, produces the same result as
147     * {@link #getDateBlock getDateBlock}( date ).
148     */
149    public void testDate()
150    {
151        String date = "1914";
152        sink.date();
153        sink.text( date );
154        sink.date_();
155        sink.flush();
156        sink.close();
157
158        String actual = testWriter.toString();
159        String expected = getDateBlock( date );
160
161        assertEquals( "Wrong date!", expected, actual );
162    }
163
164    /**
165     * Checks that the sequence <code>[head(), head_()]</code>,
166     * invoked on the current sink, produces the same result as
167     * {@link #getHeadBlock getHeadBlock()}.
168     */
169    public void testHead()
170    {
171        sink.head();
172        sink.head_();
173        sink.flush();
174        sink.close();
175
176        String actual = testWriter.toString();
177        String expected = getHeadBlock();
178
179        assertEquals( "Wrong head!", expected, actual );
180    }
181
182    /**
183     * Checks that the sequence <code>[body(), body_()]</code>,
184     * invoked on the current sink, produces the same result as
185     * {@link #getBodyBlock getBodyBlock()}.
186     */
187    public void testBody()
188    {
189        sink.body();
190        sink.body_();
191        sink.flush();
192        sink.close();
193
194        String actual = testWriter.toString();
195        String expected = getBodyBlock();
196
197        assertEquals( "Wrong body!", expected, actual );
198    }
199
200    /**
201     * Checks that the sequence <code>[sectionTitle(), text( title ),
202     * sectionTitle_()]</code>, invoked on the current sink, produces
203     * the same result as
204     * {@link #getSectionTitleBlock getSectionTitleBlock}( title ).
205     */
206    public void testSectionTitle()
207    {
208        String title = "Title";
209        sink.sectionTitle();
210        sink.text( title );
211        sink.sectionTitle_();
212        sink.flush();
213        sink.close();
214
215        String actual = testWriter.toString();
216        String expected = getSectionTitleBlock( title );
217
218        assertEquals( "Wrong sectionTitle!", expected, actual );
219    }
220
221    /**
222     * Checks that the sequence <code>[section1(), sectionTitle1(),
223     * text( title ), sectionTitle1_(), section1_()]</code>,
224     * invoked on the current sink, produces the same result as
225     * {@link #getSection1Block getSection1Block}( title ).
226     */
227    public void testSection1()
228    {
229        String title = "Title1";
230        sink.section1();
231        sink.sectionTitle1();
232        sink.text( title );
233        sink.sectionTitle1_();
234        sink.section1_();
235        sink.flush();
236        sink.close();
237
238        String actual = testWriter.toString();
239        String expected = getSection1Block( title );
240
241        assertEquals( "Wrong section1 block!", expected, actual );
242    }
243
244    /**
245     * Checks that the sequence <code>[section2(), sectionTitle2(),
246     * text( title ), sectionTitle2_(), section2_()]</code>,
247     * invoked on the current sink, produces the same result as
248     * {@link #getSection2Block getSection2Block}( title ).
249     */
250    public void testSection2()
251    {
252        String title = "Title2";
253        sink.section2();
254        sink.sectionTitle2();
255        sink.text( title );
256        sink.sectionTitle2_();
257        sink.section2_();
258        sink.flush();
259        sink.close();
260
261        String actual = testWriter.toString();
262        String expected = getSection2Block( title );
263
264        assertEquals( "Wrong section2 block!", expected, actual );
265    }
266
267    /**
268     * Checks that the sequence <code>[section3(), sectionTitle3(),
269     * text( title ), sectionTitle3_(), section3_()]</code>,
270     * invoked on the current sink, produces the same result as
271     * {@link #getSection3Block getSection3Block}( title ).
272     */
273    public void testSection3()
274    {
275        String title = "Title3";
276        sink.section3();
277        sink.sectionTitle3();
278        sink.text( title );
279        sink.sectionTitle3_();
280        sink.section3_();
281        sink.flush();
282        sink.close();
283
284        String actual = testWriter.toString();
285        String expected = getSection3Block( title );
286
287        assertEquals( "Wrong section3 block!", expected, actual );
288    }
289
290    /**
291     * Checks that the sequence <code>[section4(), sectionTitle4(),
292     * text( title ), sectionTitle4_(), section4_()]</code>,
293     * invoked on the current sink, produces the same result as
294     * {@link #getSection4Block getSection4Block}( title ).
295     *
296     */
297    public void testSection4()
298    {
299        String title = "Title4";
300        sink.section4();
301        sink.sectionTitle4();
302        sink.text( title );
303        sink.sectionTitle4_();
304        sink.section4_();
305        sink.flush();
306        sink.close();
307
308        String actual = testWriter.toString();
309        String expected = getSection4Block( title );
310
311        assertEquals( "Wrong section4 block!", expected, actual );
312    }
313
314    /**
315     * Checks that the sequence <code>[section5(), sectionTitle5(),
316     * text( title ), sectionTitle5_(), section5_()]</code>,
317     * invoked on the current sink, produces the same result as
318     * {@link #getSection5Block getSection5Block}( title ).
319     */
320    public void testSection5()
321    {
322        String title = "Title5";
323        sink.section5();
324        sink.sectionTitle5();
325        sink.text( title );
326        sink.sectionTitle5_();
327        sink.section5_();
328        sink.flush();
329        sink.close();
330
331        String actual = testWriter.toString();
332        String expected = getSection5Block( title );
333
334        assertEquals( "Wrong section5 block!", expected, actual );
335    }
336
337    /**
338     * Checks that the sequence <code>[list(), listItem(), text( item ),
339     * listItem_(), list_()]</code>, invoked on the current sink, produces
340     * the same result as {@link #getListBlock getListBlock}( item ).
341     *
342     */
343    public void testList()
344    {
345        String item = "list_item";
346        sink.list();
347        sink.listItem();
348        sink.text( item );
349        sink.listItem_();
350        sink.list_();
351        sink.flush();
352        sink.close();
353
354        String actual = testWriter.toString();
355        String expected = getListBlock( item );
356
357        assertEquals( "Wrong list!", expected, actual );
358    }
359
360    /**
361     * Checks that the sequence <code>
362     * [numberedList( Sink.NUMBERING_LOWER_ROMAN ), numberedListItem(),
363     * text( item ), numberedListItem_(), numberedList_()]</code>,
364     * invoked on the current sink, produces the same result as
365     * {@link #getNumberedListBlock getNumberedListBlock}( item ).
366     */
367    public void testNumberedList()
368    {
369        String item = "numbered_list_item";
370        sink.numberedList( Sink.NUMBERING_LOWER_ROMAN );
371        sink.numberedListItem();
372        sink.text( item );
373        sink.numberedListItem_();
374        sink.numberedList_();
375        sink.flush();
376        sink.close();
377
378        String actual = testWriter.toString();
379        String expected = getNumberedListBlock( item );
380
381        assertEquals( "Wrong numbered list!", expected, actual );
382    }
383
384    /**
385     * Checks that the sequence <code>[definitionList(), definitionListItem(),
386     * definedTerm(), text( definum ), definedTerm_(), definition(),
387     * text( definition ), definition_(), definitionListItem_(),
388     * definitionList_()]</code>, invoked on the current sink, produces the same
389     * result as {@link #getDefinitionListBlock getDefinitionListBlock}
390     * ( definum, definition ).
391     */
392    public void testDefinitionList()
393    {
394        String definum = "definum";
395        String definition = "definition";
396        sink.definitionList();
397        sink.definitionListItem();
398        sink.definedTerm();
399        sink.text( definum );
400        sink.definedTerm_();
401        sink.definition();
402        sink.text( definition );
403        sink.definition_();
404        sink.definitionListItem_();
405        sink.definitionList_();
406        sink.flush();
407        sink.close();
408
409        String actual = testWriter.toString();
410        String expected = getDefinitionListBlock( definum, definition );
411
412        assertEquals( "Wrong definition list!", expected, actual );
413    }
414
415    /**
416     * Checks that the sequence <code>[figure(), figureGraphics( source ),
417     * figureCaption(), text( caption ), figureCaption_(), figure_()]</code>,
418     * invoked on the current sink, produces the same result as
419     * {@link #getFigureBlock getFigureBlock}( source, caption ).
420     */
421    public void testFigure() throws Exception
422    {
423        String source = "figure.jpg";
424        String caption = "Figure_caption";
425        sink.figure();
426        sink.figureGraphics( source );
427        sink.figureCaption();
428        sink.text( caption );
429        sink.figureCaption_();
430        sink.figure_();
431        sink.flush();
432        sink.close();
433
434        String actual = testWriter.toString();
435        String expected = getFigureBlock( source, caption );
436
437        if ( isXmlSink() )
438        {
439            Diff diff = XMLUnit.compareXML( wrapXml( expected ), wrapXml( actual ) );
440            assertTrue( "Wrong figure!", diff.identical() );
441        }
442        else
443        {
444            assertEquals( "Wrong figure!", expected, actual );
445        }
446    }
447
448
449    public void testFigureWithoutCaption() throws Exception
450    {
451        String source = "figure.jpg";
452        sink.figure();
453        sink.figureGraphics( source );
454        sink.figure_();
455        sink.flush();
456        sink.close();
457
458        String actual = testWriter.toString();
459        String expected = getFigureBlock( source, null );
460
461        if ( isXmlSink() )
462        {
463            Diff diff = XMLUnit.compareXML( wrapXml( expected ), wrapXml( actual ) );
464            assertTrue( "Wrong figure!", diff.identical() );
465        }
466        else
467        {
468            assertEquals( "Wrong figure!", expected, actual );
469        }
470    }
471    
472    /**
473     * Checks that the sequence <code>[table(),
474     * tableRows( Sink.JUSTIFY_CENTER, false ), tableRow(), tableCell(),
475     * text( cell ), tableCell_(), tableRow_(), tableRows_(), tableCaption(),
476     * text( caption ), tableCaption_(), table_()]</code>,
477     * invoked on the current sink, produces the same result as
478     * {@link #getTableBlock getTableBlock}( cell, caption ).
479     */
480    public void testTable() throws Exception
481    {
482        String cell = "cell";
483        String caption = "Table_caption";
484        int[] justify = { Sink.JUSTIFY_CENTER };
485        sink.table();
486        sink.tableRows( justify, false );
487        sink.tableRow();
488        sink.tableCell();
489        sink.text( cell );
490        sink.tableCell_();
491        sink.tableRow_();
492        sink.tableRows_();
493        sink.tableCaption();
494        sink.text( caption );
495        sink.tableCaption_();
496        sink.table_();
497        sink.flush();
498        sink.close();
499
500        String actual = testWriter.toString();
501        String expected = getTableBlock( cell, caption );
502
503        if ( isXmlSink() )
504        {
505            Diff diff = XMLUnit.compareXML( wrapXml( expected ), wrapXml( actual ) );
506            assertTrue( "Wrong table!", diff.identical() );
507        }
508        else
509        {
510            assertEquals( "Wrong table!", expected, actual );
511        }
512    }
513
514    /**
515     * Checks that the sequence <code>[paragraph(), text( text ),
516     * paragraph_()]</code>, invoked on the current sink, produces
517     * the same result as {@link #getParagraphBlock getParagraphBlock}( text ).
518     */
519    public void testParagraph()
520    {
521        String text = "Text";
522        sink.paragraph();
523        sink.text( text );
524        sink.paragraph_();
525        sink.flush();
526        sink.close();
527
528        String actual = testWriter.toString();
529        String expected = getParagraphBlock( text );
530
531        assertEquals( "Wrong paragraph!", expected, actual );
532    }
533
534    /**
535     * Checks that the sequence <code>[verbatim( SinkEventAttributeSet.BOXED ), text( text ),
536     * verbatim_()]</code>, invoked on the current sink, produces the
537     * same result as {@link #getVerbatimBlock getVerbatimBlock}( text ).
538     */
539    public void testVerbatim()
540    {
541        String text = "Text";
542        sink.verbatim( SinkEventAttributeSet.BOXED );
543        sink.text( text );
544        sink.verbatim_();
545        sink.flush();
546        sink.close();
547
548        String actual = testWriter.toString();
549        String expected = getVerbatimBlock( text );
550
551        assertEquals( "Wrong verbatim!", expected, actual );
552    }
553
554    /**
555     * Checks that the sequence <code>[horizontalRule()]</code>,
556     * invoked on the current sink, produces the same result as
557     * {@link #getHorizontalRuleBlock getHorizontalRuleBlock()}.
558     */
559    public void testHorizontalRule()
560    {
561        sink.horizontalRule();
562        sink.flush();
563        sink.close();
564
565        String actual = testWriter.toString();
566        String expected = getHorizontalRuleBlock();
567
568        assertEquals( "Wrong horizontal rule!", expected, actual );
569    }
570
571    /**
572     * Checks that the sequence <code>[pageBreak()]</code>,
573     * invoked on the current sink, produces the same result as
574     * {@link #getPageBreakBlock getPageBreakBlock()}.
575     */
576    public void testPageBreak()
577    {
578        sink.pageBreak();
579        sink.flush();
580        sink.close();
581
582        String actual = testWriter.toString();
583        String expected = getPageBreakBlock();
584
585        assertEquals( "Wrong pageBreak!", expected, actual );
586    }
587
588    /**
589     * Checks that the sequence <code>[anchor( anchor ), text( anchor ),
590     * anchor_()]</code>, invoked on the current sink, produces the same
591     * result as {@link #getAnchorBlock getAnchorBlock}( anchor ).
592     */
593    public void testAnchor()
594    {
595        String anchor = "Anchor";
596        sink.anchor( anchor );
597        sink.text( anchor );
598        sink.anchor_();
599        sink.flush();
600        sink.close();
601
602        String actual = testWriter.toString();
603        String expected = getAnchorBlock( anchor );
604
605        assertEquals( "Wrong anchor!", expected, actual );
606    }
607
608    /**
609     * Checks that the sequence <code>[link( link ), text( text ),
610     * link_()]</code>, invoked on the current sink, produces the same
611     * result as {@link #getLinkBlock getLinkBlock}( link, text ).
612     */
613    public void testLink()
614    {
615        String link = "#Link";
616        String text = "Text";
617        sink.link( link );
618        sink.text( text );
619        sink.link_();
620        sink.flush();
621        sink.close();
622
623        String actual = testWriter.toString();
624        String expected = getLinkBlock( link, text );
625
626        assertEquals( "Wrong link!", expected, actual );
627    }
628
629    /**
630     * Checks that the sequence <code>[italic(), text( text ), italic_()]</code>,
631     * invoked on the current sink, produces the same result as
632     * {@link #getItalicBlock getItalicBlock}( text ).
633     */
634    public void testItalic()
635    {
636        String text = "Italic";
637        sink.italic();
638        sink.text( text );
639        sink.italic_();
640        sink.flush();
641        sink.close();
642
643        String actual = testWriter.toString();
644        String expected = getItalicBlock( text );
645
646        assertEquals( "Wrong italic!", expected, actual );
647    }
648
649    /**
650     * Checks that the sequence <code>[bold(), text( text ), bold_()]</code>,
651     * invoked on the current sink, produces the same result as
652     * {@link #getBoldBlock getBoldBlock}( text ).
653     */
654    public void testBold()
655    {
656        String text = "Bold";
657        sink.bold();
658        sink.text( text );
659        sink.bold_();
660        sink.flush();
661        sink.close();
662
663        String actual = testWriter.toString();
664        String expected = getBoldBlock( text );
665
666        assertEquals( "Wrong bold!", expected, actual );
667    }
668
669    /**
670     * Checks that the sequence <code>[monospaced(), text( text ),
671     * monospaced_()]</code>, invoked on the current sink, produces the same
672     * result as {@link #getMonospacedBlock getMonospacedBlock}( text ).
673     */
674    public void testMonospaced()
675    {
676        String text = "Monospaced";
677        sink.monospaced();
678        sink.text( text );
679        sink.monospaced_();
680        sink.flush();
681        sink.close();
682
683        String actual = testWriter.toString();
684        String expected = getMonospacedBlock( text );
685
686        assertEquals( "Wrong monospaced!", expected, actual );
687    }
688
689    /**
690     * Checks that the sequence <code>[lineBreak()]</code>,
691     * invoked on the current sink, produces the same result as
692     * {@link #getLineBreakBlock getLineBreakBlock()}.
693     */
694    public void testLineBreak()
695    {
696        sink.lineBreak();
697        sink.flush();
698        sink.close();
699
700        String actual = testWriter.toString();
701        String expected = getLineBreakBlock();
702
703        assertEquals( "Wrong lineBreak!", expected, actual );
704    }
705
706    /**
707     * Checks that the sequence <code>[nonBreakingSpace()]</code>,
708     * invoked on the current sink, produces the same result as
709     * {@link #getNonBreakingSpaceBlock getNonBreakingSpaceBlock()}.
710     */
711    public void testNonBreakingSpace()
712    {
713        sink.nonBreakingSpace();
714        sink.flush();
715        sink.close();
716
717        String actual = testWriter.toString();
718        String expected = getNonBreakingSpaceBlock();
719
720        assertEquals( "Wrong nonBreakingSpace!", expected, actual );
721    }
722
723    /**
724     * Checks that the sequence <code>[text( text )]</code>,
725     * invoked on the current sink, produces the same result as
726     * {@link #getTextBlock getTextBlock()}.
727     */
728    public void testText()
729    {
730        String text = "~,_=,_-,_+,_*,_[,_],_<,_>,_{,_},_\\";
731        sink.text( text );
732        sink.flush();
733        sink.close();
734
735        String actual = testWriter.toString();
736        String expected = getTextBlock( text );
737
738        assertEquals( "Wrong text!", expected, actual );
739    }
740
741    /**
742     * Checks that the sequence <code>[rawText( text )]</code>,
743     * invoked on the current sink, produces the same result as
744     * {@link #getRawTextBlock getRawTextBlock}( text ).
745     */
746    public void testRawText()
747    {
748        String text = "~,_=,_-,_+,_*,_[,_],_<,_>,_{,_},_\\";
749        sink.rawText( text );
750        sink.flush();
751        sink.close();
752
753        String actual = testWriter.toString();
754        String expected = getRawTextBlock( text );
755
756        assertEquals( "Wrong rawText!", expected, actual );
757    }
758
759    /**
760     * Checks that the sequence <code>[comment(comment)]</code>,
761     * invoked on the current sink, produces the same result as
762     * {@link #getCommentBlock getCommentBlock}( comment ).
763     * @since 1.1.1
764     */
765    public void testComment()
766    {
767        String comment = "Simple comment with ----";
768        sink.comment( comment );
769        sink.flush();
770        sink.close();
771
772        String actual = testWriter.toString();
773        String expected = getCommentBlock( comment );
774
775        assertEquals( "Wrong comment!", expected, actual );
776    }
777
778    // ----------------------------------------------------------------------
779    // Utility methods
780    // ----------------------------------------------------------------------
781
782    /**
783     * Returns the sink that is currently being tested.
784     * @return The current test sink.
785     */
786    protected Sink getSink()
787    {
788        return sink;
789    }
790
791    /**
792     * Returns a String representation of all events that have been written to the sink.
793     * @return The Sink content as a String.
794     */
795    protected String getSinkContent()
796    {
797        return testWriter.toString();
798    }
799
800    /**
801     * Returns the directory where all sink test output will go.
802     * @return The test output directory.
803     */
804    protected String getOutputDir()
805    {
806        return "sink/";
807    }
808
809    // ----------------------------------------------------------------------
810    // Abstract methods the individual SinkTests must provide
811    // ----------------------------------------------------------------------
812
813    /**
814     * This method allows to use the correct Writer in {@link #testTestDocument()}.
815     *
816     * @return <code>true</code> if the Sink is an XML one, <code>false</code> otherwise.
817     * @see #testTestDocument()
818     */
819    protected abstract boolean isXmlSink();
820
821    /**
822     * Return a new instance of the sink that is being tested.
823     * @param writer The writer for the sink.
824     * @return A new sink.
825     */
826    protected abstract Sink createSink( Writer writer );
827
828    /**
829     * Returns a title block generated by this sink.
830     * @param title The title to use.
831     * @return The result of invoking a title block on the current sink.
832     * @see #testTitle()
833     */
834    protected abstract String getTitleBlock( String title );
835
836    /**
837     * Returns an author block generated by this sink.
838     * @param author The author to use.
839     * @return The result of invoking an author block on the current sink.
840     * @see #testAuthor()
841     */
842    protected abstract String getAuthorBlock( String author );
843
844    /**
845     * Returns a date block generated by this sink.
846     * @param date The date to use.
847     * @return The result of invoking a date block on the current sink.
848     * @see #testDate()
849     */
850    protected abstract String getDateBlock( String date );
851
852    /**
853     * Returns a head block generated by this sink.
854     * @return The result of invoking a head block on the current sink.
855     * @see #testHead()
856     */
857    protected abstract String getHeadBlock();
858
859    /**
860     * Returns a body block generated by this sink.
861     * @return The result of invoking a body block on the current sink.
862     * @see #testBody()
863     */
864    protected abstract String getBodyBlock();
865
866    /**
867     * Returns a SectionTitle block generated by this sink.
868     * @param title The title to use.
869     * @return The result of invoking a SectionTitle block on the current sink.
870     * @see #testSectionTitle()
871     */
872    protected abstract String getSectionTitleBlock( String title );
873
874    /**
875     * Returns a Section1 block generated by this sink.
876     * @param title The title to use.
877     * @return The result of invoking a Section1 block on the current sink.
878     * @see #testSection1()
879     */
880    protected abstract String getSection1Block( String title );
881
882    /**
883     * Returns a Section2 block generated by this sink.
884     * @param title The title to use.
885     * @return The result of invoking a Section2 block on the current sink.
886     * @see #testSection2()
887     */
888    protected abstract String getSection2Block( String title );
889
890    /**
891     * Returns a Section3 block generated by this sink.
892     * @param title The title to use.
893     * @return The result of invoking a Section3 block on the current sink.
894     * @see #testSection3()
895     */
896    protected abstract String getSection3Block( String title );
897
898    /**
899     * Returns a Section4 block generated by this sink.
900     * @param title The title to use.
901     * @return The result of invoking a Section4 block on the current sink.
902     * @see #testSection4()
903     */
904    protected abstract String getSection4Block( String title );
905
906    /**
907     * Returns a Section5 block generated by this sink.
908     * @param title The title to use.
909     * @return The result of invoking a Section5 block on the current sink.
910     * @see #testSection5()
911     */
912    protected abstract String getSection5Block( String title );
913
914    /**
915     * Returns a list block generated by this sink.
916     * @param item The item to use.
917     * @return The result of invoking a list block on the current sink.
918     * @see #testList()
919     */
920    protected abstract String getListBlock( String item );
921
922    /**
923     * Returns a NumberedList block generated by this sink.
924     * @param item The item to use.
925     * @return The result of invoking a NumberedList block on the current sink.
926     * @see #testNumberedList()
927     */
928    protected abstract String getNumberedListBlock( String item );
929
930    /**
931     * Returns a DefinitionList block generated by this sink.
932     * @param definum The term to define.
933     * @param definition The definition.
934     * @return The result of invoking a DefinitionList block on the current sink.
935     * @see #testDefinitionList()
936     */
937    protected abstract String getDefinitionListBlock( String definum,
938        String definition );
939
940    /**
941     * Returns a Figure block generated by this sink.
942     * @param source The figure source string.
943     * @param caption The caption to use (may be null).
944     * @return The result of invoking a Figure block on the current sink.
945     * @see #testFigure()
946     */
947    protected abstract String getFigureBlock( String source, String caption );
948    
949    /**
950     * Returns a Table block generated by this sink.
951     * @param cell A tabel cell to use.
952     * @param caption The caption to use (may be null).
953     * @return The result of invoking a Table block on the current sink.
954     * @see #testTable()
955     */
956    protected abstract String getTableBlock( String cell, String caption );
957
958    /**
959     * Returns a Paragraph block generated by this sink.
960     * @param text The text to use.
961     * @return The result of invoking a Paragraph block on the current sink.
962     * @see #testParagraph()
963     */
964    protected abstract String getParagraphBlock( String text );
965
966    /**
967     * Returns a Verbatim block generated by this sink.
968     * @param text The text to use.
969     * @return The result of invoking a Verbatim block on the current sink.
970     * @see #testVerbatim()
971     */
972    protected abstract String getVerbatimBlock( String text );
973
974    /**
975     * Returns a HorizontalRule block generated by this sink.
976     * @return The result of invoking a HorizontalRule block on the current sink.
977     * @see #testHorizontalRule()
978     */
979    protected abstract String getHorizontalRuleBlock();
980
981    /**
982     * Returns a PageBreak block generated by this sink.
983     * @return The result of invoking a PageBreak block on the current sink.
984     * @see #testPageBreak()
985     */
986    protected abstract String getPageBreakBlock();
987
988    /**
989     * Returns a Anchor block generated by this sink.
990     * @param anchor The anchor to use.
991     * @return The result of invoking a Anchor block on the current sink.
992     * @see #testAnchor()
993     */
994    protected abstract String getAnchorBlock( String anchor );
995
996    /**
997     * Returns a Link block generated by this sink.
998     * @param link The link to use.
999     * @param text The link text.
1000     * @return The result of invoking a Link block on the current sink.
1001     * @see #testLink()
1002     */
1003    protected abstract String getLinkBlock( String link, String text );
1004
1005    /**
1006     * Returns a Italic block generated by this sink.
1007     * @param text The text to use.
1008     * @return The result of invoking a Italic block on the current sink.
1009     * @see #testItalic()
1010     */
1011    protected abstract String getItalicBlock( String text );
1012
1013    /**
1014     * Returns a Bold block generated by this sink.
1015     * @param text The text to use.
1016     * @return The result of invoking a Bold block on the current sink.
1017     * @see #testBold()
1018     */
1019    protected abstract String getBoldBlock( String text );
1020
1021    /**
1022     * Returns a Monospaced block generated by this sink.
1023     * @param text The text to use.
1024     * @return The result of invoking a Monospaced block on the current sink.
1025     * @see #testMonospaced()
1026     */
1027    protected abstract String getMonospacedBlock( String text );
1028
1029    /**
1030     * Returns a LineBreak block generated by this sink.
1031     * @return The result of invoking a LineBreak block on the current sink.
1032     * @see #testLineBreak()
1033     */
1034    protected abstract String getLineBreakBlock();
1035
1036    /**
1037     * Returns a NonBreakingSpace block generated by this sink.
1038     * @return The result of invoking a NonBreakingSpace block
1039     * on the current sink.
1040     * @see #testNonBreakingSpace()
1041     */
1042    protected abstract String getNonBreakingSpaceBlock();
1043
1044    /**
1045     * Returns a Text block generated by this sink.
1046     * @param text The text to use.
1047     * @return The result of invoking a Text block on the current sink.
1048     * @see #testText()
1049     */
1050    protected abstract String getTextBlock( String text );
1051
1052    /**
1053     * Returns a RawText block generated by this sink.
1054     * @param text The text to use.
1055     * @return The result of invoking a RawText block on the current sink.
1056     * @see #testRawText()
1057     */
1058    protected abstract String getRawTextBlock( String text );
1059
1060    /**
1061     * Returns a comment block generated by this sink.
1062     * @param text The text to use.
1063     * @return The result of invoking a comment block on the current sink.
1064     * @see #testComment()
1065     * @since 1.1.1
1066     */
1067    protected abstract String getCommentBlock( String text );
1068    
1069    protected final void verifyValignSup( String text )
1070    {
1071        sink.text( "ValignSup", new SinkEventAttributeSet( SinkEventAttributes.VALIGN, "sup"  ) );
1072        sink.flush();
1073        sink.close();
1074
1075        String actual = testWriter.toString();
1076
1077        assertEquals( "Wrong valign sup!", text, actual );
1078    }
1079    
1080    protected final void verifyValignSub( String text )
1081    {
1082        sink.text( "ValignSub", new SinkEventAttributeSet( SinkEventAttributes.VALIGN, "sub"  ) );
1083        sink.flush();
1084        sink.close();
1085
1086        String actual = testWriter.toString();
1087
1088        assertEquals( "Wrong valign sub!", text, actual );
1089    }
1090
1091    protected final void verifyDecorationUnderline( String text )
1092    {
1093        sink.text( "DecorationUnderline", new SinkEventAttributeSet( SinkEventAttributes.DECORATION, "underline"  ) );
1094        sink.flush();
1095        sink.close();
1096
1097        String actual = testWriter.toString();
1098
1099        assertEquals( "Wrong decoration underline!", text, actual );
1100    }
1101
1102    protected final void verifyDecorationLineThrough( String text )
1103    {
1104        sink.text( "DecorationLineThrough", new SinkEventAttributeSet( SinkEventAttributes.DECORATION, "line-through"  ) );
1105        sink.flush();
1106        sink.close();
1107
1108        String actual = testWriter.toString();
1109
1110        assertEquals( "Wrong decoration line-through!", text, actual );
1111    }
1112
1113    
1114}