All Downloads are FREE. Search and download functionalities are using the official Maven repository.

gw.test.TestClassHelper Maven / Gradle / Ivy

There is a newer version: 1.18.2
Show newest version
/*
 * Copyright 2014 Guidewire Software, Inc.
 */

package gw.test;

import gw.internal.ext.org.objectweb.asm.ClassReader;
import gw.internal.ext.org.objectweb.asm.Opcodes;
import gw.internal.ext.org.objectweb.asm.tree.AbstractInsnNode;
import gw.internal.ext.org.objectweb.asm.tree.ClassNode;
import gw.internal.ext.org.objectweb.asm.tree.LineNumberNode;
import gw.internal.ext.org.objectweb.asm.tree.MethodNode;
import gw.util.StreamUtil;
import junit.framework.Test;
import junit.framework.TestCase;

import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Modifier;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

/**
 * Helper methods for analyzing methods, and instantiating test classes.
 */
public class TestClassHelper {
  private static final Map, List> cache = new ConcurrentHashMap, List>();

  /**
   * Returns list of methods according to their order in the source file.
   * 

* Supertype methods go first in the list. *

* Returns empty list if cannot find class file for the specified class. Class file is retrieved by * using {@link Class#getResourceAsStream} so it won't work for classes generated at runtine. * * @param clazz class to analyze * @return list of method names */ @SuppressWarnings("unchecked") public static List getMethodsSorted(Class clazz) { List allMethods = cache.get(clazz); if (allMethods != null) { return allMethods; } ClassNode javaClass = parseClass(clazz); if (javaClass == null) { return Collections.emptyList(); } List currentClassMethods = javaClass.methods; Collections.sort(currentClassMethods, new Comparator() { @Override public int compare(MethodNode o1, MethodNode o2) { return getLineNumber( o1 ) - getLineNumber( o2 ); } }); allMethods = new ArrayList(); // add method of super class first Class superclass = clazz.getSuperclass(); if (superclass != null && !superclass.getClass().equals(TestCase.class)) { allMethods.addAll(getMethodsSorted((Class) superclass)); } allMethods.addAll(currentClassMethods); cache.put(clazz, Collections.unmodifiableList(new ArrayList(allMethods))); return allMethods; } private static int getLineNumber( MethodNode o2 ) { for( Iterator iter = o2.instructions.iterator(); iter.hasNext(); ) { AbstractInsnNode next = (AbstractInsnNode)iter.next(); if( next instanceof LineNumberNode ) { return ((LineNumberNode)next).line; } } return -1; } private static ClassNode parseClass(Class clazz) { String pathToClassFile = "/" + clazz.getName().replace('.', '/') + ".class"; InputStream resourceAsStream = clazz.getResourceAsStream(pathToClassFile); if (resourceAsStream == null) { return null; } try { ClassNode jclass = new ClassNode( Opcodes.ASM7 ); ClassReader cr = new ClassReader( resourceAsStream ); cr.accept( jclass, 0 ); return jclass; } catch( IOException e ) { throw new RuntimeException( "Error during analyzing byte code of the class " + clazz.getName(), e ); } finally { StreamUtil.closeNoThrow(resourceAsStream); } } public static Test createTestSuite(Class clazz, Iterable methodNames) { try { Constructor constructor = getConstructor(clazz); junit.framework.TestSuite newSuite = new junit.framework.TestSuite(); for (String name : methodNames) { TestCase test; if (constructor.getParameterTypes().length == 0) { test = constructor.newInstance(); test.setName(name); } else { test = constructor.newInstance(name); } newSuite.addTest(test); } return newSuite; } catch (InstantiationException e) { throw new RuntimeException("Cannot instantiate test class " + clazz.getName(), e); } catch (IllegalAccessException e) { throw new RuntimeException(clazz.getName() + " constructor is not accessible", e); } catch (InvocationTargetException e) { throw new RuntimeException(clazz.getName() + "(String name) constructor threw an exception", e); } } private static Constructor getConstructor(Class clazz) { try { Constructor constructor = clazz.getConstructor(String.class); if (Modifier.isPublic(constructor.getModifiers())) { return constructor; } } catch (NoSuchMethodException e) { } try { Constructor constructor = clazz.getConstructor(); if (Modifier.isPublic(constructor.getModifiers())) { return constructor; } } catch (NoSuchMethodException e) { } throw new RuntimeException("Did not find public " + clazz.getName() + "(String name) or " + clazz.getName() + "() constructor"); } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy