mirror of
https://github.com/alibaba/testable-mock.git
synced 2026-08-19 09:43:29 +08:00
feat: move collection creation methods to CollectionTool
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -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)
|
||||
);
|
||||
|
||||
@@ -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));
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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) {
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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 {
|
||||
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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]);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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")
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user