package org.apache.maven.doxia.module.twiki.parser;

/*
 * 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 org.junit.Test;

import static org.junit.Assert.assertArrayEquals;
import static org.junit.Assert.assertEquals;

/**
 * Tests the {@link org.apache.maven.doxia.module.twiki.parser.FormatedTextParser}
 *
 * @author Juan F. Codagnone
 * @since Nov 2, 2005
 */
public class FormatedTextTest
    extends AbstractBlockTestCase
{

    /**
     * test bold text
     */
    @Test
    public final void testBold()
    {
        String text;
        Block[] blocks;

        text = "*bold*";
        blocks = formatTextParser.parse( text );
        assertEquals( 1, blocks.length );
        assertEquals( new BoldBlock( new Block[] { new TextBlock( "bold" ) } ), blocks[0] );

        text = "foo *bold* bar";
        blocks = formatTextParser.parse( text );
        assertArrayEquals( new Block[] {new TextBlock( "foo " ), new BoldBlock(
                new Block[] {new TextBlock( "bold" )} ), new TextBlock( " bar" )}, blocks );

        text = "\t*bold* bar";
        blocks = formatTextParser.parse( text );
        assertArrayEquals( new Block[] {new TextBlock( "\t" ), new BoldBlock(
                new Block[] {new TextBlock( "bold" )} ), new TextBlock( " bar" )}, blocks );

        text = "*nice* foo *bold* bar";
        blocks = formatTextParser.parse( text );
        assertArrayEquals( new Block[] {new BoldBlock( new Block[] {new TextBlock( "nice" )} ), new TextBlock(
                " foo " ), new BoldBlock( new Block[] {new TextBlock( "bold" )} ), new TextBlock( " bar" )}, blocks );
    }

    /**
     * test italic text
     */
    @Test
    public final void testItalic()
    {
        String text;
        Block[] blocks;

        text = "_italic_";
        blocks = formatTextParser.parse( text );
        assertEquals( 1, blocks.length );
        assertEquals( new ItalicBlock( new Block[] { new TextBlock( "italic" ) } ), blocks[0] );

        text = "foo _italic_ bar";
        blocks = formatTextParser.parse( text );
        assertArrayEquals( new Block[] {new TextBlock( "foo " ), new ItalicBlock(
                new Block[] {new TextBlock( "italic" )} ), new TextBlock( " bar" )}, blocks );

        text = "_nice_ foo _italic_ bar";
        blocks = formatTextParser.parse( text );
        assertArrayEquals( new Block[] {new ItalicBlock( new Block[] {new TextBlock( "nice" )} ), new TextBlock(
                        " foo " ), new ItalicBlock( new Block[] {new TextBlock( "italic" )} ), new TextBlock( " bar" )},
                blocks );
    }

    /**
     * test monospaced text
     */
    @Test
    public final void testMonospaced()
    {
        String text;
        Block[] blocks;

        text = "mary =has= a =little= lamb He followed her (=to school one day=)";
        blocks = formatTextParser.parse( text );
        assertArrayEquals( new Block[] {new TextBlock( "mary " ), new MonospaceBlock(
                new Block[] {new TextBlock( "has" )} ), new TextBlock( " a " ), new MonospaceBlock(
                new Block[] {new TextBlock( "little" )} ), new TextBlock(
                " lamb He followed her (" ), new MonospaceBlock(
                new Block[] {new TextBlock( "to school one day" )} ), new TextBlock( ")" )}, blocks );
    }

    /**
     * test monospaced text
     */
    @Test
    public final void testBoldMonospaced()
    {
        String text;
        Block[] blocks;

        text = "mary ==has== a ==little== lamb";
        blocks = formatTextParser.parse( text );
        Block[] expected =
            new Block[] { new TextBlock( "mary " ),
                new BoldBlock( new Block[] { new MonospaceBlock( new Block[] { new TextBlock( "has" ) } ) } ),
                new TextBlock( " a " ),
                new BoldBlock( new Block[] { new MonospaceBlock( new Block[] { new TextBlock( "little" ) } ) } ),
                new TextBlock( " lamb" ) };

        assertArrayEquals( expected, blocks );
    }

    /**
     * test monospaced text
     */
    @Test
    public final void testBoldItalic()
    {
        String text;
        Block[] blocks;

        text = "mary __has__ a __little__ lamb";
        blocks = formatTextParser.parse( text );
        assertArrayEquals( new Block[] {new TextBlock( "mary " ), new BoldBlock(
                        new Block[] {new ItalicBlock( new Block[] {new TextBlock( "has" )} )} ), new TextBlock(
                        " a " ), new BoldBlock(
                        new Block[] {new ItalicBlock( new Block[] {new TextBlock( "little" )} )} ), new TextBlock( " lamb" )},
                blocks );
    }

    /**
     * test mixed formats side by side
     */
    @Test
    public final void testMultiFormatSideBySide()
    {
        String text;
        Block[] blocks;
        Block[] expected;

        text = "All *work and* =no play= _makes_ Juan a dull *boy*";
        blocks = formatTextParser.parse( text );

        expected =
            new Block[] { new TextBlock( "All " ), new BoldBlock( new Block[] { new TextBlock( "work and" ) } ),
                new TextBlock( " " ), new MonospaceBlock( new Block[] { new TextBlock( "no play" ) } ),
                new TextBlock( " " ), new ItalicBlock( new Block[] { new TextBlock( "makes" ) } ),
                new TextBlock( " Juan a dull " ), new BoldBlock( new Block[] { new TextBlock( "boy" ) } ) };
        assertArrayEquals( expected, blocks );

    }

    /**
     * test mixed formats recursevily
     */
    @Test
    public final void testMultiFormatInside()
    {
        String text;
        Block[] blocks;
        Block[] expected;

        text = "All *work and =no play _makes_ Juan= a dull* boy";
        blocks = formatTextParser.parse( text );

        expected =
            new Block[] {
                new TextBlock( "All " ),
                new BoldBlock(
                               new Block[] {
                                   new TextBlock( "work and " ),
                                   new MonospaceBlock( new Block[] { new TextBlock( "no play " ),
                                       new ItalicBlock( new Block[] { new TextBlock( "makes" ) } ),
                                       new TextBlock( " Juan" ) } ), new TextBlock( " a dull" ) } ),
                new TextBlock( " boy" ) };
        assertArrayEquals( expected, blocks );
    }

    /**
     * test unbonded formats
     */
    @Test
    public final void testUnboundedFormat()
    {
        internalTestHanging( "All *work and no play makes Juan a dull boy" );
        internalTestHanging( "All __work and no play makes Juan a dull boy" );
        internalTestHanging( "All __work and *no play makes _Juan a = dull boy" );
        internalTestHanging( "*" );
        internalTestHanging( "==" );
        internalTestHanging( "**" ); // hehe
        internalTestHanging( "*  hello   *" );
        internalTestHanging( "*  hello   =*" );
        internalTestHanging( "*=_  hello   _=*" );
    }

    /**
     * @param text unbonded text
     */
    private void internalTestHanging( final String text )
    {
        assertArrayEquals( new Block[] {new TextBlock( text )}, formatTextParser.parse( text ) );
    }
}
