code refactor and add test case for util classes

This commit is contained in:
金戟 2020-07-27 20:41:12 +08:00
parent 2f6c2105f6
commit e6ff355da9
17 changed files with 129 additions and 28 deletions

View File

@ -87,7 +87,7 @@ public class SourceClassHandler extends ClassHandler {
List<Byte> parameterTypes = ClassUtil.getParameterTypes(constructorDesc);
InsnList il = new InsnList();
il.add(new MethodInsnNode(INVOKESTATIC, TESTABLE_NE, TESTABLE_W,
getConstructorSubstitutionDesc(parameterTypes.size()), false));
getConstructorSubstitutionDesc(parameterTypes.size())));
il.add(new TypeInsnNode(CHECKCAST, classType));
mn.instructions.insertBefore(instructions[end], il);
mn.instructions.remove(instructions[start]);
@ -109,7 +109,7 @@ public class SourceClassHandler extends ClassHandler {
List<Byte> parameterTypes = ClassUtil.getParameterTypes(methodDesc);
InsnList il = new InsnList();
il.add(new MethodInsnNode(INVOKESTATIC, TESTABLE_NE, TESTABLE_F,
getMethodSubstitutionDesc(parameterTypes.size()), false));
getMethodSubstitutionDesc(parameterTypes.size())));
il.add(new TypeInsnNode(CHECKCAST, returnType));
mn.instructions.insertBefore(instructions[end], il);
mn.instructions.remove(instructions[end]);

View File

@ -14,6 +14,7 @@ public class TestClassHandler extends ClassHandler {
private static final List<String> TEST_ANNOTATIONS = new ArrayList<String>();
private static final String TESTABLE_SETUP_METHOD_NAME = "testableSetup";
private static final String TESTABLE_SETUP_METHOD_DESC = "()V";
static {
// JUnit4
@ -42,7 +43,7 @@ public class TestClassHandler extends ClassHandler {
if (CollectionUtil.containsAny(visibleAnnotationNames, TEST_ANNOTATIONS)) {
InsnList il = new InsnList();
il.add(new VarInsnNode(ALOAD, 0));
il.add(new MethodInsnNode(INVOKESPECIAL, cn.name, TESTABLE_SETUP_METHOD_NAME, "()V", false));
il.add(new MethodInsnNode(INVOKESPECIAL, cn.name, TESTABLE_SETUP_METHOD_NAME, TESTABLE_SETUP_METHOD_DESC));
mn.instructions.insertBefore(mn.instructions.get(0), il);
}
}

View File

@ -41,7 +41,7 @@ public class ClassUtil {
annotations.add(annotationName);
}
return annotations;
} catch (IOException e) {
} catch (Exception e) {
return new ArrayList<String>();
}
}

View File

@ -1,6 +1,9 @@
package com.alibaba.testable.agent.util;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
/**
* @author flin
@ -18,4 +21,10 @@ public class CollectionUtil {
return false;
}
public static <T> List<T> listOf(T... items) {
List<T> list = new ArrayList<T>(items.length);
Collections.addAll(list, items);
return list;
}
}

View File

@ -6,6 +6,13 @@ import static org.junit.jupiter.api.Assertions.*;
class ClassUtilTest {
@Test
void should_able_to_get_annotation() {
assertEquals(0, ClassUtil.getAnnotations("class.not.exist").size());
assertEquals(0, ClassUtil.getAnnotations("com.alibaba.testable.agent.util.ClassUtil").size());
assertEquals("org.apiguardian.api.API", ClassUtil.getAnnotations("org.junit.jupiter.api.Assertions").get(0));
}
@Test
void should_able_to_get_parameter_count() {
assertEquals(1, ClassUtil.getParameterTypes("(Ljava/lang/String;)V").size());
@ -23,4 +30,10 @@ class ClassUtilTest {
assertEquals("[Ljava/lang/String;", ClassUtil.getReturnType("(Ljava/lang/String;)[Ljava/lang/String;"));
}
@Test
void should_able_to_convert_class_name() {
assertEquals("Ljava/lang/String;", ClassUtil.toByteCodeClassName("java.lang.String"));
}
}

View File

@ -0,0 +1,19 @@
package com.alibaba.testable.agent.util;
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.*;
class CollectionUtilTest {
@Test
void should_able_to_check_collection_contains_any_element() {
assertTrue(CollectionUtil.containsAny(
CollectionUtil.listOf("a", "b"), CollectionUtil.listOf("b", "c")
));
assertFalse(CollectionUtil.containsAny(
CollectionUtil.listOf("a", "b"), CollectionUtil.listOf("c", "d")
));
}
}

View File

@ -0,0 +1,16 @@
package com.alibaba.testable.agent.util;
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.*;
class StringUtilTest {
@Test
void should_able_to_repeat_text() {
assertEquals("", StringUtil.repeat("abc", 0));
assertEquals("abc", StringUtil.repeat("abc", 1));
assertEquals("abcabcabc", StringUtil.repeat("abc", 3));
}
}

View File

@ -25,6 +25,12 @@
<scope>system</scope>
<systemPath>${java.home}/../lib/tools.jar</systemPath>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-api</artifactId>
<version>5.6.2</version>
<scope>test</scope>
</dependency>
</dependencies>
<build>

View File

@ -1,4 +1,4 @@
package com.alibaba.testable.core.util;
package com.alibaba.testable.core.constant;
/**
* @author flin

View File

@ -1,7 +1,7 @@
package com.alibaba.testable.core.generator;
import com.alibaba.testable.core.model.TestableContext;
import com.alibaba.testable.core.util.ConstPool;
import com.alibaba.testable.core.constant.ConstPool;
import com.sun.tools.javac.tree.JCTree.*;
import com.sun.tools.javac.util.List;
import com.sun.tools.javac.util.ListBuffer;

View File

@ -1,7 +1,7 @@
package com.alibaba.testable.core.generator;
import com.alibaba.testable.core.model.TestableContext;
import com.alibaba.testable.core.util.ConstPool;
import com.alibaba.testable.core.constant.ConstPool;
import com.sun.tools.javac.code.Type;
import com.sun.tools.javac.tree.JCTree.*;
import com.sun.tools.javac.util.List;

View File

@ -2,7 +2,7 @@ package com.alibaba.testable.core.processor;
import com.alibaba.testable.core.annotation.EnableTestable;
import com.alibaba.testable.core.translator.EnableTestableTranslator;
import com.alibaba.testable.core.util.ConstPool;
import com.alibaba.testable.core.constant.ConstPool;
import com.alibaba.testable.core.util.ResourceUtil;
import com.sun.tools.javac.code.Symbol;
import com.sun.tools.javac.tree.JCTree;
@ -61,7 +61,8 @@ public class EnableTestableProcessor extends BaseProcessor {
}
private void createTestableAgentJar() {
if (!checkFirstClassCompiled()) {
if (!hasFirstClassCompiled) {
hasFirstClassCompiled = true;
byte[] bytes = ResourceUtil.fetchBinary(TESTABLE_AGENT_JAR);
if (bytes.length == 0) {
cx.logger.error("Failed to generate testable agent jar");
@ -70,14 +71,6 @@ public class EnableTestableProcessor extends BaseProcessor {
}
}
private boolean checkFirstClassCompiled() {
if (!hasFirstClassCompiled) {
hasFirstClassCompiled = true;
return false;
}
return true;
}
private void writeBinaryFile(String path, String fileName, byte[] content) {
try {
FileObject resource = cx.filter.createResource(StandardLocation.SOURCE_OUTPUT, path, fileName);

View File

@ -3,10 +3,9 @@ package com.alibaba.testable.core.translator;
import com.alibaba.testable.core.generator.PrivateAccessStatementGenerator;
import com.alibaba.testable.core.generator.TestSetupMethodGenerator;
import com.alibaba.testable.core.model.TestableContext;
import com.alibaba.testable.core.util.ConstPool;
import com.alibaba.testable.core.constant.ConstPool;
import com.sun.tools.javac.tree.JCTree;
import com.sun.tools.javac.tree.JCTree.*;
import com.sun.tools.javac.util.List;
import com.sun.tools.javac.util.ListBuffer;
import com.sun.tools.javac.util.Name;
import com.sun.tools.javac.util.Pair;

View File

@ -3,14 +3,12 @@ package com.alibaba.testable.core.util;
import java.io.*;
/**
* Generate global n.e class code
*
* @author flin
*/
public class ResourceUtil {
public static String fetchText(String fileName) {
InputStream in = ResourceUtil.class.getResourceAsStream("/" + fileName);
public static String fetchText(String filePath) {
InputStream in = ResourceUtil.class.getResourceAsStream("/" + filePath);
BufferedReader reader = new BufferedReader(new InputStreamReader(in));
StringBuilder buffer = new StringBuilder();
String line;
@ -22,15 +20,15 @@ public class ResourceUtil {
reader.close();
return buffer.toString();
} catch (IOException e) {
System.err.println("Failed to fetch text file: " + fileName);
System.err.println("Failed to fetch text file: " + filePath);
return "";
}
}
public static byte[] fetchBinary(String fileName) {
InputStream in = ResourceUtil.class.getResourceAsStream("/" + fileName);
public static byte[] fetchBinary(String filePath) {
InputStream in = ResourceUtil.class.getResourceAsStream("/" + filePath);
if (in == null) {
System.err.println("Resource " + fileName + " not exist");
System.err.println("Resource " + filePath + " not exist");
return new byte[] {};
}
ByteArrayOutputStream buffer = new ByteArrayOutputStream();
@ -44,7 +42,7 @@ public class ResourceUtil {
buffer.close();
return buffer.toByteArray();
} catch (IOException e) {
System.err.println("Failed to fetch file: " + fileName);
System.err.println("Failed to fetch file: " + filePath);
return new byte[] {};
}
}

View File

@ -2,6 +2,9 @@ package com.alibaba.testable.core.util;
import java.util.List;
/**
* @author flin
*/
public class StringUtil {
static public String join(List<String> list, String conjunction)

View File

@ -0,0 +1,23 @@
package com.alibaba.testable.core.util;
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.*;
class ResourceUtilTest {
@Test
void fetchText() {
assertTrue(
ResourceUtil.fetchText("META-INF/services/javax.annotation.processing.Processor").startsWith("com.")
);
}
@Test
void should_able_to_fetch_binary() {
assertTrue(
ResourceUtil.fetchBinary("com/alibaba/testable/core/util/ResourceUtil.class").length > 0
);
}
}

View File

@ -0,0 +1,21 @@
package com.alibaba.testable.core.util;
import org.junit.jupiter.api.Test;
import java.util.ArrayList;
import java.util.List;
import static org.junit.jupiter.api.Assertions.*;
class StringUtilTest {
@Test
void should_able_to_join_string() {
List<String> list = new ArrayList<>(4);
list.add("a");
list.add("b");
list.add("c");
list.add("d");
assertEquals("a-b-c-d", StringUtil.join(list, "-"));
}
}