001package net.sf.logdistiller;
002
003/*
004 * Licensed under the Apache License, Version 2.0 (the "License");
005 * you may not use this file except in compliance with the License.
006 * You may obtain a copy of the License at
007 *
008 *     http://www.apache.org/licenses/LICENSE-2.0
009 *
010 * Unless required by applicable law or agreed to in writing, software
011 * distributed under the License is distributed on an "AS IS" BASIS,
012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013 * See the License for the specific language governing permissions and
014 * limitations under the License.
015 */
016
017import java.io.BufferedReader;
018import java.io.File;
019import java.io.FileWriter;
020import java.io.IOException;
021import java.io.InputStreamReader;
022import java.io.PrintWriter;
023import java.io.StringWriter;
024import java.net.URL;
025import java.text.ParseException;
026import java.util.HashMap;
027
028import org.apache.commons.io.IOUtils;
029
030import junit.framework.TestCase;
031
032/**
033 * Base class to write custom LogEvent junit tests more easily.
034 *
035 * @since 1.0
036 */
037public class LogEventTestCase
038    extends TestCase
039{
040    protected final LogType logtype;
041
042    protected LogType.Description description;
043
044    protected LogEvent.Factory factory;
045
046    protected LogEventTestCase( String logtype )
047    {
048        super( logtype );
049        this.logtype = LogTypes.getLogType( logtype );
050        this.description = this.logtype.newDescription( new HashMap<String, String>() );
051        this.description.setExtensions( new Attributes.Extension[0] );
052    }
053
054    /**
055     * get a resource from the current testcase class and check it has been found
056     *
057     * @param name the resource to get
058     * @return the corresponding resource, not <code>null</code>
059     * @throws RuntimeException if resource not found
060     * @see Class#getResource(String)
061     */
062    protected URL getResource( String name )
063    {
064        URL url = getClass().getResource( name );
065        if ( url == null )
066        {
067            throw new RuntimeException( "resource '" + name + "' not found in package "
068                + getClass().getPackage().getName() );
069        }
070        return url;
071    }
072
073    /**
074     * create a factory for a resource (read with platform encoding).
075     */
076    protected LogEvent.Factory newFactory( String name )
077        throws IOException
078    {
079        URL url = getResource( name );
080        String source = getClass().getPackage().getName().replace( '.', '/' ) + '/' + name;
081        return description.newFactory( new InputStreamReader( url.openStream() ), source );
082    }
083
084    private final static String HEADER = "====== log event ======";
085
086    /**
087     * Dump every LogEvent found in the factory to the given PrintWriter.
088     */
089    public static int dump( LogEvent.Factory factory, PrintWriter out )
090        throws IOException, ParseException
091    {
092        LogEvent le;
093        int count = 0;
094        while ( ( le = factory.nextEvent() ) != null )
095        {
096            out.println( HEADER );
097            le.dump( out );
098            count++;
099        }
100        return count;
101    }
102
103    /**
104     * Dump every LogEvent found in the factory to the given File using platform encoding.
105     */
106    public static int dump( LogEvent.Factory factory, File file )
107        throws IOException, ParseException
108    {
109        PrintWriter out = null;
110        try
111        {
112            out = new PrintWriter( new FileWriter( file ) );
113            return dump( factory, out );
114        }
115        finally
116        {
117            IOUtils.closeQuietly( out );
118        }
119    }
120
121    /**
122     * Read the next LogEvent dump.
123     */
124    public static String readDump( BufferedReader reader )
125        throws IOException
126    {
127        StringWriter buffer = new StringWriter();
128        PrintWriter out = new PrintWriter( buffer );
129        String line = reader.readLine();
130        if ( line == null )
131        {
132            return null;
133        }
134        if ( !HEADER.equals( line ) )
135        {
136            throw new IllegalStateException( "expected '" + HEADER + "' but got '" + line + "'" );
137        }
138        while ( !startsWith( reader, HEADER ) && ( ( line = reader.readLine() ) != null ) )
139        {
140            out.println( line );
141        }
142        out.close();
143        return buffer.toString();
144    }
145
146    /**
147     * Checks if the reader content starts with given content, without consuming any character.
148     */
149    private static boolean startsWith( BufferedReader reader, String content )
150        throws IOException
151    {
152        reader.mark( content.length() );
153        for ( int i = 0; i < content.length(); i++ )
154        {
155            if ( reader.read() != content.charAt( i ) )
156            {
157                reader.reset();
158                return false;
159            }
160        }
161        reader.reset();
162        return true;
163    }
164
165    public void checkDump( LogEvent.Factory factory, BufferedReader reader )
166        throws IOException, ParseException
167    {
168        LogEvent le = null;
169        while ( ( le = factory.nextEvent() ) != null )
170        {
171            String dump = readDump( reader );
172            System.out.println( dump );
173            assertEquals( dump, le.dump() );
174        }
175        assertEquals( "not any log event available, but dump still has content", null, readDump( reader ) );
176    }
177
178    public void checkDump( LogEvent.Factory factory, String name )
179        throws IOException, ParseException
180    {
181        BufferedReader reader = new BufferedReader( new InputStreamReader( getResource( name ).openStream() ) );
182        checkDump( factory, reader );
183    }
184}