[java] ASTLiteral - move the tests for text block content

Also fix determining the start of the content, when there are
multiple line terminators without indenting whitespace.
This commit is contained in:
Andreas Dangel
2020-02-28 09:42:15 +01:00
parent 01db024df7
commit 8a90c2d11d
4 changed files with 132 additions and 63 deletions

View File

@ -265,17 +265,22 @@ public class ASTLiteral extends AbstractJavaTypeNode {
* Returns the content of the text block after normalizing line endings to LF,
* removing incidental white space surrounding the text block and interpreting
* escape sequences.
*
* <p>Note: This is a Java 14 Preview Feature.
*/
@Experimental
public String getTextBlockContent() {
if (!isTextBlock()) {
return getImage();
}
return determineTextBlockContent(getImage());
}
int start = determineContentStart(getImage());
String content = getImage().substring(start, getImage().length() - TEXTBLOCK_DELIMITER.length());
static String determineTextBlockContent(String image) {
// normalize line endings to LF
content = content.replaceAll("\r\n|\r", "\n");
String content = image.replaceAll("\r\n|\r", "\n");
int start = determineContentStart(content);
content = content.substring(start, content.length() - TEXTBLOCK_DELIMITER.length());
int prefixLength = Integer.MAX_VALUE;
List<String> lines = Arrays.asList(content.split("\\n"));
@ -308,7 +313,7 @@ public class ASTLiteral extends AbstractJavaTypeNode {
}
String result = sb.toString();
// interpret escape sequences "\NL" "n","t","b","r","f", "s", "\"", "\'"
// interpret escape sequences "\<LF>" (line continuation), "n","t","b","r","f", "s", "\"", "\'"
result = result
.replaceAll("\\\\\n", "")
.replaceAll("\\\\n", "\n")
@ -324,15 +329,11 @@ public class ASTLiteral extends AbstractJavaTypeNode {
private static int determineContentStart(String s) {
int start = TEXTBLOCK_DELIMITER.length(); // this is the opening delimiter
boolean lineTerminator = false;
// the content begins after at the first character after the line terminator
// of the opening delimiter
while (start < s.length() && Character.isWhitespace(s.charAt(start))) {
if (s.charAt(start) == '\r' || s.charAt(start) == '\n') {
lineTerminator = true;
} else if (lineTerminator) {
// first character after the line terminator
break;
if (s.charAt(start) == '\n') {
return start + 1;
}
start++;
}

View File

@ -153,4 +153,113 @@ public class ASTLiteralTest extends BaseParserTest {
private static final String TEST6 = "public class Foo {\n double x = 3.14159;\n}";
private static final String TEST7 = "public class Foo {\n char x = 'x';\n}";
@Test
public void testTextBlockContent() {
assertEquals("empty text block", "",
ASTLiteral.determineTextBlockContent("\"\"\"\n \"\"\""));
assertEquals("single line text block", "winter",
ASTLiteral.determineTextBlockContent("\"\"\"\n winter\"\"\""));
assertEquals("single line text block with LF", "winter\n",
ASTLiteral.determineTextBlockContent("\"\"\"\n"
+ " winter\n"
+ " \"\"\""));
assertEquals("basic text block example with html",
"<html>\n"
+ " <body>\n"
+ " <p>Hello, world</p>\n"
+ " </body>\n"
+ "</html>\n",
ASTLiteral.determineTextBlockContent("\"\"\"\n"
+ " <html> \n"
+ " <body>\n"
+ " <p>Hello, world</p> \n"
+ " </body> \n"
+ " </html> \n"
+ " \"\"\""));
assertEquals("text block with escapes",
"<html>\r\n"
+ " <body>\r\n"
+ " <p>Hello, world</p>\r\n"
+ " </body>\r\n"
+ "</html>\r\n",
ASTLiteral.determineTextBlockContent("\"\"\"\n"
+ " <html>\\r\n"
+ " <body>\\r\n"
+ " <p>Hello, world</p>\\r\n"
+ " </body>\\r\n"
+ " </html>\\r\n"
+ " \"\"\""));
assertEquals("escaped text block in inside text block",
"String text = \"\"\"\n"
+ " A text block inside a text block\n"
+ "\"\"\";\n",
ASTLiteral.determineTextBlockContent("\"\"\"\n"
+ " String text = \\\"\"\"\n"
+ " A text block inside a text block\n"
+ " \\\"\"\";\n"
+ " \"\"\""));
assertEquals("new escape: line continuation",
"Lorem ipsum dolor sit amet, consectetur adipiscing "
+ "elit, sed do eiusmod tempor incididunt ut labore "
+ "et dolore magna aliqua.",
ASTLiteral.determineTextBlockContent("\"\"\"\n"
+ " Lorem ipsum dolor sit amet, consectetur adipiscing \\\n"
+ " elit, sed do eiusmod tempor incididunt ut labore \\\n"
+ " et dolore magna aliqua.\\\n"
+ " \"\"\""));
assertEquals("new escape: space escape",
"red \n"
+ "green \n"
+ "blue \n",
ASTLiteral.determineTextBlockContent("\"\"\"\n"
+ " red \\s\n"
+ " green\\s\n"
+ " blue \\s\n"
+ " \"\"\""));
assertEquals("with crlf line endings",
"<html>\n"
+ " <body>\n"
+ " <p>Hello, world</p>\n"
+ " </body>\n"
+ "</html>\n", ASTLiteral.determineTextBlockContent("\"\"\"\r\n"
+ " <html> \r\n"
+ " <body>\r\n"
+ " <p>Hello, world</p> \r\n"
+ " </body> \r\n"
+ " </html> \r\n"
+ " \"\"\""));
assertEquals("with cr line endings",
"<html>\n"
+ " <body>\n"
+ " <p>Hello, world</p>\n"
+ " </body>\n"
+ "</html>\n", ASTLiteral.determineTextBlockContent("\"\"\"\r"
+ " <html> \r"
+ " <body>\r"
+ " <p>Hello, world</p> \r"
+ " </body> \r"
+ " </html> \r"
+ " \"\"\""));
assertEquals("empty line directly after opening",
"\ntest\n", ASTLiteral.determineTextBlockContent("\"\"\"\n"
+ " \n"
+ " test\n"
+ " \"\"\""));
assertEquals("empty crlf line directly after opening",
"\ntest\n", ASTLiteral.determineTextBlockContent("\"\"\"\r\n"
+ " \r\n"
+ " test\r\n"
+ " \"\"\""));
assertEquals("empty line directly after opening without indentation",
"\ntest\n", ASTLiteral.determineTextBlockContent("\"\"\"\n"
+ "\n"
+ "test\n"
+ "\"\"\""));
assertEquals("empty crlf line directly after opening without indentation",
"\ntest\n", ASTLiteral.determineTextBlockContent("\"\"\"\r\n"
+ "\r\n"
+ "test\r\n"
+ "\"\"\""));
}
}

View File

@ -29,9 +29,11 @@ public class Java14PreviewTest {
public void textBlocks() {
ASTCompilationUnit compilationUnit = java14p.parseResource("TextBlocks.java");
List<ASTLiteral> literals = compilationUnit.findDescendantsOfType(ASTLiteral.class);
Assert.assertEquals(16, literals.size());
Assert.assertEquals(19, literals.size());
Assert.assertFalse(literals.get(2).isTextBlock());
Assert.assertFalse(literals.get(12).isTextBlock());
Assert.assertFalse(literals.get(17).isTextBlock());
Assert.assertFalse(literals.get(18).isTextBlock());
List<ASTLiteral> textBlocks = new ArrayList<>();
for (ASTLiteral literal : literals) {
@ -39,7 +41,7 @@ public class Java14PreviewTest {
textBlocks.add(literal);
}
}
Assert.assertEquals(14, textBlocks.size());
Assert.assertEquals(15, textBlocks.size());
Assert.assertEquals("\"\"\"\n"
+ " <html> \n"
+ " <body>\n"
@ -54,57 +56,7 @@ public class Java14PreviewTest {
+ " </body>\n"
+ "</html>\n", textBlocks.get(0).getTextBlockContent());
// with escapes
Assert.assertEquals("\"\"\"\n"
+ " <html>\\r\n"
+ " <body>\\r\n"
+ " <p>Hello, world</p>\\r\n"
+ " </body>\\r\n"
+ " </html>\\r\n"
+ " \"\"\"", textBlocks.get(3).getImage());
Assert.assertEquals("<html>\r\n"
+ " <body>\r\n"
+ " <p>Hello, world</p>\r\n"
+ " </body>\r\n"
+ "</html>\r\n", textBlocks.get(3).getTextBlockContent());
// season
Assert.assertEquals("\"\"\"\n winter\"\"\"", textBlocks.get(4).getImage());
Assert.assertEquals("winter", textBlocks.get(4).getTextBlockContent());
// period
Assert.assertEquals("\"\"\"\n"
+ " winter\n"
+ " \"\"\"", textBlocks.get(5).getImage());
Assert.assertEquals("winter\n", textBlocks.get(5).getTextBlockContent());
// empty
Assert.assertEquals("\"\"\"\n \"\"\"", textBlocks.get(8).getImage());
Assert.assertEquals("", textBlocks.get(8).getTextBlockContent());
// escaped text block in inside text block
Assert.assertEquals("\"\"\"\n"
+ " String text = \\\"\"\"\n"
+ " A text block inside a text block\n"
+ " \\\"\"\";\n"
+ " \"\"\"", textBlocks.get(11).getImage());
Assert.assertEquals("String text = \"\"\"\n"
+ " A text block inside a text block\n"
+ "\"\"\";\n", textBlocks.get(11).getTextBlockContent());
// new escape: line continuation
Assert.assertEquals("\"\"\"\n"
+ " Lorem ipsum dolor sit amet, consectetur adipiscing \\\n"
+ " elit, sed do eiusmod tempor incididunt ut labore \\\n"
+ " et dolore magna aliqua.\\\n"
+ " \"\"\"", textBlocks.get(12).getImage());
Assert.assertEquals("Lorem ipsum dolor sit amet, consectetur adipiscing "
+ "elit, sed do eiusmod tempor incididunt ut labore "
+ "et dolore magna aliqua.", textBlocks.get(12).getTextBlockContent());
// new escape: space escape
Assert.assertEquals("\"\"\"\n"
+ " red \\s\n"
+ " green\\s\n"
+ " blue \\s\n"
+ " \"\"\"", textBlocks.get(13).getImage());
Assert.assertEquals("red \n"
+ "green \n"
+ "blue \n", textBlocks.get(13).getTextBlockContent());
// Note: More tests are in ASTLiteralTest.
}
@Test(expected = ParseException.class)

View File

@ -96,5 +96,12 @@ public class TextBlocks {
blue \s
""";
System.out.println(colors);
// empty new line as first content
String emptyLine = """
test
""";
System.out.println(emptyLine.replaceAll("\n", "<LF>"));
}
}