From af846eef655198b12b7c43f06ccaeae18dda890f Mon Sep 17 00:00:00 2001 From: Mercy Ma Date: Sat, 14 Mar 2026 10:49:50 +0800 Subject: [PATCH 01/17] Bump project revision to 0.1.9-SNAPSHOT Update the Maven property in pom.xml from 0.1.8-SNAPSHOT to 0.1.9-SNAPSHOT to prepare the next development iteration. --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index dc5c6a270..4d3ed51e7 100644 --- a/pom.xml +++ b/pom.xml @@ -51,7 +51,7 @@ - 0.1.8-SNAPSHOT + 0.1.9-SNAPSHOT From 34db413c29a8464e3e8ee9c06254226cf92a09a9 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Wed, 18 Mar 2026 05:14:18 +0000 Subject: [PATCH 02/17] Initial plan From cb04c556f776262859efd8bd4ebb5754d6754a4c Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Wed, 18 Mar 2026 05:28:08 +0000 Subject: [PATCH 03/17] Add missing test cases for StringToByteConverter and ClassFileJarEntryFilter Co-authored-by: mercyblitz <533114+mercyblitz@users.noreply.github.com> --- .../convert/StringToByteConverterTest.java | 50 ++++++++++++++++ .../filter/ClassFileJarEntryFilterTest.java | 59 +++++++++++++++++++ 2 files changed, 109 insertions(+) create mode 100644 microsphere-java-core/src/test/java/io/microsphere/convert/StringToByteConverterTest.java create mode 100644 microsphere-java-core/src/test/java/io/microsphere/filter/ClassFileJarEntryFilterTest.java diff --git a/microsphere-java-core/src/test/java/io/microsphere/convert/StringToByteConverterTest.java b/microsphere-java-core/src/test/java/io/microsphere/convert/StringToByteConverterTest.java new file mode 100644 index 000000000..e4e4ed983 --- /dev/null +++ b/microsphere-java-core/src/test/java/io/microsphere/convert/StringToByteConverterTest.java @@ -0,0 +1,50 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package io.microsphere.convert; + +import org.junit.jupiter.api.Test; + +import static io.microsphere.convert.StringToByteConverter.INSTANCE; +import static org.junit.jupiter.api.Assertions.assertThrows; + +/** + * {@link StringToByteConverter} Test + * + * @since 1.0.0 + */ +class StringToByteConverterTest extends BaseConverterTest { + + @Override + protected AbstractConverter createConverter() { + return INSTANCE; + } + + @Override + protected String getSource() throws Throwable { + return "1"; + } + + @Override + protected Byte getTarget() throws Throwable { + return Byte.valueOf("1"); + } + + @Test + void testConvertOnFailed() { + assertThrows(NumberFormatException.class, () -> converter.convert("abc")); + } +} diff --git a/microsphere-java-core/src/test/java/io/microsphere/filter/ClassFileJarEntryFilterTest.java b/microsphere-java-core/src/test/java/io/microsphere/filter/ClassFileJarEntryFilterTest.java new file mode 100644 index 000000000..48669af7d --- /dev/null +++ b/microsphere-java-core/src/test/java/io/microsphere/filter/ClassFileJarEntryFilterTest.java @@ -0,0 +1,59 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package io.microsphere.filter; + +import org.junit.jupiter.api.Test; + +import java.util.jar.JarEntry; + +import static io.microsphere.filter.ClassFileJarEntryFilter.INSTANCE; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertTrue; + +/** + * {@link ClassFileJarEntryFilter} Test + * + * @author Mercy + * @see ClassFileJarEntryFilter + * @since 1.0.0 + */ +class ClassFileJarEntryFilterTest { + + @Test + void testAcceptClassFile() { + JarEntry classEntry = new JarEntry("io/microsphere/Example.class"); + assertTrue(INSTANCE.accept(classEntry)); + } + + @Test + void testRejectDirectory() { + JarEntry dirEntry = new JarEntry("io/microsphere/"); + assertFalse(INSTANCE.accept(dirEntry)); + } + + @Test + void testRejectNonClassFile() { + JarEntry resourceEntry = new JarEntry("META-INF/MANIFEST.MF"); + assertFalse(INSTANCE.accept(resourceEntry)); + } + + @Test + void testRejectPropertiesFile() { + JarEntry propertiesEntry = new JarEntry("META-INF/services/io.microsphere.convert.Converter"); + assertFalse(INSTANCE.accept(propertiesEntry)); + } +} From 5c8e7b6ec9e2244abffd8fd5716d51b43e32e40f Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Wed, 18 Mar 2026 06:14:24 +0000 Subject: [PATCH 04/17] Initial plan From 358629799c1a231eb9a9bd129e3ae37431070784 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Wed, 18 Mar 2026 06:37:50 +0000 Subject: [PATCH 05/17] Changes before error encountered Co-authored-by: mercyblitz <533114+mercyblitz@users.noreply.github.com> --- .../java/io/microsphere/lang/Deprecation.java | 2 +- .../microsphere/event/GenericEventTest.java | 39 ++++++++++++ .../StringSerializerAndDeserializerTest.java | 28 +++++++++ .../microsphere/json/JSONExceptionTest.java | 51 +++++++++++++++ .../io/microsphere/lang/DeprecationTest.java | 33 ++++++++++ .../microsphere/lang/MutableIntegerTest.java | 27 ++++++++ .../java/io/microsphere/lang/WrapperTest.java | 5 ++ .../lang/function/PredicatesTest.java | 21 +++++++ .../io/microsphere/util/ClassUtilsTest.java | 51 +++++++++++++++ .../java/io/microsphere/util/VersionTest.java | 63 +++++++++++++++++++ 10 files changed, 319 insertions(+), 1 deletion(-) create mode 100644 microsphere-java-core/src/test/java/io/microsphere/json/JSONExceptionTest.java diff --git a/microsphere-java-core/src/main/java/io/microsphere/lang/Deprecation.java b/microsphere-java-core/src/main/java/io/microsphere/lang/Deprecation.java index 135c872e8..eaf532f07 100644 --- a/microsphere-java-core/src/main/java/io/microsphere/lang/Deprecation.java +++ b/microsphere-java-core/src/main/java/io/microsphere/lang/Deprecation.java @@ -197,7 +197,7 @@ public static class Builder { private String link; @Nonnull - private Level level; + private Level level = DEFAULT; protected Builder() { } diff --git a/microsphere-java-core/src/test/java/io/microsphere/event/GenericEventTest.java b/microsphere-java-core/src/test/java/io/microsphere/event/GenericEventTest.java index 385730c23..5ba723195 100644 --- a/microsphere-java-core/src/test/java/io/microsphere/event/GenericEventTest.java +++ b/microsphere-java-core/src/test/java/io/microsphere/event/GenericEventTest.java @@ -18,7 +18,11 @@ import org.junit.jupiter.api.Test; +import java.util.Arrays; +import java.util.List; + import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertThrows; import static org.junit.jupiter.api.Assertions.assertTrue; /** @@ -38,4 +42,39 @@ void test() { assertTrue(event.getTimestamp() >= timestamp); } + @Test + void testNullSourceThrowsException() { + assertThrows(IllegalArgumentException.class, () -> new GenericEvent<>(null)); + } + + @Test + void testTimestampBounds() { + long before = System.currentTimeMillis(); + GenericEvent event = new GenericEvent<>("Test"); + long after = System.currentTimeMillis(); + assertTrue(event.getTimestamp() >= before); + assertTrue(event.getTimestamp() <= after); + } + + @Test + void testTimestampOrdering() throws InterruptedException { + GenericEvent event1 = new GenericEvent<>("First"); + Thread.sleep(1); + GenericEvent event2 = new GenericEvent<>("Second"); + assertTrue(event2.getTimestamp() >= event1.getTimestamp()); + } + + @Test + void testWithIntegerSource() { + GenericEvent event = new GenericEvent<>(42); + assertEquals(42, event.getSource()); + } + + @Test + void testWithListSource() { + List source = Arrays.asList("a", "b", "c"); + GenericEvent> event = new GenericEvent<>(source); + assertEquals(source, event.getSource()); + } + } diff --git a/microsphere-java-core/src/test/java/io/microsphere/io/StringSerializerAndDeserializerTest.java b/microsphere-java-core/src/test/java/io/microsphere/io/StringSerializerAndDeserializerTest.java index 046392e13..30be7a780 100644 --- a/microsphere-java-core/src/test/java/io/microsphere/io/StringSerializerAndDeserializerTest.java +++ b/microsphere-java-core/src/test/java/io/microsphere/io/StringSerializerAndDeserializerTest.java @@ -19,6 +19,7 @@ import org.junit.jupiter.api.Test; import java.io.IOException; +import java.nio.charset.Charset; import java.nio.charset.StandardCharsets; import static org.junit.jupiter.api.Assertions.assertArrayEquals; @@ -43,4 +44,31 @@ void test() throws IOException { assertArrayEquals(value.getBytes(StandardCharsets.UTF_8), bytes); assertEquals(value, deserializer.deserialize(bytes)); } + + @Test + void testWithCustomCharset() throws IOException { + Charset charset = StandardCharsets.ISO_8859_1; + StringSerializer customSerializer = new StringSerializer(charset); + StringDeserializer customDeserializer = new StringDeserializer(charset); + String value = "Test"; + byte[] bytes = customSerializer.serialize(value); + assertArrayEquals(value.getBytes(charset), bytes); + assertEquals(value, customDeserializer.deserialize(bytes)); + } + + @Test + void testSerializeEmptyString() throws IOException { + byte[] bytes = serializer.serialize(""); + assertArrayEquals(new byte[0], bytes); + assertEquals("", deserializer.deserialize(bytes)); + } + + @Test + void testRoundTripWithUTF16() throws IOException { + Charset charset = StandardCharsets.UTF_16; + StringSerializer utf16Serializer = new StringSerializer(charset); + StringDeserializer utf16Deserializer = new StringDeserializer(charset); + String value = "Hello UTF-16"; + assertEquals(value, utf16Deserializer.deserialize(utf16Serializer.serialize(value))); + } } diff --git a/microsphere-java-core/src/test/java/io/microsphere/json/JSONExceptionTest.java b/microsphere-java-core/src/test/java/io/microsphere/json/JSONExceptionTest.java new file mode 100644 index 000000000..7f6b7d35a --- /dev/null +++ b/microsphere-java-core/src/test/java/io/microsphere/json/JSONExceptionTest.java @@ -0,0 +1,51 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package io.microsphere.json; + +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertInstanceOf; +import static org.junit.jupiter.api.Assertions.assertNull; + +/** + * {@link JSONException} Test + * + * @since 1.0.0 + */ +class JSONExceptionTest { + + @Test + void testConstructorWithMessage() { + String message = "Test JSON error"; + JSONException exception = new JSONException(message); + assertEquals(message, exception.getMessage()); + } + + @Test + void testIsCheckedException() { + JSONException exception = new JSONException("error"); + assertInstanceOf(Exception.class, exception); + } + + @Test + void testNullMessage() { + JSONException exception = new JSONException(null); + assertNull(exception.getMessage()); + } + +} diff --git a/microsphere-java-core/src/test/java/io/microsphere/lang/DeprecationTest.java b/microsphere-java-core/src/test/java/io/microsphere/lang/DeprecationTest.java index 41f398f8e..6adf34180 100644 --- a/microsphere-java-core/src/test/java/io/microsphere/lang/DeprecationTest.java +++ b/microsphere-java-core/src/test/java/io/microsphere/lang/DeprecationTest.java @@ -123,6 +123,39 @@ void test() { } + @Test + void testBuilderDefaultLevel() { + Deprecation deprecation = Deprecation.builder() + .since(SINCE) + .build(); + assertEquals(DEFAULT, deprecation.getLevel()); + } + + @Test + void testBuilderNullLevelDefaultsToDefault() { + Deprecation deprecation = Deprecation.builder() + .since(SINCE) + .level(null) + .build(); + assertEquals(DEFAULT, deprecation.getLevel()); + } + + @Test + void testBuilderAllFields() { + Deprecation deprecation = Deprecation.builder() + .since(SINCE) + .replacement(REPLACEMENT) + .reason(REASON) + .link(LINK) + .level(LEVEL) + .build(); + assertEquals(Version.of(SINCE), deprecation.getSince()); + assertEquals(REPLACEMENT, deprecation.getReplacement()); + assertEquals(REASON, deprecation.getReason()); + assertEquals(LINK, deprecation.getLink()); + assertEquals(LEVEL, deprecation.getLevel()); + } + private void assertObjectMethods(Deprecation deprecation) { Deprecation copy = new Deprecation(deprecation); assertEquals(deprecation, copy); diff --git a/microsphere-java-core/src/test/java/io/microsphere/lang/MutableIntegerTest.java b/microsphere-java-core/src/test/java/io/microsphere/lang/MutableIntegerTest.java index f5f18631d..b3b208641 100644 --- a/microsphere-java-core/src/test/java/io/microsphere/lang/MutableIntegerTest.java +++ b/microsphere-java-core/src/test/java/io/microsphere/lang/MutableIntegerTest.java @@ -142,4 +142,31 @@ void testEquals() { assertFalse(a.equals(null)); assertFalse(a.equals("not an IntegerAdder")); } + + @Test + void testZeroValue() { + MutableInteger zero = of(0); + assertEquals(0, zero.get()); + assertEquals(0, zero.hashCode()); + assertEquals("0", zero.toString()); + assertEquals(0, zero.intValue()); + assertEquals(0L, zero.longValue()); + assertEquals(0.0f, zero.floatValue()); + assertEquals(0.0d, zero.doubleValue()); + } + + @Test + void testNegativeValue() { + MutableInteger neg = of(-10); + assertEquals(-10, neg.get()); + assertEquals(-9, neg.incrementAndGet()); + assertEquals(-10, neg.decrementAndGet()); + assertEquals(-5, neg.addAndGet(5)); + } + + @Test + void testEqualsWithSelf() { + MutableInteger a = of(10); + assertTrue(a.equals(a)); + } } \ No newline at end of file diff --git a/microsphere-java-core/src/test/java/io/microsphere/lang/WrapperTest.java b/microsphere-java-core/src/test/java/io/microsphere/lang/WrapperTest.java index a7190beed..a9c204369 100644 --- a/microsphere-java-core/src/test/java/io/microsphere/lang/WrapperTest.java +++ b/microsphere-java-core/src/test/java/io/microsphere/lang/WrapperTest.java @@ -44,4 +44,9 @@ void testOnNull() { assertNull(tryUnwrap(null, String.class)); } + @Test + void testOnNonWrapper() { + assertNull(tryUnwrap("not a wrapper", String.class)); + } + } diff --git a/microsphere-java-core/src/test/java/io/microsphere/lang/function/PredicatesTest.java b/microsphere-java-core/src/test/java/io/microsphere/lang/function/PredicatesTest.java index a3d0c4ef2..2fb361124 100644 --- a/microsphere-java-core/src/test/java/io/microsphere/lang/function/PredicatesTest.java +++ b/microsphere-java-core/src/test/java/io/microsphere/lang/function/PredicatesTest.java @@ -82,4 +82,25 @@ void testOr() { void testOrOnNull() { assertTrue(or(null).test(null)); } + + @Test + void testAndWithSinglePredicate() { + Predicate predicate = alwaysTrue(); + assertTrue(and(predicate).test(null)); + Predicate falsePredicate = alwaysFalse(); + assertFalse(and(falsePredicate).test(null)); + } + + @Test + void testOrWithSinglePredicate() { + Predicate predicate = alwaysTrue(); + assertTrue(or(predicate).test(null)); + Predicate falsePredicate = alwaysFalse(); + assertFalse(or(falsePredicate).test(null)); + } + + @Test + void testEmptyPredicateArrayConstant() { + assertEmptyArray(Predicates.EMPTY_PREDICATE_ARRAY); + } } diff --git a/microsphere-java-core/src/test/java/io/microsphere/util/ClassUtilsTest.java b/microsphere-java-core/src/test/java/io/microsphere/util/ClassUtilsTest.java index 0c7623b60..58422e212 100644 --- a/microsphere-java-core/src/test/java/io/microsphere/util/ClassUtilsTest.java +++ b/microsphere-java-core/src/test/java/io/microsphere/util/ClassUtilsTest.java @@ -53,9 +53,13 @@ import static io.microsphere.util.ClassUtils.cast; import static io.microsphere.util.ClassUtils.concreteClassCache; import static io.microsphere.util.ClassUtils.findAllClasses; +import static io.microsphere.util.ClassUtils.findAllInheritedClasses; +import static io.microsphere.util.ClassUtils.findAllInterfaces; +import static io.microsphere.util.ClassUtils.findAllSuperClasses; import static io.microsphere.util.ClassUtils.findClassNamesInClassPath; import static io.microsphere.util.ClassUtils.findClassNamesInJarFile; import static io.microsphere.util.ClassUtils.getAllClasses; +import static io.microsphere.util.ClassUtils.getAllInheritedClasses; import static io.microsphere.util.ClassUtils.getAllInheritedTypes; import static io.microsphere.util.ClassUtils.getAllInterfaces; import static io.microsphere.util.ClassUtils.getAllSuperClasses; @@ -598,6 +602,53 @@ void testGetAllSuperClassesOnPrimitiveType() { void testGetAllInterfaces() { assertSame(emptyList(), getAllInterfaces(null)); assertSame(emptyList(), getAllInterfaces(int.class)); + List> interfaces = getAllInterfaces(String.class); + assertTrue(interfaces.contains(Serializable.class)); + assertTrue(interfaces.contains(Comparable.class)); + assertTrue(interfaces.contains(CharSequence.class)); + } + + @Test + void testGetAllInheritedClasses() { + assertSame(emptyList(), getAllInheritedClasses(null)); + assertSame(emptyList(), getAllInheritedClasses(int.class)); + List> inherited = getAllInheritedClasses(String.class); + assertTrue(inherited.contains(Object.class)); + assertTrue(inherited.contains(Serializable.class)); + assertTrue(inherited.contains(Comparable.class)); + assertTrue(inherited.contains(CharSequence.class)); + } + + @Test + void testFindAllSuperClasses() { + assertSame(emptyList(), findAllSuperClasses(null)); + assertSame(emptyList(), findAllSuperClasses(int.class)); + List> superClasses = findAllSuperClasses(TreeMap.class); + assertTrue(superClasses.contains(AbstractMap.class)); + assertTrue(superClasses.contains(Object.class)); + assertFalse(superClasses.contains(Map.class)); + } + + @Test + void testFindAllInterfaces() { + assertSame(emptyList(), findAllInterfaces(null)); + assertSame(emptyList(), findAllInterfaces(int.class)); + List> interfaces = findAllInterfaces(TreeMap.class); + assertTrue(interfaces.contains(Map.class)); + assertTrue(interfaces.contains(SortedMap.class)); + assertTrue(interfaces.contains(NavigableMap.class)); + assertFalse(interfaces.contains(AbstractMap.class)); + } + + @Test + void testFindAllInheritedClasses() { + assertSame(emptyList(), findAllInheritedClasses(null)); + assertSame(emptyList(), findAllInheritedClasses(int.class)); + List> inherited = findAllInheritedClasses(TreeMap.class); + assertTrue(inherited.contains(AbstractMap.class)); + assertTrue(inherited.contains(Object.class)); + assertTrue(inherited.contains(Map.class)); + assertTrue(inherited.contains(NavigableMap.class)); } @Test diff --git a/microsphere-java-core/src/test/java/io/microsphere/util/VersionTest.java b/microsphere-java-core/src/test/java/io/microsphere/util/VersionTest.java index 3cce37b6d..9059a93dc 100644 --- a/microsphere-java-core/src/test/java/io/microsphere/util/VersionTest.java +++ b/microsphere-java-core/src/test/java/io/microsphere/util/VersionTest.java @@ -21,9 +21,15 @@ import static io.microsphere.constants.SymbolConstants.DOT; import static io.microsphere.constants.SymbolConstants.HYPHEN; import static io.microsphere.constants.SymbolConstants.SPACE; +import static io.microsphere.util.Version.Operator.EQ; +import static io.microsphere.util.Version.Operator.GE; +import static io.microsphere.util.Version.Operator.GT; +import static io.microsphere.util.Version.Operator.LE; +import static io.microsphere.util.Version.Operator.LT; import static io.microsphere.util.Version.getValue; import static io.microsphere.util.Version.getVersion; import static io.microsphere.util.Version.of; +import static io.microsphere.util.Version.ofVersion; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertFalse; import static org.junit.jupiter.api.Assertions.assertNotNull; @@ -312,6 +318,63 @@ void testGetPreRelease() { assertEquals("beta", TEST_BETA_PRE_RELEASE_VERSION.getPreRelease()); } + @Test + void testOfVersion() { + assertEquals(of(MAJOR), ofVersion(MAJOR)); + assertEquals(of(MAJOR, MINOR), ofVersion(MAJOR, MINOR)); + assertEquals(of(MAJOR, MINOR, PATCH), ofVersion(MAJOR, MINOR, PATCH)); + assertEquals(of(MAJOR, MINOR, PATCH, ALPHA_PRE_RELEASE), ofVersion(MAJOR, MINOR, PATCH, ALPHA_PRE_RELEASE)); + assertEquals(of(VERSION), ofVersion(VERSION)); + } + + @Test + void testIsGreaterThan() { + assertTrue(TEST_VERSION.isGreaterThan(of(MAJOR, MINOR, PATCH - 1))); + assertFalse(TEST_VERSION.isGreaterThan(TEST_VERSION)); + assertFalse(TEST_VERSION.isGreaterThan(null)); + } + + @Test + void testIsGreaterOrEqual() { + assertTrue(TEST_VERSION.isGreaterOrEqual(TEST_VERSION)); + assertTrue(TEST_VERSION.isGreaterOrEqual(of(MAJOR, MINOR, PATCH - 1))); + assertFalse(TEST_VERSION.isGreaterOrEqual(of(MAJOR, MINOR, PATCH + 1))); + assertFalse(TEST_VERSION.isGreaterOrEqual(null)); + } + + @Test + void testIsLessThan() { + assertTrue(TEST_VERSION.isLessThan(of(MAJOR, MINOR, PATCH + 1))); + assertFalse(TEST_VERSION.isLessThan(TEST_VERSION)); + assertFalse(TEST_VERSION.isLessThan(null)); + } + + @Test + void testIsLessOrEqual() { + assertTrue(TEST_VERSION.isLessOrEqual(TEST_VERSION)); + assertTrue(TEST_VERSION.isLessOrEqual(of(MAJOR, MINOR, PATCH + 1))); + assertFalse(TEST_VERSION.isLessOrEqual(of(MAJOR, MINOR, PATCH - 1))); + assertFalse(TEST_VERSION.isLessOrEqual(null)); + } + + @Test + void testEqualsVersion() { + assertTrue(TEST_VERSION.equals(TEST_VERSION)); + assertTrue(TEST_VERSION.equals(of(MAJOR, MINOR, PATCH))); + assertFalse(TEST_VERSION.equals(of(MAJOR + 1, MINOR, PATCH))); + assertFalse(TEST_VERSION.equals((Version) null)); + } + + @Test + void testOperatorOf() { + assertEquals(EQ, Version.Operator.of("=")); + assertEquals(LT, Version.Operator.of("<")); + assertEquals(LE, Version.Operator.of("<=")); + assertEquals(GT, Version.Operator.of(">")); + assertEquals(GE, Version.Operator.of(">=")); + assertThrows(IllegalArgumentException.class, () -> Version.Operator.of("!=")); + } + void assertToString(String version) { assertEquals(version, of(version).toString()); } From 2d4744e0d874f62c0aece76698f88c8b8f64eb68 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Wed, 18 Mar 2026 07:51:53 +0000 Subject: [PATCH 06/17] Initial plan From d1a41be9a7e377714f490e3941aa53faf53a0c75 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Wed, 18 Mar 2026 08:09:03 +0000 Subject: [PATCH 07/17] Enhance AbstractDequeTest.java for 100% coverage of AbstractDeque.java Co-authored-by: mercyblitz <533114+mercyblitz@users.noreply.github.com> --- .../collection/AbstractDequeTest.java | 71 +++++++++++++++++++ 1 file changed, 71 insertions(+) diff --git a/microsphere-java-core/src/test/java/io/microsphere/collection/AbstractDequeTest.java b/microsphere-java-core/src/test/java/io/microsphere/collection/AbstractDequeTest.java index df8696b1b..1361b351e 100644 --- a/microsphere-java-core/src/test/java/io/microsphere/collection/AbstractDequeTest.java +++ b/microsphere-java-core/src/test/java/io/microsphere/collection/AbstractDequeTest.java @@ -1,10 +1,28 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ package io.microsphere.collection; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; +import java.util.Iterator; import java.util.NoSuchElementException; +import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertFalse; import static org.junit.jupiter.api.Assertions.assertNull; import static org.junit.jupiter.api.Assertions.assertSame; @@ -85,6 +103,22 @@ void testPeekLast() { assertSame(TEST_VALUE, deque.peekLast()); } + @Test + void testGetFirst() { + deque.add(TEST_VALUE); + assertSame(TEST_VALUE, deque.getFirst()); + deque.clear(); + assertThrows(NoSuchElementException.class, () -> deque.getFirst()); + } + + @Test + void testGetLast() { + deque.add(TEST_VALUE); + assertSame(TEST_VALUE, deque.getLast()); + deque.clear(); + assertThrows(NoSuchElementException.class, () -> deque.getLast()); + } + @Test void testRemoveFirstOccurrence() { assertFalse(deque.removeFirstOccurrence(null)); @@ -94,6 +128,17 @@ void testRemoveFirstOccurrence() { assertFalse(deque.removeFirstOccurrence(TEST_VALUE)); } + @Test + void testRemoveLastOccurrence() { + TestDeque multiDeque = new TestDeque<>(); + multiDeque.add("A"); + multiDeque.add("B"); + multiDeque.add("A"); + assertTrue(multiDeque.removeLastOccurrence("A")); + assertEquals(2, multiDeque.size()); + assertFalse(multiDeque.removeLastOccurrence("C")); + } + @Test void testPush() { deque.push(TEST_VALUE); @@ -122,8 +167,34 @@ void testPoll() { @Test void testPeek() { + assertNull(deque.peek()); assertTrue(deque.offer(TEST_VALUE)); assertSame(TEST_VALUE, deque.peek()); assertSame(TEST_VALUE, deque.peek()); } + + @Test + void testDescendingIterator() { + TestDeque multiDeque = new TestDeque<>(); + multiDeque.add("A"); + multiDeque.add("B"); + multiDeque.add("C"); + Iterator iterator = multiDeque.descendingIterator(); + assertTrue(iterator.hasNext()); + assertEquals("C", iterator.next()); + assertTrue(iterator.hasNext()); + assertEquals("B", iterator.next()); + assertTrue(iterator.hasNext()); + assertEquals("A", iterator.next()); + assertFalse(iterator.hasNext()); + } + + @Test + void testSize() { + assertEquals(0, deque.size()); + deque.add(TEST_VALUE); + assertEquals(1, deque.size()); + deque.poll(); + assertEquals(0, deque.size()); + } } \ No newline at end of file From 2b89fe03247e8360e0aa94cb7e73b7021c1658d5 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Wed, 18 Mar 2026 09:31:07 +0000 Subject: [PATCH 08/17] Enhance ClassPathResourceConfigurationPropertyLoaderTest for 100% coverage Co-authored-by: mercyblitz <533114+mercyblitz@users.noreply.github.com> --- ...sourceConfigurationPropertyLoaderTest.java | 25 +++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/microsphere-java-core/src/test/java/io/microsphere/metadata/ClassPathResourceConfigurationPropertyLoaderTest.java b/microsphere-java-core/src/test/java/io/microsphere/metadata/ClassPathResourceConfigurationPropertyLoaderTest.java index a1e54172a..bf8126a28 100644 --- a/microsphere-java-core/src/test/java/io/microsphere/metadata/ClassPathResourceConfigurationPropertyLoaderTest.java +++ b/microsphere-java-core/src/test/java/io/microsphere/metadata/ClassPathResourceConfigurationPropertyLoaderTest.java @@ -27,6 +27,7 @@ import static io.microsphere.constants.ResourceConstants.ADDITIONAL_CONFIGURATION_PROPERTY_METADATA_RESOURCE; import static io.microsphere.util.ClassLoaderUtils.getClassLoader; import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertThrows; import static org.junit.jupiter.api.Assertions.assertTrue; /** @@ -67,6 +68,30 @@ void testLoadWithNotFoundResource() throws Throwable { assertTrue(loader.load().isEmpty()); } + @Test + void testLoadWithNotFoundResourceAndAllResources() throws Throwable { + ClassPathResourceConfigurationPropertyLoader loader = new ClassPathResourceConfigurationPropertyLoader("Not-Found-Resource", true) { + }; + assertTrue(loader.load().isEmpty()); + } + + @Test + void testLoadWithClassLoaderAndAllResources() throws Throwable { + ClassPathResourceConfigurationPropertyLoader loader = new ClassPathResourceConfigurationPropertyLoader( + ADDITIONAL_CONFIGURATION_PROPERTY_METADATA_RESOURCE, + getClassLoader(this.getClass()), + true + ) { + }; + assertConfigurationProperties(loader); + } + + @Test + void testIllegalArgumentException() { + assertThrows(IllegalArgumentException.class, () -> new ClassPathResourceConfigurationPropertyLoader("") { + }); + } + void assertConfigurationProperties(ClassPathResourceConfigurationPropertyLoader loader) throws Throwable { List configurationProperties = loader.load(); assertEquals(2, configurationProperties.size()); From 8ee92bd67408243380bc11e7cf9db2db98522c3b Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Thu, 19 Mar 2026 04:11:20 +0000 Subject: [PATCH 09/17] Initial plan From ad6511d4cc8f1f45b5f2513a38a4dc079edc385d Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Thu, 19 Mar 2026 04:19:16 +0000 Subject: [PATCH 10/17] Add test cases to enhance coverage for ThrowableFunction and FileExtensionFilter Co-authored-by: mercyblitz <533114+mercyblitz@users.noreply.github.com> --- .../io/filter/FileExtensionFilterTest.java | 17 +++++++++++ .../lang/function/ThrowableFunctionTest.java | 30 +++++++++++++++++++ 2 files changed, 47 insertions(+) diff --git a/microsphere-java-core/src/test/java/io/microsphere/io/filter/FileExtensionFilterTest.java b/microsphere-java-core/src/test/java/io/microsphere/io/filter/FileExtensionFilterTest.java index 5a3b1f671..9f724957e 100644 --- a/microsphere-java-core/src/test/java/io/microsphere/io/filter/FileExtensionFilterTest.java +++ b/microsphere-java-core/src/test/java/io/microsphere/io/filter/FileExtensionFilterTest.java @@ -60,4 +60,21 @@ void testMatches() { assertTrue(this.instance.matches("txt", false)); assertTrue(this.instance.matches("TXT", false)); } + + @Test + void testOfWithDotPrefixedExtension() throws IOException { + FileExtensionFilter dotPrefixedFilter = of(".txt"); + File testFile = createTempFile("test", ".txt"); + assertTrue(dotPrefixedFilter.accept(testFile)); + testFile.deleteOnExit(); + } + + @Test + void testAcceptFilenameFilter() throws IOException { + File tmpDir = new File(JAVA_IO_TMPDIR); + File testFile = createTempFile("test", ".txt"); + assertTrue(this.instance.accept(tmpDir, testFile.getName())); + assertFalse(this.instance.accept(tmpDir, "file.xml")); + testFile.deleteOnExit(); + } } \ No newline at end of file diff --git a/microsphere-java-core/src/test/java/io/microsphere/lang/function/ThrowableFunctionTest.java b/microsphere-java-core/src/test/java/io/microsphere/lang/function/ThrowableFunctionTest.java index 3f619c490..3be2e987c 100644 --- a/microsphere-java-core/src/test/java/io/microsphere/lang/function/ThrowableFunctionTest.java +++ b/microsphere-java-core/src/test/java/io/microsphere/lang/function/ThrowableFunctionTest.java @@ -74,9 +74,39 @@ void testCompose() throws Throwable { assertEquals(1, stringToInteger.compose(function).apply("1")); } + @Test + void testComposeWithNullBefore() { + assertThrows(IllegalArgumentException.class, () -> function.compose(null)); + } + @Test void testAndThen() throws Throwable { assertEquals(1, function.andThen(stringToInteger).apply("1")); } + @Test + void testAndThenWithNullAfter() { + assertThrows(IllegalArgumentException.class, () -> function.andThen(null)); + } + + @Test + void testExecute1WithCustomHandlerReturningFallback() { + assertEquals("fallback", throwableFunction.execute("For testing", (t, e) -> "fallback")); + } + + @Test + void testExecute2WithNullFunction() { + assertThrows(NullPointerException.class, () -> execute("test", null)); + } + + @Test + void testExecute3WithNullFunction() { + assertThrows(IllegalArgumentException.class, () -> execute("test", null, (t, e) -> t)); + } + + @Test + void testExecute3WithNullExceptionHandler() { + assertThrows(IllegalArgumentException.class, () -> execute("test", function, null)); + } + } From 0fcccbbe18908915a4eeae9ec9aa80a9ff6cbe68 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Thu, 19 Mar 2026 04:39:55 +0000 Subject: [PATCH 11/17] Add test cases to enhance coverage for JSONArray, JSONObject, StandardFileWatchService, and ArtifactDetector Co-authored-by: mercyblitz <533114+mercyblitz@users.noreply.github.com> --- .../classloading/ArtifactDetectorTest.java | 14 +++++ .../io/StandardFileWatchServiceTest.java | 48 ++++++++++++++ .../io/microsphere/json/JSONArrayTest.java | 62 +++++++++++++++++++ .../io/microsphere/json/JSONObjectTest.java | 51 +++++++++++++++ 4 files changed, 175 insertions(+) diff --git a/microsphere-java-core/src/test/java/io/microsphere/classloading/ArtifactDetectorTest.java b/microsphere-java-core/src/test/java/io/microsphere/classloading/ArtifactDetectorTest.java index efb90f837..5fa93f64a 100644 --- a/microsphere-java-core/src/test/java/io/microsphere/classloading/ArtifactDetectorTest.java +++ b/microsphere-java-core/src/test/java/io/microsphere/classloading/ArtifactDetectorTest.java @@ -54,4 +54,18 @@ void testDetectOnEmptySet() { ArtifactDetector instance = new ArtifactDetector(null); assertTrue(instance.detect(emptySet()).isEmpty()); } + + @Test + void testDetectWithIncludedJdkLibraries() { + ArtifactDetector instance = new ArtifactDetector(); + List artifacts = instance.detect(true); + assertNotNull(artifacts); + } + + @Test + void testDetectWithExcludedJdkLibraries() { + ArtifactDetector instance = new ArtifactDetector(); + List artifacts = instance.detect(false); + assertNotNull(artifacts); + } } diff --git a/microsphere-java-core/src/test/java/io/microsphere/io/StandardFileWatchServiceTest.java b/microsphere-java-core/src/test/java/io/microsphere/io/StandardFileWatchServiceTest.java index 721d0c541..f31c4e5f0 100644 --- a/microsphere-java-core/src/test/java/io/microsphere/io/StandardFileWatchServiceTest.java +++ b/microsphere-java-core/src/test/java/io/microsphere/io/StandardFileWatchServiceTest.java @@ -52,6 +52,7 @@ import static io.microsphere.util.ArrayUtils.ofArray; import static io.microsphere.util.ClassLoaderUtils.getResource; import static io.microsphere.util.ExceptionUtils.wrap; +import static io.microsphere.collection.Lists.ofList; import static java.nio.charset.StandardCharsets.UTF_8; import static java.nio.file.Files.copy; import static java.nio.file.Files.write; @@ -265,4 +266,51 @@ private void async(ThrowableAction task) { } } + @Test + void testIsStartedBeforeStart() { + StandardFileWatchService fileWatchService = new StandardFileWatchService(); + assertFalse(fileWatchService.isStarted()); + } + + @Test + void testCloseWithoutStart() throws Exception { + StandardFileWatchService fileWatchService = new StandardFileWatchService(); + assertFalse(fileWatchService.isStarted()); + fileWatchService.close(); + assertFalse(fileWatchService.isStarted()); + } + + @Test + void testWatchWithMultipleListeners() throws Exception { + AtomicReference fileReference = new AtomicReference<>(); + + try (StandardFileWatchService fileWatchService = new StandardFileWatchService()) { + + FileChangedListener listener1 = new FileChangedListener() { + @Override + public void onFileCreated(FileChangedEvent event) { + fileReference.set(event.getFile()); + } + }; + + FileChangedListener listener2 = new LoggingFileChangedListener(); + + fileWatchService.watch(this.testDir, ofList(listener1, listener2), CREATED); + + fileWatchService.start(); + + assertTrue(fileWatchService.isStarted()); + + File testFile = createRandomFile(testDir); + + while (!testFile.equals(fileReference.get())) { + // spin + } + + fileWatchService.stop(); + + assertFalse(fileWatchService.isStarted()); + } + } + } diff --git a/microsphere-java-core/src/test/java/io/microsphere/json/JSONArrayTest.java b/microsphere-java-core/src/test/java/io/microsphere/json/JSONArrayTest.java index 4947aa4b4..c1b36ae30 100644 --- a/microsphere-java-core/src/test/java/io/microsphere/json/JSONArrayTest.java +++ b/microsphere-java-core/src/test/java/io/microsphere/json/JSONArrayTest.java @@ -446,4 +446,66 @@ void testHashCode() { assertEquals(jsonArray.hashCode(), jsonArray.hashCode()); assertEquals(ofList(1, 2, 3).hashCode(), jsonArray.hashCode()); } + + @Test + void testPutDoubleOnInvalidValue() { + assertThrows(JSONException.class, () -> jsonArray.put(NaN)); + assertThrows(JSONException.class, () -> jsonArray.put(Double.POSITIVE_INFINITY)); + assertThrows(JSONException.class, () -> jsonArray.put(Double.NEGATIVE_INFINITY)); + } + + @Test + void testPutDoubleWithIndexOnInvalidValue() { + assertThrows(JSONException.class, () -> jsonArray.put(0, NaN)); + assertThrows(JSONException.class, () -> jsonArray.put(0, Double.POSITIVE_INFINITY)); + assertThrows(JSONException.class, () -> jsonArray.put(0, Double.NEGATIVE_INFINITY)); + } + + @Test + void testOptBooleanWithFallback() { + jsonArray.put(true); + jsonArray.put("false"); + assertTrue(jsonArray.optBoolean(0, false)); + assertFalse(jsonArray.optBoolean(1, true)); + assertTrue(jsonArray.optBoolean(2, true)); + assertFalse(jsonArray.optBoolean(-1, false)); + } + + @Test + void testOptDoubleWithFallback() throws JSONException { + jsonArray.put(1.0); + jsonArray.put("not-a-number"); + assertEquals(1.0, jsonArray.optDouble(0, 99.0)); + assertEquals(99.0, jsonArray.optDouble(1, 99.0)); + assertEquals(99.0, jsonArray.optDouble(2, 99.0)); + assertEquals(99.0, jsonArray.optDouble(-1, 99.0)); + } + + @Test + void testOptIntWithFallback() throws JSONException { + jsonArray.put(42); + jsonArray.put("not-a-number"); + assertEquals(42, jsonArray.optInt(0, 99)); + assertEquals(99, jsonArray.optInt(1, 99)); + assertEquals(99, jsonArray.optInt(2, 99)); + assertEquals(99, jsonArray.optInt(-1, 99)); + } + + @Test + void testOptLongWithFallback() throws JSONException { + jsonArray.put(42L); + jsonArray.put("not-a-number"); + assertEquals(42L, jsonArray.optLong(0, 99L)); + assertEquals(99L, jsonArray.optLong(1, 99L)); + assertEquals(99L, jsonArray.optLong(2, 99L)); + assertEquals(99L, jsonArray.optLong(-1, 99L)); + } + + @Test + void testOptStringWithFallback() { + jsonArray.put("Hello"); + assertEquals("Hello", jsonArray.optString(0, "default")); + assertEquals("default", jsonArray.optString(1, "default")); + assertEquals("default", jsonArray.optString(-1, "default")); + } } \ No newline at end of file diff --git a/microsphere-java-core/src/test/java/io/microsphere/json/JSONObjectTest.java b/microsphere-java-core/src/test/java/io/microsphere/json/JSONObjectTest.java index 27577d142..65d9c398c 100644 --- a/microsphere-java-core/src/test/java/io/microsphere/json/JSONObjectTest.java +++ b/microsphere-java-core/src/test/java/io/microsphere/json/JSONObjectTest.java @@ -538,6 +538,57 @@ void testNULLToString() { assertEquals("null", NULL.toString()); } + @Test + void testPutDoubleOnInvalidValue() { + assertThrows(JSONException.class, () -> jsonObject.put("value", NaN)); + assertThrows(JSONException.class, () -> jsonObject.put("value", POSITIVE_INFINITY)); + assertThrows(JSONException.class, () -> jsonObject.put("value", NEGATIVE_INFINITY)); + } + + @Test + void testOptBooleanWithFallback() throws JSONException { + jsonObject.put("value", TRUE); + assertEquals(true, jsonObject.optBoolean("value", false)); + assertEquals(false, jsonObject.optBoolean("missing", false)); + assertEquals(true, jsonObject.optBoolean("missing", true)); + } + + @Test + void testOptDoubleWithFallback() throws JSONException { + jsonObject.put("value", Double.valueOf(1.0)); + assertEquals(1.0, jsonObject.optDouble("value", 99.0)); + assertEquals(99.0, jsonObject.optDouble("missing", 99.0)); + } + + @Test + void testOptIntWithFallback() throws JSONException { + jsonObject.put("value", Integer.valueOf(42)); + assertEquals(42, jsonObject.optInt("value", 99)); + assertEquals(99, jsonObject.optInt("missing", 99)); + } + + @Test + void testOptLongWithFallback() throws JSONException { + jsonObject.put("value", Long.valueOf(42L)); + assertEquals(42L, jsonObject.optLong("value", 99L)); + assertEquals(99L, jsonObject.optLong("missing", 99L)); + } + + @Test + void testOptStringWithFallback() throws JSONException { + jsonObject.put("name", "Mercy"); + assertEquals("Mercy", jsonObject.optString("name", "default")); + assertEquals("default", jsonObject.optString("missing", "default")); + } + + @Test + void testWriteTo() throws JSONException { + jsonObject.put("name", "Mercy").put("age", 18); + JSONStringer stringer = new JSONStringer(); + jsonObject.writeTo(stringer); + assertEquals("{\"name\":\"Mercy\",\"age\":18}", stringer.toString()); + } + void assertWrap(Object object) { assertEquals(object, wrap(object)); } From 2d1195f07c00bac62b0e0fb3a738042db5beeeeb Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Thu, 19 Mar 2026 05:04:32 +0000 Subject: [PATCH 12/17] Add test cases to enhance coverage for AbstractConverter, AbstractDeque, StringToIterableConverter, and AbstractURLClassPathHandle Co-authored-by: mercyblitz <533114+mercyblitz@users.noreply.github.com> --- .../AbstractURLClassPathHandleTest.java | 10 ++ .../collection/AbstractDequeTest.java | 40 ++++++ .../convert/AbstractConverterTest.java | 22 ++++ .../StringToIterableConverterTest.java | 124 ++++++++++++++++++ 4 files changed, 196 insertions(+) create mode 100644 microsphere-java-core/src/test/java/io/microsphere/convert/multiple/StringToIterableConverterTest.java diff --git a/microsphere-java-core/src/test/java/io/microsphere/classloading/AbstractURLClassPathHandleTest.java b/microsphere-java-core/src/test/java/io/microsphere/classloading/AbstractURLClassPathHandleTest.java index 6a1e12c1c..112764087 100644 --- a/microsphere-java-core/src/test/java/io/microsphere/classloading/AbstractURLClassPathHandleTest.java +++ b/microsphere-java-core/src/test/java/io/microsphere/classloading/AbstractURLClassPathHandleTest.java @@ -43,4 +43,14 @@ abstract class AbstractURLClassPathHandleTest extends BaseURLClassPathHandleTest void testGetPriority() { assertEquals(DEFAULT_PRIORITY, handle.getPriority()); } + + @Test + void testSetPriority() { + int newPriority = 42; + handle.setPriority(newPriority); + assertEquals(newPriority, handle.getPriority()); + // Restore default priority + handle.setPriority(DEFAULT_PRIORITY); + assertEquals(DEFAULT_PRIORITY, handle.getPriority()); + } } diff --git a/microsphere-java-core/src/test/java/io/microsphere/collection/AbstractDequeTest.java b/microsphere-java-core/src/test/java/io/microsphere/collection/AbstractDequeTest.java index 1361b351e..7e6ba5eb5 100644 --- a/microsphere-java-core/src/test/java/io/microsphere/collection/AbstractDequeTest.java +++ b/microsphere-java-core/src/test/java/io/microsphere/collection/AbstractDequeTest.java @@ -197,4 +197,44 @@ void testSize() { deque.poll(); assertEquals(0, deque.size()); } + + @Test + void testRemoveFirstOccurrenceWithMultipleOccurrences() { + TestDeque multiDeque = new TestDeque<>(); + multiDeque.add("A"); + multiDeque.add("B"); + multiDeque.add("A"); + // removeFirstOccurrence delegates to remove(o) in AbstractDeque which removes the first occurrence + assertTrue(multiDeque.removeFirstOccurrence("A")); + assertEquals(2, multiDeque.size()); + // "B" and the second "A" should remain, in order + Iterator it = multiDeque.iterator(); + assertEquals("B", it.next()); + assertEquals("A", it.next()); + assertFalse(it.hasNext()); + } + + @Test + void testOfferAndPollSequence() { + TestDeque multiDeque = new TestDeque<>(); + assertTrue(multiDeque.offer("X")); + assertTrue(multiDeque.offer("Y")); + assertTrue(multiDeque.offer("Z")); + // offer delegates to offerLast; poll delegates to pollFirst (FIFO) + assertEquals("X", multiDeque.poll()); + assertEquals("Y", multiDeque.poll()); + assertEquals("Z", multiDeque.poll()); + assertNull(multiDeque.poll()); + } + + @Test + void testPushAndPop() { + TestDeque multiDeque = new TestDeque<>(); + multiDeque.push("X"); + multiDeque.push("Y"); + // push delegates to addFirst (LIFO) + assertEquals("Y", multiDeque.pop()); + assertEquals("X", multiDeque.pop()); + assertThrows(NoSuchElementException.class, () -> multiDeque.pop()); + } } \ No newline at end of file diff --git a/microsphere-java-core/src/test/java/io/microsphere/convert/AbstractConverterTest.java b/microsphere-java-core/src/test/java/io/microsphere/convert/AbstractConverterTest.java index 08b924c4a..28eb8e1fe 100644 --- a/microsphere-java-core/src/test/java/io/microsphere/convert/AbstractConverterTest.java +++ b/microsphere-java-core/src/test/java/io/microsphere/convert/AbstractConverterTest.java @@ -25,6 +25,7 @@ import static org.junit.jupiter.api.Assertions.assertNotEquals; import static org.junit.jupiter.api.Assertions.assertNotNull; import static org.junit.jupiter.api.Assertions.assertThrows; +import static org.junit.jupiter.api.Assertions.assertTrue; /** * {@link AbstractConverter} Test @@ -102,4 +103,25 @@ void testEquals() { assertNotEquals(this.converter, StringToBooleanConverter.INSTANCE); assertNotEquals(this.converter, ObjectToStringConverter.INSTANCE); } + + @Test + void testHashCode() { + AbstractConverter another = createConverter(); + assertEquals(this.converter.hashCode(), another.hashCode()); + assertNotEquals(this.converter.hashCode(), StringToBooleanConverter.INSTANCE.hashCode()); + assertNotEquals(this.converter.hashCode(), ObjectToStringConverter.INSTANCE.hashCode()); + } + + @Test + void testResolvePriority() { + // When resolvePriority() returns a non-null value, getPriority() returns that value + AbstractConverter converter = new AbstractConverter() { + @Override + protected Integer doConvert(String source) { + return Integer.parseInt(source); + } + }; + // The priority is derived from the type hierarchy and must be negative + assertTrue(converter.getPriority() < 0); + } } diff --git a/microsphere-java-core/src/test/java/io/microsphere/convert/multiple/StringToIterableConverterTest.java b/microsphere-java-core/src/test/java/io/microsphere/convert/multiple/StringToIterableConverterTest.java new file mode 100644 index 000000000..d1ef1e2e8 --- /dev/null +++ b/microsphere-java-core/src/test/java/io/microsphere/convert/multiple/StringToIterableConverterTest.java @@ -0,0 +1,124 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package io.microsphere.convert.multiple; + +import io.microsphere.convert.StringConverter; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; + +import java.util.Collection; +import java.util.Collections; +import java.util.List; +import java.util.Optional; +import java.util.Set; + +import static java.lang.Integer.MAX_VALUE; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertNull; +import static org.junit.jupiter.api.Assertions.assertTrue; + +/** + * {@link StringToIterableConverter} Test + * + * @author Mercy + * @see StringToIterableConverter + * @since 1.0.0 + */ +class StringToIterableConverterTest { + + private StringToCollectionConverter converter; + + @BeforeEach + void setUp() { + converter = new StringToCollectionConverter(); + } + + @Test + void testAccept() { + assertTrue(converter.accept(String.class, Collection.class)); + assertTrue(converter.accept(String.class, List.class)); + assertTrue(converter.accept(String.class, Set.class)); + assertFalse(converter.accept(String.class, String.class)); + assertFalse(converter.accept(null, null)); + } + + @Test + void testConvert() { + Collection result = (Collection) converter.convert("1,2,3", Collection.class, Integer.class); + assertNotNull(result); + assertEquals(3, result.size()); + assertTrue(result.contains(1)); + assertTrue(result.contains(2)); + assertTrue(result.contains(3)); + + Collection strResult = (Collection) converter.convert("a,b", Collection.class, String.class); + assertNotNull(strResult); + assertEquals(2, strResult.size()); + assertTrue(strResult.contains("a")); + assertTrue(strResult.contains("b")); + } + + @Test + void testConvertOnNoStringConverter() { + // No StringConverter registered for Object.class → returns null + assertNull(converter.convert(new String[]{"a"}, 1, Collection.class, Object.class)); + } + + @Test + void testConvertOnNonCollectionIterable() { + // When createMultiValue returns a non-Collection Iterable, the elements are not added; + // the iterable is returned as-is once a StringConverter is found for the element type. + StringToIterableConverter iterableConverter = new StringToIterableConverter() { + @Override + protected Iterable createMultiValue(int size, Class multiValueType) { + return Collections::emptyIterator; + } + }; + + Object result = iterableConverter.convert(new String[]{"1", "2"}, 2, Iterable.class, Integer.class); + assertNotNull(result); + } + + @Test + void testGetStringConverter() { + // Integer has a registered StringConverter + Optional intConverter = converter.getStringConverter(Integer.class); + assertTrue(intConverter.isPresent()); + + // Object.class has no registered StringConverter + Optional objectConverter = converter.getStringConverter(Object.class); + assertFalse(objectConverter.isPresent()); + } + + @Test + void testGetSupportedType() { + assertEquals(Collection.class, converter.getSupportedType()); + } + + @Test + void testGetPriority() { + // Collection has 1 interface level above Iterable, so level=1 → priority = MAX_VALUE - 1 + assertEquals(MAX_VALUE - 1, converter.getPriority()); + } + + @Test + void testGetSourceType() { + assertEquals(String.class, converter.getSourceType()); + } +} From fd30f1ff6cfb976b1a70165f3e81560f076fd9e7 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Thu, 19 Mar 2026 07:04:42 +0000 Subject: [PATCH 13/17] Add test cases to enhance coverage for Sets, Lists, Maps, and ReflectionUtils Co-authored-by: mercyblitz <533114+mercyblitz@users.noreply.github.com> --- .../io/microsphere/collection/ListsTest.java | 9 ++++ .../io/microsphere/collection/MapsTest.java | 19 +++++++ .../io/microsphere/collection/SetsTest.java | 9 ++++ .../StringToIterableConverterTest.java | 4 ++ .../reflect/ReflectionUtilsTest.java | 50 +++++++++++++++++++ 5 files changed, 91 insertions(+) diff --git a/microsphere-java-core/src/test/java/io/microsphere/collection/ListsTest.java b/microsphere-java-core/src/test/java/io/microsphere/collection/ListsTest.java index 5cce7323f..375751aeb 100644 --- a/microsphere-java-core/src/test/java/io/microsphere/collection/ListsTest.java +++ b/microsphere-java-core/src/test/java/io/microsphere/collection/ListsTest.java @@ -7,6 +7,7 @@ import static io.microsphere.collection.Lists.ofList; import static java.util.Collections.emptyList; import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertThrows; /** * {@link Lists} Test @@ -77,4 +78,12 @@ void testOfList() { assertEquals(emptyList(), ofList(TEST_NULL_OBJECT_ARRAY)); assertEquals(of(1, 2, 3), ofList(1, 2, 3)); } + + @Test + void testOfListImmutability() { + assertThrows(UnsupportedOperationException.class, () -> ofList().add("x")); + assertThrows(UnsupportedOperationException.class, () -> ofList(1).add(2)); + assertThrows(UnsupportedOperationException.class, () -> ofList(1, 2).remove(0)); + assertThrows(UnsupportedOperationException.class, () -> ofList(1, 2, 3).clear()); + } } \ No newline at end of file diff --git a/microsphere-java-core/src/test/java/io/microsphere/collection/MapsTest.java b/microsphere-java-core/src/test/java/io/microsphere/collection/MapsTest.java index 5205f2710..0ec9c6c59 100644 --- a/microsphere-java-core/src/test/java/io/microsphere/collection/MapsTest.java +++ b/microsphere-java-core/src/test/java/io/microsphere/collection/MapsTest.java @@ -11,6 +11,7 @@ import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertNull; import static org.junit.jupiter.api.Assertions.assertSame; +import static org.junit.jupiter.api.Assertions.assertThrows; /** * {@link Maps} Test @@ -186,4 +187,22 @@ void testMapOfOnEmptyEntries() { Map map = Maps.ofMap(new Map.Entry[0]); assertSame(emptyMap(), map); } + + @Test + void testOfMapOnSingleEntry() { + Map.Entry entry = ofEntry("A", 1); + Map map = Maps.ofMap(entry); + assertEquals(1, map.size()); + assertEquals(1, map.get("A")); + assertNull(map.get("B")); + assertOfMap(map); + } + + @Test + void testOfMapImmutability() { + assertThrows(UnsupportedOperationException.class, () -> ofMap().put("k", "v")); + assertThrows(UnsupportedOperationException.class, () -> ofMap("A", 1).put("B", 2)); + assertThrows(UnsupportedOperationException.class, () -> ofMap("A", 1, "B", 2).remove("A")); + assertThrows(UnsupportedOperationException.class, () -> ofMap("A", 1, "B", 2, "C", 3).clear()); + } } \ No newline at end of file diff --git a/microsphere-java-core/src/test/java/io/microsphere/collection/SetsTest.java b/microsphere-java-core/src/test/java/io/microsphere/collection/SetsTest.java index afdabee1c..521663ae2 100644 --- a/microsphere-java-core/src/test/java/io/microsphere/collection/SetsTest.java +++ b/microsphere-java-core/src/test/java/io/microsphere/collection/SetsTest.java @@ -7,6 +7,7 @@ import static io.microsphere.collection.Sets.ofSet; import static java.util.Collections.emptySet; import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertThrows; /** * {@link Sets} Test @@ -77,4 +78,12 @@ void testOfSet() { assertEquals(emptySet(), ofSet(TEST_NULL_OBJECT_ARRAY)); assertEquals(of(1, 2, 3), ofSet(1, 2, 3)); } + + @Test + void testOfSetImmutability() { + assertThrows(UnsupportedOperationException.class, () -> ofSet().add("x")); + assertThrows(UnsupportedOperationException.class, () -> ofSet(1).add(2)); + assertThrows(UnsupportedOperationException.class, () -> ofSet(1, 2).remove(1)); + assertThrows(UnsupportedOperationException.class, () -> ofSet(1, 2, 3).clear()); + } } \ No newline at end of file diff --git a/microsphere-java-core/src/test/java/io/microsphere/convert/multiple/StringToIterableConverterTest.java b/microsphere-java-core/src/test/java/io/microsphere/convert/multiple/StringToIterableConverterTest.java index d1ef1e2e8..cc42d91ac 100644 --- a/microsphere-java-core/src/test/java/io/microsphere/convert/multiple/StringToIterableConverterTest.java +++ b/microsphere-java-core/src/test/java/io/microsphere/convert/multiple/StringToIterableConverterTest.java @@ -36,8 +36,12 @@ /** * {@link StringToIterableConverter} Test * + *

Tests the abstract {@link StringToIterableConverter} behavior using + * {@link StringToCollectionConverter} as the concrete implementation.

+ * * @author Mercy * @see StringToIterableConverter + * @see StringToCollectionConverter * @since 1.0.0 */ class StringToIterableConverterTest { diff --git a/microsphere-java-core/src/test/java/io/microsphere/reflect/ReflectionUtilsTest.java b/microsphere-java-core/src/test/java/io/microsphere/reflect/ReflectionUtilsTest.java index 8060c6a43..0d639d66c 100644 --- a/microsphere-java-core/src/test/java/io/microsphere/reflect/ReflectionUtilsTest.java +++ b/microsphere-java-core/src/test/java/io/microsphere/reflect/ReflectionUtilsTest.java @@ -10,6 +10,12 @@ import static io.microsphere.collection.Lists.ofList; import static io.microsphere.reflect.ReflectionUtils.INACCESSIBLE_OBJECT_EXCEPTION_CLASS; import static io.microsphere.reflect.ReflectionUtils.INACCESSIBLE_OBJECT_EXCEPTION_CLASS_NAME; +import static io.microsphere.reflect.ReflectionUtils.STACK_WALKER_CLASS; +import static io.microsphere.reflect.ReflectionUtils.STACK_WALKER_CLASS_NAME; +import static io.microsphere.reflect.ReflectionUtils.STACK_WALKER_STACK_FRAME_CLASS; +import static io.microsphere.reflect.ReflectionUtils.STACK_WALKER_STACK_FRAME_CLASS_NAME; +import static io.microsphere.reflect.ReflectionUtils.SUN_REFLECT_REFLECTION_CLASS; +import static io.microsphere.reflect.ReflectionUtils.SUN_REFLECT_REFLECTION_CLASS_NAME; import static io.microsphere.reflect.ReflectionUtils.getCallerClass; import static io.microsphere.reflect.ReflectionUtils.getCallerClassInSunReflectReflection; import static io.microsphere.reflect.ReflectionUtils.getCallerClassName; @@ -28,6 +34,7 @@ import static java.util.Arrays.asList; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertNotNull; import static org.junit.jupiter.api.Assertions.assertNull; import static org.junit.jupiter.api.Assertions.assertThrows; import static org.junit.jupiter.api.Assertions.assertTrue; @@ -144,6 +151,49 @@ void testIsInaccessibleObjectException() { assertTrue(isInaccessibleObjectException(INACCESSIBLE_OBJECT_EXCEPTION_CLASS_NAME)); } + @Test + void testReadFieldsAsMapOnNull() { + assertTrue(readFieldsAsMap(null).isEmpty()); + } + + @Test + void testConstants() { + assertEquals("sun.reflect.Reflection", SUN_REFLECT_REFLECTION_CLASS_NAME); + assertEquals("java.lang.StackWalker", STACK_WALKER_CLASS_NAME); + assertEquals("java.lang.StackWalker$StackFrame", STACK_WALKER_STACK_FRAME_CLASS_NAME); + assertEquals("java.lang.reflect.InaccessibleObjectException", INACCESSIBLE_OBJECT_EXCEPTION_CLASS_NAME); + } + + @Test + void testStackWalkerClassAvailability() { + if (testCurrentJavaVersion("<", JAVA_VERSION_9)) { + assertNull(STACK_WALKER_CLASS); + assertNull(STACK_WALKER_STACK_FRAME_CLASS); + } else { + assertNotNull(STACK_WALKER_CLASS); + assertNotNull(STACK_WALKER_STACK_FRAME_CLASS); + } + } + + @Test + void testSunReflectReflectionClassAvailability() { + boolean supported = isSupportedSunReflectReflection(); + if (supported) { + assertNotNull(SUN_REFLECT_REFLECTION_CLASS); + } + // On JDK 9+, sun.reflect.Reflection#getCallerClass(int) was removed, + // so isSupportedSunReflectReflection() returns false even though the class may exist + } + + @Test + void testGetCallerClassInSunReflectReflectionWithOffset() { + if (isSupportedSunReflectReflection()) { + assertNotNull(getCallerClassInSunReflectReflection(0)); + } else { + assertNull(getCallerClassInSunReflectReflection(0)); + } + } + static class T extends Data { private T self; From af5d740f8158c23cf337c059435881d42530fc28 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Thu, 19 Mar 2026 07:12:09 +0000 Subject: [PATCH 14/17] Update JUnit Jupiter from 5.14.2 to 5.14.3 on Maven profile java8-16 Co-authored-by: mercyblitz <533114+mercyblitz@users.noreply.github.com> --- microsphere-java-parent/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/microsphere-java-parent/pom.xml b/microsphere-java-parent/pom.xml index 7e44ed37b..6dd2b30be 100644 --- a/microsphere-java-parent/pom.xml +++ b/microsphere-java-parent/pom.xml @@ -152,7 +152,7 @@ 5.3.39 - 5.14.2 + 5.14.3 4.11.0 From a6018657b8bc78676250e9d2c26a00cf5bd757bc Mon Sep 17 00:00:00 2001 From: Mercy Ma Date: Thu, 19 Mar 2026 19:14:09 +0800 Subject: [PATCH 15/17] Enhance maven-publish and add merge workflow Update the maven-publish workflow to require a strict major.minor.patch revision input (updated description/default) and validate its format. Add a release job that tags the repo, creates a GitHub release (using gh), increments the patch to a next SNAPSHOT in pom.xml, and commits the bumped version. Add a new workflow (merge-main-to-branches.yml) that automatically merges main into dev and release on pushes to main, handling missing branches and merge conflicts with fail/notify behavior. --- .github/workflows/maven-publish.yml | 65 ++++++++++++++++++- .github/workflows/merge-main-to-branches.yml | 66 ++++++++++++++++++++ 2 files changed, 129 insertions(+), 2 deletions(-) create mode 100644 .github/workflows/merge-main-to-branches.yml diff --git a/.github/workflows/maven-publish.yml b/.github/workflows/maven-publish.yml index 61db0dc6d..dd76c6718 100644 --- a/.github/workflows/maven-publish.yml +++ b/.github/workflows/maven-publish.yml @@ -14,9 +14,9 @@ on: workflow_dispatch: inputs: revision: - description: 'The version to release' + description: 'The version to publish (must match ${major}.${minor}.${patch})' required: true - default: '0.0.1-SNAPSHOT' + default: '${major}.${minor}.${patch}' jobs: build: @@ -26,6 +26,13 @@ jobs: - name: Checkout Source uses: actions/checkout@v5 + - name: Validate version format + run: | + if ! echo "${{ inputs.revision }}" | grep -qE '^[0-9]+\.[0-9]+\.[0-9]+$'; then + echo "Error: version '${{ inputs.revision }}' does not match the required pattern major.minor.patch" + exit 1 + fi + - name: Setup Maven Central Repository uses: actions/setup-java@v5 with: @@ -51,3 +58,57 @@ jobs: SIGN_KEY_ID: ${{ secrets.OSS_SIGNING_KEY_ID_LONG }} SIGN_KEY: ${{ secrets.OSS_SIGNING_KEY }} SIGN_KEY_PASS: ${{ secrets.OSS_SIGNING_PASSWORD }} + + release: + runs-on: ubuntu-latest + needs: build + permissions: + contents: write + steps: + - name: Checkout Source + uses: actions/checkout@v5 + with: + fetch-depth: 0 + + - name: Create Tag + run: | + git config user.name "github-actions[bot]" + git config user.email "github-actions[bot]@users.noreply.github.com" + if git rev-parse "${{ inputs.revision }}" >/dev/null 2>&1; then + echo "Tag ${{ inputs.revision }} already exists, skipping." + else + git tag ${{ inputs.revision }} + git push origin ${{ inputs.revision }} + fi + + - name: Create Release + run: | + if gh release view "v${{ inputs.revision }}" >/dev/null 2>&1; then + echo "Release v${{ inputs.revision }} already exists, skipping." + else + gh release create v${{ inputs.revision }} \ + --title "v${{ inputs.revision }}" \ + --generate-notes \ + --latest + fi + env: + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + + - name: Increment patch version + run: | + CURRENT="${{ inputs.revision }}" + MAJOR=$(echo "$CURRENT" | cut -d. -f1) + MINOR=$(echo "$CURRENT" | cut -d. -f2) + PATCH=$(echo "$CURRENT" | cut -d. -f3) + NEXT_PATCH=$((PATCH + 1)) + NEXT_VERSION="${MAJOR}.${MINOR}.${NEXT_PATCH}-SNAPSHOT" + sed -i "s|^\( *\)[^<]*|\1${NEXT_VERSION}|" pom.xml + echo "Bumped version from ${CURRENT} to ${NEXT_VERSION}" + + - name: Commit and push next version + run: | + git config user.name "github-actions[bot]" + git config user.email "github-actions[bot]@users.noreply.github.com" + git add pom.xml + git diff --cached --quiet && echo "No changes to commit" || \ + git commit -m "chore: bump version to next patch after publishing ${{ inputs.revision }}" && git push diff --git a/.github/workflows/merge-main-to-branches.yml b/.github/workflows/merge-main-to-branches.yml new file mode 100644 index 000000000..f47152388 --- /dev/null +++ b/.github/workflows/merge-main-to-branches.yml @@ -0,0 +1,66 @@ +# This workflow automatically merges the 'main' branch into 'dev' and 'release' branches +# whenever changes are pushed to 'main', without requiring manual confirmation. + +name: Merge Main to Dev and Release + +on: + push: + branches: + - main + +concurrency: + group: merge-main-to-branches + cancel-in-progress: false + +jobs: + merge-to-dev: + name: Merge main → dev + runs-on: ubuntu-latest + permissions: + contents: write + steps: + - name: Checkout Repository + uses: actions/checkout@v5 + with: + fetch-depth: 0 + token: ${{ secrets.GITHUB_TOKEN }} + + - name: Merge main into dev + run: | + git config user.name "github-actions[bot]" + git config user.email "github-actions[bot]@users.noreply.github.com" + if ! git checkout dev; then + echo "::error::Branch 'dev' does not exist. Skipping merge." + exit 1 + fi + if ! git merge --no-ff origin/main -m "chore: merge main into dev [skip ci]"; then + echo "::error::Merge conflict detected when merging main into dev. Manual intervention required." + exit 1 + fi + git push origin dev + + merge-to-release: + name: Merge main → release + runs-on: ubuntu-latest + permissions: + contents: write + steps: + - name: Checkout Repository + uses: actions/checkout@v5 + with: + fetch-depth: 0 + token: ${{ secrets.GITHUB_TOKEN }} + + - name: Merge main into release + run: | + git config user.name "github-actions[bot]" + git config user.email "github-actions[bot]@users.noreply.github.com" + if ! git checkout release; then + echo "::error::Branch 'release' does not exist. Skipping merge." + exit 1 + fi + if ! git merge --no-ff origin/main -m "chore: merge main into release [skip ci]"; then + echo "::error::Merge conflict detected when merging main into release. Manual intervention required." + exit 1 + fi + git push origin release From 5a954cb47b0f9048717b40a09465e65318daef88 Mon Sep 17 00:00:00 2001 From: Mercy Ma Date: Thu, 19 Mar 2026 19:25:53 +0800 Subject: [PATCH 16/17] Bump parent POM version to 0.2.5 Update the project parent version from 0.2.3 to 0.2.5 to pick up updates in the microsphere-build parent POM (build/config fixes or improvements). No other source changes were made. --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 4d3ed51e7..6309c4106 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ io.github.microsphere-projects microsphere-build - 0.2.3 + 0.2.5 io.github.microsphere-projects From 4ee8d7e0cfaa7ecbf9ae2aace032d098b9782e90 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Thu, 19 Mar 2026 12:44:07 +0000 Subject: [PATCH 17/17] refactor: extract MethodHandle helpers in Sets/Maps/Lists for full branch coverage Co-authored-by: mercyblitz <533114+mercyblitz@users.noreply.github.com> --- .../java/io/microsphere/collection/Lists.java | 96 +++++++--- .../java/io/microsphere/collection/Maps.java | 99 +++++++--- .../java/io/microsphere/collection/Sets.java | 96 +++++++--- .../io/microsphere/collection/ListsTest.java | 150 +++++++++++++++ .../io/microsphere/collection/MapsTest.java | 179 ++++++++++++++++++ .../io/microsphere/collection/SetsTest.java | 150 +++++++++++++++ 6 files changed, 698 insertions(+), 72 deletions(-) diff --git a/microsphere-java-core/src/main/java/io/microsphere/collection/Lists.java b/microsphere-java-core/src/main/java/io/microsphere/collection/Lists.java index 6407c2d61..f5851a805 100644 --- a/microsphere-java-core/src/main/java/io/microsphere/collection/Lists.java +++ b/microsphere-java-core/src/main/java/io/microsphere/collection/Lists.java @@ -117,11 +117,15 @@ public abstract class Lists implements Utils { @Nonnull @Immutable public static List ofList() { - if (of0MethodHandle == null) { + return ofList0(of0MethodHandle); + } + + static List ofList0(MethodHandle methodHandle) { + if (methodHandle == null) { return emptyList(); } try { - return (List) of0MethodHandle.invokeExact(); + return (List) methodHandle.invokeExact(); } catch (Throwable e) { return emptyList(); } @@ -146,11 +150,15 @@ public static List ofList() { @Nonnull @Immutable public static List ofList(E e1) { - if (of1MethodHandle == null) { + return ofList1(of1MethodHandle, e1); + } + + static List ofList1(MethodHandle methodHandle, E e1) { + if (methodHandle == null) { return singletonList(e1); } try { - return (List) of1MethodHandle.invokeExact(e1); + return (List) methodHandle.invokeExact(e1); } catch (Throwable e) { return singletonList(e1); } @@ -176,11 +184,15 @@ public static List ofList(E e1) { @Nonnull @Immutable public static List ofList(E e1, E e2) { - if (of2MethodHandle == null) { + return ofList2(of2MethodHandle, e1, e2); + } + + static List ofList2(MethodHandle methodHandle, E e1, E e2) { + if (methodHandle == null) { return of(e1, e2); } try { - return (List) of2MethodHandle.invokeExact(e1, e2); + return (List) methodHandle.invokeExact(e1, e2); } catch (Throwable e) { return of(e1, e2); } @@ -207,11 +219,15 @@ public static List ofList(E e1, E e2) { @Nonnull @Immutable public static List ofList(E e1, E e2, E e3) { - if (of3MethodHandle == null) { + return ofList3(of3MethodHandle, e1, e2, e3); + } + + static List ofList3(MethodHandle methodHandle, E e1, E e2, E e3) { + if (methodHandle == null) { return of(e1, e2, e3); } try { - return (List) of3MethodHandle.invokeExact(e1, e2, e3); + return (List) methodHandle.invokeExact(e1, e2, e3); } catch (Throwable e) { return of(e1, e2, e3); } @@ -239,11 +255,15 @@ public static List ofList(E e1, E e2, E e3) { @Nonnull @Immutable public static List ofList(E e1, E e2, E e3, E e4) { - if (of4MethodHandle == null) { + return ofList4(of4MethodHandle, e1, e2, e3, e4); + } + + static List ofList4(MethodHandle methodHandle, E e1, E e2, E e3, E e4) { + if (methodHandle == null) { return of(e1, e2, e3, e4); } try { - return (List) of4MethodHandle.invokeExact(e1, e2, e3, e4); + return (List) methodHandle.invokeExact(e1, e2, e3, e4); } catch (Throwable e) { return of(e1, e2, e3, e4); } @@ -272,11 +292,15 @@ public static List ofList(E e1, E e2, E e3, E e4) { @Nonnull @Immutable public static List ofList(E e1, E e2, E e3, E e4, E e5) { - if (of5MethodHandle == null) { + return ofList5(of5MethodHandle, e1, e2, e3, e4, e5); + } + + static List ofList5(MethodHandle methodHandle, E e1, E e2, E e3, E e4, E e5) { + if (methodHandle == null) { return of(e1, e2, e3, e4, e5); } try { - return (List) of5MethodHandle.invokeExact(e1, e2, e3, e4, e5); + return (List) methodHandle.invokeExact(e1, e2, e3, e4, e5); } catch (Throwable e) { return of(e1, e2, e3, e4, e5); } @@ -298,11 +322,15 @@ public static List ofList(E e1, E e2, E e3, E e4, E e5) { @Nonnull @Immutable static List ofList(E e1, E e2, E e3, E e4, E e5, E e6) { - if (of6MethodHandle == null) { + return ofList6(of6MethodHandle, e1, e2, e3, e4, e5, e6); + } + + static List ofList6(MethodHandle methodHandle, E e1, E e2, E e3, E e4, E e5, E e6) { + if (methodHandle == null) { return of(e1, e2, e3, e4, e5, e6); } try { - return (List) of6MethodHandle.invokeExact(e1, e2, e3, e4, e5, e6); + return (List) methodHandle.invokeExact(e1, e2, e3, e4, e5, e6); } catch (Throwable e) { return of(e1, e2, e3, e4, e5, e6); } @@ -333,11 +361,15 @@ static List ofList(E e1, E e2, E e3, E e4, E e5, E e6) { @Nonnull @Immutable public static List ofList(E e1, E e2, E e3, E e4, E e5, E e6, E e7) { - if (of7MethodHandle == null) { + return ofList7(of7MethodHandle, e1, e2, e3, e4, e5, e6, e7); + } + + static List ofList7(MethodHandle methodHandle, E e1, E e2, E e3, E e4, E e5, E e6, E e7) { + if (methodHandle == null) { return of(e1, e2, e3, e4, e5, e6, e7); } try { - return (List) of7MethodHandle.invokeExact(e1, e2, e3, e4, e5, e6, e7); + return (List) methodHandle.invokeExact(e1, e2, e3, e4, e5, e6, e7); } catch (Throwable e) { return of(e1, e2, e3, e4, e5, e6, e7); } @@ -369,11 +401,15 @@ public static List ofList(E e1, E e2, E e3, E e4, E e5, E e6, E e7) { @Nonnull @Immutable public static List ofList(E e1, E e2, E e3, E e4, E e5, E e6, E e7, E e8) { - if (of8MethodHandle == null) { + return ofList8(of8MethodHandle, e1, e2, e3, e4, e5, e6, e7, e8); + } + + static List ofList8(MethodHandle methodHandle, E e1, E e2, E e3, E e4, E e5, E e6, E e7, E e8) { + if (methodHandle == null) { return of(e1, e2, e3, e4, e5, e6, e7, e8); } try { - return (List) of8MethodHandle.invokeExact(e1, e2, e3, e4, e5, e6, e7, e8); + return (List) methodHandle.invokeExact(e1, e2, e3, e4, e5, e6, e7, e8); } catch (Throwable e) { return of(e1, e2, e3, e4, e5, e6, e7, e8); } @@ -406,11 +442,15 @@ public static List ofList(E e1, E e2, E e3, E e4, E e5, E e6, E e7, E e8) @Nonnull @Immutable public static List ofList(E e1, E e2, E e3, E e4, E e5, E e6, E e7, E e8, E e9) { - if (of9MethodHandle == null) { + return ofList9(of9MethodHandle, e1, e2, e3, e4, e5, e6, e7, e8, e9); + } + + static List ofList9(MethodHandle methodHandle, E e1, E e2, E e3, E e4, E e5, E e6, E e7, E e8, E e9) { + if (methodHandle == null) { return of(e1, e2, e3, e4, e5, e6, e7, e8, e9); } try { - return (List) of9MethodHandle.invokeExact(e1, e2, e3, e4, e5, e6, e7, e8, e9); + return (List) methodHandle.invokeExact(e1, e2, e3, e4, e5, e6, e7, e8, e9); } catch (Throwable e) { return of(e1, e2, e3, e4, e5, e6, e7, e8, e9); } @@ -436,11 +476,15 @@ public static List ofList(E e1, E e2, E e3, E e4, E e5, E e6, E e7, E e8, @Nonnull @Immutable static List ofList(E e1, E e2, E e3, E e4, E e5, E e6, E e7, E e8, E e9, E e10) { - if (of10MethodHandle == null) { + return ofList10(of10MethodHandle, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10); + } + + static List ofList10(MethodHandle methodHandle, E e1, E e2, E e3, E e4, E e5, E e6, E e7, E e8, E e9, E e10) { + if (methodHandle == null) { return of(e1, e2, e3, e4, e5, e6, e7, e8, e9, e10); } try { - return (List) of10MethodHandle.invokeExact(e1, e2, e3, e4, e5, e6, e7, e8, e9, e10); + return (List) methodHandle.invokeExact(e1, e2, e3, e4, e5, e6, e7, e8, e9, e10); } catch (Throwable e) { return of(e1, e2, e3, e4, e5, e6, e7, e8, e9, e10); } @@ -470,11 +514,15 @@ public static List ofList(E... elements) { if (length(elements) < 1) { return ofList(); } - if (ofMethodHandle == null) { + return ofListElements(ofMethodHandle, elements); + } + + static List ofListElements(MethodHandle methodHandle, E[] elements) { + if (methodHandle == null) { return of(elements); } try { - return (List) ofMethodHandle.invokeExact(elements); + return (List) methodHandle.invokeExact(elements); } catch (Throwable e) { return of(elements); } diff --git a/microsphere-java-core/src/main/java/io/microsphere/collection/Maps.java b/microsphere-java-core/src/main/java/io/microsphere/collection/Maps.java index a3716cf12..093ec44c4 100644 --- a/microsphere-java-core/src/main/java/io/microsphere/collection/Maps.java +++ b/microsphere-java-core/src/main/java/io/microsphere/collection/Maps.java @@ -114,11 +114,15 @@ public abstract class Maps implements Utils { @Nonnull @Immutable public static Map ofMap() { - if (of0MethodHandle == null) { + return ofMap0(of0MethodHandle); + } + + static Map ofMap0(MethodHandle methodHandle) { + if (methodHandle == null) { return emptyMap(); } try { - return (Map) of0MethodHandle.invokeExact(); + return (Map) methodHandle.invokeExact(); } catch (Throwable e) { return emptyMap(); } @@ -144,11 +148,15 @@ public static Map ofMap() { @Nonnull @Immutable public static Map ofMap(K k1, V v1) { - if (of1MethodHandle == null) { + return ofMap1(of1MethodHandle, k1, v1); + } + + static Map ofMap1(MethodHandle methodHandle, K k1, V v1) { + if (methodHandle == null) { return singletonMap(k1, v1); } try { - return (Map) of1MethodHandle.invokeExact(k1, v1); + return (Map) methodHandle.invokeExact(k1, v1); } catch (Throwable e) { return singletonMap(k1, v1); } @@ -175,11 +183,15 @@ public static Map ofMap(K k1, V v1) { @Nonnull @Immutable public static Map ofMap(K k1, V v1, K k2, V v2) { - if (of2MethodHandle == null) { + return ofMap2(of2MethodHandle, k1, v1, k2, v2); + } + + static Map ofMap2(MethodHandle methodHandle, K k1, V v1, K k2, V v2) { + if (methodHandle == null) { return of(k1, v1, k2, v2); } try { - return (Map) of2MethodHandle.invokeExact(k1, v1, k2, v2); + return (Map) methodHandle.invokeExact(k1, v1, k2, v2); } catch (Throwable e) { return of(k1, v1, k2, v2); } @@ -208,11 +220,15 @@ public static Map ofMap(K k1, V v1, K k2, V v2) { @Nonnull @Immutable public static Map ofMap(K k1, V v1, K k2, V v2, K k3, V v3) { - if (of3MethodHandle == null) { + return ofMap3(of3MethodHandle, k1, v1, k2, v2, k3, v3); + } + + static Map ofMap3(MethodHandle methodHandle, K k1, V v1, K k2, V v2, K k3, V v3) { + if (methodHandle == null) { return of(k1, v1, k2, v2, k3, v3); } try { - return (Map) of3MethodHandle.invokeExact(k1, v1, k2, v2, k3, v3); + return (Map) methodHandle.invokeExact(k1, v1, k2, v2, k3, v3); } catch (Throwable e) { return of(k1, v1, k2, v2, k3, v3); } @@ -243,11 +259,15 @@ public static Map ofMap(K k1, V v1, K k2, V v2, K k3, V v3) { @Nonnull @Immutable public static Map ofMap(K k1, V v1, K k2, V v2, K k3, V v3, K k4, V v4) { - if (of4MethodHandle == null) { + return ofMap4(of4MethodHandle, k1, v1, k2, v2, k3, v3, k4, v4); + } + + static Map ofMap4(MethodHandle methodHandle, K k1, V v1, K k2, V v2, K k3, V v3, K k4, V v4) { + if (methodHandle == null) { return of(k1, v1, k2, v2, k3, v3, k4, v4); } try { - return (Map) of4MethodHandle.invokeExact(k1, v1, k2, v2, k3, v3, k4, v4); + return (Map) methodHandle.invokeExact(k1, v1, k2, v2, k3, v3, k4, v4); } catch (Throwable e) { return of(k1, v1, k2, v2, k3, v3, k4, v4); } @@ -280,11 +300,15 @@ public static Map ofMap(K k1, V v1, K k2, V v2, K k3, V v3, K k4, V @Nonnull @Immutable public static Map ofMap(K k1, V v1, K k2, V v2, K k3, V v3, K k4, V v4, K k5, V v5) { - if (of5MethodHandle == null) { + return ofMap5(of5MethodHandle, k1, v1, k2, v2, k3, v3, k4, v4, k5, v5); + } + + static Map ofMap5(MethodHandle methodHandle, K k1, V v1, K k2, V v2, K k3, V v3, K k4, V v4, K k5, V v5) { + if (methodHandle == null) { return of(k1, v1, k2, v2, k3, v3, k4, v4, k5, v5); } try { - return (Map) of5MethodHandle.invokeExact(k1, v1, k2, v2, k3, v3, k4, v4, k5, v5); + return (Map) methodHandle.invokeExact(k1, v1, k2, v2, k3, v3, k4, v4, k5, v5); } catch (Throwable e) { return of(k1, v1, k2, v2, k3, v3, k4, v4, k5, v5); } @@ -319,11 +343,15 @@ public static Map ofMap(K k1, V v1, K k2, V v2, K k3, V v3, K k4, V @Nonnull @Immutable public static Map ofMap(K k1, V v1, K k2, V v2, K k3, V v3, K k4, V v4, K k5, V v5, K k6, V v6) { - if (of6MethodHandle == null) { + return ofMap6(of6MethodHandle, k1, v1, k2, v2, k3, v3, k4, v4, k5, v5, k6, v6); + } + + static Map ofMap6(MethodHandle methodHandle, K k1, V v1, K k2, V v2, K k3, V v3, K k4, V v4, K k5, V v5, K k6, V v6) { + if (methodHandle == null) { return of(k1, v1, k2, v2, k3, v3, k4, v4, k5, v5, k6, v6); } try { - return (Map) of6MethodHandle.invokeExact(k1, v1, k2, v2, k3, v3, k4, v4, k5, v5, k6, v6); + return (Map) methodHandle.invokeExact(k1, v1, k2, v2, k3, v3, k4, v4, k5, v5, k6, v6); } catch (Throwable e) { return of(k1, v1, k2, v2, k3, v3, k4, v4, k5, v5, k6, v6); } @@ -361,11 +389,15 @@ public static Map ofMap(K k1, V v1, K k2, V v2, K k3, V v3, K k4, V @Nonnull @Immutable public static Map ofMap(K k1, V v1, K k2, V v2, K k3, V v3, K k4, V v4, K k5, V v5, K k6, V v6, K k7, V v7) { - if (of7MethodHandle == null) { + return ofMap7(of7MethodHandle, k1, v1, k2, v2, k3, v3, k4, v4, k5, v5, k6, v6, k7, v7); + } + + static Map ofMap7(MethodHandle methodHandle, K k1, V v1, K k2, V v2, K k3, V v3, K k4, V v4, K k5, V v5, K k6, V v6, K k7, V v7) { + if (methodHandle == null) { return of(k1, v1, k2, v2, k3, v3, k4, v4, k5, v5, k6, v6, k7, v7); } try { - return (Map) of7MethodHandle.invokeExact(k1, v1, k2, v2, k3, v3, k4, v4, k5, v5, k6, v6, k7, v7); + return (Map) methodHandle.invokeExact(k1, v1, k2, v2, k3, v3, k4, v4, k5, v5, k6, v6, k7, v7); } catch (Throwable e) { return of(k1, v1, k2, v2, k3, v3, k4, v4, k5, v5, k6, v6, k7, v7); } @@ -406,11 +438,16 @@ public static Map ofMap(K k1, V v1, K k2, V v2, K k3, V v3, K k4, V @Immutable public static Map ofMap(K k1, V v1, K k2, V v2, K k3, V v3, K k4, V v4, K k5, V v5, K k6, V v6, K k7, V v7, K k8, V v8) { - if (of8MethodHandle == null) { + return ofMap8(of8MethodHandle, k1, v1, k2, v2, k3, v3, k4, v4, k5, v5, k6, v6, k7, v7, k8, v8); + } + + static Map ofMap8(MethodHandle methodHandle, K k1, V v1, K k2, V v2, K k3, V v3, K k4, V v4, K k5, V v5, K k6, V v6, K k7, V v7, + K k8, V v8) { + if (methodHandle == null) { return of(k1, v1, k2, v2, k3, v3, k4, v4, k5, v5, k6, v6, k7, v7, k8, v8); } try { - return (Map) of8MethodHandle.invokeExact(k1, v1, k2, v2, k3, v3, k4, v4, k5, v5, k6, v6, k7, v7, k8, v8); + return (Map) methodHandle.invokeExact(k1, v1, k2, v2, k3, v3, k4, v4, k5, v5, k6, v6, k7, v7, k8, v8); } catch (Throwable e) { return of(k1, v1, k2, v2, k3, v3, k4, v4, k5, v5, k6, v6, k7, v7, k8, v8); } @@ -453,11 +490,16 @@ public static Map ofMap(K k1, V v1, K k2, V v2, K k3, V v3, K k4, V @Immutable public static Map ofMap(K k1, V v1, K k2, V v2, K k3, V v3, K k4, V v4, K k5, V v5, K k6, V v6, K k7, V v7, K k8, V v8, K k9, V v9) { - if (of9MethodHandle == null) { + return ofMap9(of9MethodHandle, k1, v1, k2, v2, k3, v3, k4, v4, k5, v5, k6, v6, k7, v7, k8, v8, k9, v9); + } + + static Map ofMap9(MethodHandle methodHandle, K k1, V v1, K k2, V v2, K k3, V v3, K k4, V v4, K k5, V v5, K k6, V v6, K k7, V v7, + K k8, V v8, K k9, V v9) { + if (methodHandle == null) { return of(k1, v1, k2, v2, k3, v3, k4, v4, k5, v5, k6, v6, k7, v7, k8, v8, k9, v9); } try { - return (Map) of9MethodHandle.invokeExact(k1, v1, k2, v2, k3, v3, k4, v4, k5, v5, k6, v6, k7, v7, k8, v8, k9, v9); + return (Map) methodHandle.invokeExact(k1, v1, k2, v2, k3, v3, k4, v4, k5, v5, k6, v6, k7, v7, k8, v8, k9, v9); } catch (Throwable e) { return of(k1, v1, k2, v2, k3, v3, k4, v4, k5, v5, k6, v6, k7, v7, k8, v8, k9, v9); } @@ -503,11 +545,16 @@ public static Map ofMap(K k1, V v1, K k2, V v2, K k3, V v3, K k4, V @Immutable public static Map ofMap(K k1, V v1, K k2, V v2, K k3, V v3, K k4, V v4, K k5, V v5, K k6, V v6, K k7, V v7, K k8, V v8, K k9, V v9, K k10, V v10) { - if (of10MethodHandle == null) { + return ofMap10(of10MethodHandle, k1, v1, k2, v2, k3, v3, k4, v4, k5, v5, k6, v6, k7, v7, k8, v8, k9, v9, k10, v10); + } + + static Map ofMap10(MethodHandle methodHandle, K k1, V v1, K k2, V v2, K k3, V v3, K k4, V v4, K k5, V v5, K k6, V v6, K k7, V v7, + K k8, V v8, K k9, V v9, K k10, V v10) { + if (methodHandle == null) { return of(k1, v1, k2, v2, k3, v3, k4, v4, k5, v5, k6, v6, k7, v7, k8, v8, k9, v9, k10, v10); } try { - return (Map) of10MethodHandle.invokeExact(k1, v1, k2, v2, k3, v3, k4, v4, k5, v5, k6, v6, k7, v7, k8, v8, k9, v9, k10, v10); + return (Map) methodHandle.invokeExact(k1, v1, k2, v2, k3, v3, k4, v4, k5, v5, k6, v6, k7, v7, k8, v8, k9, v9, k10, v10); } catch (Throwable e) { return of(k1, v1, k2, v2, k3, v3, k4, v4, k5, v5, k6, v6, k7, v7, k8, v8, k9, v9, k10, v10); } @@ -539,11 +586,15 @@ public static Map ofMap(Map.Entry... entr if (length(entries) < 1) { return emptyMap(); } - if (ofEntriesMethodHandle == null) { + return ofMapEntries(ofEntriesMethodHandle, entries); + } + + static Map ofMapEntries(MethodHandle methodHandle, Map.Entry[] entries) { + if (methodHandle == null) { return of(entries); } try { - return (Map) ofEntriesMethodHandle.invokeExact(entries); + return (Map) methodHandle.invokeExact(entries); } catch (Throwable e) { return of(entries); } diff --git a/microsphere-java-core/src/main/java/io/microsphere/collection/Sets.java b/microsphere-java-core/src/main/java/io/microsphere/collection/Sets.java index 9c4891a43..f8effe0e5 100644 --- a/microsphere-java-core/src/main/java/io/microsphere/collection/Sets.java +++ b/microsphere-java-core/src/main/java/io/microsphere/collection/Sets.java @@ -119,11 +119,15 @@ public abstract class Sets implements Utils { @Nonnull @Immutable public static Set ofSet() { - if (of0MethodHandle == null) { + return ofSet0(of0MethodHandle); + } + + static Set ofSet0(MethodHandle methodHandle) { + if (methodHandle == null) { return emptySet(); } try { - return (Set) of0MethodHandle.invokeExact(); + return (Set) methodHandle.invokeExact(); } catch (Throwable e) { return emptySet(); } @@ -152,11 +156,15 @@ public static Set ofSet() { @Nonnull @Immutable public static Set ofSet(E e1) { - if (of1MethodHandle == null) { + return ofSet1(of1MethodHandle, e1); + } + + static Set ofSet1(MethodHandle methodHandle, E e1) { + if (methodHandle == null) { return singleton(e1); } try { - return (Set) of1MethodHandle.invokeExact(e1); + return (Set) methodHandle.invokeExact(e1); } catch (Throwable e) { return singleton(e1); } @@ -185,11 +193,15 @@ public static Set ofSet(E e1) { @Nonnull @Immutable public static Set ofSet(E e1, E e2) { - if (of2MethodHandle == null) { + return ofSet2(of2MethodHandle, e1, e2); + } + + static Set ofSet2(MethodHandle methodHandle, E e1, E e2) { + if (methodHandle == null) { return of(e1, e2); } try { - return (Set) of2MethodHandle.invokeExact(e1, e2); + return (Set) methodHandle.invokeExact(e1, e2); } catch (Throwable e) { return of(e1, e2); } @@ -219,11 +231,15 @@ public static Set ofSet(E e1, E e2) { @Nonnull @Immutable public static Set ofSet(E e1, E e2, E e3) { - if (of3MethodHandle == null) { + return ofSet3(of3MethodHandle, e1, e2, e3); + } + + static Set ofSet3(MethodHandle methodHandle, E e1, E e2, E e3) { + if (methodHandle == null) { return of(e1, e2, e3); } try { - return (Set) of3MethodHandle.invokeExact(e1, e2, e3); + return (Set) methodHandle.invokeExact(e1, e2, e3); } catch (Throwable e) { return of(e1, e2, e3); } @@ -254,11 +270,15 @@ public static Set ofSet(E e1, E e2, E e3) { @Nonnull @Immutable public static Set ofSet(E e1, E e2, E e3, E e4) { - if (of4MethodHandle == null) { + return ofSet4(of4MethodHandle, e1, e2, e3, e4); + } + + static Set ofSet4(MethodHandle methodHandle, E e1, E e2, E e3, E e4) { + if (methodHandle == null) { return of(e1, e2, e3, e4); } try { - return (Set) of4MethodHandle.invokeExact(e1, e2, e3, e4); + return (Set) methodHandle.invokeExact(e1, e2, e3, e4); } catch (Throwable e) { return of(e1, e2, e3, e4); } @@ -279,11 +299,15 @@ public static Set ofSet(E e1, E e2, E e3, E e4) { @Nonnull @Immutable public static Set ofSet(E e1, E e2, E e3, E e4, E e5) { - if (of5MethodHandle == null) { + return ofSet5(of5MethodHandle, e1, e2, e3, e4, e5); + } + + static Set ofSet5(MethodHandle methodHandle, E e1, E e2, E e3, E e4, E e5) { + if (methodHandle == null) { return of(e1, e2, e3, e4, e5); } try { - return (Set) of5MethodHandle.invokeExact(e1, e2, e3, e4, e5); + return (Set) methodHandle.invokeExact(e1, e2, e3, e4, e5); } catch (Throwable e) { return of(e1, e2, e3, e4, e5); } @@ -316,11 +340,15 @@ public static Set ofSet(E e1, E e2, E e3, E e4, E e5) { @Nonnull @Immutable public static Set ofSet(E e1, E e2, E e3, E e4, E e5, E e6) { - if (of6MethodHandle == null) { + return ofSet6(of6MethodHandle, e1, e2, e3, e4, e5, e6); + } + + static Set ofSet6(MethodHandle methodHandle, E e1, E e2, E e3, E e4, E e5, E e6) { + if (methodHandle == null) { return of(e1, e2, e3, e4, e5, e6); } try { - return (Set) of6MethodHandle.invokeExact(e1, e2, e3, e4, e5, e6); + return (Set) methodHandle.invokeExact(e1, e2, e3, e4, e5, e6); } catch (Throwable e) { return of(e1, e2, e3, e4, e5, e6); } @@ -354,11 +382,15 @@ public static Set ofSet(E e1, E e2, E e3, E e4, E e5, E e6) { @Nonnull @Immutable public static Set ofSet(E e1, E e2, E e3, E e4, E e5, E e6, E e7) { - if (of7MethodHandle == null) { + return ofSet7(of7MethodHandle, e1, e2, e3, e4, e5, e6, e7); + } + + static Set ofSet7(MethodHandle methodHandle, E e1, E e2, E e3, E e4, E e5, E e6, E e7) { + if (methodHandle == null) { return of(e1, e2, e3, e4, e5, e6, e7); } try { - return (Set) of7MethodHandle.invokeExact(e1, e2, e3, e4, e5, e6, e7); + return (Set) methodHandle.invokeExact(e1, e2, e3, e4, e5, e6, e7); } catch (Throwable e) { return of(e1, e2, e3, e4, e5, e6, e7); } @@ -393,11 +425,15 @@ public static Set ofSet(E e1, E e2, E e3, E e4, E e5, E e6, E e7) { @Nonnull @Immutable public static Set ofSet(E e1, E e2, E e3, E e4, E e5, E e6, E e7, E e8) { - if (of8MethodHandle == null) { + return ofSet8(of8MethodHandle, e1, e2, e3, e4, e5, e6, e7, e8); + } + + static Set ofSet8(MethodHandle methodHandle, E e1, E e2, E e3, E e4, E e5, E e6, E e7, E e8) { + if (methodHandle == null) { return of(e1, e2, e3, e4, e5, e6, e7, e8); } try { - return (Set) of8MethodHandle.invokeExact(e1, e2, e3, e4, e5, e6, e7, e8); + return (Set) methodHandle.invokeExact(e1, e2, e3, e4, e5, e6, e7, e8); } catch (Throwable e) { return of(e1, e2, e3, e4, e5, e6, e7, e8); } @@ -433,11 +469,15 @@ public static Set ofSet(E e1, E e2, E e3, E e4, E e5, E e6, E e7, E e8) { @Nonnull @Immutable public static Set ofSet(E e1, E e2, E e3, E e4, E e5, E e6, E e7, E e8, E e9) { - if (of9MethodHandle == null) { + return ofSet9(of9MethodHandle, e1, e2, e3, e4, e5, e6, e7, e8, e9); + } + + static Set ofSet9(MethodHandle methodHandle, E e1, E e2, E e3, E e4, E e5, E e6, E e7, E e8, E e9) { + if (methodHandle == null) { return of(e1, e2, e3, e4, e5, e6, e7, e8, e9); } try { - return (Set) of9MethodHandle.invokeExact(e1, e2, e3, e4, e5, e6, e7, e8, e9); + return (Set) methodHandle.invokeExact(e1, e2, e3, e4, e5, e6, e7, e8, e9); } catch (Throwable e) { return of(e1, e2, e3, e4, e5, e6, e7, e8, e9); } @@ -474,11 +514,15 @@ public static Set ofSet(E e1, E e2, E e3, E e4, E e5, E e6, E e7, E e8, E @Nonnull @Immutable public static Set ofSet(E e1, E e2, E e3, E e4, E e5, E e6, E e7, E e8, E e9, E e10) { - if (of10MethodHandle == null) { + return ofSet10(of10MethodHandle, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10); + } + + static Set ofSet10(MethodHandle methodHandle, E e1, E e2, E e3, E e4, E e5, E e6, E e7, E e8, E e9, E e10) { + if (methodHandle == null) { return of(e1, e2, e3, e4, e5, e6, e7, e8, e9, e10); } try { - return (Set) of10MethodHandle.invokeExact(e1, e2, e3, e4, e5, e6, e7, e8, e9, e10); + return (Set) methodHandle.invokeExact(e1, e2, e3, e4, e5, e6, e7, e8, e9, e10); } catch (Throwable e) { return of(e1, e2, e3, e4, e5, e6, e7, e8, e9, e10); } @@ -509,11 +553,15 @@ public static Set ofSet(E... elements) { if (length(elements) < 1) { return ofSet(); } - if (ofMethodHandle == null) { + return ofSetElements(ofMethodHandle, elements); + } + + static Set ofSetElements(MethodHandle methodHandle, E[] elements) { + if (methodHandle == null) { return of(elements); } try { - return (Set) ofMethodHandle.invokeExact(elements); + return (Set) methodHandle.invokeExact(elements); } catch (Throwable e) { return of(elements); } diff --git a/microsphere-java-core/src/test/java/io/microsphere/collection/ListsTest.java b/microsphere-java-core/src/test/java/io/microsphere/collection/ListsTest.java index 375751aeb..298d06b5a 100644 --- a/microsphere-java-core/src/test/java/io/microsphere/collection/ListsTest.java +++ b/microsphere-java-core/src/test/java/io/microsphere/collection/ListsTest.java @@ -2,10 +2,26 @@ import org.junit.jupiter.api.Test; +import java.lang.invoke.MethodHandle; + import static io.microsphere.AbstractTestCase.TEST_NULL_OBJECT_ARRAY; import static io.microsphere.collection.ListUtils.of; import static io.microsphere.collection.Lists.ofList; +import static io.microsphere.collection.Lists.ofList0; +import static io.microsphere.collection.Lists.ofList1; +import static io.microsphere.collection.Lists.ofList2; +import static io.microsphere.collection.Lists.ofList3; +import static io.microsphere.collection.Lists.ofList4; +import static io.microsphere.collection.Lists.ofList5; +import static io.microsphere.collection.Lists.ofList6; +import static io.microsphere.collection.Lists.ofList7; +import static io.microsphere.collection.Lists.ofList8; +import static io.microsphere.collection.Lists.ofList9; +import static io.microsphere.collection.Lists.ofList10; +import static io.microsphere.collection.Lists.ofListElements; +import static io.microsphere.invoke.MethodHandlesLookupUtils.findPublicStatic; import static java.util.Collections.emptyList; +import static java.util.Collections.singletonList; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertThrows; @@ -86,4 +102,138 @@ void testOfListImmutability() { assertThrows(UnsupportedOperationException.class, () -> ofList(1, 2).remove(0)); assertThrows(UnsupportedOperationException.class, () -> ofList(1, 2, 3).clear()); } + + @Test + void testOfList0WithNull() { + assertEquals(emptyList(), ofList0(null)); + } + + @Test + void testOfList0WithWrongMethodHandle() { + MethodHandle wrongMethodHandle = findPublicStatic(java.util.Collections.class, "emptyList"); + assertEquals(emptyList(), ofList0(wrongMethodHandle)); + } + + @Test + void testOfList1WithNull() { + assertEquals(singletonList(1), ofList1(null, 1)); + } + + @Test + void testOfList1WithWrongMethodHandle() { + MethodHandle wrongMethodHandle = findPublicStatic(java.util.Collections.class, "emptyList"); + assertEquals(singletonList(1), ofList1(wrongMethodHandle, 1)); + } + + @Test + void testOfList2WithNull() { + assertEquals(of(1, 2), ofList2(null, 1, 2)); + } + + @Test + void testOfList2WithWrongMethodHandle() { + MethodHandle wrongMethodHandle = findPublicStatic(java.util.Collections.class, "emptyList"); + assertEquals(of(1, 2), ofList2(wrongMethodHandle, 1, 2)); + } + + @Test + void testOfList3WithNull() { + assertEquals(of(1, 2, 3), ofList3(null, 1, 2, 3)); + } + + @Test + void testOfList3WithWrongMethodHandle() { + MethodHandle wrongMethodHandle = findPublicStatic(java.util.Collections.class, "emptyList"); + assertEquals(of(1, 2, 3), ofList3(wrongMethodHandle, 1, 2, 3)); + } + + @Test + void testOfList4WithNull() { + assertEquals(of(1, 2, 3, 4), ofList4(null, 1, 2, 3, 4)); + } + + @Test + void testOfList4WithWrongMethodHandle() { + MethodHandle wrongMethodHandle = findPublicStatic(java.util.Collections.class, "emptyList"); + assertEquals(of(1, 2, 3, 4), ofList4(wrongMethodHandle, 1, 2, 3, 4)); + } + + @Test + void testOfList5WithNull() { + assertEquals(of(1, 2, 3, 4, 5), ofList5(null, 1, 2, 3, 4, 5)); + } + + @Test + void testOfList5WithWrongMethodHandle() { + MethodHandle wrongMethodHandle = findPublicStatic(java.util.Collections.class, "emptyList"); + assertEquals(of(1, 2, 3, 4, 5), ofList5(wrongMethodHandle, 1, 2, 3, 4, 5)); + } + + @Test + void testOfList6WithNull() { + assertEquals(of(1, 2, 3, 4, 5, 6), ofList6(null, 1, 2, 3, 4, 5, 6)); + } + + @Test + void testOfList6WithWrongMethodHandle() { + MethodHandle wrongMethodHandle = findPublicStatic(java.util.Collections.class, "emptyList"); + assertEquals(of(1, 2, 3, 4, 5, 6), ofList6(wrongMethodHandle, 1, 2, 3, 4, 5, 6)); + } + + @Test + void testOfList7WithNull() { + assertEquals(of(1, 2, 3, 4, 5, 6, 7), ofList7(null, 1, 2, 3, 4, 5, 6, 7)); + } + + @Test + void testOfList7WithWrongMethodHandle() { + MethodHandle wrongMethodHandle = findPublicStatic(java.util.Collections.class, "emptyList"); + assertEquals(of(1, 2, 3, 4, 5, 6, 7), ofList7(wrongMethodHandle, 1, 2, 3, 4, 5, 6, 7)); + } + + @Test + void testOfList8WithNull() { + assertEquals(of(1, 2, 3, 4, 5, 6, 7, 8), ofList8(null, 1, 2, 3, 4, 5, 6, 7, 8)); + } + + @Test + void testOfList8WithWrongMethodHandle() { + MethodHandle wrongMethodHandle = findPublicStatic(java.util.Collections.class, "emptyList"); + assertEquals(of(1, 2, 3, 4, 5, 6, 7, 8), ofList8(wrongMethodHandle, 1, 2, 3, 4, 5, 6, 7, 8)); + } + + @Test + void testOfList9WithNull() { + assertEquals(of(1, 2, 3, 4, 5, 6, 7, 8, 9), ofList9(null, 1, 2, 3, 4, 5, 6, 7, 8, 9)); + } + + @Test + void testOfList9WithWrongMethodHandle() { + MethodHandle wrongMethodHandle = findPublicStatic(java.util.Collections.class, "emptyList"); + assertEquals(of(1, 2, 3, 4, 5, 6, 7, 8, 9), ofList9(wrongMethodHandle, 1, 2, 3, 4, 5, 6, 7, 8, 9)); + } + + @Test + void testOfList10WithNull() { + assertEquals(of(1, 2, 3, 4, 5, 6, 7, 8, 9, 10), ofList10(null, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10)); + } + + @Test + void testOfList10WithWrongMethodHandle() { + MethodHandle wrongMethodHandle = findPublicStatic(java.util.Collections.class, "emptyList"); + assertEquals(of(1, 2, 3, 4, 5, 6, 7, 8, 9, 10), ofList10(wrongMethodHandle, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10)); + } + + @Test + void testOfListElementsWithNull() { + Integer[] elements = {1, 2, 3}; + assertEquals(of(elements), ofListElements(null, elements)); + } + + @Test + void testOfListElementsWithWrongMethodHandle() { + MethodHandle wrongMethodHandle = findPublicStatic(java.util.Collections.class, "emptyList"); + Integer[] elements = {1, 2, 3}; + assertEquals(of(elements), ofListElements(wrongMethodHandle, elements)); + } } \ No newline at end of file diff --git a/microsphere-java-core/src/test/java/io/microsphere/collection/MapsTest.java b/microsphere-java-core/src/test/java/io/microsphere/collection/MapsTest.java index 0ec9c6c59..325159209 100644 --- a/microsphere-java-core/src/test/java/io/microsphere/collection/MapsTest.java +++ b/microsphere-java-core/src/test/java/io/microsphere/collection/MapsTest.java @@ -2,12 +2,27 @@ import org.junit.jupiter.api.Test; +import java.lang.invoke.MethodHandle; import java.util.Map; import static io.microsphere.collection.MapUtils.ofEntry; import static io.microsphere.collection.MapUtilsTest.assertOfMap; import static io.microsphere.collection.Maps.ofMap; +import static io.microsphere.collection.Maps.ofMap0; +import static io.microsphere.collection.Maps.ofMap1; +import static io.microsphere.collection.Maps.ofMap2; +import static io.microsphere.collection.Maps.ofMap3; +import static io.microsphere.collection.Maps.ofMap4; +import static io.microsphere.collection.Maps.ofMap5; +import static io.microsphere.collection.Maps.ofMap6; +import static io.microsphere.collection.Maps.ofMap7; +import static io.microsphere.collection.Maps.ofMap8; +import static io.microsphere.collection.Maps.ofMap9; +import static io.microsphere.collection.Maps.ofMap10; +import static io.microsphere.collection.Maps.ofMapEntries; +import static io.microsphere.invoke.MethodHandlesLookupUtils.findPublicStatic; import static java.util.Collections.emptyMap; +import static java.util.Collections.singletonMap; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertNull; import static org.junit.jupiter.api.Assertions.assertSame; @@ -205,4 +220,168 @@ void testOfMapImmutability() { assertThrows(UnsupportedOperationException.class, () -> ofMap("A", 1, "B", 2).remove("A")); assertThrows(UnsupportedOperationException.class, () -> ofMap("A", 1, "B", 2, "C", 3).clear()); } + + @Test + void testOfMap0WithNull() { + assertEquals(emptyMap(), ofMap0(null)); + } + + @Test + void testOfMap0WithWrongMethodHandle() { + MethodHandle wrongMethodHandle = findPublicStatic(java.util.Collections.class, "emptyMap"); + assertEquals(emptyMap(), ofMap0(wrongMethodHandle)); + } + + @Test + void testOfMap1WithNull() { + assertEquals(singletonMap("A", 1), ofMap1(null, "A", 1)); + } + + @Test + void testOfMap1WithWrongMethodHandle() { + MethodHandle wrongMethodHandle = findPublicStatic(java.util.Collections.class, "emptyMap"); + assertEquals(singletonMap("A", 1), ofMap1(wrongMethodHandle, "A", 1)); + } + + @Test + void testOfMap2WithNull() { + Map map = ofMap2(null, "A", 1, "B", 2); + assertEquals(2, map.size()); + assertEquals(1, map.get("A")); + assertEquals(2, map.get("B")); + } + + @Test + void testOfMap2WithWrongMethodHandle() { + MethodHandle wrongMethodHandle = findPublicStatic(java.util.Collections.class, "emptyMap"); + Map map = ofMap2(wrongMethodHandle, "A", 1, "B", 2); + assertEquals(2, map.size()); + assertEquals(1, map.get("A")); + assertEquals(2, map.get("B")); + } + + @Test + void testOfMap3WithNull() { + Map map = ofMap3(null, "A", 1, "B", 2, "C", 3); + assertEquals(3, map.size()); + } + + @Test + void testOfMap3WithWrongMethodHandle() { + MethodHandle wrongMethodHandle = findPublicStatic(java.util.Collections.class, "emptyMap"); + Map map = ofMap3(wrongMethodHandle, "A", 1, "B", 2, "C", 3); + assertEquals(3, map.size()); + } + + @Test + void testOfMap4WithNull() { + Map map = ofMap4(null, "A", 1, "B", 2, "C", 3, "D", 4); + assertEquals(4, map.size()); + } + + @Test + void testOfMap4WithWrongMethodHandle() { + MethodHandle wrongMethodHandle = findPublicStatic(java.util.Collections.class, "emptyMap"); + Map map = ofMap4(wrongMethodHandle, "A", 1, "B", 2, "C", 3, "D", 4); + assertEquals(4, map.size()); + } + + @Test + void testOfMap5WithNull() { + Map map = ofMap5(null, "A", 1, "B", 2, "C", 3, "D", 4, "E", 5); + assertEquals(5, map.size()); + } + + @Test + void testOfMap5WithWrongMethodHandle() { + MethodHandle wrongMethodHandle = findPublicStatic(java.util.Collections.class, "emptyMap"); + Map map = ofMap5(wrongMethodHandle, "A", 1, "B", 2, "C", 3, "D", 4, "E", 5); + assertEquals(5, map.size()); + } + + @Test + void testOfMap6WithNull() { + Map map = ofMap6(null, "A", 1, "B", 2, "C", 3, "D", 4, "E", 5, "F", 6); + assertEquals(6, map.size()); + } + + @Test + void testOfMap6WithWrongMethodHandle() { + MethodHandle wrongMethodHandle = findPublicStatic(java.util.Collections.class, "emptyMap"); + Map map = ofMap6(wrongMethodHandle, "A", 1, "B", 2, "C", 3, "D", 4, "E", 5, "F", 6); + assertEquals(6, map.size()); + } + + @Test + void testOfMap7WithNull() { + Map map = ofMap7(null, "A", 1, "B", 2, "C", 3, "D", 4, "E", 5, "F", 6, "G", 7); + assertEquals(7, map.size()); + } + + @Test + void testOfMap7WithWrongMethodHandle() { + MethodHandle wrongMethodHandle = findPublicStatic(java.util.Collections.class, "emptyMap"); + Map map = ofMap7(wrongMethodHandle, "A", 1, "B", 2, "C", 3, "D", 4, "E", 5, "F", 6, "G", 7); + assertEquals(7, map.size()); + } + + @Test + void testOfMap8WithNull() { + Map map = ofMap8(null, "A", 1, "B", 2, "C", 3, "D", 4, "E", 5, "F", 6, "G", 7, "H", 8); + assertEquals(8, map.size()); + } + + @Test + void testOfMap8WithWrongMethodHandle() { + MethodHandle wrongMethodHandle = findPublicStatic(java.util.Collections.class, "emptyMap"); + Map map = ofMap8(wrongMethodHandle, "A", 1, "B", 2, "C", 3, "D", 4, "E", 5, "F", 6, "G", 7, "H", 8); + assertEquals(8, map.size()); + } + + @Test + void testOfMap9WithNull() { + Map map = ofMap9(null, "A", 1, "B", 2, "C", 3, "D", 4, "E", 5, "F", 6, "G", 7, "H", 8, "I", 9); + assertEquals(9, map.size()); + } + + @Test + void testOfMap9WithWrongMethodHandle() { + MethodHandle wrongMethodHandle = findPublicStatic(java.util.Collections.class, "emptyMap"); + Map map = ofMap9(wrongMethodHandle, "A", 1, "B", 2, "C", 3, "D", 4, "E", 5, "F", 6, "G", 7, "H", 8, "I", 9); + assertEquals(9, map.size()); + } + + @Test + void testOfMap10WithNull() { + Map map = ofMap10(null, "A", 1, "B", 2, "C", 3, "D", 4, "E", 5, "F", 6, "G", 7, "H", 8, "I", 9, "J", 10); + assertEquals(10, map.size()); + } + + @Test + void testOfMap10WithWrongMethodHandle() { + MethodHandle wrongMethodHandle = findPublicStatic(java.util.Collections.class, "emptyMap"); + Map map = ofMap10(wrongMethodHandle, "A", 1, "B", 2, "C", 3, "D", 4, "E", 5, "F", 6, "G", 7, "H", 8, "I", 9, "J", 10); + assertEquals(10, map.size()); + } + + @Test + void testOfMapEntriesWithNull() { + Map.Entry entryA = ofEntry("A", 1); + Map.Entry entryB = ofEntry("B", 2); + Map map = ofMapEntries(null, new Map.Entry[]{entryA, entryB}); + assertEquals(2, map.size()); + assertEquals(1, map.get("A")); + assertEquals(2, map.get("B")); + } + + @Test + void testOfMapEntriesWithWrongMethodHandle() { + MethodHandle wrongMethodHandle = findPublicStatic(java.util.Collections.class, "emptyMap"); + Map.Entry entryA = ofEntry("A", 1); + Map.Entry entryB = ofEntry("B", 2); + Map map = ofMapEntries(wrongMethodHandle, new Map.Entry[]{entryA, entryB}); + assertEquals(2, map.size()); + assertEquals(1, map.get("A")); + assertEquals(2, map.get("B")); + } } \ No newline at end of file diff --git a/microsphere-java-core/src/test/java/io/microsphere/collection/SetsTest.java b/microsphere-java-core/src/test/java/io/microsphere/collection/SetsTest.java index 521663ae2..f718e84e8 100644 --- a/microsphere-java-core/src/test/java/io/microsphere/collection/SetsTest.java +++ b/microsphere-java-core/src/test/java/io/microsphere/collection/SetsTest.java @@ -2,10 +2,26 @@ import org.junit.jupiter.api.Test; +import java.lang.invoke.MethodHandle; + import static io.microsphere.AbstractTestCase.TEST_NULL_OBJECT_ARRAY; import static io.microsphere.collection.SetUtils.of; import static io.microsphere.collection.Sets.ofSet; +import static io.microsphere.collection.Sets.ofSet0; +import static io.microsphere.collection.Sets.ofSet1; +import static io.microsphere.collection.Sets.ofSet2; +import static io.microsphere.collection.Sets.ofSet3; +import static io.microsphere.collection.Sets.ofSet4; +import static io.microsphere.collection.Sets.ofSet5; +import static io.microsphere.collection.Sets.ofSet6; +import static io.microsphere.collection.Sets.ofSet7; +import static io.microsphere.collection.Sets.ofSet8; +import static io.microsphere.collection.Sets.ofSet9; +import static io.microsphere.collection.Sets.ofSet10; +import static io.microsphere.collection.Sets.ofSetElements; +import static io.microsphere.invoke.MethodHandlesLookupUtils.findPublicStatic; import static java.util.Collections.emptySet; +import static java.util.Collections.singleton; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertThrows; @@ -86,4 +102,138 @@ void testOfSetImmutability() { assertThrows(UnsupportedOperationException.class, () -> ofSet(1, 2).remove(1)); assertThrows(UnsupportedOperationException.class, () -> ofSet(1, 2, 3).clear()); } + + @Test + void testOfSet0WithNull() { + assertEquals(emptySet(), ofSet0(null)); + } + + @Test + void testOfSet0WithWrongMethodHandle() { + MethodHandle wrongMethodHandle = findPublicStatic(java.util.Collections.class, "emptySet"); + assertEquals(emptySet(), ofSet0(wrongMethodHandle)); + } + + @Test + void testOfSet1WithNull() { + assertEquals(singleton(1), ofSet1(null, 1)); + } + + @Test + void testOfSet1WithWrongMethodHandle() { + MethodHandle wrongMethodHandle = findPublicStatic(java.util.Collections.class, "emptySet"); + assertEquals(singleton(1), ofSet1(wrongMethodHandle, 1)); + } + + @Test + void testOfSet2WithNull() { + assertEquals(of(1, 2), ofSet2(null, 1, 2)); + } + + @Test + void testOfSet2WithWrongMethodHandle() { + MethodHandle wrongMethodHandle = findPublicStatic(java.util.Collections.class, "emptySet"); + assertEquals(of(1, 2), ofSet2(wrongMethodHandle, 1, 2)); + } + + @Test + void testOfSet3WithNull() { + assertEquals(of(1, 2, 3), ofSet3(null, 1, 2, 3)); + } + + @Test + void testOfSet3WithWrongMethodHandle() { + MethodHandle wrongMethodHandle = findPublicStatic(java.util.Collections.class, "emptySet"); + assertEquals(of(1, 2, 3), ofSet3(wrongMethodHandle, 1, 2, 3)); + } + + @Test + void testOfSet4WithNull() { + assertEquals(of(1, 2, 3, 4), ofSet4(null, 1, 2, 3, 4)); + } + + @Test + void testOfSet4WithWrongMethodHandle() { + MethodHandle wrongMethodHandle = findPublicStatic(java.util.Collections.class, "emptySet"); + assertEquals(of(1, 2, 3, 4), ofSet4(wrongMethodHandle, 1, 2, 3, 4)); + } + + @Test + void testOfSet5WithNull() { + assertEquals(of(1, 2, 3, 4, 5), ofSet5(null, 1, 2, 3, 4, 5)); + } + + @Test + void testOfSet5WithWrongMethodHandle() { + MethodHandle wrongMethodHandle = findPublicStatic(java.util.Collections.class, "emptySet"); + assertEquals(of(1, 2, 3, 4, 5), ofSet5(wrongMethodHandle, 1, 2, 3, 4, 5)); + } + + @Test + void testOfSet6WithNull() { + assertEquals(of(1, 2, 3, 4, 5, 6), ofSet6(null, 1, 2, 3, 4, 5, 6)); + } + + @Test + void testOfSet6WithWrongMethodHandle() { + MethodHandle wrongMethodHandle = findPublicStatic(java.util.Collections.class, "emptySet"); + assertEquals(of(1, 2, 3, 4, 5, 6), ofSet6(wrongMethodHandle, 1, 2, 3, 4, 5, 6)); + } + + @Test + void testOfSet7WithNull() { + assertEquals(of(1, 2, 3, 4, 5, 6, 7), ofSet7(null, 1, 2, 3, 4, 5, 6, 7)); + } + + @Test + void testOfSet7WithWrongMethodHandle() { + MethodHandle wrongMethodHandle = findPublicStatic(java.util.Collections.class, "emptySet"); + assertEquals(of(1, 2, 3, 4, 5, 6, 7), ofSet7(wrongMethodHandle, 1, 2, 3, 4, 5, 6, 7)); + } + + @Test + void testOfSet8WithNull() { + assertEquals(of(1, 2, 3, 4, 5, 6, 7, 8), ofSet8(null, 1, 2, 3, 4, 5, 6, 7, 8)); + } + + @Test + void testOfSet8WithWrongMethodHandle() { + MethodHandle wrongMethodHandle = findPublicStatic(java.util.Collections.class, "emptySet"); + assertEquals(of(1, 2, 3, 4, 5, 6, 7, 8), ofSet8(wrongMethodHandle, 1, 2, 3, 4, 5, 6, 7, 8)); + } + + @Test + void testOfSet9WithNull() { + assertEquals(of(1, 2, 3, 4, 5, 6, 7, 8, 9), ofSet9(null, 1, 2, 3, 4, 5, 6, 7, 8, 9)); + } + + @Test + void testOfSet9WithWrongMethodHandle() { + MethodHandle wrongMethodHandle = findPublicStatic(java.util.Collections.class, "emptySet"); + assertEquals(of(1, 2, 3, 4, 5, 6, 7, 8, 9), ofSet9(wrongMethodHandle, 1, 2, 3, 4, 5, 6, 7, 8, 9)); + } + + @Test + void testOfSet10WithNull() { + assertEquals(of(1, 2, 3, 4, 5, 6, 7, 8, 9, 10), ofSet10(null, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10)); + } + + @Test + void testOfSet10WithWrongMethodHandle() { + MethodHandle wrongMethodHandle = findPublicStatic(java.util.Collections.class, "emptySet"); + assertEquals(of(1, 2, 3, 4, 5, 6, 7, 8, 9, 10), ofSet10(wrongMethodHandle, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10)); + } + + @Test + void testOfSetElementsWithNull() { + Integer[] elements = {1, 2, 3}; + assertEquals(of(elements), ofSetElements(null, elements)); + } + + @Test + void testOfSetElementsWithWrongMethodHandle() { + MethodHandle wrongMethodHandle = findPublicStatic(java.util.Collections.class, "emptySet"); + Integer[] elements = {1, 2, 3}; + assertEquals(of(elements), ofSetElements(wrongMethodHandle, elements)); + } } \ No newline at end of file