This is an automated email from the ASF dual-hosted git repository.

Aias00 pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/shenyu.git


The following commit(s) were added to refs/heads/master by this push:
     new 1bc544c196 test(task#5161): improve test coverage for matcher in 
shenyu-client-core (#7030)
1bc544c196 is described below

commit 1bc544c196c4a109380214ec577e3e9f1edfb347
Author: Sf331 <[email protected]>
AuthorDate: Fri Sep 4 20:57:39 2026 +0800

    test(task#5161): improve test coverage for matcher in shenyu-client-core 
(#7030)
    
    Signed-off-by: SF331 <[email protected]>
    Co-authored-by: aias00 <[email protected]>
---
 .../matcher/AnnotatedApiBeanMatcherTest.java       |  84 ++++++++++++++++
 .../matcher/AnnotatedApiDefinitionMatcherTest.java |  90 +++++++++++++++++
 .../register/matcher/ExtractorProcessorTest.java   |  60 +++++++++++
 .../client/core/register/matcher/MatcherTest.java  | 112 +++++++++++++++++++++
 4 files changed, 346 insertions(+)

diff --git 
a/shenyu-client/shenyu-client-core/src/test/java/org/apache/shenyu/client/core/register/matcher/AnnotatedApiBeanMatcherTest.java
 
b/shenyu-client/shenyu-client-core/src/test/java/org/apache/shenyu/client/core/register/matcher/AnnotatedApiBeanMatcherTest.java
new file mode 100644
index 0000000000..4f9a0ce43c
--- /dev/null
+++ 
b/shenyu-client/shenyu-client-core/src/test/java/org/apache/shenyu/client/core/register/matcher/AnnotatedApiBeanMatcherTest.java
@@ -0,0 +1,84 @@
+/*
+ * 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 org.apache.shenyu.client.core.register.matcher;
+
+import org.apache.shenyu.client.core.register.ApiBean;
+import org.junit.jupiter.api.Test;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+import java.util.Collections;
+
+import static org.junit.jupiter.api.Assertions.assertFalse;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+
+public class AnnotatedApiBeanMatcherTest {
+
+    @Test
+    public void testMatchAnnotatedBean() {
+        ApiBean apiBean = new ApiBean("test", "annotatedBean", new 
AnnotatedService());
+        AnnotatedApiBeanMatcher matcher = new 
AnnotatedApiBeanMatcher(BeanMarker.class);
+        assertTrue(matcher.match(apiBean));
+    }
+
+    @Test
+    public void testMatchPlainBean() {
+        ApiBean apiBean = new ApiBean("test", "plainBean", new PlainService());
+        AnnotatedApiBeanMatcher matcher = new 
AnnotatedApiBeanMatcher(BeanMarker.class);
+        assertFalse(matcher.match(apiBean));
+    }
+
+    @Test
+    public void testMatchDoesNotConsiderInheritedAnnotations() {
+        ApiBean apiBean = new ApiBean("test", "inheritedBean", new 
InheritedService());
+        AnnotatedApiBeanMatcher matcher = new 
AnnotatedApiBeanMatcher(BeanMarker.class);
+        assertFalse(matcher.match(apiBean),
+                "isAnnotationDeclaredLocally should not match annotations 
inherited from a superclass");
+    }
+
+    @Test
+    public void testMatchOtherAnnotation() {
+        ApiBean apiBean = new ApiBean("test", "annotatedBean", new 
AnnotatedService());
+        AnnotatedApiBeanMatcher matcher = new 
AnnotatedApiBeanMatcher(Deprecated.class);
+        assertFalse(matcher.match(apiBean));
+    }
+
+    @Test
+    public void testMatchWithEmptyApiDefinitions() {
+        ApiBean apiBean = new ApiBean("test", "annotatedBean", new 
AnnotatedService(), Collections.emptyList());
+        AnnotatedApiBeanMatcher matcher = new 
AnnotatedApiBeanMatcher(BeanMarker.class);
+        assertTrue(matcher.match(apiBean));
+    }
+
+    @Retention(RetentionPolicy.RUNTIME)
+    @Target(ElementType.TYPE)
+    @interface BeanMarker {
+    }
+
+    @BeanMarker
+    static class AnnotatedService {
+    }
+
+    static class PlainService {
+    }
+
+    static class InheritedService extends AnnotatedService {
+    }
+}
diff --git 
a/shenyu-client/shenyu-client-core/src/test/java/org/apache/shenyu/client/core/register/matcher/AnnotatedApiDefinitionMatcherTest.java
 
b/shenyu-client/shenyu-client-core/src/test/java/org/apache/shenyu/client/core/register/matcher/AnnotatedApiDefinitionMatcherTest.java
new file mode 100644
index 0000000000..40ff40b38e
--- /dev/null
+++ 
b/shenyu-client/shenyu-client-core/src/test/java/org/apache/shenyu/client/core/register/matcher/AnnotatedApiDefinitionMatcherTest.java
@@ -0,0 +1,90 @@
+/*
+ * 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 org.apache.shenyu.client.core.register.matcher;
+
+import org.apache.shenyu.client.core.register.ApiBean;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+import java.lang.reflect.Method;
+
+import static org.junit.jupiter.api.Assertions.assertFalse;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+
+public class AnnotatedApiDefinitionMatcherTest {
+
+    private ApiBean apiBean;
+
+    @BeforeEach
+    public void setUp() {
+        apiBean = new ApiBean("test", "serviceBean", new Service());
+    }
+
+    private ApiBean.ApiDefinition apiDefinitionOf(final String methodName) 
throws NoSuchMethodException {
+        Method method = Service.class.getDeclaredMethod(methodName);
+        return new ApiBean.ApiDefinition(method);
+    }
+
+    @Test
+    public void testMatchAnnotatedMethod() throws NoSuchMethodException {
+        AnnotatedApiDefinitionMatcher matcher = new 
AnnotatedApiDefinitionMatcher(ApiMarker.class);
+        assertTrue(matcher.match(apiDefinitionOf("annotatedMethod")));
+    }
+
+    @Test
+    public void testMatchPlainMethod() throws NoSuchMethodException {
+        AnnotatedApiDefinitionMatcher matcher = new 
AnnotatedApiDefinitionMatcher(ApiMarker.class);
+        assertFalse(matcher.match(apiDefinitionOf("plainMethod")));
+    }
+
+    @Test
+    public void testMatchOtherAnnotation() throws NoSuchMethodException {
+        AnnotatedApiDefinitionMatcher matcher = new 
AnnotatedApiDefinitionMatcher(Deprecated.class);
+        assertFalse(matcher.match(apiDefinitionOf("annotatedMethod")));
+    }
+
+    @Test
+    public void testMatchApiDefinitionFromApiBean() throws 
NoSuchMethodException {
+        
apiBean.addApiDefinition(Service.class.getDeclaredMethod("annotatedMethod"), 
"/annotated");
+        
apiBean.addApiDefinition(Service.class.getDeclaredMethod("plainMethod"), 
"/plain");
+
+        AnnotatedApiDefinitionMatcher matcher = new 
AnnotatedApiDefinitionMatcher(ApiMarker.class);
+
+        assertTrue(matcher.match(apiBean.getApiDefinitions().get(0)));
+        assertFalse(matcher.match(apiBean.getApiDefinitions().get(1)));
+    }
+
+    @Retention(RetentionPolicy.RUNTIME)
+    @Target(ElementType.METHOD)
+    @interface ApiMarker {
+    }
+
+    static class Service {
+
+        @ApiMarker
+        public void annotatedMethod() {
+        }
+
+        public void plainMethod() {
+        }
+    }
+}
diff --git 
a/shenyu-client/shenyu-client-core/src/test/java/org/apache/shenyu/client/core/register/matcher/ExtractorProcessorTest.java
 
b/shenyu-client/shenyu-client-core/src/test/java/org/apache/shenyu/client/core/register/matcher/ExtractorProcessorTest.java
new file mode 100644
index 0000000000..35dc2255b2
--- /dev/null
+++ 
b/shenyu-client/shenyu-client-core/src/test/java/org/apache/shenyu/client/core/register/matcher/ExtractorProcessorTest.java
@@ -0,0 +1,60 @@
+/*
+ * 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 org.apache.shenyu.client.core.register.matcher;
+
+import org.apache.shenyu.client.core.register.ApiBean;
+import org.apache.shenyu.common.enums.RpcTypeEnum;
+import org.junit.jupiter.api.Test;
+
+import java.util.Arrays;
+import java.util.List;
+import java.util.stream.Collectors;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertNotNull;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+
+public class ExtractorProcessorTest {
+
+    private final ExtractorProcessor extractorProcessor = new 
ExtractorProcessor() {
+
+        @Override
+        public void process(final ApiBean apiBean) {
+        }
+
+        @Override
+        public void process(final ApiBean.ApiDefinition apiDefinition) {
+        }
+    };
+
+    @Test
+    public void testSupportedClientContainsAllRpcTypes() {
+        List<String> expected = Arrays.stream(RpcTypeEnum.values())
+                .map(RpcTypeEnum::getName)
+                .collect(Collectors.toList());
+        List<String> actual = extractorProcessor.supportedClient();
+        assertEquals(expected, actual);
+    }
+
+    @Test
+    public void testSupportedClientNotEmpty() {
+        List<String> supportedClient = extractorProcessor.supportedClient();
+        assertNotNull(supportedClient);
+        assertTrue(supportedClient.contains(RpcTypeEnum.HTTP.getName()));
+    }
+}
diff --git 
a/shenyu-client/shenyu-client-core/src/test/java/org/apache/shenyu/client/core/register/matcher/MatcherTest.java
 
b/shenyu-client/shenyu-client-core/src/test/java/org/apache/shenyu/client/core/register/matcher/MatcherTest.java
new file mode 100644
index 0000000000..61551d2e7a
--- /dev/null
+++ 
b/shenyu-client/shenyu-client-core/src/test/java/org/apache/shenyu/client/core/register/matcher/MatcherTest.java
@@ -0,0 +1,112 @@
+/*
+ * 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 org.apache.shenyu.client.core.register.matcher;
+
+import org.junit.jupiter.api.Test;
+
+import java.util.concurrent.atomic.AtomicInteger;
+
+import static org.junit.jupiter.api.Assertions.assertFalse;
+import static org.junit.jupiter.api.Assertions.assertNotNull;
+import static org.junit.jupiter.api.Assertions.assertThrows;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+
+public class MatcherTest {
+
+    @Test
+    public void testMatch() {
+        Matcher<String> matcher = s -> s.startsWith("shen");
+        assertTrue(matcher.match("shenyu"));
+        assertFalse(matcher.match("apache"));
+    }
+
+    @Test
+    public void testAnd() {
+        Matcher<String> startsWithShen = s -> s.startsWith("shen");
+        Matcher<String> endsWithYu = s -> s.endsWith("yu");
+        assertTrue(startsWithShen.and(endsWithYu).match("shenyu"));
+        assertFalse(startsWithShen.and(endsWithYu).match("shenyu-java"));
+        assertFalse(startsWithShen.and(endsWithYu).match("apache-yu"));
+    }
+
+    @Test
+    public void testAndShortCircuit() {
+        AtomicInteger evaluations = new AtomicInteger();
+        Matcher<String> first = s -> false;
+        Matcher<String> second = s -> {
+            evaluations.incrementAndGet();
+            return true;
+        };
+        assertFalse(first.and(second).match("shenyu"));
+        assertTrue(evaluations.get() == 0, "second matcher should not be 
evaluated when first is false");
+    }
+
+    @Test
+    public void testOr() {
+        Matcher<String> startsWithShen = s -> s.startsWith("shen");
+        Matcher<String> endsWithYu = s -> s.endsWith("yu");
+        assertTrue(startsWithShen.or(endsWithYu).match("shenyu-java"));
+        assertTrue(startsWithShen.or(endsWithYu).match("apache-yu"));
+        assertFalse(startsWithShen.or(endsWithYu).match("apache"));
+    }
+
+    @Test
+    public void testOrShortCircuit() {
+        AtomicInteger evaluations = new AtomicInteger();
+        Matcher<String> first = s -> true;
+        Matcher<String> second = s -> {
+            evaluations.incrementAndGet();
+            return true;
+        };
+        assertTrue(first.or(second).match("shenyu"));
+        assertTrue(evaluations.get() == 0, "second matcher should not be 
evaluated when first is true");
+    }
+
+    @Test
+    public void testNegate() {
+        Matcher<String> matcher = s -> s.isEmpty();
+        assertFalse(matcher.negate().match(""));
+        assertTrue(matcher.negate().match("shenyu"));
+    }
+
+    @Test
+    public void testNot() {
+        Matcher<String> matcher = s -> s.isEmpty();
+        Matcher<String> not = Matcher.not(matcher);
+        assertNotNull(not);
+        assertFalse(not.match(""));
+        assertTrue(not.match("shenyu"));
+    }
+
+    @Test
+    public void testAndWithNullThrowsNpe() {
+        Matcher<String> matcher = s -> true;
+        assertThrows(NullPointerException.class, () -> matcher.and(null));
+    }
+
+    @Test
+    public void testOrWithNullThrowsNpe() {
+        Matcher<String> matcher = s -> true;
+        assertThrows(NullPointerException.class, () -> matcher.or(null));
+    }
+
+    @Test
+    public void testNotWithNullThrowsNpe() {
+        assertThrows(NullPointerException.class, () -> Matcher.not(null));
+    }
+}

Reply via email to