package org.apache.velocity.test;

/*
 * Copyright 2001-2006 The Apache Software Foundation.
 *
 * Licensed 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.File;
import java.io.IOException;

import junit.framework.TestCase;

import org.apache.oro.text.perl.Perl5Util;
import org.apache.velocity.runtime.RuntimeSingleton;
import org.apache.velocity.util.StringUtils;

/**
 * Base test case that provides a few utility methods for
 * the rest of the tests.
 *
 * @author <a href="mailto:dlr@finemaltcoding.com">Daniel Rall</a>
 * @version $Id$
 */
public abstract class BaseTestCase
        extends TestCase
        implements TemplateTestBase
{
    /**
     *  used for nomalization of output and compare data
     */
    private Perl5Util perl = new Perl5Util();

    /**
     * Default constructor.
     */
    public BaseTestCase(String name)
    {
        super(name);
    }

    /**
     * Concatenates the file name parts together appropriately.
     *
     * @return The full path to the file.
     */
    protected static String getFileName (String dir, String base, String ext)
    {
        StringBuffer buf = new StringBuffer();

        try
        {
            File baseFile = new File(base);

            if (dir != null)
            {
                if (!baseFile.isAbsolute())
                {
                    baseFile = new File(dir, base);
                }

                buf.append(baseFile.getCanonicalPath());
            }
            else
            {
                buf.append(baseFile.getPath());
            }
            
            buf.append('.').append(ext);
            
        }
        catch (IOException e)
        {
            fail("IO Exception while running getFileName(" + dir + ", " + base + ", "+ ext + "): " + e.getMessage());
        }

        return buf.toString();
    }

    /**
     * Assures that the results directory exists.  If the results directory
     * cannot be created, fails the test.
     */
    protected static void assureResultsDirectoryExists (String resultsDirectory)
    {
        File dir = new File(resultsDirectory);
        if (!dir.exists())
        {
            RuntimeSingleton.getLog().info("Template results directory does not exist");
            if (dir.mkdirs())
            {
                RuntimeSingleton.getLog().info("Created template results directory");
            }
            else
            {
                String errMsg = "Unable to create template results directory";
                RuntimeSingleton.getLog().warn(errMsg);
                fail(errMsg);
            }
        }
    }


    /**
     * Normalizes lines to account for platform differences.  Macs use
     * a single \r, DOS derived operating systems use \r\n, and Unix
     * uses \n.  Replace each with a single \n.
     *
     * @author <a href="mailto:rubys@us.ibm.com">Sam Ruby</a>
     * @return source with all line terminations changed to Unix style
     */
    protected String normalizeNewlines (String source)
    {
        return perl.substitute("s/\r[\r]?[\n]/\n/g", source);
    }

    /**
     * Returns whether the processed template matches the
     * content of the provided comparison file.
     *
     * @return Whether the output matches the contents
     *         of the comparison file.
     *
     * @exception Exception Test failure condition.
     */
    protected boolean isMatch (String resultsDir,
                               String compareDir,
                               String baseFileName,
                               String resultExt,
                               String compareExt)
        throws Exception
    {
        String result = StringUtils.fileContentsToString
            (getFileName(resultsDir, baseFileName, resultExt));

        String compare = StringUtils.fileContentsToString
             (getFileName(compareDir, baseFileName, compareExt));

        /*
         *  normalize each wrt newline
         */

        return normalizeNewlines(result).equals(
                           normalizeNewlines( compare ) );
    }

    /**
     * Turns a base file name into a test case name.
     *
     * @param s The base file name.
     * @return  The test case name.
     */
    protected  static final String getTestCaseName (String s)
    {
        StringBuffer name = new StringBuffer();
        name.append(Character.toTitleCase(s.charAt(0)));
        name.append(s.substring(1, s.length()).toLowerCase());
        return name.toString();
    }
}

@@ -1552,24 +1552,30 @@
 etFileName (
+final 
 String dir, 
@@ -1573,16 +1573,22 @@
 ing dir,
+ final
  String 
@@ -1592,16 +1592,22 @@
 ng base,
+ final
  String 
@@ -1609,32 +1609,217 @@
 ring ext)%0A    %7B%0A
+        return getFileName(dir, base, ext, false);%0A    %7D%0A%0A    protected static String getFileName (final String dir, final String base, final String ext, final boolean mustExist)%0A    %7B%0A
         StringBu
@@ -2311,28 +2311,494 @@
 d(ext);%0A
-            
+%0A            if (mustExist)%0A            %7B%0A                File testFile = new File(buf.toString());%0A                        %0A                if (!testFile.exists())%0A                %7B%0A                    fail(%22getFileName() result %22 + testFile.getPath() + %22 does not exist!%22); %0A                %7D%0A%0A                if (!testFile.isFile())%0A                %7B%0A                    fail(%22getFileName() result %22 + testFile.getPath() + %22 is not a file!%22); %0A                %7D%0A            %7D
 %0A       
@@ -2932,16 +2932,35 @@
 %22+ ext +
+ %22, %22 + mustExist +
  %22): %22 +
@@ -4891,32 +4891,36 @@
 ing%0A            
+    
 (getFileName(res
@@ -4951,16 +4951,22 @@
 esultExt
+, true
 ));%0A%0A   
@@ -5025,32 +5025,35 @@
 ng%0A             
+   
 (getFileName(com
@@ -5085,16 +5085,22 @@
 mpareExt
+, true
 ));%0A%0A   

Add an explicit "does that file exist" test to getFileName() and enforce it for isMatch. isMatch only makes sense if both files to test exists. Let's see if we can provoke some hidden errors in the unit tests...