package org.apache.maven.doxia.sink.impl;

/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */

import java.io.CharArrayWriter;
import java.io.IOException;
import java.io.Writer;

import org.apache.maven.doxia.AbstractModuleTest;
import org.apache.maven.doxia.logging.PlexusLoggerWrapper;
import org.apache.maven.doxia.sink.Sink;
import org.apache.maven.doxia.sink.SinkEventAttributes;
import org.codehaus.plexus.DefaultPlexusContainer;
import org.codehaus.plexus.util.IOUtil;

import static org.hamcrest.MatcherAssert.assertThat;
import static org.xmlunit.matchers.CompareMatcher.isIdenticalTo;

/**
 * Abstract base class to test sinks.
 */
public abstract class AbstractSinkTest
    extends AbstractModuleTest
{
    private final CharArrayWriter testWriter = new CharArrayWriter();
    private Sink sink;

    /**
     * Resets the writer and creates a new sink with it.
     *
     * {@inheritDoc}
     *
     * @throws java.lang.Exception if something goes wrong.
     */
    @Override
    protected void setUp()
        throws Exception
    {
        super.setUp();

        testWriter.reset();
        sink = createSink( testWriter );
        sink.enableLogging( new PlexusLoggerWrapper( ( ( DefaultPlexusContainer )getContainer() ).getLogger() ) );
    }

    /**
     * Ability to wrap the xmlFragment with a roottag and namespaces, when required
     *
     * @param xmlFragment
     * @return valid XML
     */
    protected String wrapXml( String xmlFragment )
    {
        return xmlFragment;
    }

    /**
     * Transforms a given string to be compatible to XML comments.
     *
     * @param comment The string to transform.
     *
     * @return The given string transformed to be compatible to XML comments.
     *
     * @see <a href="http://www.w3.org/TR/2000/REC-xml-20001006#sec-comments">
     *   http://www.w3.org/TR/2000/REC-xml-20001006#sec-comments</a>
     * @since 1.7
     */
    protected static String toXmlComment( final String comment )
    {
        String processed = comment;

        if ( processed != null )
        {
            while ( processed.contains( "--" ) )
            {
                processed = processed.replace( "--", "- -" );
            }

            if ( processed.endsWith( "-" ) )
            {
                processed += " ";
            }
        }

        return processed;
    }

    // ---------------------------------------------------------------------
    // Common test cases
    // ----------------------------------------------------------------------

    /**
     * Tests that the current sink is able to render the common test document. If the sink is an Xml sink defined
     * by {@link #isXmlSink()}, it uses an Xml Writer defined by {@link #getXmlTestWriter(String)}. If not, it uses
     * the Writer defined by {@link #getTestWriter(String)}.
     *
     * @see SinkTestDocument
     * @throws IOException If the target test document could not be generated.
     * @see #isXmlSink()
     * @see #getTestWriter(String)
     * @see #getXmlTestWriter(String)
     */
    public final void testTestDocument() throws IOException
    {
        Writer writer = ( isXmlSink() ? getXmlTestWriter( "testDocument" ) : getTestWriter( "testDocument" ) );
        Sink testSink = createSink( writer );

        try
        {
            SinkTestDocument.generate( testSink );
        }
        finally
        {
            testSink.close();
            IOUtil.close( writer );
        }
    }

    /**
     * Checks that the sequence <code>[title(), text( title ), title_()]</code>,
     * invoked on the current sink, produces the same result as
     * {@link #getTitleBlock getTitleBlock}( title ).
     */
    public void testTitle()
    {
        String title = "Grodek";
        sink.title();
        sink.text( title );
        sink.title_();
        sink.flush();
        sink.close();

        String actual = testWriter.toString();
        String expected = getTitleBlock( title );

        assertEquals( "Wrong title!", expected, actual );
    }

    /**
     * Checks that the sequence <code>[author(), text( author ), author_()]
     * </code>, invoked on the current sink, produces the same result as
     * {@link #getAuthorBlock getAuthorBlock}( author ).
     */
    public void testAuthor()
    {
        String author = "Georg_Trakl";
        sink.author();
        sink.text( author );
        sink.author_();
        sink.flush();
        sink.close();

        String actual = testWriter.toString();
        String expected = getAuthorBlock( author );

        assertEquals( "Wrong author!", expected, actual );
    }

    /**
     * Checks that the sequence <code>[date(), text( date ), date_()]</code>,
     * invoked on the current sink, produces the same result as
     * {@link #getDateBlock getDateBlock}( date ).
     */
    public void testDate()
    {
        String date = "1914";
        sink.date();
        sink.text( date );
        sink.date_();
        sink.flush();
        sink.close();

        String actual = testWriter.toString();
        String expected = getDateBlock( date );

        assertEquals( "Wrong date!", expected, actual );
    }

    /**
     * Checks that the sequence <code>[head(), head_()]</code>,
     * invoked on the current sink, produces the same result as
     * {@link #getHeadBlock getHeadBlock()}.
     */
    public void testHead()
    {
        sink.head();
        sink.head_();
        sink.flush();
        sink.close();

        String actual = normalizeLineEnds( testWriter.toString() );
        String expected = normalizeLineEnds( getHeadBlock() );

        assertEquals( "Wrong head!", expected, actual );
    }

    /**
     * Checks that the sequence <code>[body(), body_()]</code>,
     * invoked on the current sink, produces the same result as
     * {@link #getBodyBlock getBodyBlock()}.
     */
    public void testBody()
    {
        sink.body();
        sink.body_();
        sink.flush();
        sink.close();

        String actual = testWriter.toString();
        String expected = getBodyBlock();

        assertEquals( "Wrong body!", expected, actual );
    }

    /**
     * Checks that the sequence <code>[article(), article_()]</code>,
     * invoked on the current sink, produces the same result as
     * {@link #getArticleBlock getArticleBlock()}.
     */
    public void testArticle()
    {
        sink.article();
        sink.article_();
        sink.flush();
        sink.close();

        String actual = testWriter.toString();
        String expected = getArticleBlock();

        assertEquals( "Wrong article!", expected, actual );
    }

    /**
     * Checks that the sequence <code>[navigation(), navigation_()]</code>,
     * invoked on the current sink, produces the same result as
     * {@link #getNavigationBlock getNavigationBlock()}.
     */
    public void testNavigation()
    {
        sink.navigation();
        sink.navigation_();
        sink.flush();
        sink.close();

        String actual = testWriter.toString();
        String expected = getNavigationBlock();

        assertEquals( "Wrong navigation!", expected, actual );
    }

    /**
     * Checks that the sequence <code>[sidebar(), sidebar_()]</code>,
     * invoked on the current sink, produces the same result as
     * {@link #getSidebarBlock getSidebarBlock()}.
     */
    public void testSidebar()
    {
        sink.sidebar();
        sink.sidebar_();
        sink.flush();
        sink.close();

        String actual = testWriter.toString();
        String expected = getSidebarBlock();

        assertEquals( "Wrong sidebar!", expected, actual );
    }

    /**
     * Checks that the sequence <code>[sectionTitle(), text( title ),
     * sectionTitle_()]</code>, invoked on the current sink, produces
     * the same result as
     * {@link #getSectionTitleBlock getSectionTitleBlock}( title ).
     */
    public void testSectionTitle()
    {
        String title = "Title";
        sink.sectionTitle();
        sink.text( title );
        sink.sectionTitle_();
        sink.flush();
        sink.close();

        String actual = testWriter.toString();
        String expected = getSectionTitleBlock( title );

        assertEquals( "Wrong sectionTitle!", expected, actual );
    }

    /**
     * Checks that the sequence <code>[section1(), sectionTitle1(),
     * text( title ), sectionTitle1_(), section1_()]</code>,
     * invoked on the current sink, produces the same result as
     * {@link #getSection1Block getSection1Block}( title ).
     */
    public void testSection1()
    {
        String title = "Title1";
        sink.section1();
        sink.header();
        sink.sectionTitle1();
        sink.text( title );
        sink.sectionTitle1_();
        sink.header_();
        sink.section1_();
        sink.flush();
        sink.close();

        String actual = testWriter.toString();
        String expected = getSection1Block( title );

        assertEquals( "Wrong section1 block!", expected, actual );
    }

    /**
     * Checks that the sequence <code>[section2(), sectionTitle2(),
     * text( title ), sectionTitle2_(), section2_()]</code>,
     * invoked on the current sink, produces the same result as
     * {@link #getSection2Block getSection2Block}( title ).
     */
    public void testSection2()
    {
        String title = "Title2";
        sink.section2();
        sink.header();
        sink.sectionTitle2();
        sink.text( title );
        sink.sectionTitle2_();
        sink.header_();
        sink.section2_();
        sink.flush();
        sink.close();

        String actual = testWriter.toString();
        String expected = getSection2Block( title );

        assertEquals( "Wrong section2 block!", expected, actual );
    }

    /**
     * Checks that the sequence <code>[section3(), sectionTitle3(),
     * text( title ), sectionTitle3_(), section3_()]</code>,
     * invoked on the current sink, produces the same result as
     * {@link #getSection3Block getSection3Block}( title ).
     */
    public void testSection3()
    {
        String title = "Title3";
        sink.section3();
        sink.header();
        sink.sectionTitle3();
        sink.text( title );
        sink.sectionTitle3_();
        sink.header_();
        sink.section3_();
        sink.flush();
        sink.close();

        String actual = testWriter.toString();
        String expected = getSection3Block( title );

        assertEquals( "Wrong section3 block!", expected, actual );
    }

    /**
     * Checks that the sequence <code>[section4(), sectionTitle4(),
     * text( title ), sectionTitle4_(), section4_()]</code>,
     * invoked on the current sink, produces the same result as
     * {@link #getSection4Block getSection4Block}( title ).
     *
     */
    public void testSection4()
    {
        String title = "Title4";
        sink.section4();
        sink.header();
        sink.sectionTitle4();
        sink.text( title );
        sink.sectionTitle4_();
        sink.header_();
        sink.section4_();
        sink.flush();
        sink.close();

        String actual = testWriter.toString();
        String expected = getSection4Block( title );

        assertEquals( "Wrong section4 block!", expected, actual );
    }

    /**
     * Checks that the sequence <code>[section5(), sectionTitle5(),
     * text( title ), sectionTitle5_(), section5_()]</code>,
     * invoked on the current sink, produces the same result as
     * {@link #getSection5Block getSection5Block}( title ).
     */
    public void testSection5()
    {
        String title = "Title5";
        sink.section5();
        sink.header();
        sink.sectionTitle5();
        sink.text( title );
        sink.sectionTitle5_();
        sink.header_();
        sink.section5_();
        sink.flush();
        sink.close();

        String actual = testWriter.toString();
        String expected = getSection5Block( title );

        assertEquals( "Wrong section5 block!", expected, actual );
    }

    /**
     * Checks that the sequence <code>[header(), header_()]</code>,
     * invoked on the current sink, produces the same result as
     * {@link #getHeaderBlock getHeaderBlock()}.
     */
    public void testHeader()
    {
        sink.header();
        sink.header_();
        sink.flush();
        sink.close();

        String actual = testWriter.toString();
        String expected = getHeaderBlock();

        assertEquals( "Wrong header!", expected, actual );
    }

    /**
     * Checks that the sequence <code>[content(), content(), content_(), content_()]</code>,
     * invoked on the current sink, produces the same result as
     * {@link #getContentBlock getContentBlock()}.
     */
    public void testContent()
    {
        sink.content();
        sink.content();
        sink.content_();
        sink.content_();
        sink.flush();
        sink.close();

        String actual = testWriter.toString();
        String expected = getContentBlock();

        assertEquals( "Wrong content!", expected, actual );
    }

    /**
     * Checks that the sequence <code>[footer(), footer_()]</code>,
     * invoked on the current sink, produces the same result as
     * {@link #getHeaderBlock getHeaderBlock()}.
     */
    public void testFooter()
    {
        sink.footer();
        sink.footer_();
        sink.flush();
        sink.close();

        String actual = testWriter.toString();
        String expected = getFooterBlock();

        assertEquals( "Wrong footer!", expected, actual );
    }

    /**
     * Checks that the sequence <code>[list(), listItem(), text( item ),
     * listItem_(), list_()]</code>, invoked on the current sink, produces
     * the same result as {@link #getListBlock getListBlock}( item ).
     *
     */
    public void testList()
    {
        String item = "list_item";
        sink.list();
        sink.listItem();
        sink.text( item );
        sink.listItem_();
        sink.list_();
        sink.flush();
        sink.close();

        String actual = testWriter.toString();
        String expected = getListBlock( item );

        assertEquals( "Wrong list!", expected, actual );
    }

    /**
     * Checks that the sequence <code>
     * [numberedList( Sink.NUMBERING_LOWER_ROMAN ), numberedListItem(),
     * text( item ), numberedListItem_(), numberedList_()]</code>,
     * invoked on the current sink, produces the same result as
     * {@link #getNumberedListBlock getNumberedListBlock}( item ).
     */
    public void testNumberedList()
    {
        String item = "numbered_list_item";
        sink.numberedList( Sink.NUMBERING_LOWER_ROMAN );
        sink.numberedListItem();
        sink.text( item );
        sink.numberedListItem_();
        sink.numberedList_();
        sink.flush();
        sink.close();

        String actual = testWriter.toString();
        String expected = getNumberedListBlock( item );

        assertEquals( "Wrong numbered list!", expected, actual );
    }

    /**
     * Checks that the sequence <code>[definitionList(), definitionListItem(),
     * definedTerm(), text( definum ), definedTerm_(), definition(),
     * text( definition ), definition_(), definitionListItem_(),
     * definitionList_()]</code>, invoked on the current sink, produces the same
     * result as {@link #getDefinitionListBlock getDefinitionListBlock}
     * ( definum, definition ).
     */
    public void testDefinitionList()
    {
        String definum = "definum";
        String definition = "definition";
        sink.definitionList();
        sink.definitionListItem();
        sink.definedTerm();
        sink.text( definum );
        sink.definedTerm_();
        sink.definition();
        sink.text( definition );
        sink.definition_();
        sink.definitionListItem_();
        sink.definitionList_();
        sink.flush();
        sink.close();

        String actual = testWriter.toString();
        String expected = getDefinitionListBlock( definum, definition );

        assertEquals( "Wrong definition list!", expected, actual );
    }

    /**
     * Checks that the sequence <code>[figure(), figureGraphics( source ),
     * figureCaption(), text( caption ), figureCaption_(), figure_()]</code>,
     * invoked on the current sink, produces the same result as
     * {@link #getFigureBlock getFigureBlock}( source, caption ).
     */
    public void testFigure()
    {
        String source = "figure.jpg";
        String caption = "Figure_caption";
        sink.figure();
        sink.figureGraphics( source );
        sink.figureCaption();
        sink.text( caption );
        sink.figureCaption_();
        sink.figure_();
        sink.flush();
        sink.close();

        String actual = testWriter.toString();
        String expected = getFigureBlock( source, caption );

        if ( isXmlSink() )
        {
            assertThat ( wrapXml( actual ), isIdenticalTo( wrapXml( expected ) ));
        }
        else
        {
            assertEquals( actual, expected );
        }
    }


    public void testFigureWithoutCaption()
    {
        String source = "figure.jpg";
        sink.figure();
        sink.figureGraphics( source );
        sink.figure_();
        sink.flush();
        sink.close();

        String actual = testWriter.toString();
        String expected = getFigureBlock( source, null );

        if ( isXmlSink() )
        {
            assertThat ( wrapXml( actual ), isIdenticalTo( wrapXml( expected ) ));
        }
        else
        {
            assertEquals( actual, expected );
        }
    }
    public void testFigureFromUrl()
    {
        String source = "http://www.gravatar.com/avatar/cdbe99fe3d6af6a18dd8c35b0687a50b?d=mm&s=60";
        sink.figure();
        sink.figureGraphics( source );
        sink.figure_();
        sink.flush();
        sink.close();

        String actual = testWriter.toString();
        String expected = getFigureBlock( source, null );

        if ( isXmlSink() )
        {
            assertThat ( wrapXml( actual ), isIdenticalTo( wrapXml( expected ) ));
        }
        else
        {
            assertEquals( actual, expected );
        }
    }

    /**
     * Checks that the sequence <code>[table(),
     * tableRows( Sink.JUSTIFY_CENTER, false ), tableRow(), tableCell(),
     * text( cell ), tableCell_(), tableRow_(), tableRows_(), tableCaption(),
     * text( caption ), tableCaption_(), table_()]</code>,
     * invoked on the current sink, produces the same result as
     * {@link #getTableBlock getTableBlock}( cell, caption ).
     */
    public void testTable()
    {
        String cell = "cell";
        String caption = "Table_caption";
        int[] justify = { Sink.JUSTIFY_CENTER };
        sink.table();
        sink.tableRows( justify, false );
        sink.tableRow();
        sink.tableCell();
        sink.text( cell );
        sink.tableCell_();
        sink.tableRow_();
        sink.tableRows_();
        sink.tableCaption();
        sink.text( caption );
        sink.tableCaption_();
        sink.table_();
        sink.flush();
        sink.close();

        String actual = testWriter.toString();
        String expected = getTableBlock( cell, caption );

        if ( isXmlSink() )
        {
            assertThat ( wrapXml( actual ), isIdenticalTo( wrapXml( expected ) ));
        }
        else
        {
            assertEquals( actual, expected );
        }
    }

    /**
     * Checks that the sequence <code>[paragraph(), text( text ),
     * paragraph_()]</code>, invoked on the current sink, produces
     * the same result as {@link #getParagraphBlock getParagraphBlock}( text ).
     */
    public void testParagraph()
    {
        String text = "Text";
        sink.paragraph();
        sink.text( text );
        sink.paragraph_();
        sink.flush();
        sink.close();

        String actual = testWriter.toString();
        String expected = getParagraphBlock( text );

        assertEquals( "Wrong paragraph!", expected, actual );
    }

    /**
     * Checks that the sequence <code>[data(), text( text ),
     * data_()]</code>, invoked on the current sink, produces
     * the same result as {@link #getDataBlock getDataBlock}( text ).
     */
    public void testData()
    {
        String value = "Value";
        String text = "Text";
        sink.data( value );
        sink.text( text );
        sink.data_();
        sink.flush();
        sink.close();

        String actual = testWriter.toString();
        String expected = getDataBlock( value, text );

        assertEquals( "Wrong data!", expected, actual );
    }

    /**
     * Checks that the sequence <code>[time(), text( text ),
     * time_()]</code>, invoked on the current sink, produces
     * the same result as {@link #getTimeBlock getTimeBlock}( text ).
     */
    public void testTime()
    {
        String datetime = "DateTime";
        String text = "Text";
        sink.time( datetime );
        sink.text( text );
        sink.time_();
        sink.flush();
        sink.close();

        String actual = testWriter.toString();
        String expected = getTimeBlock( datetime, text );

        assertEquals( "Wrong time!", expected, actual );
    }

    /**
     * Checks that the sequence <code>[address(), text( text ),
     * address_()]</code>, invoked on the current sink, produces
     * the same result as {@link #getAddressBlock getAddressBlock}( text ).
     */
    public void testAddress()
    {
        String text = "Text";
        sink.address();
        sink.text( text );
        sink.address_();
        sink.flush();
        sink.close();

        String actual = testWriter.toString();
        String expected = getAddressBlock( text );

        assertEquals( "Wrong address!", expected, actual );
    }

    /**
     * Checks that the sequence <code>[blockquote(), text( text ),
     * blockquote_()]</code>, invoked on the current sink, produces
     * the same result as {@link #getBlackquoteBlock getBlockquoteBlock}( text ).
     */
    public void testBlockquote()
    {
        String text = "Text";
        sink.blockquote();
        sink.text( text );
        sink.blockquote_();
        sink.flush();
        sink.close();

        String actual = testWriter.toString();
        String expected = getBlockquoteBlock( text );

        assertEquals( "Wrong blockquote!", expected, actual );
    }

    /**
     * Checks that the sequence <code>[division(), text( text ),
     * division_()]</code>, invoked on the current sink, produces
     * the same result as {@link #getDivisionBlock getDivisionBlock}( text ).
     */
    public void testDivider()
    {
        String text = "Text";
        sink.division();
        sink.text( text );
        sink.division_();
        sink.flush();
        sink.close();

        String actual = testWriter.toString();
        String expected = getDivisionBlock( text );

        assertEquals( "Wrong division!", expected, actual );
    }

    /**
     * Checks that the sequence <code>[verbatim( SinkEventAttributeSet.BOXED ), text( text ),
     * verbatim_()]</code>, invoked on the current sink, produces the
     * same result as {@link #getVerbatimBlock getVerbatimBlock}( text ).
     */
    public void testVerbatim()
    {
        String text = "Text";
        sink.verbatim( SinkEventAttributeSet.BOXED );
        sink.text( text );
        sink.verbatim_();
        sink.flush();
        sink.close();

        String actual = testWriter.toString();
        String expected = getVerbatimBlock( text );

        assertEquals( "Wrong verbatim!", expected, actual );
    }

    /**
     * Checks that the sequence <code>[horizontalRule()]</code>,
     * invoked on the current sink, produces the same result as
     * {@link #getHorizontalRuleBlock getHorizontalRuleBlock()}.
     */
    public void testHorizontalRule()
    {
        sink.horizontalRule();
        sink.flush();
        sink.close();

        String actual = testWriter.toString();
        String expected = getHorizontalRuleBlock();

        assertEquals( "Wrong horizontal rule!", expected, actual );
    }

    /**
     * Checks that the sequence <code>[pageBreak()]</code>,
     * invoked on the current sink, produces the same result as
     * {@link #getPageBreakBlock getPageBreakBlock()}.
     */
    public void testPageBreak()
    {
        sink.pageBreak();
        sink.flush();
        sink.close();

        String actual = testWriter.toString();
        String expected = getPageBreakBlock();

        assertEquals( "Wrong pageBreak!", expected, actual );
    }

    /**
     * Checks that the sequence <code>[anchor( anchor ), text( anchor ),
     * anchor_()]</code>, invoked on the current sink, produces the same
     * result as {@link #getAnchorBlock getAnchorBlock}( anchor ).
     */
    public void testAnchor()
    {
        String anchor = "Anchor";
        sink.anchor( anchor );
        sink.text( anchor );
        sink.anchor_();
        sink.flush();
        sink.close();

        String actual = testWriter.toString();
        String expected = getAnchorBlock( anchor );

        assertEquals( "Wrong anchor!", expected, actual );
    }

    /**
     * Checks that the sequence <code>[link( link ), text( text ),
     * link_()]</code>, invoked on the current sink, produces the same
     * result as {@link #getLinkBlock getLinkBlock}( link, text ).
     */
    public void testLink()
    {
        String link = "#Link";
        String text = "Text";
        sink.link( link );
        sink.text( text );
        sink.link_();
        sink.flush();
        sink.close();

        String actual = testWriter.toString();
        String expected = getLinkBlock( link, text );

        assertEquals( "Wrong link!", expected, actual );
    }

    /**
     * Checks that the sequence <code>[inline(), text( text ), inline_()]</code>,
     * invoked on the current sink, produces the same result as
     * {@link #getInlineBlock getInlineBlock}( text ).
     */
    public void testInline()
    {
        String text = "Inline";
        sink.inline();
        sink.text( text );
        sink.inline_();
        sink.flush();
        sink.close();

        String actual = testWriter.toString();
        String expected = getInlineBlock( text );

        assertEquals( "Wrong inline!", expected, actual );
    }

    /**
     * Checks that the sequence <code>[inline(bold), text( text ), inline_()]</code>,
     * invoked on the current sink, produces the same result as
     * {@link #getInlineBoldBlock getInlineBoldBlock}( text ).
     */
    public void testInlineBold()
    {
        String text = "InlineBold";
        sink.inline( SinkEventAttributeSet.Semantics.BOLD );
        sink.text( text );
        sink.inline_();
        sink.flush();
        sink.close();

        String actual = testWriter.toString();
        String expected = getInlineBoldBlock( text );

        assertEquals( "Wrong inline bold!", expected, actual );
    }

    /**
     * Checks that the sequence <code>[inline(italic), text( text ), inline_()]</code>,
     * invoked on the current sink, produces the same result as
     * {@link #getInlineBoldBlock getInlineBoldBlock}( text ).
     */
    public void testInlineItalic()
    {
        String text = "InlineItalic";
        sink.inline( SinkEventAttributeSet.Semantics.ITALIC );
        sink.text( text );
        sink.inline_();
        sink.flush();
        sink.close();

        String actual = testWriter.toString();
        String expected = getInlineItalicBlock( text );

        assertEquals( "Wrong inline italic!", expected, actual );
    }

    /**
     * Checks that the sequence <code>[inline(code), text( text ), inline_()]</code>,
     * invoked on the current sink, produces the same result as
     * {@link #getInlineBoldBlock getInlineBoldBlock}( text ).
     */
    public void testInlineCode()
    {
        String text = "InlineCode";
        sink.inline( SinkEventAttributeSet.Semantics.CODE );
        sink.text( text );
        sink.inline_();
        sink.flush();
        sink.close();

        String actual = testWriter.toString();
        String expected = getInlineCodeBlock( text );

        assertEquals( "Wrong inline code!", expected, actual );
    }

    /**
     * Checks that the sequence <code>[lineBreak()]</code>,
     * invoked on the current sink, produces the same result as
     * {@link #getLineBreakBlock getLineBreakBlock()}.
     */
    public void testLineBreak()
    {
        sink.lineBreak();
        sink.flush();
        sink.close();

        String actual = testWriter.toString();
        String expected = getLineBreakBlock();

        assertEquals( "Wrong lineBreak!", expected, actual );
    }

    /**
     * Checks that the sequence <code>[lineBreakOpportunity()]</code>,
     * invoked on the current sink, produces the same result as
     * {@link #getLineBreakOpportunityBlock getLineBreakOpportunityBlock()}.
     */
    public void testLineBreakOpportunity()
    {
        sink.lineBreakOpportunity();
        sink.flush();
        sink.close();

        String actual = testWriter.toString();
        String expected = getLineBreakOpportunityBlock();

        assertEquals( "Wrong lineBreakOpportunity!", expected, actual );
    }

    /**
     * Checks that the sequence <code>[nonBreakingSpace()]</code>,
     * invoked on the current sink, produces the same result as
     * {@link #getNonBreakingSpaceBlock getNonBreakingSpaceBlock()}.
     */
    public void testNonBreakingSpace()
    {
        sink.nonBreakingSpace();
        sink.flush();
        sink.close();

        String actual = testWriter.toString();
        String expected = getNonBreakingSpaceBlock();

        assertEquals( "Wrong nonBreakingSpace!", expected, actual );
    }

    /**
     * Checks that the sequence <code>[text( text )]</code>,
     * invoked on the current sink, produces the same result as
     * {@link #getTextBlock getTextBlock()}.
     */
    public void testText()
    {
        String text = "~,_=,_-,_+,_*,_[,_],_<,_>,_{,_},_\\";
        sink.text( text );
        sink.flush();
        sink.close();

        String actual = testWriter.toString();
        String expected = getTextBlock( text );

        assertEquals( "Wrong text!", expected, actual );
    }

    /**
     * Checks that the sequence <code>[rawText( text )]</code>,
     * invoked on the current sink, produces the same result as
     * {@link #getRawTextBlock getRawTextBlock}( text ).
     */
    public void testRawText()
    {
        String text = "~,_=,_-,_+,_*,_[,_],_<,_>,_{,_},_\\";
        sink.rawText( text );
        sink.flush();
        sink.close();

        String actual = testWriter.toString();
        String expected = getRawTextBlock( text );

        assertEquals( "Wrong rawText!", expected, actual );
    }

    /**
     * Checks that the sequence <code>[comment(comment)]</code>,
     * invoked on the current sink, produces the same result as
     * {@link #getCommentBlock getCommentBlock}( comment ).
     * @since 1.1.1
     */
    public void testComment()
    {
        String comment = "Simple comment with ----";
        sink.comment( comment );
        sink.flush();
        sink.close();

        String actual = testWriter.toString();
        String expected = getCommentBlock( comment );

        assertEquals( "Wrong comment!", expected, actual );

        testWriter.reset();
        sink = createSink( testWriter );
        sink.enableLogging( new PlexusLoggerWrapper( ( ( DefaultPlexusContainer )getContainer() ).getLogger() ) );

        comment = "-";
        sink.comment( comment );
        sink.flush();
        sink.close();

        actual = testWriter.toString();
        expected = getCommentBlock( comment );

        assertEquals( "Wrong comment!", expected, actual );
    }

    // ----------------------------------------------------------------------
    // Utility methods
    // ----------------------------------------------------------------------

    /**
     * Returns the sink that is currently being tested.
     * @return The current test sink.
     */
    protected Sink getSink()
    {
        return sink;
    }

    /**
     * Returns a String representation of all events that have been written to the sink.
     * @return The Sink content as a String.
     */
    protected String getSinkContent()
    {
        return testWriter.toString();
    }

    /**
     * Returns the directory where all sink test output will go.
     * @return The test output directory.
     */
    protected String getOutputDir()
    {
        return "sink/";
    }

    // ----------------------------------------------------------------------
    // Abstract methods the individual SinkTests must provide
    // ----------------------------------------------------------------------

    /**
     * This method allows to use the correct Writer in {@link #testTestDocument()}.
     *
     * @return <code>true</code> if the Sink is an XML one, <code>false</code> otherwise.
     * @see #testTestDocument()
     */
    protected abstract boolean isXmlSink();

    /**
     * Return a new instance of the sink that is being tested.
     * @param writer The writer for the sink.
     * @return A new sink.
     */
    protected abstract Sink createSink( Writer writer );

    /**
     * Returns a title block generated by this sink.
     * @param title The title to use.
     * @return The result of invoking a title block on the current sink.
     * @see #testTitle()
     */
    protected abstract String getTitleBlock( String title );

    /**
     * Returns an author block generated by this sink.
     * @param author The author to use.
     * @return The result of invoking an author block on the current sink.
     * @see #testAuthor()
     */
    protected abstract String getAuthorBlock( String author );

    /**
     * Returns a date block generated by this sink.
     * @param date The date to use.
     * @return The result of invoking a date block on the current sink.
     * @see #testDate()
     */
    protected abstract String getDateBlock( String date );

    /**
     * Returns a head block generated by this sink.
     * @return The result of invoking a head block on the current sink.
     * @see #testHead()
     */
    protected abstract String getHeadBlock();

    /**
     * Returns a body block generated by this sink.
     * @return The result of invoking a body block on the current sink.
     * @see #testBody()
     */
    protected abstract String getBodyBlock();

    /**
     * Returns an article block generated by this sink.
     * @return The result of invoking an article block on the current sink.
     * @see #testArticle()
     */
    protected abstract String getArticleBlock();

    /**
     * Returns an navigation block generated by this sink.
     * @return The result of invoking an navigation block on the current sink.
     * @see #testNavigation()
     */
    protected abstract String getNavigationBlock();

    /**
     * Returns a sidebar block generated by this sink.
     * @return The result of invoking an sidebar block on the current sink.
     * @see #testSidebar()
     */
    protected abstract String getSidebarBlock();

    /**
     * Returns a SectionTitle block generated by this sink.
     * @param title The title to use.
     * @return The result of invoking a SectionTitle block on the current sink.
     * @see #testSectionTitle()
     */
    protected abstract String getSectionTitleBlock( String title );

    /**
     * Returns a Section1 block generated by this sink.
     * @param title The title to use.
     * @return The result of invoking a Section1 block on the current sink.
     * @see #testSection1()
     */
    protected abstract String getSection1Block( String title );

    /**
     * Returns a Section2 block generated by this sink.
     * @param title The title to use.
     * @return The result of invoking a Section2 block on the current sink.
     * @see #testSection2()
     */
    protected abstract String getSection2Block( String title );

    /**
     * Returns a Section3 block generated by this sink.
     * @param title The title to use.
     * @return The result of invoking a Section3 block on the current sink.
     * @see #testSection3()
     */
    protected abstract String getSection3Block( String title );

    /**
     * Returns a Section4 block generated by this sink.
     * @param title The title to use.
     * @return The result of invoking a Section4 block on the current sink.
     * @see #testSection4()
     */
    protected abstract String getSection4Block( String title );

    /**
     * Returns a Section5 block generated by this sink.
     * @param title The title to use.
     * @return The result of invoking a Section5 block on the current sink.
     * @see #testSection5()
     */
    protected abstract String getSection5Block( String title );

    /**
     * Returns a header block generated by this sink.
     * @return The result of invoking a header block on the current sink.
     * @see #testHeader()
     */
    protected abstract String getHeaderBlock();

    /**
     * Returns a content block generated by this sink.
     * @return The result of invoking a content block on the current sink.
     * @see #testContent()
     */
    protected abstract String getContentBlock();

    /**
     * Returns a footer block generated by this sink.
     * @return The result of invoking a footer block on the current sink.
     * @see #testFooter()
     */
    protected abstract String getFooterBlock();

    /**
     * Returns a list block generated by this sink.
     * @param item The item to use.
     * @return The result of invoking a list block on the current sink.
     * @see #testList()
     */
    protected abstract String getListBlock( String item );

    /**
     * Returns a NumberedList block generated by this sink.
     * @param item The item to use.
     * @return The result of invoking a NumberedList block on the current sink.
     * @see #testNumberedList()
     */
    protected abstract String getNumberedListBlock( String item );

    /**
     * Returns a DefinitionList block generated by this sink.
     * @param definum The term to define.
     * @param definition The definition.
     * @return The result of invoking a DefinitionList block on the current sink.
     * @see #testDefinitionList()
     */
    protected abstract String getDefinitionListBlock( String definum,
        String definition );

    /**
     * Returns a Figure block generated by this sink.
     * @param source The figure source string.
     * @param caption The caption to use (may be null).
     * @return The result of invoking a Figure block on the current sink.
     * @see #testFigure()
     */
    protected abstract String getFigureBlock( String source, String caption );

    /**
     * Returns a Table block generated by this sink.
     * @param cell A tabel cell to use.
     * @param caption The caption to use (may be null).
     * @return The result of invoking a Table block on the current sink.
     * @see #testTable()
     */
    protected abstract String getTableBlock( String cell, String caption );

    /**
     * Returns a Paragraph block generated by this sink.
     * @param text The text to use.
     * @return The result of invoking a Paragraph block on the current sink.
     * @see #testParagraph()
     */
    protected abstract String getParagraphBlock( String text );

    /**
     * Returns a Data block generated by this sink.
     * @param value The value to use.
     * @param text The text to use.
     * @return The result of invoking a Data block on the current sink.
     * @see #testData()
     */
    protected abstract String getDataBlock( String value, String text );

    /**
     * Returns a Time block generated by this sink.
     * @param datetime The datetime to use.
     * @param text The text to use.
     * @return The result of invoking a Time block on the current sink.
     * @see #testTime()
     */
    protected abstract String getTimeBlock( String datetime, String text );

    /**
     * Returns an Address block generated by this sink.
     * @param text The text to use.
     * @return The result of invoking an Address block on the current sink.
     * @see #testAddress()
     */
    protected abstract String getAddressBlock( String text );

    /**
     * Returns a Blockquote block generated by this sink.
     * @param text The text to use.
     * @return The result of invoking a Blockquote block on the current sink.
     * @see #testBlockquote()
     */
    protected abstract String getBlockquoteBlock( String text );

    /**
     * Returns a Division block generated by this sink.
     * @param text The text to use.
     * @return The result of invoking a Division block on the current sink.
     * @see #testDivision()
     */
    protected abstract String getDivisionBlock( String text );

    /**
     * Returns a Verbatim block generated by this sink.
     * @param text The text to use.
     * @return The result of invoking a Verbatim block on the current sink.
     * @see #testVerbatim()
     */
    protected abstract String getVerbatimBlock( String text );

    /**
     * Returns a HorizontalRule block generated by this sink.
     * @return The result of invoking a HorizontalRule block on the current sink.
     * @see #testHorizontalRule()
     */
    protected abstract String getHorizontalRuleBlock();

    /**
     * Returns a PageBreak block generated by this sink.
     * @return The result of invoking a PageBreak block on the current sink.
     * @see #testPageBreak()
     */
    protected abstract String getPageBreakBlock();

    /**
     * Returns a Anchor block generated by this sink.
     * @param anchor The anchor to use.
     * @return The result of invoking a Anchor block on the current sink.
     * @see #testAnchor()
     */
    protected abstract String getAnchorBlock( String anchor );

    /**
     * Returns a Link block generated by this sink.
     * @param link The link to use.
     * @param text The link text.
     * @return The result of invoking a Link block on the current sink.
     * @see #testLink()
     */
    protected abstract String getLinkBlock( String link, String text );

    /**
     * Returns an Inline block generated by this sink.
     * @param text The text to use.
     * @return The result of invoking a Inline block on the current sink.
     * @see #testInline()
     */
    protected abstract String getInlineBlock( String text );

    /**
     * Returns an Inline italic block generated by this sink.
     * @param text The text to use.
     * @return The result of invoking a Inline italic block on the current sink.
     * @see #testInlineItalic()
     */
    protected abstract String getInlineItalicBlock( String text );

    /**
     * Returns an Inline bold block generated by this sink.
     * @param text The text to use.
     * @return The result of invoking a Inline bold block on the current sink.
     * @see #testInlineBold()
     */
    protected abstract String getInlineBoldBlock( String text );

    /**
     * Returns an Inline code block generated by this sink.
     * @param text The text to use.
     * @return The result of invoking a Inline code block on the current sink.
     * @see #testInlineBold()
     */
    protected abstract String getInlineCodeBlock( String text );

    /**
     * Returns a LineBreak block generated by this sink.
     * @return The result of invoking a LineBreak block on the current sink.
     * @see #testLineBreak()
     */
    protected abstract String getLineBreakBlock();

    /**
     * Returns a LineBreakOpportunity block generated by this sink.
     * @return The result of invoking a LineBreakOpportunity block on the
     * current sink.
     * @see #testLineBreakOpportunity()
     */
    protected abstract String getLineBreakOpportunityBlock();

    /**
     * Returns a NonBreakingSpace block generated by this sink.
     * @return The result of invoking a NonBreakingSpace block
     * on the current sink.
     * @see #testNonBreakingSpace()
     */
    protected abstract String getNonBreakingSpaceBlock();

    /**
     * Returns a Text block generated by this sink.
     * @param text The text to use.
     * @return The result of invoking a Text block on the current sink.
     * @see #testText()
     */
    protected abstract String getTextBlock( String text );

    /**
     * Returns a RawText block generated by this sink.
     * @param text The text to use.
     * @return The result of invoking a RawText block on the current sink.
     * @see #testRawText()
     */
    protected abstract String getRawTextBlock( String text );

    /**
     * Returns a comment block generated by this sink.
     * @param text The text to use.
     * @return The result of invoking a comment block on the current sink.
     * @see #testComment()
     * @since 1.1.1
     */
    protected abstract String getCommentBlock( String text );

    protected final void verifyValignSup( String text )
    {
        sink.text( "ValignSup", new SinkEventAttributeSet( SinkEventAttributes.VALIGN, "sup"  ) );
        sink.flush();
        sink.close();

        String actual = testWriter.toString();

        assertEquals( "Wrong valign sup!", text, actual );
    }

    protected final void verifyValignSub( String text )
    {
        sink.text( "ValignSub", new SinkEventAttributeSet( SinkEventAttributes.VALIGN, "sub"  ) );
        sink.flush();
        sink.close();

        String actual = testWriter.toString();

        assertEquals( "Wrong valign sub!", text, actual );
    }

    protected final void verifyDecorationUnderline( String text )
    {
        sink.text( "DecorationUnderline", new SinkEventAttributeSet( SinkEventAttributes.DECORATION, "underline"  ) );
        sink.flush();
        sink.close();

        String actual = testWriter.toString();

        assertEquals( "Wrong decoration underline!", text, actual );
    }

    protected final void verifyDecorationLineThrough( String text )
    {
        sink.text( "DecorationLineThrough", new SinkEventAttributeSet( SinkEventAttributes.DECORATION, "line-through"  ) );
        sink.flush();
        sink.close();

        String actual = testWriter.toString();

        assertEquals( "Wrong decoration line-through!", text, actual );
    }


}
