Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: Fixes description indenting #691

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
import io.github.springwolf.core.asyncapi.scanners.common.payload.PayloadClassExtractor;
import io.github.springwolf.core.asyncapi.scanners.common.utils.AnnotationScannerUtil;
import io.github.springwolf.core.asyncapi.scanners.common.utils.AsyncAnnotationUtil;
import io.github.springwolf.core.asyncapi.scanners.common.utils.TextUtils;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
Expand Down Expand Up @@ -67,6 +68,8 @@ protected Operation buildOperation(AsyncOperation asyncOperation, Method method,
String description = this.resolver.resolveStringValue(asyncOperation.description());
if (!StringUtils.hasText(description)) {
description = "Auto-generated description";
} else {
description = TextUtils.trimIndent(description);
}

String operationTitle = channelName + "_" + this.asyncAnnotationProvider.getOperationType().type;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,7 @@ public static void processAsyncMessageAnnotation(
StringValueResolver resolver) {
String annotationMessageDescription = resolver.resolveStringValue(asyncMessage.description());
if (StringUtils.hasText(annotationMessageDescription)) {
annotationMessageDescription = TextUtils.trimIndent(annotationMessageDescription);
messageBuilder.description(annotationMessageDescription);
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
// SPDX-License-Identifier: Apache-2.0
package io.github.springwolf.core.asyncapi.scanners.common.utils;

import org.apache.commons.lang3.StringUtils;

import java.util.Arrays;

/**
* Auxiliary class to manage Description or long texts.
*/
public class TextUtils {
private TextUtils() {}

/**
* This method removes the smallest common indentation from all the lines in the input string,
* and removes it.
* Any leading empty line will be also removed.
*
* @param text The original string with possible leading indentation.
* @return The string with leading indentation removed from each line.
*/
public static String trimIndent(String text) {
if (text == null) {
return null;
}
final String newLine = System.lineSeparator();
String[] lines = text.split(newLine);
int firstNonEmptyLine = findFirstNonEmptyIndex(lines);
if (firstNonEmptyLine == -1) {
return text;
}
lines = Arrays.copyOfRange(lines, firstNonEmptyLine, lines.length);
int minIndent = resolveMinIndent(lines);
var result = Arrays.stream(lines)
.map(line -> line.substring(Math.min(line.length(), minIndent)))
.reduce((a, b) -> a + newLine + b)
.orElse(StringUtils.EMPTY);

if (StringUtils.endsWith(text, "\n")) {
result = result.concat(newLine);
}

return result;
}

/**
* @return The index of the first non-empty line, or {@code -1} if all lines are empty
*/
private static int findFirstNonEmptyIndex(String[] lines) {
for (int i = 0; i < lines.length; i++) {
if (!lines[i].trim().isEmpty()) {
return i;
}
}
return -1;
}

private static int resolveMinIndent(String[] lines) {
return Arrays.stream(lines)
.filter(line -> !line.trim().isEmpty())
.mapToInt(line -> StringUtils.indexOfAnyBut(line, ' '))
.filter(i -> i >= 0)
.min()
.orElse(0);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
// SPDX-License-Identifier: Apache-2.0
package io.github.springwolf.core.asyncapi.scanners.common.utils;

import org.junit.jupiter.api.Test;

import static org.assertj.core.api.Assertions.assertThat;

class TextUtilsTest {

@Test
void textWithoutIndentShouldBeUntouched() {
var description = """
This is a string
with two lines
""";

var result = TextUtils.trimIndent(description);

assertThat(result).isEqualTo("This is a string\nwith two lines\n");
}

@Test
void textWithSingleIndentShouldBeUntouched() {
var description = """
This is a string
with two lines
""";

var result = TextUtils.trimIndent(description);

assertThat(result).isEqualTo(" This is a string\nwith two lines\n");
}

@Test
void removeIndent() {
var description =
"""
This is a string
with two lines
""";

var result = TextUtils.trimIndent(description);

assertThat(result).isEqualTo("This is a string\nwith two lines\n");
}

@Test
void simpleTextWithoutIndentShouldBeUntouched() {
var description = "This is a string\nwith two lines";
var result = TextUtils.trimIndent(description);

assertThat(result).isEqualTo("This is a string\nwith two lines");
}

@Test
void removeEmptyLinesUntilTextIsFound() {
var description =
"""

This is a string

with two lines
""";
var result = TextUtils.trimIndent(description);

assertThat(result).isEqualTo("This is a string\n\nwith two lines\n");
}

@Test
void onlyEmptyLinesShouldBeUntouched() {
var description = "\n\n\n";
var result = TextUtils.trimIndent(description);

assertThat(result).isEqualTo("\n\n\n");
}

@Test
void nullTextShouldNotFail() {
String nullDescription = null;
var result = TextUtils.trimIndent(nullDescription);
assertThat(result).isNull();
}
}