Skip to content

Commit cd0537b

Browse files
authored
Create properties for record accessors (#2161)
Consider record accessor methods as similar to getters so that we create object properties for them.
1 parent 339efd3 commit cd0537b

File tree

3 files changed

+126
-1
lines changed

3 files changed

+126
-1
lines changed

core/src/main/java/io/smallrye/openapi/runtime/scanner/dataobject/TypeResolver.java

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1027,7 +1027,8 @@ static String propertyName(Map<String, TypeResolver> properties, MethodInfo meth
10271027
/**
10281028
* Returns whether a method follows the Java bean convention for an accessor
10291029
* method (getter). The method name typically begins with "get", but may also
1030-
* begin with "is" when the return type is boolean.
1030+
* begin with "is" when the return type is boolean. Record component accessor
1031+
* methods are also accessors.
10311032
*
10321033
* @param method the method to check
10331034
* @return true if the method is a Java bean getter, otherwise false
@@ -1037,6 +1038,11 @@ private static boolean isAccessor(AnnotationScannerContext context, MethodInfo m
10371038
return false;
10381039
}
10391040

1041+
ClassInfo clazz = method.declaringClass();
1042+
if (clazz.isRecord() && clazz.recordComponent(method.name()) != null) {
1043+
return true;
1044+
}
1045+
10401046
String namePrefix = methodNamePrefix(method);
10411047

10421048
if (METHOD_PREFIX_GET.equals(namePrefix)) {
Lines changed: 100 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,100 @@
1+
package io.smallrye.openapi.testdata;
2+
3+
import static java.util.Collections.emptyMap;
4+
import static java.util.Collections.singletonMap;
5+
6+
import java.io.IOException;
7+
import java.io.InputStreamReader;
8+
import java.io.Reader;
9+
import java.net.URL;
10+
import java.nio.charset.StandardCharsets;
11+
import java.util.Map;
12+
13+
import org.eclipse.microprofile.config.Config;
14+
import org.eclipse.microprofile.config.spi.ConfigSource;
15+
import org.eclipse.microprofile.openapi.annotations.media.Schema;
16+
import org.jboss.jandex.Index;
17+
import org.jboss.logging.Logger;
18+
import org.json.JSONException;
19+
import org.junit.jupiter.api.Test;
20+
import org.skyscreamer.jsonassert.JSONAssert;
21+
import org.skyscreamer.jsonassert.JSONCompareMode;
22+
23+
import io.smallrye.config.PropertiesConfigSource;
24+
import io.smallrye.config.SmallRyeConfigBuilder;
25+
import io.smallrye.openapi.api.SmallRyeOASConfig;
26+
import io.smallrye.openapi.api.SmallRyeOpenAPI;
27+
28+
/**
29+
* These tests can be moved to StandaloneSchemaScanTest once those tests are changed to compile with Java 17
30+
*/
31+
public class RecordSchemaTest {
32+
33+
private static final Logger LOG = Logger.getLogger(RecordSchemaTest.class);
34+
35+
@Schema
36+
record TestRecord(String a,
37+
@Schema(description = "b") String b) {
38+
}
39+
40+
@Test
41+
void testRecordSchema() throws IOException, JSONException {
42+
43+
Index index = Index.of(TestRecord.class);
44+
45+
String result = SmallRyeOpenAPI.builder()
46+
.defaultRequiredProperties(false)
47+
.withIndex(index)
48+
.withConfig(config(emptyMap()))
49+
.build()
50+
.toJSON();
51+
52+
LOG.debug(result);
53+
assertJsonEquals("components.schemas.record.json", result);
54+
}
55+
56+
@Test
57+
void testRecordSchemaNoPrivateFields() throws IOException, JSONException {
58+
59+
Index index = Index.of(TestRecord.class);
60+
61+
String result = SmallRyeOpenAPI.builder()
62+
.defaultRequiredProperties(false)
63+
.withIndex(index)
64+
.withConfig(config(singletonMap(
65+
SmallRyeOASConfig.SMALLRYE_PRIVATE_PROPERTIES_ENABLE,
66+
"false")))
67+
.build()
68+
.toJSON();
69+
70+
LOG.debug(result);
71+
assertJsonEquals("components.schemas.record.json", result);
72+
}
73+
74+
private void assertJsonEquals(String expectedResource, String result) throws IOException, JSONException {
75+
String expected = loadResource(RecordSchemaTest.class.getResource(expectedResource));
76+
JSONAssert.assertEquals(expected, result, JSONCompareMode.STRICT);
77+
}
78+
79+
public static String loadResource(URL testResource) throws IOException {
80+
final char[] buffer = new char[8192];
81+
final StringBuilder result = new StringBuilder();
82+
83+
try (Reader reader = new InputStreamReader(testResource.openStream(), StandardCharsets.UTF_8)) {
84+
int count;
85+
while ((count = reader.read(buffer, 0, buffer.length)) > 0) {
86+
result.append(buffer, 0, count);
87+
}
88+
}
89+
90+
return result.toString();
91+
}
92+
93+
private static Config config(Map<String, String> properties) {
94+
return new SmallRyeConfigBuilder()
95+
.addDefaultSources()
96+
.withSources(new PropertiesConfigSource(properties, "unit-test", ConfigSource.DEFAULT_ORDINAL))
97+
.build();
98+
}
99+
100+
}
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
{
2+
"openapi" : "3.1.0",
3+
"components" : {
4+
"schemas" : {
5+
"TestRecord" : {
6+
"type" : "object",
7+
"properties" : {
8+
"a" : {
9+
"type" : "string"
10+
},
11+
"b" : {
12+
"type" : "string",
13+
"description" : "b"
14+
}
15+
}
16+
}
17+
}
18+
}
19+
}

0 commit comments

Comments
 (0)