diff --git a/spring-grpc-core/src/main/java/org/springframework/grpc/client/GrpcClientFactory.java b/spring-grpc-core/src/main/java/org/springframework/grpc/client/GrpcClientFactory.java index ea552709..e0807c7c 100644 --- a/spring-grpc-core/src/main/java/org/springframework/grpc/client/GrpcClientFactory.java +++ b/spring-grpc-core/src/main/java/org/springframework/grpc/client/GrpcClientFactory.java @@ -325,11 +325,8 @@ public GrpcClientRegistrationSpec packages(String... packages) { public GrpcClientRegistrationSpec packageClasses(Class... packageClasses) { String[] packages = new String[packageClasses.length]; - for (Class basePackageClass : packageClasses) { - for (int i = 0; i < packageClasses.length; i++) { - String basePackage = ClassUtils.getPackageName(basePackageClass); - packages[i] = basePackage; - } + for (int i = 0; i < packageClasses.length; i++) { + packages[i] = ClassUtils.getPackageName(packageClasses[i]); } return packages(packages); } diff --git a/spring-grpc-core/src/test/java/org/springframework/grpc/client/GrpcClientFactoryTests.java b/spring-grpc-core/src/test/java/org/springframework/grpc/client/GrpcClientFactoryTests.java index 95291bb1..293659b1 100644 --- a/spring-grpc-core/src/test/java/org/springframework/grpc/client/GrpcClientFactoryTests.java +++ b/spring-grpc-core/src/test/java/org/springframework/grpc/client/GrpcClientFactoryTests.java @@ -21,6 +21,8 @@ import java.util.function.Supplier; +import org.assertj.core.api.InstanceOfAssertFactories; +import org.junit.jupiter.api.Nested; import org.junit.jupiter.api.Test; import org.mockito.Mockito; @@ -30,6 +32,9 @@ import org.springframework.context.support.StaticApplicationContext; import org.springframework.grpc.client.GrpcClientFactory.GrpcClientRegistrationSpec; import org.springframework.grpc.client.GrpcClientFactoryTests.MyProto.MyStub; +import org.springframework.grpc.client.bar.Bar; +import org.springframework.grpc.client.foo.ExtraFoo; +import org.springframework.grpc.client.foo.Foo; import io.grpc.CallOptions; import io.grpc.Channel; @@ -37,7 +42,7 @@ import io.grpc.kotlin.AbstractCoroutineStub; import io.grpc.stub.AbstractStub; -public class GrpcClientFactoryTests { +class GrpcClientFactoryTests { private GrpcChannelFactory channelFactory = Mockito.mock(GrpcChannelFactory.class); @@ -114,6 +119,42 @@ void testCoroutineStubFactoryAfterDefault() { assertThat(factory.getClient("local", MyStub.class, null)).isNotNull(); } + @Nested // GH-361 + class GrpcClientRegistrationSpecPackageClassesShould { + + private GrpcClientRegistrationSpec spec = GrpcClientRegistrationSpec.of("local"); + + @Test + void returnSinglePackageGivenSingleClass() { + assertThat(spec.packageClasses(Foo.class)).extracting(GrpcClientRegistrationSpec::packages) + .asInstanceOf(InstanceOfAssertFactories.array(String[].class)) + .containsExactly("org.springframework.grpc.client.foo"); + } + + @Test + void returnSinglePackageGivenMultipleClassesInSamePackage() { + assertThat(spec.packageClasses(Foo.class, ExtraFoo.class)).extracting(GrpcClientRegistrationSpec::packages) + .asInstanceOf(InstanceOfAssertFactories.array(String[].class)) + .containsExactly("org.springframework.grpc.client.foo"); + } + + @Test + void returnMultiPackagesGivenMultipleClassesInDifferentPackage() { + assertThat(spec.packageClasses(Foo.class, Bar.class)).extracting(GrpcClientRegistrationSpec::packages) + .asInstanceOf(InstanceOfAssertFactories.array(String[].class)) + .containsExactly("org.springframework.grpc.client.foo", "org.springframework.grpc.client.bar"); + } + + @Test + void returnMultiPackagesGivenMultipleClassesInSameAndDifferentPackage() { + assertThat(spec.packageClasses(Foo.class, Bar.class, ExtraFoo.class)) + .extracting(GrpcClientRegistrationSpec::packages) + .asInstanceOf(InstanceOfAssertFactories.array(String[].class)) + .containsExactly("org.springframework.grpc.client.foo", "org.springframework.grpc.client.bar"); + } + + } + static class OtherStubFactory implements StubFactory { @Override diff --git a/spring-grpc-core/src/test/java/org/springframework/grpc/client/bar/Bar.java b/spring-grpc-core/src/test/java/org/springframework/grpc/client/bar/Bar.java new file mode 100644 index 00000000..9d0f318b --- /dev/null +++ b/spring-grpc-core/src/test/java/org/springframework/grpc/client/bar/Bar.java @@ -0,0 +1,26 @@ +/* + * Copyright 2026-present the original author or authors. + * + * Licensed 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 + * + * https://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.springframework.grpc.client.bar; + +/** + * Simple test record used to help test {@code GrpcClientRegistrationSpec} in + * {@code GrpcClientFactoryTests}. + * + * @param msg some context that can be used to differentiate instances + */ +public record Bar(String msg) { +} diff --git a/spring-grpc-core/src/test/java/org/springframework/grpc/client/foo/ExtraFoo.java b/spring-grpc-core/src/test/java/org/springframework/grpc/client/foo/ExtraFoo.java new file mode 100644 index 00000000..5e87abf6 --- /dev/null +++ b/spring-grpc-core/src/test/java/org/springframework/grpc/client/foo/ExtraFoo.java @@ -0,0 +1,26 @@ +/* + * Copyright 2026-present the original author or authors. + * + * Licensed 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 + * + * https://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.springframework.grpc.client.foo; + +/** + * Simple test record used to help test {@code GrpcClientRegistrationSpec} in + * {@code GrpcClientFactoryTests}. + * + * @param msg some context that can be used to differentiate instances + */ +public record ExtraFoo(String msg) { +} diff --git a/spring-grpc-core/src/test/java/org/springframework/grpc/client/foo/Foo.java b/spring-grpc-core/src/test/java/org/springframework/grpc/client/foo/Foo.java new file mode 100644 index 00000000..16de75b9 --- /dev/null +++ b/spring-grpc-core/src/test/java/org/springframework/grpc/client/foo/Foo.java @@ -0,0 +1,26 @@ +/* + * Copyright 2026-present the original author or authors. + * + * Licensed 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 + * + * https://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.springframework.grpc.client.foo; + +/** + * Simple test record used to help test {@code GrpcClientRegistrationSpec} in + * {@code GrpcClientFactoryTests}. + * + * @param msg some context that can be used to differentiate instances + */ +public record Foo(String msg) { +} diff --git a/src/checkstyle/checkstyle-suppressions.xml b/src/checkstyle/checkstyle-suppressions.xml index b1b406d7..3e064991 100644 --- a/src/checkstyle/checkstyle-suppressions.xml +++ b/src/checkstyle/checkstyle-suppressions.xml @@ -8,7 +8,8 @@ - + +