diff --git a/testable-agent/src/main/java/com/alibaba/testable/agent/handler/BaseClassHandler.java b/testable-agent/src/main/java/com/alibaba/testable/agent/handler/BaseClassHandler.java index 859a222..9fbbb67 100644 --- a/testable-agent/src/main/java/com/alibaba/testable/agent/handler/BaseClassHandler.java +++ b/testable-agent/src/main/java/com/alibaba/testable/agent/handler/BaseClassHandler.java @@ -10,13 +10,10 @@ import org.objectweb.asm.tree.ClassNode; */ abstract public class BaseClassHandler implements Opcodes { - protected static final String TESTABLE_REF = "__testable"; protected static final String GET_TESTABLE_REF = "testableIns"; protected static final String VOID_ARGS = "()"; protected static final String VOID_RES = "V"; - protected String mockClassName; - public byte[] getBytes(byte[] classFileBuffer) { ClassReader cr = new ClassReader(classFileBuffer); ClassNode cn = new ClassNode(); diff --git a/testable-agent/src/main/java/com/alibaba/testable/agent/handler/MockClassHandler.java b/testable-agent/src/main/java/com/alibaba/testable/agent/handler/MockClassHandler.java index d509f4c..2d987a8 100644 --- a/testable-agent/src/main/java/com/alibaba/testable/agent/handler/MockClassHandler.java +++ b/testable-agent/src/main/java/com/alibaba/testable/agent/handler/MockClassHandler.java @@ -34,6 +34,9 @@ public class MockClassHandler extends BaseClassWithContextHandler { private static final String METHOD_IS_ASSOCIATED = "isAssociated"; private static final String SIGNATURE_IS_ASSOCIATED = "()Z"; private static final String SELF_REF = "__self"; + private static final String TESTABLE_REF = "__testable"; + + private final String mockClassName; public MockClassHandler(String className) { this.mockClassName = className; diff --git a/testable-agent/src/main/java/com/alibaba/testable/agent/handler/OmniClassHandler.java b/testable-agent/src/main/java/com/alibaba/testable/agent/handler/OmniClassHandler.java new file mode 100644 index 0000000..fa12d68 --- /dev/null +++ b/testable-agent/src/main/java/com/alibaba/testable/agent/handler/OmniClassHandler.java @@ -0,0 +1,24 @@ +package com.alibaba.testable.agent.handler; + +import com.alibaba.testable.agent.util.ClassUtil; +import org.objectweb.asm.tree.ClassNode; +import org.objectweb.asm.tree.MethodNode; + +import static com.alibaba.testable.core.constant.ConstPool.CONSTRUCTOR; + +/** + * @author flin + */ +public class OmniClassHandler extends BaseClassHandler { + + private static final String TYPE_NULL = "com.alibaba.testable.core.model.Null"; + + @Override + protected void transform(ClassNode cn) { + if ((cn.access & (ACC_ABSTRACT | ACC_SUPER)) == 0) { + cn.methods.add(new MethodNode(ACC_PRIVATE, CONSTRUCTOR, + "(" + ClassUtil.toByteCodeClassName(TYPE_NULL) + ")V", null, null)); + } + } + +} diff --git a/testable-agent/src/main/java/com/alibaba/testable/agent/handler/SourceClassHandler.java b/testable-agent/src/main/java/com/alibaba/testable/agent/handler/SourceClassHandler.java index 0257d58..ee631dc 100644 --- a/testable-agent/src/main/java/com/alibaba/testable/agent/handler/SourceClassHandler.java +++ b/testable-agent/src/main/java/com/alibaba/testable/agent/handler/SourceClassHandler.java @@ -21,6 +21,7 @@ import static com.alibaba.testable.core.constant.ConstPool.CONSTRUCTOR; */ public class SourceClassHandler extends BaseClassHandler { + private final String mockClassName; private final List injectMethods; private final Set invokeOps = new HashSet() {{ add(Opcodes.INVOKEVIRTUAL); diff --git a/testable-agent/src/main/java/com/alibaba/testable/agent/handler/TestClassHandler.java b/testable-agent/src/main/java/com/alibaba/testable/agent/handler/TestClassHandler.java index 79c4c69..5c4d242 100644 --- a/testable-agent/src/main/java/com/alibaba/testable/agent/handler/TestClassHandler.java +++ b/testable-agent/src/main/java/com/alibaba/testable/agent/handler/TestClassHandler.java @@ -22,6 +22,7 @@ public class TestClassHandler extends BaseClassWithContextHandler { private static final String DESC_METHOD_CLEAN = "()V"; private static final String THIS = "this"; + private final String mockClassName; private int testCaseCount = 0; private final Framework[] frameworkClasses = new Framework[] { diff --git a/testable-agent/src/main/java/com/alibaba/testable/agent/transformer/TestableClassTransformer.java b/testable-agent/src/main/java/com/alibaba/testable/agent/transformer/TestableClassTransformer.java index 3379e32..b7aff27 100644 --- a/testable-agent/src/main/java/com/alibaba/testable/agent/transformer/TestableClassTransformer.java +++ b/testable-agent/src/main/java/com/alibaba/testable/agent/transformer/TestableClassTransformer.java @@ -2,6 +2,7 @@ package com.alibaba.testable.agent.transformer; import com.alibaba.testable.agent.constant.ConstPool; import com.alibaba.testable.agent.handler.MockClassHandler; +import com.alibaba.testable.agent.handler.OmniClassHandler; import com.alibaba.testable.agent.handler.SourceClassHandler; import com.alibaba.testable.agent.handler.TestClassHandler; import com.alibaba.testable.agent.model.MethodInfo; @@ -43,7 +44,7 @@ public class TestableClassTransformer implements ClassFileTransformer { * Just avoid spend time to scan those surely non-user classes Should keep these lists as tiny as possible */ private final String[] BLACKLIST_PREFIXES = new String[] {"jdk/", "java/", "javax/", "sun/", "com/sun/", - "org/apache/maven/", "com/alibaba/testable/", "junit/", "org/junit/", "org/testng/"}; + "org/groovy", "org/apache/maven/", "com/alibaba/testable/", "junit/", "org/junit/", "org/testng/"}; public MockClassParser mockClassParser = new MockClassParser(); @@ -55,19 +56,19 @@ public class TestableClassTransformer implements ClassFileTransformer { return null; } LogUtil.verbose("Handle class: " + className); - byte[] bytes = null; + byte[] bytes = new OmniClassHandler().getBytes(classFileBuffer); try { if (mockClassParser.isMockClass(className)) { // it's a mock class LogUtil.diagnose("Handling mock class %s", className); - bytes = new MockClassHandler(className).getBytes(classFileBuffer); + bytes = new MockClassHandler(className).getBytes(bytes); dumpByte(className, bytes); } else { String mockClass = foundMockForTestClass(className); if (mockClass != null) { // it's a test class with testable enabled LogUtil.diagnose("Handling test class %s", className); - bytes = new TestClassHandler(mockClass).getBytes(classFileBuffer); + bytes = new TestClassHandler(mockClass).getBytes(bytes); dumpByte(className, bytes); } else { mockClass = foundMockForSourceClass(className); @@ -75,7 +76,7 @@ public class TestableClassTransformer implements ClassFileTransformer { // it's a source class with testable enabled List injectMethods = mockClassParser.getTestableMockMethods(mockClass); LogUtil.diagnose("Handling source class %s", className); - bytes = new SourceClassHandler(injectMethods, mockClass).getBytes(classFileBuffer); + bytes = new SourceClassHandler(injectMethods, mockClass).getBytes(bytes); dumpByte(className, bytes); } } diff --git a/testable-core/src/main/java/com/alibaba/testable/core/model/Null.java b/testable-core/src/main/java/com/alibaba/testable/core/model/Null.java new file mode 100644 index 0000000..136655c --- /dev/null +++ b/testable-core/src/main/java/com/alibaba/testable/core/model/Null.java @@ -0,0 +1,7 @@ +package com.alibaba.testable.core.model; + +/** + * @author flin + */ +public class Null { +}