Skip to content

Commit

Permalink
Create properties for record accessors (#2161)
Browse files Browse the repository at this point in the history
Consider record accessor methods as similar to getters so that we create
object properties for them.
  • Loading branch information
Azquelt authored Jan 17, 2025
1 parent 339efd3 commit cd0537b
Show file tree
Hide file tree
Showing 3 changed files with 126 additions and 1 deletion.
Original file line number Diff line number Diff line change
Expand Up @@ -1027,7 +1027,8 @@ static String propertyName(Map<String, TypeResolver> properties, MethodInfo meth
/**
* Returns whether a method follows the Java bean convention for an accessor
* method (getter). The method name typically begins with "get", but may also
* begin with "is" when the return type is boolean.
* begin with "is" when the return type is boolean. Record component accessor
* methods are also accessors.
*
* @param method the method to check
* @return true if the method is a Java bean getter, otherwise false
Expand All @@ -1037,6 +1038,11 @@ private static boolean isAccessor(AnnotationScannerContext context, MethodInfo m
return false;
}

ClassInfo clazz = method.declaringClass();
if (clazz.isRecord() && clazz.recordComponent(method.name()) != null) {
return true;
}

String namePrefix = methodNamePrefix(method);

if (METHOD_PREFIX_GET.equals(namePrefix)) {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
package io.smallrye.openapi.testdata;

import static java.util.Collections.emptyMap;
import static java.util.Collections.singletonMap;

import java.io.IOException;
import java.io.InputStreamReader;
import java.io.Reader;
import java.net.URL;
import java.nio.charset.StandardCharsets;
import java.util.Map;

import org.eclipse.microprofile.config.Config;
import org.eclipse.microprofile.config.spi.ConfigSource;
import org.eclipse.microprofile.openapi.annotations.media.Schema;
import org.jboss.jandex.Index;
import org.jboss.logging.Logger;
import org.json.JSONException;
import org.junit.jupiter.api.Test;
import org.skyscreamer.jsonassert.JSONAssert;
import org.skyscreamer.jsonassert.JSONCompareMode;

import io.smallrye.config.PropertiesConfigSource;
import io.smallrye.config.SmallRyeConfigBuilder;
import io.smallrye.openapi.api.SmallRyeOASConfig;
import io.smallrye.openapi.api.SmallRyeOpenAPI;

/**
* These tests can be moved to StandaloneSchemaScanTest once those tests are changed to compile with Java 17
*/
public class RecordSchemaTest {

private static final Logger LOG = Logger.getLogger(RecordSchemaTest.class);

@Schema
record TestRecord(String a,
@Schema(description = "b") String b) {
}

@Test
void testRecordSchema() throws IOException, JSONException {

Index index = Index.of(TestRecord.class);

String result = SmallRyeOpenAPI.builder()
.defaultRequiredProperties(false)
.withIndex(index)
.withConfig(config(emptyMap()))
.build()
.toJSON();

LOG.debug(result);
assertJsonEquals("components.schemas.record.json", result);
}

@Test
void testRecordSchemaNoPrivateFields() throws IOException, JSONException {

Index index = Index.of(TestRecord.class);

String result = SmallRyeOpenAPI.builder()
.defaultRequiredProperties(false)
.withIndex(index)
.withConfig(config(singletonMap(
SmallRyeOASConfig.SMALLRYE_PRIVATE_PROPERTIES_ENABLE,
"false")))
.build()
.toJSON();

LOG.debug(result);
assertJsonEquals("components.schemas.record.json", result);
}

private void assertJsonEquals(String expectedResource, String result) throws IOException, JSONException {
String expected = loadResource(RecordSchemaTest.class.getResource(expectedResource));
JSONAssert.assertEquals(expected, result, JSONCompareMode.STRICT);
}

public static String loadResource(URL testResource) throws IOException {
final char[] buffer = new char[8192];
final StringBuilder result = new StringBuilder();

try (Reader reader = new InputStreamReader(testResource.openStream(), StandardCharsets.UTF_8)) {
int count;
while ((count = reader.read(buffer, 0, buffer.length)) > 0) {
result.append(buffer, 0, count);
}
}

return result.toString();
}

private static Config config(Map<String, String> properties) {
return new SmallRyeConfigBuilder()
.addDefaultSources()
.withSources(new PropertiesConfigSource(properties, "unit-test", ConfigSource.DEFAULT_ORDINAL))
.build();
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
{
"openapi" : "3.1.0",
"components" : {
"schemas" : {
"TestRecord" : {
"type" : "object",
"properties" : {
"a" : {
"type" : "string"
},
"b" : {
"type" : "string",
"description" : "b"
}
}
}
}
}
}

0 comments on commit cd0537b

Please sign in to comment.