Skip to content

Commit

Permalink
Add tests for Java 21 string patterns
Browse files Browse the repository at this point in the history
TODO: Due to eclipse-jdt/eclipse.jdt.core#1719, one line per test is
currently rendered incorrectly. After the upstream fix, change
"\Bill \Duck" to "Bill Duck".

Signed-off-by: Alexander Kriegisch <[email protected]>
  • Loading branch information
kriegaex committed Dec 11, 2023
1 parent 920e9f5 commit 6be5a0a
Show file tree
Hide file tree
Showing 4 changed files with 309 additions and 2 deletions.
114 changes: 114 additions & 0 deletions tests/features1921/java21/StringPatternsPreview1.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,114 @@
import java.io.File;
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.format.DateTimeFormatter;

import static java.lang.StringTemplate.RAW;
import static java.util.FormatProcessor.FMT;

/**
* Examples taken from <a href="https://openjdk.org/jeps/430">JEP 430</a>
*/
public class StringPatternsPreview1 {
public static void main(String[] args) {
// Embedded expressions can be strings
String firstName = "Bill", lastName = "Duck";
// TODO: Due to https://github.com/eclipse-jdt/eclipse.jdt.core/issues/1719, this is currently rendered incorrectly
System.out.println(STR."\{firstName} \{lastName}");

// Embedded expressions can perform arithmetic
int x = 10, y = 20;
System.out.println(STR."\{x} + \{y} = \{x + y}");

// Embedded expressions can invoke methods and access fields
System.out.println(STR."You have a \{getOfferType()} waiting for you!");
Request req = new Request();
System.out.println(STR."Access at \{req.date} \{req.time} from \{req.ipAddress}");

// Embedded expressions can use double quotes without escaping them
String filePath = "_dummy.dat";
File file = new File(filePath);
System.out.println(STR."The file \{filePath} \{file.exists() ? "does" : "does not"} exist");

// Embedded expressions can span multiple lines
System.out.println(
STR."The time is \{
DateTimeFormatter
.ofPattern("HH:mm:ss")
.format(LocalTime.of(11, 11, 11))
} or roughly eleven after eleven"
);

// Embedded expressions can be nested
String[] fruit = { "apples", "oranges", "peaches" };
System.out.println(STR."\{fruit[0]}, \{STR."\{fruit[1]}, \{fruit[2]}"}\n");

// Embedded expressions can be used in multi-line strings
String title = "My Web Page";
String text = "Hello, world";
String html = STR."""
<html>
<head>
<title>\{title}</title>
</head>
<body>
<p>\{text}</p>
</body>
</html>
""";
System.out.println(html);

// The FMT template processor interprets format specifiers which appear to the left of embedded expressions.
// The format specifiers are the same as those defined in java.util.Formatter.
Rectangle[] zone = new Rectangle[] {
new Rectangle("Alfa", 17.8, 31.4),
new Rectangle("Bravo", 9.6, 12.4),
new Rectangle("Charlie", 7.1, 11.23),
};
String table = FMT."""
Description Width Height Area
%-12s\{zone[0].name} %7.2f\{zone[0].width} %7.2f\{zone[0].height} %7.2f\{zone[0].area()}
%-12s\{zone[1].name} %7.2f\{zone[1].width} %7.2f\{zone[1].height} %7.2f\{zone[1].area()}
%-12s\{zone[2].name} %7.2f\{zone[2].width} %7.2f\{zone[2].height} %7.2f\{zone[2].area()}
\{" ".repeat(28)} Total %7.2f\{zone[0].area() + zone[1].area() + zone[2].area()}
""";
System.out.println(table);

// Built-in security: Each template expression needs to pass through a processor.
String name = "Joan";
StringTemplate stringTemplate = RAW."My name is \{name}";
String processedTemplate = STR.process(stringTemplate);
System.out.println(processedTemplate);
}

static Object getOfferType() {
return "special New Year's sale discount";
}

static class Request {
LocalDate date;
LocalTime time;
InetAddress ipAddress;

Request() {
LocalDateTime dateTime = LocalDateTime.of(2011, 11, 11, 11, 11, 11);
date = dateTime.toLocalDate();
time = dateTime.toLocalTime();
try {
// localhost/127.0.0.1
ipAddress = InetAddress.getByAddress("localhost", new byte[] { 127, 0, 0, 1 });
} catch (UnknownHostException e) {
throw new RuntimeException(e);
}
}
}

record Rectangle(String name, double width, double height) {
double area() {
return width * height;
}
}
}
118 changes: 118 additions & 0 deletions tests/features1921/java21/StringPatternsPreview1Aspect.aj
Original file line number Diff line number Diff line change
@@ -0,0 +1,118 @@
import java.io.File;
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.format.DateTimeFormatter;

import static java.lang.StringTemplate.RAW;
import static java.util.FormatProcessor.FMT;

/**
* Examples taken from <a href="https://openjdk.org/jeps/430">JEP 430</a>
*/
public aspect StringPatternsPreview1Aspect {
public static void main(String[] args) {}

before() : execution(* main(String[])) {
System.out.println(thisJoinPoint);

// Embedded expressions can be strings
String firstName = "Bill", lastName = "Duck";
// TODO: Due to https://github.com/eclipse-jdt/eclipse.jdt.core/issues/1719, this is currently rendered incorrectly
System.out.println(STR."\{firstName} \{lastName}");

// Embedded expressions can perform arithmetic
int x = 10, y = 20;
System.out.println(STR."\{x} + \{y} = \{x + y}");

// Embedded expressions can invoke methods and access fields
System.out.println(STR."You have a \{getOfferType()} waiting for you!");
Request req = new Request();
System.out.println(STR."Access at \{req.date} \{req.time} from \{req.ipAddress}");

// Embedded expressions can use double quotes without escaping them
String filePath = "_dummy.dat";
File file = new File(filePath);
System.out.println(STR."The file \{filePath} \{file.exists() ? "does" : "does not"} exist");

// Embedded expressions can span multiple lines
System.out.println(
STR."The time is \{
DateTimeFormatter
.ofPattern("HH:mm:ss")
.format(LocalTime.of(11, 11, 11))
} or roughly eleven after eleven"
);

// Embedded expressions can be nested
String[] fruit = { "apples", "oranges", "peaches" };
System.out.println(STR."\{fruit[0]}, \{STR."\{fruit[1]}, \{fruit[2]}"}\n");

// Embedded expressions can be used in multi-line strings
String title = "My Web Page";
String text = "Hello, world";
String html = STR."""
<html>
<head>
<title>\{title}</title>
</head>
<body>
<p>\{text}</p>
</body>
</html>
""";
System.out.println(html);

// The FMT template processor interprets format specifiers which appear to the left of embedded expressions.
// The format specifiers are the same as those defined in java.util.Formatter.
Rectangle[] zone = new Rectangle[] {
new Rectangle("Alfa", 17.8, 31.4),
new Rectangle("Bravo", 9.6, 12.4),
new Rectangle("Charlie", 7.1, 11.23),
};
String table = FMT."""
Description Width Height Area
%-12s\{zone[0].name} %7.2f\{zone[0].width} %7.2f\{zone[0].height} %7.2f\{zone[0].area()}
%-12s\{zone[1].name} %7.2f\{zone[1].width} %7.2f\{zone[1].height} %7.2f\{zone[1].area()}
%-12s\{zone[2].name} %7.2f\{zone[2].width} %7.2f\{zone[2].height} %7.2f\{zone[2].area()}
\{" ".repeat(28)} Total %7.2f\{zone[0].area() + zone[1].area() + zone[2].area()}
""";
System.out.println(table);

// Built-in security: Each template expression needs to pass through a processor.
String name = "Joan";
StringTemplate stringTemplate = RAW."My name is \{name}";
String processedTemplate = STR.process(stringTemplate);
System.out.println(processedTemplate);
}

static Object getOfferType() {
return "special New Year's sale discount";
}

static class Request {
LocalDate date;
LocalTime time;
InetAddress ipAddress;

Request() {
LocalDateTime dateTime = LocalDateTime.of(2011, 11, 11, 11, 11, 11);
date = dateTime.toLocalDate();
time = dateTime.toLocalTime();
try {
// localhost/127.0.0.1
ipAddress = InetAddress.getByAddress("localhost", new byte[] { 127, 0, 0, 1 });
} catch (UnknownHostException e) {
throw new RuntimeException(e);
}
}
}

record Rectangle(String name, double width, double height) {
double area() {
return width * height;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,12 @@
*/
public class Java21PreviewFeaturesTests extends XMLBasedAjcTestCaseForJava21Only {

public void testDummyPreviewJava21() {
//runTest("dummy preview Java 21");
public void testStringPatterns() {
runTest("string patterns");
}

public void testStringPatternsAspect() {
runTest("string patterns aspect");
}

public static Test suite() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -188,4 +188,75 @@
</run>
</ajc-test>

<!-- Java 21 preview -->
<ajc-test dir="features1921/java21" vm="21" title="string patterns">
<compile files="StringPatternsPreview1.java" options="--enable-preview -21"/>
<run class="StringPatternsPreview1" vmargs="--enable-preview">
<stdout ordered="yes">
<!-- TODO: Due to https://github.com/eclipse-jdt/eclipse.jdt.core/issues/1719, this is currently rendered
incorrectly. After the upstream fix, change "\Bill \Duck" to "Bill Duck". -->
<line text="\Bill \Duck"/>
<line text="10 + 20 = 30"/>
<line text="You have a special New Year's sale discount waiting for you!"/>
<line text="Access at 2011-11-11 11:11:11 from localhost/127.0.0.1"/>
<line text="The file _dummy.dat does not exist"/>
<line text="The time is 11:11:11 or roughly eleven after eleven"/>
<line text="apples, oranges, peaches"/>
<line text=""/>
<line text="&lt;html&gt;"/>
<line text=" &lt;head&gt;"/>
<line text=" &lt;title&gt;My Web Page&lt;/title&gt;"/>
<line text=" &lt;/head&gt;"/>
<line text=" &lt;body&gt;"/>
<line text=" &lt;p&gt;Hello, world&lt;/p&gt;"/>
<line text=" &lt;/body&gt;"/>
<line text="&lt;/html&gt;"/>
<line text=""/>
<line text="Description Width Height Area"/>
<line text="Alfa 17.80 31.40 558.92"/>
<line text="Bravo 9.60 12.40 119.04"/>
<line text="Charlie 7.10 11.23 79.73"/>
<line text=" Total 757.69"/>
<line text=""/>
<line text="My name is Joan"/>
</stdout>
</run>
</ajc-test>

<!-- Java 21 preview -->
<ajc-test dir="features1921/java21" vm="21" title="string patterns aspect">
<compile files="StringPatternsPreview1Aspect.aj" options="--enable-preview -21"/>
<run class="StringPatternsPreview1Aspect" vmargs="--enable-preview">
<stdout ordered="yes">
<line text="execution(void StringPatternsPreview1Aspect.main(String[]))"/>
<!-- TODO: Due to https://github.com/eclipse-jdt/eclipse.jdt.core/issues/1719, this is currently rendered
incorrectly. After the upstream fix, change "\Bill \Duck" to "Bill Duck". -->
<line text="\Bill \Duck"/>
<line text="10 + 20 = 30"/>
<line text="You have a special New Year's sale discount waiting for you!"/>
<line text="Access at 2011-11-11 11:11:11 from localhost/127.0.0.1"/>
<line text="The file _dummy.dat does not exist"/>
<line text="The time is 11:11:11 or roughly eleven after eleven"/>
<line text="apples, oranges, peaches"/>
<line text=""/>
<line text="&lt;html&gt;"/>
<line text=" &lt;head&gt;"/>
<line text=" &lt;title&gt;My Web Page&lt;/title&gt;"/>
<line text=" &lt;/head&gt;"/>
<line text=" &lt;body&gt;"/>
<line text=" &lt;p&gt;Hello, world&lt;/p&gt;"/>
<line text=" &lt;/body&gt;"/>
<line text="&lt;/html&gt;"/>
<line text=""/>
<line text="Description Width Height Area"/>
<line text="Alfa 17.80 31.40 558.92"/>
<line text="Bravo 9.60 12.40 119.04"/>
<line text="Charlie 7.10 11.23 79.73"/>
<line text=" Total 757.69"/>
<line text=""/>
<line text="My name is Joan"/>
</stdout>
</run>
</ajc-test>

</suite>

0 comments on commit 6be5a0a

Please sign in to comment.