alvinalexander.com | career | drupal | java | mac | mysql | perl | scala | uml | unix  

What this is

This file is included in the DevDaily.com "Java Source Code Warehouse" project. The intent of this project is to help you "Learn Java by Example" TM.

Other links

The source code

/*
 *                 Sun Public License Notice
 * 
 * The contents of this file are subject to the Sun Public License
 * Version 1.0 (the "License"). You may not use this file except in
 * compliance with the License. A copy of the License is available at
 * http://www.sun.com/
 * 
 * The Original Code is NetBeans. The Initial Developer of the Original
 * Code is Sun Microsystems, Inc. Portions Copyright 1997-2004 Sun
 * Microsystems, Inc. All Rights Reserved.
 */
/*
 * TestCreator.java
 *
 * Created on January 19, 2001, 1:02 PM
 */

package org.netbeans.modules.junit;

import java.lang.reflect.Modifier;
import java.text.MessageFormat;
import java.util.*;
import org.openide.ErrorManager;
import org.openide.filesystems.FileObject;

import org.openide.util.NbBundle;
import org.netbeans.jmi.javamodel.*;
import org.netbeans.modules.javacore.api.JavaModel;
import org.netbeans.api.mdr.MDRepository;


/**
 *
 * @author  vstejskal
 * @author  Marian Petras
 * @version 1.0
 */
public class TestCreator extends java.lang.Object {

    /* attributes - private */
    static private final String JUNIT_SUPER_CLASS_NAME                = "TestCase";
    static private final String JUNIT_FRAMEWORK_PACKAGE_NAME    = "junit.framework";    
    
    static private final String GENERATED_SUITE_BLOCK_START                = "--JUNIT:";
    static private final String GENERATED_SUITE_BLOCK_END                  = ":JUNIT--";    
    private static final String METHOD_NAME_SETUP = "setUp";            //NOI18N
    private static final String METHOD_NAME_TEARDOWN = "tearDown";      //NOI18N

    /* public methods */

    /** Creates new TestCreator */
    public TestCreator() {
    }
    
    private static String arrayToString(Object[] array) {
        String result=array.getClass().getName()+":";
        for (int i=0; istatic public Test suite() and fills its body,
     * appends all test functions in the class and creates sub-suites for
     * all test inner classes.
     */
    static private Method createTestClassSuiteMethod(JavaClass tgtClass) {

        JavaModelPackage pkg = (JavaModelPackage)tgtClass.refImmediatePackage();
        
        // create header of function
        Method method = createSuiteMethod(pkg);
        
        StringBuffer body = new StringBuffer(1024);
        body.append("\njunit.framework.TestSuite suite = new junit.framework.TestSuite(");
        body.append(tgtClass.getSimpleName());
        body.append(".class);\n");
        
        Collection innerClasses = TestUtil.filterFeatures(tgtClass, JavaClass.class);
        Iterator itic = innerClasses.iterator();
        while (itic.hasNext()) {
            JavaClass jc = (JavaClass)itic.next();
            if (TestUtil.isClassTest(jc)) {
                body.append("suite.addTest(");
                body.append(jc.getSimpleName());
                body.append(".suite());\n");
            } 
        }
        
        body.append("\nreturn suite;\n");
        method.setBodyText(body.toString());
        return method;
    }

    static private List createTestConstructorParams(JavaModelPackage pkg) {
        Parameter param = pkg.getParameter().
            createParameter("testName",
                            Collections.EMPTY_LIST, // annotations
                            false, // isFinal
                            pkg.getMultipartId().createMultipartId("java.lang.String", null, Collections.EMPTY_LIST),// typeName
                            0, // dimCount
                            false); // isvararg
        return Collections.singletonList(param);
    }


    static private Constructor createTestConstructor(JavaModelPackage pkg, String className) {




        Constructor constr = pkg.getConstructor()
            .createConstructor(
                               className, // name
                               Collections.EMPTY_LIST, // annotations
                               Modifier.PUBLIC, // modifiers
                               null, // javadoc text
                               null, // javadoc - object repre
                               null, // body - object repre
                               "\nsuper(testName);\n", // body -
                                                      // string repre
                               Collections.EMPTY_LIST,// type parameters
                               createTestConstructorParams(pkg),// parameters
                               null); // exception names
        return constr;
    }

    static private List createTestMethodParams(Method sm, JavaModelPackage pkg) {
        return Collections.EMPTY_LIST;
    }

    static private String createTestMethodName(String smName) {
        return "test" + smName.substring(0,1).toUpperCase() + smName.substring(1);
    }

    static private Method createTestMethod(JavaClass sclass, Method sm, JavaModelPackage pkg) {

        String smName = sm.getName();

        // method name
        String newName = createTestMethodName(smName);

        List annotations = Collections.EMPTY_LIST;
        int modifiers = Modifier.PUBLIC;

        // javadoc
        String javadocText = 
            JUnitSettings.getDefault().isJavaDoc() ? 
            MessageFormat.format(NbBundle.getMessage(TestCreator.class,
                                                     "TestCreator.variantMethods.JavaDoc.comment"), 
                                 new Object[] {smName, sclass.getName()})
            : null;
            
        // create body of the method
        StringBuffer newBody = new StringBuffer(512);
        newBody.append("\n");
        if (JUnitSettings.getDefault().isBodyContent()) {
            // generate default bodies, printing the name of method
            newBody.append("System.out.println(\"" + newName + "\");\n");
        }
        if (JUnitSettings.getDefault().isBodyComments()) {
            // generate comments to bodies
            newBody.append("\n"+NbBundle.getMessage(TestCreator.class,"TestCreator.variantMethods.defaultComment")+"\n");
        }
        if (JUnitSettings.getDefault().isBodyContent()) {
            // generate a test failuare by default (in response to request 022).
            newBody.append(NbBundle.getMessage(TestCreator.class,"TestCreator.variantMethods.defaultBody")+"\n");
        }
            
        // return type
        TypeReference typeName = pkg.getMultipartId().createMultipartId("void", null, Collections.EMPTY_LIST);

        // method parameters
        List params = createTestMethodParams(sm, pkg);
            
        Method ret = pkg.getMethod().createMethod(newName,
                                                  annotations,
                                                  modifiers,
                                                  javadocText,
                                                  null, // javadoc
                                                  null, // body
                                                  newBody.toString(),
                                                  Collections.EMPTY_LIST, // type parameters
                                                  params,
                                                  Collections.EMPTY_LIST, // exceptions
                                                  typeName,
                                                  0);
        return ret;
    }


     

    static private boolean hasTestableMethods(JavaClass cls) {

        Iterator methods = TestUtil.collectFeatures(cls, Method.class, 0, true).iterator();
        while (methods.hasNext()) {
            if (isMethodAcceptable((Method)methods.next()))
                return true;
        }
        
        return false;
    }



    static public void fillGeneral(JavaClass testClass) {
        // public entry points are wrapped in MDR transactions
        JavaModel.getJavaRepository().beginTrans(true);
        try {

            JavaModelPackage pkg = (JavaModelPackage)testClass.refImmediatePackage();
        
            testClass.setSuperClassName(pkg.getMultipartId().createMultipartId(JUNIT_SUPER_CLASS_NAME, null, Collections.EMPTY_LIST));
            testClass.setModifiers(Modifier.PUBLIC);

            // remove default ctor, if exists (shouldn't throw exception)
            if (null == testClass.getConstructor(Collections.singletonList(createStringType(pkg)), false)) {
                //fill classe's constructor
                Constructor newConstr = createTestConstructor(pkg, testClass.getSimpleName());
                testClass.getFeatures().add(newConstr);
            }
        

            //add method setUp() (optionally):
            if (JUnitSettings.getDefault().isGenerateSetUp()
                && !hasInitMethod(testClass, METHOD_NAME_SETUP)) {

                testClass.getFeatures().add(generateInitMethod(pkg, METHOD_NAME_SETUP));
            }
        
            //add method tearDown() (optionally):
            if (JUnitSettings.getDefault().isGenerateTearDown()
                && !hasInitMethod(testClass, METHOD_NAME_TEARDOWN)) {
                testClass.getFeatures().add(generateInitMethod(pkg, METHOD_NAME_TEARDOWN));
            }
        } finally {
            JavaModel.getJavaRepository().endTrans();
        }

    }

    
    /**
     * Detects whether a given class contains a no-argument method of a given
     * name, having protected or public member access.
     *
     * @param  cls  class the method is to be found in
     * @param  methodName  name of the method to be found
     * @return  true if the class contains such a method,
     *          false otherwise
     */
    private static boolean hasInitMethod(JavaClass cls,
                                         String methodName) {
        return cls.getMethod(methodName,
                             Collections.EMPTY_LIST,
                             false) != null;
    }

    
    /**
     * Generates a set-up or a tear-down method.
     * The generated method will have no arguments, void return type
     * and a declaration that it may throw java.lang.Exception.
     * The method will have a declared protected member access.
     *
     * @param  methodName  name of the method to be created
     * @return  created method
     * @see  http://junit.sourceforge.net/javadoc/junit/framework/TestCase.html
     *       methods setUp() and tearDown()
     */
    private static Method generateInitMethod(JavaModelPackage pkg, String methodName)
    {
        Method method = pkg.getMethod().
            createMethod(methodName, // name
                         Collections.EMPTY_LIST, // annotations
                         Modifier.PROTECTED, // modifiers
                         null, // javadoc text
                         null, // javadoc object
                         null, // body object
                         "\n", // body text
                         Collections.EMPTY_LIST, // type parameters
                         Collections.EMPTY_LIST, // parameters
                         Collections.singletonList(pkg.getMultipartId().createMultipartId("java.lang.Exception", null, Collections.EMPTY_LIST)), // exception names
                         pkg.getMultipartId().createMultipartId("void", null, Collections.EMPTY_LIST), // typeName
                         0 // dimCount
                         );
        return method;
    }




    static private void fillTestClass(Resource srcRc, JavaClass srcClass, Resource tgtRc, JavaClass tgtClass) 
    {
        fillGeneral(tgtClass);

        List    innerClasses = TestUtil.filterFeatures(srcClass, JavaClass.class);
        
        // create test classes for inner classes
        Iterator itInner = innerClasses.iterator();
        while (itInner.hasNext()) {
            JavaClass theClass = (JavaClass)itInner.next();
            JavaModelPackage pkg = ((JavaModelPackage)tgtClass.refImmediatePackage());

            if (isClassTestable(theClass)) {
                // create new test class
                JavaClass innerTester;
                String    name = TestUtil.getTestClassName(theClass.getSimpleName());
                
                if (null == (innerTester = TestUtil.getClassBySimpleName(tgtClass, name))) {

                    innerTester = pkg.getJavaClass().createJavaClass();
                    innerTester.setSimpleName(tgtClass.getName()+"."+name);
                    tgtClass.getFeatures().add(innerTester);
                }
                
                // process tested inner class the same way like top-level class
                fillTestClass(srcRc, theClass, tgtRc, innerTester);
                
                // do additional things for test class to became inner class usable for testing in JUnit
                innerTester.setModifiers(innerTester.getModifiers() | Modifier.STATIC);

            }
        }
          
        // add suite method ... only if we are supposed to do so

        if (JUnitSettings.getDefault().isGenerateSuiteClasses() &&
            (!hasSuiteMethod(tgtClass))) {
            tgtClass.getFeatures().add(createTestClassSuiteMethod(tgtClass));            
        } 

        

        // fill methods according to the iface of tested class
        Iterator methit = TestUtil.filterFeatures(srcClass, Method.class).iterator();
        while (methit.hasNext()) {
            Method sm = (Method)methit.next();
            if (isMethodAcceptable(sm) &&
                tgtClass.getMethod(createTestMethodName(sm.getName()),
                                   createTestMethodParams(sm, (JavaModelPackage)tgtClass.refImmediatePackage()), 
                                   false) == null) 
                {
                    Method tm = createTestMethod(srcClass, sm, (JavaModelPackage)tgtClass.refImmediatePackage());
                    tgtClass.getFeatures().add(tm);
                } 

        }


        // create abstract class implementation
         if (
             (JUnitSettings.getDefault().isGenerateAbstractImpl()) &&
             (
              (Modifier.ABSTRACT == (srcClass.getModifiers() & Modifier.ABSTRACT)) |
              (srcClass.isInterface())
              )
             ) {
             createAbstractImpl(srcClass, tgtClass);
         }
         
    }        
  

    static private void fillSuiteClass(List listMembers, 
                                       String packageName, 
                                       JavaClass tgtClass)  {
        
        JavaModelPackage pkg = (JavaModelPackage)tgtClass.refImmediatePackage();                 
        fillGeneral(tgtClass);

        // find "suite()" method 
        Method suiteMethod = tgtClass.getMethod("suite", Collections.EMPTY_LIST, false);
        tgtClass.getFeatures().remove(suiteMethod);
        
        suiteMethod = createSuiteMethod(pkg);
        String javadocText = NbBundle.getMessage(TestCreator.class,"TestCreator.suiteMethod.JavaDoc.comment");
        JavaDoc jd = pkg.getJavaDoc().createJavaDoc(javadocText, Collections.EMPTY_LIST);
        suiteMethod.setJavadoc(jd);
        
        StringBuffer newBody = new StringBuffer();
        generateSuiteBody(pkg, tgtClass.getSimpleName(), newBody, listMembers, true);
        suiteMethod.setBodyText(newBody.toString());
        tgtClass.getFeatures().add(suiteMethod);

    }


    

    static private void generateSuiteBody(JavaModelPackage pkg, String testName, StringBuffer body, List members, boolean alreadyExists) {
        Iterator    li;
        String      name;
        
           
        body.append('\n');
        //body.append("//" + GENERATED_SUITE_BLOCK_START + "\n");
        //body.append(NbBundle.getMessage(TestCreator.class,"TestCreator.suiteMethod.suiteBlock.comment")+"\n");
        body.append("junit.framework.TestSuite suite = new junit.framework.TestSuite(\"" + testName + "\");\n");
        
        li = members.listIterator();
        TypeClass typeClass = pkg.getType();

        while (li.hasNext()) {
            name = (String) li.next();
            
            Type ty = (Type)typeClass.resolve(name);
            if (ty instanceof ClassDefinition) {
                Method suiteMethod = ((ClassDefinition)ty).getMethod("suite", Collections.EMPTY_LIST, true);
                if (suiteMethod != null && 
                    ((suiteMethod.getModifiers() & Modifier.STATIC) == Modifier.STATIC))
                    body.append("suite.addTest(" + name + ".suite());\n");
            }
        }

        body.append("return suite;\n");
        //body.append("//" + GENERATED_SUITE_BLOCK_END + "\n");
                
    }



    static private boolean isMethodAcceptable(Method m) {
        return (
                (m.getModifiers() & Modifier.PRIVATE) == 0 &&
                (
                 (m.getModifiers() & cfg_MethodsFilter) != 0 ||
                 (
                  (m.getModifiers() & (Modifier.PUBLIC | Modifier.PROTECTED)) == 0 
                  && cfg_MethodsFilterPackage
                  )
                 )
                );
    }


    static private void createAbstractImpl(JavaClass srcClass, JavaClass tgtClass) {
        JavaModelPackage pkg = (JavaModelPackage)tgtClass.refImmediatePackage();
        String implClassName = srcClass.getSimpleName() + "Impl";
        JavaClass innerClass = tgtClass.getInnerClass(implClassName, false);

        if (innerClass == null) {
            String name = implClassName;
            List annotations = Collections.EMPTY_LIST;
            int modifiers = Modifier.PRIVATE;

            // generate JavaDoc for the generated implementation of tested abstract class
            String javadocText = null;
            if (JUnitSettings.getDefault().isJavaDoc()) {
                javadocText = MessageFormat.format(NbBundle.getMessage(TestCreator.class,"TestCreator.abstracImpl.JavaDoc.comment"), 
                                new Object[] {srcClass.getName()});
            }
            
            // superclass
            MultipartId supClass = null;
            if (srcClass.isInner())
                supClass = pkg.getMultipartId().createMultipartId(srcClass.getName(), 
                                                                null,
                                                                Collections.EMPTY_LIST);
            else
                supClass = pkg.getMultipartId().createMultipartId(srcClass.getSimpleName(), 
                                                                null,
                                                                Collections.EMPTY_LIST);

            innerClass = pkg.getJavaClass().createJavaClass(name, 
                                                            annotations,
                                                            modifiers,
                                                            javadocText,
                                                            null,
                                                            Collections.EMPTY_LIST,
                                                            null,
                                                            Collections.EMPTY_LIST,
                                                            Collections.EMPTY_LIST);
            if (srcClass.isInterface()) 
                innerClass.getInterfaceNames().add(supClass);
            else
                innerClass.setSuperClassName(supClass);


            createImpleConstructors(srcClass, innerClass);
            tgtClass.getFeatures().add(innerClass);
        }

        // created dummy implementation for all abstract methods
        Iterator it = TestUtil.collectFeatures(srcClass, Method.class,
                                               Modifier.ABSTRACT, true).iterator();

        while (it.hasNext()) {
            Method oldMethod = (Method)it.next();
            if (innerClass.getMethod(oldMethod.getName(),
                                     TestUtil.getParameterTypes(oldMethod.getParameters()),
                                     false) == null) {
                Method newMethod = createMethodImpl(pkg, oldMethod);
                innerClass.getFeatures().add(newMethod);
            } 

        }


    }
    

    static private Method createMethodImpl(JavaModelPackage pkg, Method origMethod)  {
        Method   newMethod = pkg.getMethod().createMethod();

        newMethod.setName(origMethod.getName());

        // compute modifiers of the method
        int mod = origMethod.getModifiers() & ~Modifier.ABSTRACT;
        if (((JavaClass)origMethod.getDeclaringClass()).isInterface())
            mod |= Modifier.PUBLIC;
        newMethod.setModifiers(mod);

        // prepare the body of method implementation
        StringBuffer    body = new StringBuffer(200);
        body.append('\n');
        if (JUnitSettings.getDefault().isBodyComments()) {
            body.append(NbBundle.getMessage(TestCreator.class,"TestCreator.methodImpl.bodyComment"));
            body.append('\n');
        }

        newMethod.setType(origMethod.getType());
        Type type= origMethod.getType();
        if (type != null) {
            String value = null;
            if ((type instanceof JavaClass) || (type instanceof Array)) {
                value = "null";
            } else if (type instanceof PrimitiveType) {
                PrimitiveTypeKindEnum tke = (PrimitiveTypeKindEnum)((PrimitiveType)type).getKind();
                if (tke.equals(PrimitiveTypeKindEnum.BOOLEAN)) value = "false";
                else if (!tke.equals(PrimitiveTypeKindEnum.VOID)) value = "0";
            }

            if (value != null) 
                body.append("\nreturn "+value+";\n");
        }

        newMethod.setBodyText(body.toString());
        
        // parameters
        newMethod.getParameters().addAll(TestUtil.cloneParams(origMethod.getParameters(), pkg));

        return newMethod;
     }



     static private void createImpleConstructors(JavaClass srcClass, JavaClass tgtClass) {
         JavaModelPackage pkg = (JavaModelPackage)tgtClass.refImmediatePackage();

         Iterator it = TestUtil.filterFeatures(srcClass, Constructor.class).iterator();
         while (it.hasNext()) {
             Constructor ctr = (Constructor)it.next();

             if (0 == (ctr.getModifiers() & Modifier.PRIVATE)) {
                 Constructor nctr = pkg.getConstructor().createConstructor();
                 nctr.setBodyText("\nsuper(" + getParameterString(ctr.getParameters()) + ");\n");
                 nctr.getParameters().addAll(TestUtil.cloneParams(ctr.getParameters(),pkg));
                 tgtClass.getFeatures().add(nctr);
             }
         }
     }



     static private String getParameterString(List params) {
         StringBuffer paramString = new StringBuffer();
         
         Iterator it = params.iterator();
         while (it.hasNext()) {
             Parameter param= (Parameter)it.next();
             if (paramString.length() > 0) {
                 paramString.append(", ");
             }
             paramString.append(param.getName());
         }
         
         return paramString.toString();
     }



    private static void removeSuiteMethod(JavaClass tgtClass) {
        Method sm = tgtClass.getMethod("suite", Collections.EMPTY_LIST, false);
        if (sm != null) tgtClass.getFeatures().remove(sm);
    }


    private static void addMainMethod(JavaClass tgtClass) {
        JavaModelPackage pkg = (JavaModelPackage)tgtClass.refImmediatePackage();  
        if ((JUnitSettings.getDefault().isGenerateMainMethod()) && (!TestUtil.hasMainMethod(tgtClass))) {
            // add main method
            String mainMethodBodySetting = 
                JUnitSettings.getDefault().getGenerateMainMethodBody();

            if ((mainMethodBodySetting != null) && (mainMethodBodySetting.length() > 0) ) {
                // create body
                StringBuffer mainMethodBody = new StringBuffer(mainMethodBodySetting.length() + 2);
                mainMethodBody.append('\n');
                mainMethodBody.append(mainMethodBodySetting);
                mainMethodBody.append('\n');

                Type paramType = pkg.getArray().resolveArray(TestUtil.getStringType(pkg));
                Parameter param = pkg.getParameter().createParameter("argList", 
                                                                     Collections.EMPTY_LIST, // annotations
                                                                     false, // is final
                                                                     null, // typename
                                                                     0, // dimCount
                                                                     false);
                param.setType(paramType);
                                                                         

                Method mainMethod = pkg.getMethod().createMethod("main",
                                                                 Collections.EMPTY_LIST,
                                                                 Modifier.STATIC | Modifier.PUBLIC,
                                                                 null, // javadoc text
                                                                 null, // jvadoc
                                                                 null, // object body
                                                                 mainMethodBody.toString(), // string body
                                                                 Collections.EMPTY_LIST, // type params
                                                                 Collections.singletonList(param), // parameters
                                                                 Collections.EMPTY_LIST, // exceptions
                                                                 TestUtil.getTypeReference(pkg, "void"), // type
                                                                 0);
                tgtClass.getFeatures().add(mainMethod);
            }
        }
    }


    private static Type createStringType(JavaModelPackage pkg) {
        return pkg.getType().resolve("java.lang.String");
    }



}
... this post is sponsored by my books ...

#1 New Release!

FP Best Seller

 

new blog posts

 

Copyright 1998-2021 Alvin Alexander, alvinalexander.com
All Rights Reserved.

A percentage of advertising revenue from
pages under the /java/jwarehouse URI on this website is
paid back to open source projects.