Skip to content

Commit 8a8ebbe

Browse files
authored
Apply @CheckReturnValue to Assert implementations (#7038)
* Apply @CheckReturnValue to Assert implementations Signed-off-by: Johnny Lim <[email protected]> * Add ArchUnit tests This commit also changes Assert implementations to comply with the rules. Signed-off-by: Johnny Lim <[email protected]> * Use @CanIgnoreReturnValue for exceptional cases This commit also updates ArchUnit tests to cover them. Signed-off-by: Johnny Lim <[email protected]> --------- Signed-off-by: Johnny Lim <[email protected]>
1 parent 4b5ff0e commit 8a8ebbe

File tree

12 files changed

+164
-0
lines changed

12 files changed

+164
-0
lines changed

micrometer-observation-test/build.gradle

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,4 +12,5 @@ dependencies {
1212
implementation('org.mockito:mockito-core:4.11.0')
1313

1414
testImplementation libs.awaitility
15+
testImplementation libs.archunitJunit5
1516
}

micrometer-observation-test/src/main/java/io/micrometer/observation/tck/ObservationContextAssert.java

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
import io.micrometer.common.KeyValues;
2020
import io.micrometer.observation.Observation;
2121
import io.micrometer.observation.ObservationView;
22+
import org.assertj.core.annotation.CheckReturnValue;
2223
import org.assertj.core.api.AbstractAssert;
2324
import org.assertj.core.api.AbstractThrowableAssert;
2425
import org.assertj.core.api.ThrowingConsumer;
@@ -55,6 +56,7 @@ protected ObservationContextAssert(Observation.ContextView actual) {
5556
* @param actual context to assert against
5657
* @return Observation assertions
5758
*/
59+
@CheckReturnValue
5860
public static ObservationContextAssert<?> assertThat(Observation.ContextView actual) {
5961
return new ObservationContextAssert<>(actual);
6062
}
@@ -64,6 +66,7 @@ public static ObservationContextAssert<?> assertThat(Observation.ContextView act
6466
* @param actual context to assert against
6567
* @return Observation assertions
6668
*/
69+
@CheckReturnValue
6770
public static ObservationContextAssert<?> then(Observation.ContextView actual) {
6871
return new ObservationContextAssert<>(actual);
6972
}
@@ -426,10 +429,12 @@ public SELF hasError(Throwable expectedError) {
426429
return (SELF) this;
427430
}
428431

432+
@CheckReturnValue
429433
public ObservationContextAssertReturningThrowableAssert assertThatError() {
430434
return new ObservationContextAssertReturningThrowableAssert(actual.getError(), this);
431435
}
432436

437+
@CheckReturnValue
433438
public ObservationContextAssertReturningThrowableAssert thenError() {
434439
return assertThatError();
435440
}
@@ -551,6 +556,7 @@ public ObservationContextAssertReturningThrowableAssert(@Nullable Throwable thro
551556
this.observationContextAssert = observationContextAssert;
552557
}
553558

559+
@CheckReturnValue
554560
public ObservationContextAssert backToContext() {
555561
return this.observationContextAssert;
556562
}

micrometer-observation-test/src/main/java/io/micrometer/observation/tck/ObservationRegistryAssert.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717

1818
import io.micrometer.observation.Observation;
1919
import io.micrometer.observation.ObservationRegistry;
20+
import org.assertj.core.annotation.CheckReturnValue;
2021
import org.assertj.core.api.AbstractAssert;
2122

2223
/**
@@ -46,6 +47,7 @@ protected ObservationRegistryAssert(ACTUAL actual, Class<SELF> clazz) {
4647
* @param actual observation registry to assert against
4748
* @return meter registry assertions
4849
*/
50+
@CheckReturnValue
4951
public static ObservationRegistryAssert assertThat(ObservationRegistry actual) {
5052
return new ObservationRegistryAssert(actual);
5153
}
@@ -55,6 +57,7 @@ public static ObservationRegistryAssert assertThat(ObservationRegistry actual) {
5557
* @param actual observation registry to assert against
5658
* @return meter registry assertions
5759
*/
60+
@CheckReturnValue
5861
public static ObservationRegistryAssert then(ObservationRegistry actual) {
5962
return new ObservationRegistryAssert(actual);
6063
}

micrometer-observation-test/src/main/java/io/micrometer/observation/tck/TestObservationRegistryAssert.java

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,8 @@
1818
import io.micrometer.common.KeyValue;
1919
import io.micrometer.common.docs.KeyName;
2020
import io.micrometer.observation.Observation;
21+
import org.assertj.core.annotation.CanIgnoreReturnValue;
22+
import org.assertj.core.annotation.CheckReturnValue;
2123
import org.assertj.core.api.ThrowingConsumer;
2224
import org.jspecify.annotations.Nullable;
2325

@@ -67,6 +69,7 @@ public static TestObservationRegistryAssert then(TestObservationRegistry actual)
6769
* @return this
6870
* @throws AssertionError if there is none or more than one observation
6971
*/
72+
@CheckReturnValue
7073
public TestObservationRegistryAssertReturningObservationContextAssert hasSingleObservationThat() {
7174
Queue<TestObservationRegistry.TestObservationContext> contexts = actual.getContexts();
7275
if (contexts.isEmpty()) {
@@ -91,6 +94,7 @@ private void failForNoObservations() {
9194
* @return this
9295
* @throws AssertionError if there is no matching observation
9396
*/
97+
@CanIgnoreReturnValue
9498
public That hasObservationWithNameEqualTo(@Nullable String name) {
9599
Queue<TestObservationRegistry.TestObservationContext> contexts = this.actual.getContexts();
96100
if (contexts.isEmpty()) {
@@ -121,6 +125,7 @@ private String observations() {
121125
* @return this
122126
* @throws AssertionError if there is no matching observation
123127
*/
128+
@CanIgnoreReturnValue
124129
public That hasObservationWithNameEqualToIgnoringCase(String name) {
125130
Queue<TestObservationRegistry.TestObservationContext> contexts = this.actual.getContexts();
126131
if (contexts.isEmpty()) {
@@ -572,6 +577,7 @@ public TestObservationRegistryAssertReturningObservationContextAssert isNotStopp
572577
* Returns the original {@link TestObservationRegistryAssert} for chaining.
573578
* @return the original assertion for chaining
574579
*/
580+
@CheckReturnValue
575581
public TestObservationRegistryAssert backToTestObservationRegistry() {
576582
return this.originalAssert;
577583
}
Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
/*
2+
* Copyright 2026 VMware, Inc.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* https://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
package io.micrometer.observation.tck;
17+
18+
import com.tngtech.archunit.base.DescribedPredicate;
19+
import com.tngtech.archunit.core.domain.JavaMethod;
20+
import com.tngtech.archunit.core.domain.JavaModifier;
21+
import com.tngtech.archunit.junit.AnalyzeClasses;
22+
import com.tngtech.archunit.junit.ArchTest;
23+
import com.tngtech.archunit.lang.ArchRule;
24+
import com.tngtech.archunit.lang.syntax.ArchRuleDefinition;
25+
import org.assertj.core.annotation.CanIgnoreReturnValue;
26+
import org.assertj.core.annotation.CheckReturnValue;
27+
import org.assertj.core.api.Assert;
28+
29+
/**
30+
* Architecture tests for AssertJ.
31+
*
32+
* @author Stefano Cordio
33+
* @author Johnny Lim
34+
*/
35+
@AnalyzeClasses(packages = "io.micrometer")
36+
class AssertJArchitectureTests {
37+
38+
@ArchTest
39+
static final ArchRule allCustomAssertionMethodsNotReturningSelfShouldBeAnnotatedWithCheckReturnValue = ArchRuleDefinition
40+
.methods()
41+
.that()
42+
.areDeclaredInClassesThat()
43+
.implement(Assert.class)
44+
.and()
45+
.arePublic()
46+
.and()
47+
.doNotHaveRawReturnType(void.class)
48+
.and()
49+
.doNotHaveModifier(JavaModifier.BRIDGE)
50+
.and(doNotReturnSelfType())
51+
.and()
52+
.areNotAnnotatedWith(CanIgnoreReturnValue.class)
53+
.should()
54+
.beAnnotatedWith(CheckReturnValue.class)
55+
.allowEmptyShould(true);
56+
57+
private static DescribedPredicate<JavaMethod> doNotReturnSelfType() {
58+
return DescribedPredicate.describe("do not return self type",
59+
(method) -> !method.getRawReturnType().equals(method.getOwner()));
60+
}
61+
62+
}

micrometer-test/build.gradle

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,8 @@ dependencies {
2727
testImplementation project(':micrometer-jakarta9')
2828
testImplementation project(':micrometer-java11')
2929

30+
testImplementation libs.archunitJunit5
31+
3032
testImplementation libs.jsr107
3133

3234
// We have tests for the many features that are optional dependencies, so add

micrometer-test/src/main/java/io/micrometer/core/tck/MeterRegistryAssert.java

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
import io.micrometer.test.assertions.MeterAssert;
2222
import io.micrometer.test.assertions.TimerAssert;
2323
import io.micrometer.core.instrument.*;
24+
import org.assertj.core.annotation.CheckReturnValue;
2425
import org.assertj.core.api.AbstractAssert;
2526
import org.assertj.core.api.Assertions;
2627

@@ -49,6 +50,7 @@ protected MeterRegistryAssert(MeterRegistry actual) {
4950
* @param actual meter registry to assert against
5051
* @return meter registry assertions
5152
*/
53+
@CheckReturnValue
5254
public static MeterRegistryAssert assertThat(MeterRegistry actual) {
5355
return new MeterRegistryAssert(actual);
5456
}
@@ -58,6 +60,7 @@ public static MeterRegistryAssert assertThat(MeterRegistry actual) {
5860
* @param actual meter registry to assert against
5961
* @return meter registry assertions
6062
*/
63+
@CheckReturnValue
6164
public static MeterRegistryAssert then(MeterRegistry actual) {
6265
return new MeterRegistryAssert(actual);
6366
}
@@ -385,6 +388,7 @@ private String allMetrics() {
385388
* @return a {@link MeterAssert} for the found meter
386389
* @throws AssertionError if the meter is not found
387390
*/
391+
@CheckReturnValue
388392
public MeterAssert<?> meter(String meterName, Tag... tags) {
389393
return this.meter(meterName, Arrays.asList(tags));
390394
}
@@ -397,6 +401,7 @@ public MeterAssert<?> meter(String meterName, Tag... tags) {
397401
* @return a {@link MeterAssert} for the found meter
398402
* @throws AssertionError if the meter is not found
399403
*/
404+
@CheckReturnValue
400405
public MeterAssert<?> meter(String meterName, Iterable<Tag> tags) {
401406
hasMeterWithName(meterName);
402407
Meter meter = actual.find(meterName).tags(tags).meter();
@@ -424,6 +429,7 @@ public MeterAssert<?> meter(String meterName, Iterable<Tag> tags) {
424429
* @throws AssertionError if the counter is not found
425430
* @see CounterAssert
426431
*/
432+
@CheckReturnValue
427433
public CounterAssert counter(String name, Tag... tags) {
428434
MeterAssert<?> meter = meter(name, tags).hasType(Counter.class);
429435

@@ -453,6 +459,7 @@ public CounterAssert counter(String name, Tag... tags) {
453459
* @throws AssertionError if the timer is not found
454460
* @see TimerAssert
455461
*/
462+
@CheckReturnValue
456463
public TimerAssert timer(String name, Tag... tags) {
457464
MeterAssert<?> meter = meter(name, tags).hasType(Timer.class);
458465
return TimerAssert.assertThat((Timer) meter.actual())
@@ -479,6 +486,7 @@ public TimerAssert timer(String name, Tag... tags) {
479486
* @throws AssertionError if the gauge is not found
480487
* @see GaugeAssert
481488
*/
489+
@CheckReturnValue
482490
public GaugeAssert gauge(String name, Tag... tags) {
483491
MeterAssert<?> meter = meter(name, tags).hasType(Gauge.class);
484492
return GaugeAssert.assertThat((Gauge) meter.actual())

micrometer-test/src/main/java/io/micrometer/test/assertions/CounterAssert.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717

1818
import io.micrometer.core.instrument.Counter;
1919
import io.micrometer.core.instrument.Tag;
20+
import org.assertj.core.annotation.CheckReturnValue;
2021
import org.assertj.core.api.AbstractAssert;
2122
import org.assertj.core.api.IntegerAssert;
2223

@@ -37,6 +38,7 @@ public class CounterAssert extends AbstractAssert<CounterAssert, Counter> {
3738
* @param actual the counter to assert on
3839
* @return the created assertion object
3940
*/
41+
@CheckReturnValue
4042
public static CounterAssert assertThat(Counter actual) {
4143
return new CounterAssert(actual);
4244
}
@@ -78,6 +80,7 @@ public CounterAssert hasCount(int expected) {
7880
* @return an {@link IntegerAssert} for further assertions
7981
* @see #hasCount(int)
8082
*/
83+
@CheckReturnValue
8184
public IntegerAssert count() {
8285
return new IntegerAssert((int) actual.count());
8386
}

micrometer-test/src/main/java/io/micrometer/test/assertions/GaugeAssert.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717

1818
import io.micrometer.core.instrument.Gauge;
1919
import io.micrometer.core.instrument.Tag;
20+
import org.assertj.core.annotation.CheckReturnValue;
2021
import org.assertj.core.api.AbstractAssert;
2122
import org.assertj.core.api.DoubleAssert;
2223

@@ -36,6 +37,7 @@ public class GaugeAssert extends AbstractAssert<GaugeAssert, Gauge> {
3637
* @param actual the gauge to assert on
3738
* @return the created assertion object
3839
*/
40+
@CheckReturnValue
3941
public static GaugeAssert assertThat(Gauge actual) {
4042
return new GaugeAssert(actual);
4143
}
@@ -74,6 +76,7 @@ public GaugeAssert hasValue(double expected) {
7476
* @return a {@link DoubleAssert} for further assertions
7577
* @see #hasValue(double)
7678
*/
79+
@CheckReturnValue
7780
public DoubleAssert value() {
7881
return new DoubleAssert(actual.value());
7982
}

micrometer-test/src/main/java/io/micrometer/test/assertions/MeterAssert.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
import io.micrometer.core.instrument.Meter;
2020
import io.micrometer.core.instrument.Statistic;
2121
import io.micrometer.core.instrument.Tag;
22+
import org.assertj.core.annotation.CheckReturnValue;
2223
import org.assertj.core.api.AbstractAssert;
2324
import org.assertj.core.api.Assertions;
2425

@@ -50,6 +51,7 @@ public class MeterAssert<METER extends Meter> extends AbstractAssert<MeterAssert
5051
* @param <M> the meter type
5152
* @return the created assertion object
5253
*/
54+
@CheckReturnValue
5355
public static <M extends Meter> MeterAssert<M> assertThat(M actual) {
5456
return new MeterAssert<>(actual, MeterAssert.class);
5557
}

0 commit comments

Comments
 (0)