001package org.apache.maven.doxia.parser;
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 org.apache.maven.doxia.AbstractModuleTest;
023import org.apache.maven.doxia.sink.impl.SinkEventAttributeSet;
024import org.apache.maven.doxia.sink.impl.SinkEventElement;
025import org.apache.maven.doxia.sink.impl.TextSink;
026import org.apache.maven.doxia.sink.impl.WellformednessCheckingSink;
027import org.apache.maven.doxia.sink.Sink;
028import org.codehaus.plexus.util.IOUtil;
029import org.junit.Assert;
030
031import java.io.IOException;
032import java.io.Reader;
033import java.io.Writer;
034import java.util.Iterator;
035
036/**
037 * Test the parsing of sample input files.
038 * <br/>
039 * <b>Note</b>: you have to provide a sample "test." + outputExtension()
040 * file in the test resources directory if you extend this class.
041 *
042 * @version $Id$
043 * @since 1.0
044 */
045public abstract class AbstractParserTest
046    extends AbstractModuleTest
047{
048    /**
049     * Create a new instance of the parser to test.
050     *
051     * @return the parser to test.
052     */
053    protected abstract Parser createParser();
054
055    /**
056     * Returns the directory where all parser test output will go.
057     *
058     * @return The test output directory.
059     */
060    protected String getOutputDir()
061    {
062        return "parser/";
063    }
064
065    /**
066     * Parse a test document '"test." + outputExtension()'
067     * with parser from {@link #createParser()}, and output to a new
068     * {@link WellformednessCheckingSink}. Asserts that output is well-formed.
069     *
070     * @throws IOException if the test document cannot be read.
071     * @throws ParseException if the test document cannot be parsed.
072     */
073    public final void testParser()
074        throws IOException, ParseException
075    {
076        WellformednessCheckingSink sink = new WellformednessCheckingSink();
077
078        Reader reader = null;
079        try
080        {
081            reader = getTestReader( "test", outputExtension() );
082
083            createParser().parse( reader, sink );
084
085            assertTrue( "Parser output not well-formed, last offending element: "
086                + sink.getOffender(), sink.isWellformed() );
087        }
088        finally
089        {
090            IOUtil.close( reader );
091        }
092    }
093
094     /**
095     * Parse a test document '"test." + outputExtension()'
096     * with parser from {@link #createParser()}, and output to a text file,
097     * using the {@link org.apache.maven.doxia.sink.impl.TextSink TextSink}.
098     *
099     * @throws IOException if the test document cannot be read.
100     * @throws ParseException if the test document cannot be parsed.
101     */
102    public final void testDocument()
103        throws IOException, ParseException
104    {
105        Writer writer = null;
106        Reader reader = null;
107
108        try
109        {
110            writer = getTestWriter( "test", "txt" );
111
112            reader = getTestReader( "test", outputExtension() );
113
114            Sink sink = new TextSink( writer );
115
116            createParser().parse( reader, sink );
117        }
118        finally
119        {
120            IOUtil.close( reader );
121            IOUtil.close( writer );
122        }
123    }
124
125    protected void assertEquals( SinkEventElement element, String name, Object... args )
126    {
127        assertEquals( "Name of element doesn't match", name, element.getName() );
128        Assert.assertArrayEquals( "Arguments don't match",  args, element.getArgs() );
129    }
130
131    protected void assertAttributeEquals( SinkEventElement element, String name, String attr, String value )
132    {
133        assertEquals( name, element.getName() );
134        SinkEventAttributeSet atts = (SinkEventAttributeSet) element.getArgs()[0];
135        assertEquals( value, atts.getAttribute( attr ) );
136    }
137
138    protected void assertEquals( Iterator<SinkEventElement> it, String... names )
139    {
140        StringBuilder expected = new StringBuilder();
141        StringBuilder actual = new StringBuilder();
142
143        for ( String name : names )
144        {
145            expected.append( name ).append( '\n' );
146        }
147
148        while ( it.hasNext() )
149        {
150            actual.append( it.next().getName() ).append( '\n' );
151        }
152
153        assertEquals( expected.toString(), actual.toString() );
154    }
155
156    protected void assertStartsWith( Iterator<SinkEventElement> it, String... names )
157    {
158        StringBuilder expected = new StringBuilder();
159        StringBuilder actual = new StringBuilder();
160
161        for ( String name : names )
162        {
163            expected.append( name ).append( '\n' );
164            if ( it.hasNext() )
165            {
166                actual.append( it.next().getName() ).append( '\n' );
167            }
168        }
169        assertEquals( expected.toString(), actual.toString() );
170    }
171}