feat: move collection creation methods to CollectionTool

This commit is contained in:
金戟
2022-12-14 00:34:03 +08:00
parent e7a2b06698
commit 1e9079e8d3
12 changed files with 156 additions and 138 deletions

View File

@@ -18,7 +18,7 @@ import static com.alibaba.testable.agent.constant.ByteCodeConst.TYPE_CLASS;
import static com.alibaba.testable.agent.constant.ConstPool.*;
import static com.alibaba.testable.agent.util.MockInvokeUtil.*;
import static com.alibaba.testable.core.constant.ConstPool.CONSTRUCTOR;
import static com.alibaba.testable.core.util.CollectionUtil.listOf;
import static com.alibaba.testable.core.tool.CollectionTool.fastListOf;
/**
* @author flin
@@ -119,7 +119,7 @@ public class MockClassHandler extends BaseClassWithContextHandler {
mockMethod.instructions = il;
mockMethod.maxStack = maxStack;
mockMethod.maxLocals = 2 + parameters.size();
mockMethod.visibleAnnotations = listOf(new AnnotationNode(ClassUtil.toByteCodeClassName(MOCK_INVOKE)));
mockMethod.visibleAnnotations = fastListOf(new AnnotationNode(ClassUtil.toByteCodeClassName(MOCK_INVOKE)));
cn.methods.add(mockMethod);
} else if ((ClassUtil.toByteCodeClassName(MOCK_NEW)).equals(an.desc)) {
// TODO: should also support MockNew annotation

View File

@@ -5,7 +5,7 @@ import com.alibaba.testable.agent.handler.test.JUnit5Framework;
import com.alibaba.testable.agent.util.AnnotationUtil;
import com.alibaba.testable.agent.util.BytecodeUtil;
import com.alibaba.testable.agent.util.ClassUtil;
import com.alibaba.testable.core.exception.ClassConstructionException;
import com.alibaba.testable.core.tool.CollectionTool;
import com.alibaba.testable.core.util.CollectionUtil;
import com.alibaba.testable.core.util.LogUtil;
import com.alibaba.testable.core.util.StringUtil;
@@ -21,7 +21,7 @@ import java.util.Map;
import static com.alibaba.testable.agent.constant.ConstPool.CLASS_OBJECT;
import static com.alibaba.testable.core.constant.ConstPool.CONSTRUCTOR;
import static com.alibaba.testable.core.constant.ConstPool.THIS_REF;
import static com.alibaba.testable.core.util.CollectionUtil.*;
import static com.alibaba.testable.core.tool.CollectionTool.*;
/**
* @author flin
@@ -41,7 +41,7 @@ public class OmniClassHandler extends BaseClassHandler {
// below classes are loaded before OmniClassHandler, cannot be instrumented
// map of class name to constructor parameters
private static final Map<String, String[]> PRELOADED_CLASSES = mapOf(
entryOf(CLASS_OBJECT, CollectionUtil.<String>arrayOf())
entryOf(CLASS_OBJECT, CollectionTool.<String>arrayOf())
);
private static final String[] JUNIT_TEST_ANNOTATIONS = new String[] {
@@ -146,7 +146,7 @@ public class OmniClassHandler extends BaseClassHandler {
continue;
}
for (AnnotationNode an : mn.visibleAnnotations) {
if (contains(JUNIT_TEST_ANNOTATIONS, an.desc)) {
if (CollectionUtil.contains(JUNIT_TEST_ANNOTATIONS, an.desc)) {
return true;
}
}
@@ -185,7 +185,7 @@ public class OmniClassHandler extends BaseClassHandler {
}
private List<LocalVariableNode> createLocalVariables(ClassNode cn, LabelNode start, LabelNode end) {
return CollectionUtil.mutableListOf(
return listOf(
new LocalVariableNode(THIS_REF, ClassUtil.toByteCodeClassName(cn.name), null, start, end, 0),
new LocalVariableNode(IGNORE, ClassUtil.toByteCodeClassName(VOID_TYPE), null, start, end, 1)
);

View File

@@ -3,7 +3,7 @@ package com.alibaba.testable.agent.util;
import org.junit.jupiter.api.Test;
import org.objectweb.asm.tree.AnnotationNode;
import static com.alibaba.testable.core.util.CollectionUtil.listOf;
import static com.alibaba.testable.core.tool.CollectionTool.fastListOf;
import static org.junit.jupiter.api.Assertions.*;
class AnnotationUtilTest {
@@ -11,7 +11,7 @@ class AnnotationUtilTest {
@Test
void should_get_annotation_parameter() {
AnnotationNode an = new AnnotationNode("");
an.values = listOf((Object)"testKey", "testValue", "demoKey", "demoValue");
an.values = fastListOf((Object)"testKey", "testValue", "demoKey", "demoValue");
assertEquals("testValue", AnnotationUtil.getAnnotationParameter(an, "testKey", "none", String.class));
assertEquals("demoValue", AnnotationUtil.getAnnotationParameter(an, "demoKey", "none", String.class));
assertEquals("none", AnnotationUtil.getAnnotationParameter(an, "testValue", "none", String.class));

View File

@@ -0,0 +1,105 @@
package com.alibaba.testable.core.tool;
import java.lang.reflect.Array;
import java.util.*;
public class CollectionTool {
/**
* Get slice of args[startPos, args.length]
* @param args original item array
* @param startPos index of the first item to keep
* @return a new array with sliced items
*/
public static <T> T[] slice(T[] args, int startPos) {
return slice(args, startPos, args.length - 1);
}
/**
* Get slice of args[startPos, endPos]
* @param args original item array
* @param startPos index of the first item to keep
* @param endPos index of the last item to keep
* @return a new array with sliced items
*/
public static <T> T[] slice(T[] args, int startPos, int endPos) {
int size = endPos - startPos + 1;
if (size <= 0) {
return (T[]) Array.newInstance(args.getClass().getComponentType(), 0);
}
T[] slicedArgs = (T[])Array.newInstance(args.getClass().getComponentType(), size);
System.arraycopy(args, startPos, slicedArgs, 0, size);
return slicedArgs;
}
/**
* Create an array
* @param items elements to add
* @return array of the provided items
*/
public static <T> T[] arrayOf(T... items) {
return items;
}
/**
* Create an immutable list
* @param items elements to add
* @return list of the provided items
*/
public static <T> List<T> fastListOf(T... items) {
return Arrays.asList(items);
}
/**
* Create a mutable list
* @param items elements to add
* @return list of the provided items
*/
public static <T> List<T> listOf(T... items) {
return new ArrayList<T>(Arrays.asList(items));
}
/**
* Create a mutable set
* @param items elements to add
* @return set of the provided items
*/
public static <T> Set<T> setOf(T... items) {
return new HashSet<T>(Arrays.asList(items));
}
/**
* Create a mutable map
* @param entry elements to add
* @return map of the provided items
*/
public static <K, V> Map<K, V> mapOf(Map.Entry<K, V>... entry) {
return appendMap(new HashMap<K, V>(entry.length), entry);
}
/**
* Create an mutable ordered map
* @param entry elements to add
* @return ordered map of the provided items
*/
public static <K, V> Map<K, V> orderedMapOf(Map.Entry<K, V>... entry) {
return appendMap(new LinkedHashMap<K, V>(entry.length), entry);
}
/**
* Create a map entry
* @param key the key
* @param value the value
* @return entry of provided key and value
*/
public static <K, V> Map.Entry<K, V> entryOf(K key, V value) {
return new AbstractMap.SimpleEntry<K, V>(key, value);
}
private static <K, V> Map<K, V> appendMap(Map<K, V> kvs, Map.Entry<K, V>[] entry) {
for (Map.Entry<K, V> p : entry) {
kvs.put(p.getKey(), p.getValue());
}
return kvs;
}
}

View File

@@ -139,7 +139,7 @@ public class OmniAccessor {
for (int i = 0; i < querySegments.length; i++) {
patternSegments[i] = toSinglePattern(querySegments[i]);
}
return PATTERN_PREFIX + CollectionUtil.join(Arrays.asList(patternSegments), SLASH);
return PATTERN_PREFIX + CollectionUtil.joinToString(Arrays.asList(patternSegments), SLASH);
}
private static String toSinglePattern(String querySegment) {

View File

@@ -4,40 +4,13 @@ import java.util.*;
public class CollectionUtil {
/**
* Get slice of args[startPos, args.length]
* @param args original item array
* @param startPos index of the first item to keep
* @return a new array with sliced items
*/
public static Object[] slice(Object[] args, int startPos) {
return slice(args, startPos, args.length - 1);
}
/**
* Get slice of args[startPos, endPos]
* @param args original item array
* @param startPos index of the first item to keep
* @param endPos index of the last item to keep
* @return a new array with sliced items
*/
public static Object[] slice(Object[] args, int startPos, int endPos) {
int size = endPos - startPos + 1;
if (size <= 0) {
return new Object[0];
}
Object[] slicedArgs = new Object[size];
System.arraycopy(args, startPos, slicedArgs, 0, size);
return slicedArgs;
}
/**
* Join a collection into string
* @param collection many items with proper toString() method
* @param joinSymbol splitter of echo items
* @return a joined string
*/
public static String join(Collection<?> collection, String joinSymbol) {
public static String joinToString(Collection<?> collection, String joinSymbol) {
StringBuilder sb = new StringBuilder();
for(Iterator<?> i = collection.iterator(); i.hasNext(); sb.append(i.next().toString())) {
if (sb.length() != 0) {
@@ -68,10 +41,10 @@ public class CollectionUtil {
* @param collectionRight the second collection
* @return whether any equaled item found
*/
public static boolean containsAny(Collection<?> collectionLeft, Collection<?> collectionRight) {
for (Object o : collectionLeft) {
for (Object i : collectionRight) {
if (o.equals(i)) {
public static <T> boolean containsAny(Collection<T> collectionLeft, Collection<T> collectionRight) {
for (T left : collectionLeft) {
for (T right : collectionRight) {
if (left.equals(right)) {
return true;
}
}
@@ -79,76 +52,4 @@ public class CollectionUtil {
return false;
}
/**
* Create an array
* @param items elements to add
* @return array of the provided items
*/
public static <T> T[] arrayOf(T... items) {
return items;
}
/**
* Create a list
* @param items elements to add
* @return list of the provided items
*/
public static <T> List<T> listOf(T... items) {
return Arrays.asList(items);
}
/**
* Generate a list of item
* @param items elements to add
* @return mutable list of the provided items
*/
public static <T> List<T> mutableListOf(T... items) {
List<T> list = new ArrayList<T>(items.length);
Collections.addAll(list, items);
return list;
}
/**
* Create a set
* @param items elements to add
* @return set of the provided items
*/
public static <T> Set<T> setOf(T... items) {
return new HashSet<T>(Arrays.asList(items));
}
/**
* Create a map
* @param entry elements to add
* @return map of the provided items
*/
public static <K, V> Map<K, V> mapOf(Map.Entry<K, V>... entry) {
return appendMap(new HashMap<K, V>(entry.length), entry);
}
/**
* Create an ordered map
* @param entry elements to add
* @return ordered map of the provided items
*/
public static <K, V> Map<K, V> orderMapOf(Map.Entry<K, V>... entry) {
return appendMap(new LinkedHashMap<K, V>(entry.length), entry);
}
/**
* Create a map entry
* @param key the key
* @param value the value
* @return entry of provided key and value
*/
public static <K, V> Map.Entry<K, V> entryOf(K key, V value) {
return new AbstractMap.SimpleEntry<K, V>(key, value);
}
private static <K, V> Map<K, V> appendMap(Map<K, V> kvs, Map.Entry<K, V>[] entry) {
for (Map.Entry<K, V> p : entry) {
kvs.put(p.getKey(), p.getValue());
}
return kvs;
}
}

View File

@@ -10,8 +10,8 @@ import java.util.*;
import static com.alibaba.testable.core.constant.ConstPool.DOT;
import static com.alibaba.testable.core.model.ConstructionOption.EXCEPT_CONSTRUCTOR_PARAMETER;
import static com.alibaba.testable.core.model.ConstructionOption.EXCEPT_RETURN_VALUE;
import static com.alibaba.testable.core.util.CollectionUtil.entryOf;
import static com.alibaba.testable.core.util.CollectionUtil.mapOf;
import static com.alibaba.testable.core.tool.CollectionTool.entryOf;
import static com.alibaba.testable.core.tool.CollectionTool.mapOf;
public class ConstructionUtil {

View File

@@ -1,6 +1,7 @@
package com.alibaba.testable.core.util;
import com.alibaba.testable.core.model.MockContext;
import com.alibaba.testable.core.tool.CollectionTool;
/**
* @author flin
@@ -31,7 +32,7 @@ public class InvokeRecordUtil {
mockContext.invokeRecord.get(mockMethodName).add(args);
LogUtil.verbose(" Mock constructor \"%s\" invoked in %s::%s", mockMethodName, testClass, testCaseName);
} else {
mockContext.invokeRecord.get(mockMethodName).add(CollectionUtil.slice(args, 1));
mockContext.invokeRecord.get(mockMethodName).add(CollectionTool.slice(args, 1));
LogUtil.verbose(" Mock method \"%s\" invoked in %s::%s\"", mockMethodName, testClass, testCaseName);
}
}

View File

@@ -2,6 +2,7 @@ package com.alibaba.testable.core.util;
import com.alibaba.testable.core.exception.MemberAccessException;
import com.alibaba.testable.core.model.MockContext;
import com.alibaba.testable.core.tool.CollectionTool;
import java.util.HashSet;
import java.util.Map;
@@ -71,7 +72,7 @@ public class MockAssociationUtil {
return construct(originClass, args);
} else if (args[0] == null) {
try {
return invokeStatic(originClass, originMethod, CollectionUtil.slice(args, 1));
return invokeStatic(originClass, originMethod, CollectionTool.slice(args, 1));
} catch (RuntimeException e) {
if (e instanceof MemberAccessException && e.getCause() instanceof NoSuchFieldException) {
throw new NullPointerException("Invoking method \"" + originMethod + "\" of null object");
@@ -79,7 +80,7 @@ public class MockAssociationUtil {
throw e;
}
} else {
return invoke(args[0], originMethod, CollectionUtil.slice(args, 1));
return invoke(args[0], originMethod, CollectionTool.slice(args, 1));
}
}

View File

@@ -0,0 +1,23 @@
package com.alibaba.testable.core.tool;
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.assertEquals;
class CollectionToolTest {
@Test
void should_slice_array() {
Object[] args = new Object[]{"1", "2", "3", "4"};
Object[] slicedArgs = CollectionTool.slice(args, 1);
assertEquals(3, slicedArgs.length);
assertEquals("2", slicedArgs[0]);
assertEquals("3", slicedArgs[1]);
assertEquals("4", slicedArgs[2]);
slicedArgs = CollectionTool.slice(args, 1, 2);
assertEquals(2, slicedArgs.length);
assertEquals("2", slicedArgs[0]);
assertEquals("3", slicedArgs[1]);
}
}

View File

@@ -2,32 +2,19 @@ package com.alibaba.testable.core.util;
import org.junit.jupiter.api.Test;
import static com.alibaba.testable.core.tool.PrivateAccessor.invokeStatic;
import static org.junit.jupiter.api.Assertions.*;
import static com.alibaba.testable.core.tool.CollectionTool.fastListOf;
import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertTrue;
class CollectionUtilTest {
@Test
void should_slice_array() {
Object[] args = new Object[]{"1", "2", "3", "4"};
Object[] slicedArgs = CollectionUtil.slice(args, 1);
assertEquals(3, slicedArgs.length);
assertEquals("2", slicedArgs[0]);
assertEquals("3", slicedArgs[1]);
assertEquals("4", slicedArgs[2]);
slicedArgs = CollectionUtil.slice(args, 1, 2);
assertEquals(2, slicedArgs.length);
assertEquals("2", slicedArgs[0]);
assertEquals("3", slicedArgs[1]);
}
@Test
void should_check_collection_contains_any_element() {
assertTrue(CollectionUtil.containsAny(
CollectionUtil.listOf("a", "b"), CollectionUtil.listOf("b", "c")
fastListOf("a", "b"), fastListOf("b", "c")
));
assertFalse(CollectionUtil.containsAny(
CollectionUtil.listOf("a", "b"), CollectionUtil.listOf("c", "d")
fastListOf("a", "b"), fastListOf("c", "d")
));
}
}

View File

@@ -18,7 +18,7 @@ import java.util.Map;
import static com.alibaba.testable.core.tool.PrivateAccessor.construct;
import static com.alibaba.testable.core.tool.PrivateAccessor.invokeStatic;
import static com.alibaba.testable.core.util.CollectionUtil.arrayOf;
import static com.alibaba.testable.core.tool.CollectionTool.arrayOf;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNotNull;