diff --git a/pom.xml b/pom.xml
index 3108a575a..4ed093d52 100644
--- a/pom.xml
+++ b/pom.xml
@@ -37,7 +37,8 @@
1.8
UTF-8
5.13.4
- 3.19.2.RELEASE
+ 4.11.0
+ 3.19.2.RELEASE
2.2.9
2.0.3.5
1.9.0
@@ -61,6 +62,12 @@
${junit.jupiter.version}
test
+
+ org.mockito
+ mockito-junit-jupiter
+ ${mockito.version}
+ test
+
com.ibeetl
beetl
diff --git a/src/main/java/com/ly/doc/utils/DocUtil.java b/src/main/java/com/ly/doc/utils/DocUtil.java
index 1945aab77..6ac6371f2 100644
--- a/src/main/java/com/ly/doc/utils/DocUtil.java
+++ b/src/main/java/com/ly/doc/utils/DocUtil.java
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2018-2024 smart-doc
+ * Copyright (C) 2018-2025 smart-doc
*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
@@ -18,6 +18,7 @@
* specific language governing permissions and limitations
* under the License.
*/
+
package com.ly.doc.utils;
import com.ly.doc.builder.WordDocBuilder;
@@ -745,12 +746,27 @@ private static Map getCommentsByTag(List paramTags, f
if (DocTags.PARAM.equals(tagName) || DocTags.EXTENSION.equals(tagName)) {
String pName = value;
String pValue = DocGlobalConstants.NO_COMMENTS_FOUND;
- int idx = value.indexOf(" ");
- // existed \n
- if (idx > -1) {
- pName = value.substring(0, idx);
- pValue = value.substring(idx + 1);
+
+ // Fixed #1129
+ // Split the value by the first sequence of whitespace
+ // (space,newline,tab, etc.) only into two parts.
+ String[] parts = value.trim().split("\\s+", 2);
+ // Successfully split into parameter name and description
+ if (parts.length == 2) {
+ // Parameter name
+ pName = parts[0];
+ // Description, preserving internal newlines and formatting
+ pValue = parts[1];
}
+ // Only one part found, likely just the parameter name
+ // without a description, OR an empty/whitespace-only value after trim
+ else if (parts.length == 1) {
+ // Covers both "paramName" and "" cases
+ // pValue remains DocGlobalConstants.NO_COMMENTS_FOUND
+ // Set pName based on whether the single part is empty
+ pName = parts[0];
+ }
+
if ("|".equals(StringUtil.trim(pValue)) && StringUtil.isNotEmpty(className)) {
throw new RuntimeException(tagValErrorMsg);
}
diff --git a/src/test/java/com/ly/doc/util/DocUtilTest.java b/src/test/java/com/ly/doc/util/DocUtilTest.java
index f444faee0..28c81ec6e 100644
--- a/src/test/java/com/ly/doc/util/DocUtilTest.java
+++ b/src/test/java/com/ly/doc/util/DocUtilTest.java
@@ -1,21 +1,45 @@
package com.ly.doc.util;
import com.ly.doc.constants.DocGlobalConstants;
+import com.ly.doc.constants.DocLanguage;
+import com.ly.doc.constants.DocTags;
import com.ly.doc.enums.IEnum;
import com.ly.doc.enums.OrderEnum;
import com.ly.doc.utils.DocUtil;
-import com.ly.doc.constants.DocLanguage;
+import com.thoughtworks.qdox.model.DocletTag;
import org.junit.jupiter.api.Test;
+import org.mockito.Mockito;
+import java.util.Arrays;
+import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+import static org.mockito.Mockito.when;
+
/**
* @author yu 2018/12/10.
*/
public class DocUtilTest {
+ /**
+ * Assuming DocTags.PARAM is "param"
+ */
+ private static final String TAG_NAME_PARAM = DocTags.PARAM;
+
+ /**
+ * Assuming DocTags.EXTENSION is "extension"
+ */
+ private static final String TAG_NAME_EXTENSION = DocTags.EXTENSION;
+
+ /**
+ * Assuming DocGlobalConstants.NO_COMMENTS_FOUND
+ */
+ private static final String NO_COMMENTS_FOUND = DocGlobalConstants.NO_COMMENTS_FOUND;
+
@Test
public void test() {
System.setProperty(DocGlobalConstants.DOC_LANGUAGE, DocLanguage.CHINESE.getCode());
@@ -80,4 +104,127 @@ public void testReplaceGenericParameter() {
System.out.println(result); // Output: com.Test 0.");
+ // Scenario 4: Only parameter name, no description
+ DocletTag tag4 = createMockTag("flag");
+ // Scenario 5: Parameter name with leading/trailing whitespace in the raw value
+ // part that's not the name itself
+ DocletTag tag5 = createMockTag(" email user's email address ");
+ // Scenario 6: Description starts immediately after parameter name WITH A SPACE
+ // (Standard Javadoc format)
+ DocletTag tag6 = createMockTag("status Active user status flag");
+ // Scenario 7: Description contains leading whitespace after the parameter name
+ DocletTag tag7 = createMockTag("count Number of items to retrieve");
+
+ List tags = Arrays.asList(tag1, tag2, tag3, tag4, tag5, tag6, tag7);
+
+ Map result = DocUtil.getCommentsByTag(tags, TAG_NAME_PARAM);
+
+ // Verify results
+ assertEquals("user identifier", result.get("id"), "Scenario 1: Description should be 'user identifier'");
+ assertEquals("user's full name", result.get("name"),
+ "Scenario 2: Description should be 'user's full name', preserving content after newline.");
+ assertEquals("user's age in years\n Default is 25.\n NOTE: Must be > 0.",
+ result.get("age"), "Scenario 3: Description should preserve newlines and formatting.");
+ assertEquals(NO_COMMENTS_FOUND, result.get("flag"), "Scenario 4: Should return NO_COMMENTS_FOUND for 'flag'");
+ assertEquals("user's email address", result.get("email"),
+ "Scenario 5: Name should be 'email', description should be 'user's email address'");
+ assertEquals("Active user status flag", result.get("status"),
+ "Scenario 6: Description should be 'Active user status flag'");
+ assertEquals("Number of items to retrieve", result.get("count"),
+ "Scenario 7: Description should be 'Number of items to retrieve'");
+
+ }
+
+ @Test
+ public void testGetCommentsByTag_ExtensionWithNewlines() {
+ // Similar scenarios for @extension
+ DocletTag tag1 = createMockTag("extId extension identifier");
+ DocletTag tag2 = createMockTag("extName\n extension name");
+ DocletTag tag3 = createMockTag("extConfig extension configuration details\n with multiple lines.");
+ DocletTag tag4 = createMockTag("extFlag");
+
+ List tags = Arrays.asList(tag1, tag2, tag3, tag4);
+
+ Map result = DocUtil.getCommentsByTag(tags, TAG_NAME_EXTENSION);
+
+ // Verify results
+ assertEquals("extension identifier", result.get("extId"));
+ assertEquals("extension name", result.get("extName"));
+ assertEquals("extension configuration details\n with multiple lines.", result.get("extConfig"));
+ assertEquals(NO_COMMENTS_FOUND, result.get("extFlag"));
+ }
+
+ @Test
+ public void testGetCommentsByTag_ParamWithCarriageReturn() {
+ // Scenario: Description has Windows-style CRLF (\r\n)
+ String valueWithCRLF = "token\r\n Authentication token,\r\n required for access.";
+ DocletTag tag = createMockTag(valueWithCRLF);
+
+ List tags = Collections.singletonList(tag);
+ Map result = DocUtil.getCommentsByTag(tags, TAG_NAME_PARAM);
+
+ assertEquals("Authentication token,\r\n required for access.", result.get("token"),
+ "Should handle CRLF correctly, preserving the newline and content.");
+ }
+
+ @Test
+ public void testGetCommentsByTag_ParamOnlyName() {
+ // Scenario: Only parameter name exists, no space/description
+ DocletTag tag = createMockTag("justParamName");
+ List tags = Collections.singletonList(tag);
+ Map result = DocUtil.getCommentsByTag(tags, TAG_NAME_PARAM);
+
+ assertEquals(NO_COMMENTS_FOUND, result.get("justParamName"),
+ "Should return NO_COMMENTS_FOUND for 'justParamName'");
+ }
+
+ @Test
+ public void testGetCommentsByTag_ParamEmptyValue() {
+ // Scenario: Empty value string
+ DocletTag tag = createMockTag("");
+ List tags = Collections.singletonList(tag);
+ Map result = DocUtil.getCommentsByTag(tags, TAG_NAME_PARAM);
+
+ // An empty string after trim results in [""], so parts[0] is "", and parts.length
+ // is 1.
+ // The logic assigns pName = parts[0] (which is ""), and pValue remains the
+ // default NO_COMMENTS_FOUND.
+ // The map.put(pName.trim(), pValue) effectively does map.put("",
+ // NO_COMMENTS_FOUND).
+ assertEquals(NO_COMMENTS_FOUND, result.get(""), // 修正 NO_COMMENTS_FOUND 的值
+ "Should handle empty value, key should be empty string.");
+ assertTrue(result.containsKey(""), "Map should contain an entry with an empty string key.");
+ }
+
+ @Test
+ public void testGetCommentsByTag_ParamWhitespaceOnlyValue() {
+ // Scenario: Value is only whitespace
+ DocletTag tag = createMockTag(" \t \n ");
+ List tags = Collections.singletonList(tag);
+ Map result = DocUtil.getCommentsByTag(tags, TAG_NAME_PARAM);
+
+ // Whitespace-only string after trim becomes "", same as empty value scenario.
+ // After trim and split, pName should be "" and pValue should be
+ // NO_COMMENTS_FOUND.
+ assertEquals(NO_COMMENTS_FOUND, result.get(""),
+ "Should handle whitespace-only value, key should be empty string.");
+ assertTrue(result.containsKey(""), "Map should contain an entry with an empty string key.");
+ }
+
}