/*
 * Copyright (C) 2001-2004 Red Hat Inc. All Rights Reserved.
 *
 * The contents of this file are subject to the CCM Public
 * License (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.redhat.com/licenses/ccmpl.html.
 *
 * Software distributed under the License is distributed on an
 * "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, either express
 * or implied. See the License for the specific language
 * governing rights and limitations under the License.
 *
 */
package com.arsdigita.bebop;

import java.io.PrintWriter;
import java.io.StringWriter;
import com.arsdigita.tools.junit.framework.BaseTestCase;
import com.arsdigita.util.RequestEnvironment;
//import junit.framework.TestCase;

/**
 *      This test performs regression testing on bebop Component XML
 *      generation. Since each Bebop component has a complex set of
 *      possible outputs, each test of a Bebop component should subclass
 *      the XMLComponentRegressionBase class, and test methods to generate
 *      specific use cases of Bebop should be added.
 *
 *      For the test, XML is generated for the Component, and compared against
 *      canonical XML reference files that are under change control. If there
 *      are file differences, or any other error, the test will fail.
 *
 *      The xml files for each class are named FULL_CLASS_NAME.xml
 *      ex. com.arsdigita.bebop.Page.xml
 *
 *      At present, the XML files are expected in the same directory as this test.
 *      This may not work for automated testing, and may have to change.
 *
 *      To (re)generate the XML files, call this class directly as a main
 *      class with the -regenerate flag.
 *
 * @version $Revision: #8 $ $Date: 2004/04/07 $ */

public class XMLComponentRegressionBase extends BaseTestCase {

    public static final String versionId = "$Id: //core-platform/dev/test/src/com/arsdigita/bebop/XMLComponentRegressionBase.java#8 $ by $Author: dennis $, $DateTime: 2004/04/07 16:07:11 $";

    public XMLComponentRegressionBase(String id) {
        super(id);
    }

    /**
     *  Run a comparison test for a component.
     *
     *  @param c The component to test.
     *  @param testName The name of the test. The testName parameter
     *  should be the same for tests that should produce the same XML
     *  output but in different ways. For instance, a Bebop component
     *  may have an overloaded constructor that accepts multiple
     *  arguments that can also be set individually with methods. The
     *  XML output of the component should be the same in both cases,
     *  so the testName should be the same for both tests.
     *
     *  This method is protected to give extending classes outside the
     *  package access.
     */
    protected void testComponent(Component c, String testName) {
        try
            {
                new RequestEnvironment();
                SingleComponentXMLComparator comp =
                    new SingleComponentXMLComparator(c, testName);
                comp.testXMLGeneration();
            }
        catch(XMLComparatorError xe)
            {
                fail("Failed comparing XML.\n" + getStackTrace(xe));
            }
        catch(Exception e)
            {
                fail("Unknown Error: " + getStackTrace(e));
            }
    }

    /**
     *  Run a regular expression test for a component.
     *
     *  @param c The component to test.
     *  @param regexp The regular expression to look for in the XML
     *  generated by the component.
     *  @param is_debug Should the RequestContext indicate we're debugging?
     *
     *  This method is protected to give extending classes outside the
     *  package access.  */
    protected void regexpComponent(Component c, String regexp,
                                   boolean is_debug) {
        try
            {
                ComponentXMLRegexper comp =
                    new ComponentXMLRegexper(c, regexp);
                comp.testXMLGeneration(is_debug);
            }
        catch(XMLComparatorError xe)
            {
                fail("Failed finding regexp in XML.\n" + getStackTrace(xe));
            }
        catch(Exception e)
            {
                fail("Unknown Error: " + getStackTrace(e));
            }
    }

    /**
     *  Utility method for copying an Exception stack trace to
     *  a String.
     *
     *  @param e The Exception to get the stack trace from.
     *
     *  @return The stack trace.
     */
    static String getStackTrace(Exception e) {
        StringWriter stackTrace = new StringWriter();
        PrintWriter writer = new PrintWriter( stackTrace, true );
        e.printStackTrace(writer);
        return stackTrace.toString();
    }

    public static void main(String args[])
    {

        if( args.length != 0 )
            {
                if( args.length > 1 )
                    {
                        System.err.println("Usage: {-regenerate}");
                        System.exit(0);
                    }
                if( args[0].equals("-regenerate") )
                    {
                        System.out.println("Regenerating XML files");
                        ComponentXMLComparator.GENERATE_FILES = true;
                    }
                else
                    {
                        System.err.println("Usage: {-regenerate}");
                        System.exit(0);
                    }
            }
        junit.textui.TestRunner.run(XMLComponentRegressionBase.class);
    }

}
