From 1e9079e8d3043965ccb401a3ed0d732ec4ab1a5b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=87=91=E6=88=9F?= Date: Wed, 14 Dec 2022 00:34:03 +0800 Subject: [PATCH] feat: move collection creation methods to CollectionTool --- .../agent/handler/MockClassHandler.java | 4 +- .../agent/handler/OmniClassHandler.java | 10 +- .../agent/util/AnnotationUtilTest.java | 4 +- .../testable/core/tool/CollectionTool.java | 105 +++++++++++++++++ .../testable/core/tool/OmniAccessor.java | 2 +- .../testable/core/util/CollectionUtil.java | 109 +----------------- .../testable/core/util/ConstructionUtil.java | 4 +- .../testable/core/util/InvokeRecordUtil.java | 3 +- .../core/util/MockAssociationUtil.java | 5 +- .../core/tool/CollectionToolTest.java | 23 ++++ .../core/util/CollectionUtilTest.java | 23 +--- .../core/util/ConstructionUtilTest.java | 2 +- 12 files changed, 156 insertions(+), 138 deletions(-) create mode 100644 testable-core/src/main/java/com/alibaba/testable/core/tool/CollectionTool.java create mode 100644 testable-core/src/test/java/com/alibaba/testable/core/tool/CollectionToolTest.java 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 dea2177..0991dd2 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 @@ -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 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 index ffab665..e2318ae 100644 --- 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 @@ -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 PRELOADED_CLASSES = mapOf( - entryOf(CLASS_OBJECT, CollectionUtil.arrayOf()) + entryOf(CLASS_OBJECT, CollectionTool.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 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) ); diff --git a/testable-agent/src/test/java/com/alibaba/testable/agent/util/AnnotationUtilTest.java b/testable-agent/src/test/java/com/alibaba/testable/agent/util/AnnotationUtilTest.java index 11f6c3c..b9765a4 100644 --- a/testable-agent/src/test/java/com/alibaba/testable/agent/util/AnnotationUtilTest.java +++ b/testable-agent/src/test/java/com/alibaba/testable/agent/util/AnnotationUtilTest.java @@ -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)); diff --git a/testable-core/src/main/java/com/alibaba/testable/core/tool/CollectionTool.java b/testable-core/src/main/java/com/alibaba/testable/core/tool/CollectionTool.java new file mode 100644 index 0000000..148aacb --- /dev/null +++ b/testable-core/src/main/java/com/alibaba/testable/core/tool/CollectionTool.java @@ -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[] 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[] 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[] arrayOf(T... items) { + return items; + } + + /** + * Create an immutable list + * @param items elements to add + * @return list of the provided items + */ + public static List fastListOf(T... items) { + return Arrays.asList(items); + } + + /** + * Create a mutable list + * @param items elements to add + * @return list of the provided items + */ + public static List listOf(T... items) { + return new ArrayList(Arrays.asList(items)); + } + + /** + * Create a mutable set + * @param items elements to add + * @return set of the provided items + */ + public static Set setOf(T... items) { + return new HashSet(Arrays.asList(items)); + } + + /** + * Create a mutable map + * @param entry elements to add + * @return map of the provided items + */ + public static Map mapOf(Map.Entry... entry) { + return appendMap(new HashMap(entry.length), entry); + } + + /** + * Create an mutable ordered map + * @param entry elements to add + * @return ordered map of the provided items + */ + public static Map orderedMapOf(Map.Entry... entry) { + return appendMap(new LinkedHashMap(entry.length), entry); + } + + /** + * Create a map entry + * @param key the key + * @param value the value + * @return entry of provided key and value + */ + public static Map.Entry entryOf(K key, V value) { + return new AbstractMap.SimpleEntry(key, value); + } + + private static Map appendMap(Map kvs, Map.Entry[] entry) { + for (Map.Entry p : entry) { + kvs.put(p.getKey(), p.getValue()); + } + return kvs; + } +} diff --git a/testable-core/src/main/java/com/alibaba/testable/core/tool/OmniAccessor.java b/testable-core/src/main/java/com/alibaba/testable/core/tool/OmniAccessor.java index 74eb903..5850295 100644 --- a/testable-core/src/main/java/com/alibaba/testable/core/tool/OmniAccessor.java +++ b/testable-core/src/main/java/com/alibaba/testable/core/tool/OmniAccessor.java @@ -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) { diff --git a/testable-core/src/main/java/com/alibaba/testable/core/util/CollectionUtil.java b/testable-core/src/main/java/com/alibaba/testable/core/util/CollectionUtil.java index 3d5a062..ca5b0fd 100644 --- a/testable-core/src/main/java/com/alibaba/testable/core/util/CollectionUtil.java +++ b/testable-core/src/main/java/com/alibaba/testable/core/util/CollectionUtil.java @@ -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 boolean containsAny(Collection collectionLeft, Collection 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[] arrayOf(T... items) { - return items; - } - - /** - * Create a list - * @param items elements to add - * @return list of the provided items - */ - public static List 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 List mutableListOf(T... items) { - List list = new ArrayList(items.length); - Collections.addAll(list, items); - return list; - } - - /** - * Create a set - * @param items elements to add - * @return set of the provided items - */ - public static Set setOf(T... items) { - return new HashSet(Arrays.asList(items)); - } - - /** - * Create a map - * @param entry elements to add - * @return map of the provided items - */ - public static Map mapOf(Map.Entry... entry) { - return appendMap(new HashMap(entry.length), entry); - } - - /** - * Create an ordered map - * @param entry elements to add - * @return ordered map of the provided items - */ - public static Map orderMapOf(Map.Entry... entry) { - return appendMap(new LinkedHashMap(entry.length), entry); - } - - /** - * Create a map entry - * @param key the key - * @param value the value - * @return entry of provided key and value - */ - public static Map.Entry entryOf(K key, V value) { - return new AbstractMap.SimpleEntry(key, value); - } - - private static Map appendMap(Map kvs, Map.Entry[] entry) { - for (Map.Entry p : entry) { - kvs.put(p.getKey(), p.getValue()); - } - return kvs; - } } diff --git a/testable-core/src/main/java/com/alibaba/testable/core/util/ConstructionUtil.java b/testable-core/src/main/java/com/alibaba/testable/core/util/ConstructionUtil.java index a5b8bf7..631b122 100644 --- a/testable-core/src/main/java/com/alibaba/testable/core/util/ConstructionUtil.java +++ b/testable-core/src/main/java/com/alibaba/testable/core/util/ConstructionUtil.java @@ -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 { diff --git a/testable-core/src/main/java/com/alibaba/testable/core/util/InvokeRecordUtil.java b/testable-core/src/main/java/com/alibaba/testable/core/util/InvokeRecordUtil.java index 6feca76..1f89534 100644 --- a/testable-core/src/main/java/com/alibaba/testable/core/util/InvokeRecordUtil.java +++ b/testable-core/src/main/java/com/alibaba/testable/core/util/InvokeRecordUtil.java @@ -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); } } diff --git a/testable-core/src/main/java/com/alibaba/testable/core/util/MockAssociationUtil.java b/testable-core/src/main/java/com/alibaba/testable/core/util/MockAssociationUtil.java index 97c9073..f7f2967 100644 --- a/testable-core/src/main/java/com/alibaba/testable/core/util/MockAssociationUtil.java +++ b/testable-core/src/main/java/com/alibaba/testable/core/util/MockAssociationUtil.java @@ -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)); } } diff --git a/testable-core/src/test/java/com/alibaba/testable/core/tool/CollectionToolTest.java b/testable-core/src/test/java/com/alibaba/testable/core/tool/CollectionToolTest.java new file mode 100644 index 0000000..125c876 --- /dev/null +++ b/testable-core/src/test/java/com/alibaba/testable/core/tool/CollectionToolTest.java @@ -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]); + } + +} \ No newline at end of file diff --git a/testable-core/src/test/java/com/alibaba/testable/core/util/CollectionUtilTest.java b/testable-core/src/test/java/com/alibaba/testable/core/util/CollectionUtilTest.java index dff8a95..e2fe346 100644 --- a/testable-core/src/test/java/com/alibaba/testable/core/util/CollectionUtilTest.java +++ b/testable-core/src/test/java/com/alibaba/testable/core/util/CollectionUtilTest.java @@ -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") )); } } diff --git a/testable-core/src/test/java/com/alibaba/testable/core/util/ConstructionUtilTest.java b/testable-core/src/test/java/com/alibaba/testable/core/util/ConstructionUtilTest.java index 7a6021d..b77417a 100644 --- a/testable-core/src/test/java/com/alibaba/testable/core/util/ConstructionUtilTest.java +++ b/testable-core/src/test/java/com/alibaba/testable/core/util/ConstructionUtilTest.java @@ -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;