This is an automated email from the ASF dual-hosted git repository. lukaszlenart pushed a commit to branch WW-5016-uses-proper-format in repository https://gitbox.apache.org/repos/asf/struts.git
commit 804e1546f149174f6e88d69b77bd3fa9e8b9a76d Author: Lukasz Lenart <lukaszlen...@apache.org> AuthorDate: Sun Feb 6 12:23:39 2022 +0100 WW-5016 Adds support for LocalDate and adjusts tests to use the new Java 8 API --- .../java/org/apache/struts2/components/Date.java | 44 ++-- .../apache/struts2/views/jsp/ui/DateTagTest.java | 228 +++++++++++++-------- 2 files changed, 165 insertions(+), 107 deletions(-) diff --git a/core/src/main/java/org/apache/struts2/components/Date.java b/core/src/main/java/org/apache/struts2/components/Date.java index 5f65d9c..ec9bb19 100644 --- a/core/src/main/java/org/apache/struts2/components/Date.java +++ b/core/src/main/java/org/apache/struts2/components/Date.java @@ -29,6 +29,7 @@ import org.apache.struts2.views.annotations.StrutsTagAttribute; import java.io.IOException; import java.io.Writer; import java.time.Instant; +import java.time.LocalDate; import java.time.LocalDateTime; import java.time.ZoneId; import java.time.ZonedDateTime; @@ -40,7 +41,7 @@ import java.util.List; /** * <!-- START SNIPPET: javadoc --> - * + * <p> * Format Date object in different ways. * <p> * The date tag will allow you to format a Date in a quick and easy way. @@ -59,6 +60,12 @@ import java.util.List; * </p> * * <p> + * <b>Note</b>: Since Struts 2.6 a new Java 8 API has been used to format the Date, it's based on + * <a href="https://docs.oracle.com/javase/8/docs/api/java/time/format/DateTimeFormatter.html">DateTimeFormatter</a> + * which uses a bit different patterns. + * </p> + * + * <p> * Configurable attributes are: * </p> * @@ -130,8 +137,8 @@ import java.util.List; * <td>if one is not found DateFormat.MEDIUM format will be used</td> * </tr> * </table> - * - * + * <p> + * <p> * <!-- END SNIPPET: javadoc --> * * <p><b>Examples</b></p> @@ -145,9 +152,8 @@ import java.util.List; * </pre> * * <code>Date</code> - * */ -@StrutsTag(name="date", tldBodyContent="empty", tldTagClass="org.apache.struts2.views.jsp.DateTag", description="Render a formatted date.") +@StrutsTag(name = "date", tldBodyContent = "empty", tldTagClass = "org.apache.struts2.views.jsp.DateTag", description = "Render a formatted date.") public class Date extends ContextBean { private static final Logger LOG = LogManager.getLogger(Date.class); @@ -292,6 +298,8 @@ public class Date extends ContextBean { date = Instant.ofEpochMilli((long) dateObject).atZone(tz); } else if (dateObject instanceof LocalDateTime) { date = ((LocalDateTime) dateObject).atZone(tz); + } else if (dateObject instanceof LocalDate) { + date = ((LocalDate) dateObject).atStartOfDay(tz); } else if (dateObject instanceof Instant) { date = ((Instant) dateObject).atZone(tz); } else { @@ -300,18 +308,18 @@ public class Date extends ContextBean { String developerNotification = ""; if (tp != null) { developerNotification = findProviderInStack().getText( - "devmode.notification", - "Developer Notification:\n{0}", - new String[]{ - "Expression [" + name + "] passed to <s:date/> tag which was evaluated to [" + dateObject + "](" - + (dateObject != null ? dateObject.getClass() : "null") + ") isn't supported!" - } + "devmode.notification", + "Developer Notification:\n{0}", + new String[]{ + "Expression [" + name + "] passed to <s:date/> tag which was evaluated to [" + dateObject + "](" + + (dateObject != null ? dateObject.getClass() : "null") + ") isn't supported!" + } ); } LOG.warn(developerNotification); } else { LOG.debug("Expression [{}] passed to <s:date/> tag which was evaluated to [{}]({}) isn't supported!", - name, dateObject, (dateObject != null ? dateObject.getClass() : "null")); + name, dateObject, (dateObject != null ? dateObject.getClass() : "null")); } } @@ -338,11 +346,11 @@ public class Date extends ContextBean { // returned string is the same as input = // DATETAG_PROPERTY if (globalFormat != null - && !DATETAG_PROPERTY.equals(globalFormat)) { + && !DATETAG_PROPERTY.equals(globalFormat)) { dtf = DateTimeFormatter.ofPattern(globalFormat, ActionContext.getContext().getLocale()); } else { dtf = DateTimeFormatter.ofLocalizedDateTime(FormatStyle.MEDIUM) - .withLocale(ActionContext.getContext().getLocale()); + .withLocale(ActionContext.getContext().getLocale()); } } else { dtf = DateTimeFormatter.ofPattern(format, ActionContext.getContext().getLocale()); @@ -378,17 +386,17 @@ public class Date extends ContextBean { return tz; } - @StrutsTagAttribute(description="Date or DateTime format pattern", rtexprvalue=false) + @StrutsTagAttribute(description = "Date or DateTime format pattern") public void setFormat(String format) { this.format = format; } - @StrutsTagAttribute(description="Whether to print out the date nicely", type="Boolean", defaultValue="false") + @StrutsTagAttribute(description = "Whether to print out the date nicely", type = "Boolean", defaultValue = "false") public void setNice(boolean nice) { this.nice = nice; } - @StrutsTagAttribute(description = "The specific timezone in which to format the date", required = false) + @StrutsTagAttribute(description = "The specific timezone in which to format the date") public void setTimezone(String timezone) { this.timezone = timezone; } @@ -400,7 +408,7 @@ public class Date extends ContextBean { return name; } - @StrutsTagAttribute(description="The date value to format", required=true) + @StrutsTagAttribute(description = "The date value to format", required = true) public void setName(String name) { this.name = name; } diff --git a/core/src/test/java/org/apache/struts2/views/jsp/ui/DateTagTest.java b/core/src/test/java/org/apache/struts2/views/jsp/ui/DateTagTest.java index 6f6e31e..05e267e 100644 --- a/core/src/test/java/org/apache/struts2/views/jsp/ui/DateTagTest.java +++ b/core/src/test/java/org/apache/struts2/views/jsp/ui/DateTagTest.java @@ -19,35 +19,33 @@ package org.apache.struts2.views.jsp.ui; import com.opensymphony.xwork2.ActionContext; - import org.apache.struts2.TestAction; +import org.apache.struts2.components.Component; +import org.apache.struts2.components.DateTextField; import org.apache.struts2.views.jsp.AbstractTagTest; import org.apache.struts2.views.jsp.DateTag; +import javax.servlet.jsp.JspException; import java.text.DateFormat; -import java.text.SimpleDateFormat; import java.time.Instant; +import java.time.LocalDate; import java.time.LocalDateTime; import java.time.ZoneId; import java.time.format.DateTimeFormatter; import java.util.Calendar; import java.util.Date; -import java.util.TimeZone; -import org.apache.struts2.components.Component; -import org.apache.struts2.components.DateTextField; /** * Unit test for {@link org.apache.struts2.components.Date}. - * */ public class DateTagTest extends AbstractTagTest { private DateTag tag; - public void testCustomFormat() throws Exception { + public void testCustomFormatForDateTime() throws Exception { String format = "yyyy/MM/dd hh:mm:ss"; - Date now = new Date(); - String formatted = new SimpleDateFormat(format).format(now); + LocalDateTime now = LocalDateTime.now(); + String formatted = DateTimeFormatter.ofPattern(format).format(now); context.put("myDate", now); tag.setName("myDate"); @@ -62,13 +60,55 @@ public class DateTagTest extends AbstractTagTest { freshTag.setPageContext(pageContext); assertFalse("Tag state after doEndTag() under default tag clear state is equal to new Tag with pageContext/parent set. " + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", - strutsBodyTagsAreReflectionEqual(tag, freshTag)); + strutsBodyTagsAreReflectionEqual(tag, freshTag)); + } + + public void testCustomFormatForLong() throws Exception { + String format = "yyyy/MM/dd"; + long now = new Date().getTime(); + String formatted = DateTimeFormatter.ofPattern(format).format(Instant.ofEpochMilli(now).atZone(ZoneId.systemDefault())); + context.put("myDate", now); + + tag.setName("myDate"); + tag.setNice(false); + tag.setFormat(format); + tag.doStartTag(); + tag.doEndTag(); + assertEquals(formatted, writer.toString()); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + DateTag freshTag = new DateTag(); + freshTag.setPageContext(pageContext); + assertFalse("Tag state after doEndTag() under default tag clear state is equal to new Tag with pageContext/parent set. " + + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", + strutsBodyTagsAreReflectionEqual(tag, freshTag)); + } + + public void testCustomFormatForDate() throws Exception { + String format = "yyyy/MM/dd"; + LocalDate now = LocalDate.now(); + String formatted = DateTimeFormatter.ofPattern(format).format(now); + context.put("myDate", now); + + tag.setName("myDate"); + tag.setNice(false); + tag.setFormat(format); + tag.doStartTag(); + tag.doEndTag(); + assertEquals(formatted, writer.toString()); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + DateTag freshTag = new DateTag(); + freshTag.setPageContext(pageContext); + assertFalse("Tag state after doEndTag() under default tag clear state is equal to new Tag with pageContext/parent set. " + + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", + strutsBodyTagsAreReflectionEqual(tag, freshTag)); } public void testCustomFormat_clearTagStateSet() throws Exception { String format = "yyyy/MM/dd hh:mm:ss"; - Date now = new Date(); - String formatted = new SimpleDateFormat(format).format(now); + LocalDateTime now = LocalDateTime.now(); + String formatted = DateTimeFormatter.ofPattern(format).format(now); context.put("myDate", now); tag.setPerformClearTagStateForTagPoolingServers(true); // Explicitly request tag state clearing. @@ -86,13 +126,13 @@ public class DateTagTest extends AbstractTagTest { freshTag.setPageContext(pageContext); assertTrue("Tag state after doEndTag() and explicit tag state clearing is inequal to new Tag with pageContext/parent set. " + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", - strutsBodyTagsAreReflectionEqual(tag, freshTag)); + strutsBodyTagsAreReflectionEqual(tag, freshTag)); } public void testCustomGlobalFormatFormat() throws Exception { String format = "yyyy/MM/dd hh:mm:ss"; - Date now = new Date(); - String formatted = new SimpleDateFormat(format).format(now); + LocalDateTime now = LocalDateTime.now(); + String formatted = DateTimeFormatter.ofPattern(format).format(now); context.put("myDate", now); ((TestAction) action).setText(org.apache.struts2.components.Date.DATETAG_PROPERTY, format); @@ -106,10 +146,8 @@ public class DateTagTest extends AbstractTagTest { public void testCustomFormatWithTimezone() throws Exception { String format = "yyyy/MM/dd hh:mm:ss"; - Date now = Calendar.getInstance(TimeZone.getTimeZone("GMT+1")).getTime(); - SimpleDateFormat sdf = new SimpleDateFormat(format); - sdf.setTimeZone(TimeZone.getTimeZone("GMT+1")); - String formatted = sdf.format(now); + LocalDateTime now = LocalDateTime.now(ZoneId.of("GMT+1")); + String formatted = DateTimeFormatter.ofPattern(format).format(now); context.put("myDate", now); tag.setName("myDate"); @@ -126,15 +164,13 @@ public class DateTagTest extends AbstractTagTest { freshTag.setPageContext(pageContext); assertFalse("Tag state after doEndTag() under default tag clear state is equal to new Tag with pageContext/parent set. " + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", - strutsBodyTagsAreReflectionEqual(tag, freshTag)); + strutsBodyTagsAreReflectionEqual(tag, freshTag)); } public void testCustomFormatWithTimezone_clearTagStateSet() throws Exception { String format = "yyyy/MM/dd hh:mm:ss"; - Date now = Calendar.getInstance(TimeZone.getTimeZone("GMT+1")).getTime(); - SimpleDateFormat sdf = new SimpleDateFormat(format); - sdf.setTimeZone(TimeZone.getTimeZone("GMT+1")); - String formatted = sdf.format(now); + LocalDateTime now = LocalDateTime.now(ZoneId.of("GMT+1")); + String formatted = DateTimeFormatter.ofPattern(format).format(now); context.put("myDate", now); tag.setPerformClearTagStateForTagPoolingServers(true); // Explicitly request tag state clearing. @@ -153,15 +189,13 @@ public class DateTagTest extends AbstractTagTest { freshTag.setPageContext(pageContext); assertTrue("Tag state after doEndTag() and explicit tag state clearing is inequal to new Tag with pageContext/parent set. " + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", - strutsBodyTagsAreReflectionEqual(tag, freshTag)); + strutsBodyTagsAreReflectionEqual(tag, freshTag)); } public void testCustomFormatWithTimezoneAsExpression() throws Exception { String format = "yyyy/MM/dd hh:mm:ss"; - Date now = Calendar.getInstance(TimeZone.getTimeZone("GMT+2")).getTime(); - SimpleDateFormat sdf = new SimpleDateFormat(format); - sdf.setTimeZone(TimeZone.getTimeZone("GMT+2")); - String formatted = sdf.format(now); + LocalDateTime now = LocalDateTime.now(ZoneId.of("GMT+2")); + String formatted = DateTimeFormatter.ofPattern(format).format(now); context.put("myDate", now); context.put("myTimezone", "GMT+2"); @@ -178,15 +212,13 @@ public class DateTagTest extends AbstractTagTest { freshTag.setPageContext(pageContext); assertFalse("Tag state after doEndTag() under default tag clear state is equal to new Tag with pageContext/parent set. " + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", - strutsBodyTagsAreReflectionEqual(tag, freshTag)); + strutsBodyTagsAreReflectionEqual(tag, freshTag)); } public void testCustomFormatWithTimezoneAsExpression_clearTagStateSet() throws Exception { String format = "yyyy/MM/dd hh:mm:ss"; - Date now = Calendar.getInstance(TimeZone.getTimeZone("GMT+2")).getTime(); - SimpleDateFormat sdf = new SimpleDateFormat(format); - sdf.setTimeZone(TimeZone.getTimeZone("GMT+2")); - String formatted = sdf.format(now); + LocalDateTime now = LocalDateTime.now(ZoneId.of("GMT+2")); + String formatted = DateTimeFormatter.ofPattern(format).format(now); context.put("myDate", now); context.put("myTimezone", "GMT+2"); @@ -206,13 +238,13 @@ public class DateTagTest extends AbstractTagTest { freshTag.setPageContext(pageContext); assertTrue("Tag state after doEndTag() and explicit tag state clearing is inequal to new Tag with pageContext/parent set. " + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", - strutsBodyTagsAreReflectionEqual(tag, freshTag)); + strutsBodyTagsAreReflectionEqual(tag, freshTag)); } public void testCustomFormatCalendar() throws Exception { String format = "yyyy/MM/dd hh:mm:ss"; Calendar calendar = Calendar.getInstance(); - String formatted = new SimpleDateFormat(format).format(calendar.getTime()); + String formatted = DateTimeFormatter.ofPattern(format).format(calendar.toInstant().atZone(ZoneId.systemDefault())); context.put("myDate", calendar); tag.setName("myDate"); @@ -227,13 +259,13 @@ public class DateTagTest extends AbstractTagTest { freshTag.setPageContext(pageContext); assertFalse("Tag state after doEndTag() under default tag clear state is equal to new Tag with pageContext/parent set. " + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", - strutsBodyTagsAreReflectionEqual(tag, freshTag)); + strutsBodyTagsAreReflectionEqual(tag, freshTag)); } public void testCustomFormatCalendar_clearTagStateSet() throws Exception { String format = "yyyy/MM/dd hh:mm:ss"; Calendar calendar = Calendar.getInstance(); - String formatted = new SimpleDateFormat(format).format(calendar.getTime()); + String formatted = DateTimeFormatter.ofPattern(format).format(calendar.toInstant().atZone(ZoneId.systemDefault())); context.put("myDate", calendar); tag.setPerformClearTagStateForTagPoolingServers(true); // Explicitly request tag state clearing. @@ -251,13 +283,13 @@ public class DateTagTest extends AbstractTagTest { freshTag.setPageContext(pageContext); assertTrue("Tag state after doEndTag() and explicit tag state clearing is inequal to new Tag with pageContext/parent set. " + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", - strutsBodyTagsAreReflectionEqual(tag, freshTag)); + strutsBodyTagsAreReflectionEqual(tag, freshTag)); } public void testCustomFormatLong() throws Exception { String format = "yyyy/MM/dd hh:mm:ss"; Date date = new Date(); - String formatted = new SimpleDateFormat(format).format(date); + String formatted = DateTimeFormatter.ofPattern(format).format(date.toInstant().atZone(ZoneId.systemDefault())); // long context.put("myDate", date.getTime()); @@ -273,13 +305,13 @@ public class DateTagTest extends AbstractTagTest { freshTag.setPageContext(pageContext); assertFalse("Tag state after doEndTag() under default tag clear state is equal to new Tag with pageContext/parent set. " + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", - strutsBodyTagsAreReflectionEqual(tag, freshTag)); + strutsBodyTagsAreReflectionEqual(tag, freshTag)); } public void testCustomFormatLong_clearTagStateSet() throws Exception { String format = "yyyy/MM/dd hh:mm:ss"; Date date = new Date(); - String formatted = new SimpleDateFormat(format).format(date); + String formatted = DateTimeFormatter.ofPattern(format).format(date.toInstant().atZone(ZoneId.systemDefault())); // long context.put("myDate", date.getTime()); @@ -298,7 +330,7 @@ public class DateTagTest extends AbstractTagTest { freshTag.setPageContext(pageContext); assertTrue("Tag state after doEndTag() and explicit tag state clearing is inequal to new Tag with pageContext/parent set. " + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", - strutsBodyTagsAreReflectionEqual(tag, freshTag)); + strutsBodyTagsAreReflectionEqual(tag, freshTag)); } public void testCustomFormatLocalDateTime() throws Exception { @@ -332,7 +364,7 @@ public class DateTagTest extends AbstractTagTest { public void testDefaultFormat() throws Exception { Date now = new Date(); String formatted = DateFormat.getDateTimeInstance(DateFormat.MEDIUM, DateFormat.MEDIUM, - ActionContext.getContext().getLocale()).format(now); + ActionContext.getContext().getLocale()).format(now); context.put("myDate", now); tag.setName("myDate"); @@ -346,13 +378,13 @@ public class DateTagTest extends AbstractTagTest { freshTag.setPageContext(pageContext); assertFalse("Tag state after doEndTag() under default tag clear state is equal to new Tag with pageContext/parent set. " + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", - strutsBodyTagsAreReflectionEqual(tag, freshTag)); + strutsBodyTagsAreReflectionEqual(tag, freshTag)); } public void testDefaultFormat_clearTagStateSet() throws Exception { Date now = new Date(); String formatted = DateFormat.getDateTimeInstance(DateFormat.MEDIUM, DateFormat.MEDIUM, - ActionContext.getContext().getLocale()).format(now); + ActionContext.getContext().getLocale()).format(now); context.put("myDate", now); tag.setPerformClearTagStateForTagPoolingServers(true); // Explicitly request tag state clearing. @@ -369,13 +401,13 @@ public class DateTagTest extends AbstractTagTest { freshTag.setPageContext(pageContext); assertTrue("Tag state after doEndTag() and explicit tag state clearing is inequal to new Tag with pageContext/parent set. " + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", - strutsBodyTagsAreReflectionEqual(tag, freshTag)); + strutsBodyTagsAreReflectionEqual(tag, freshTag)); } public void testCustomFormatAndComponent() throws Exception { String format = "yyyy/MM/dd hh:mm:ss"; - Date now = new Date(); - String formatted = new SimpleDateFormat(format).format(now); + LocalDateTime now = LocalDateTime.now(); + String formatted = DateTimeFormatter.ofPattern(format).format(now); context.put("myDate", now); tag.setName("myDate"); @@ -388,7 +420,7 @@ public class DateTagTest extends AbstractTagTest { org.apache.struts2.components.Date component = (org.apache.struts2.components.Date) tag.getComponent(); assertEquals("myDate", component.getName()); assertEquals(format, component.getFormat()); - assertEquals(false, component.isNice()); + assertFalse(component.isNice()); tag.doEndTag(); @@ -399,13 +431,13 @@ public class DateTagTest extends AbstractTagTest { freshTag.setPageContext(pageContext); assertFalse("Tag state after doEndTag() under default tag clear state is equal to new Tag with pageContext/parent set. " + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", - strutsBodyTagsAreReflectionEqual(tag, freshTag)); + strutsBodyTagsAreReflectionEqual(tag, freshTag)); } public void testCustomFormatAndComponent_clearTagStateSet() throws Exception { String format = "yyyy/MM/dd hh:mm:ss"; - Date now = new Date(); - String formatted = new SimpleDateFormat(format).format(now); + LocalDateTime now = LocalDateTime.now(); + String formatted = DateTimeFormatter.ofPattern(format).format(now); context.put("myDate", now); tag.setPerformClearTagStateForTagPoolingServers(true); // Explicitly request tag state clearing. @@ -420,7 +452,7 @@ public class DateTagTest extends AbstractTagTest { org.apache.struts2.components.Date component = (org.apache.struts2.components.Date) tag.getComponent(); assertEquals("myDate", component.getName()); assertEquals(format, component.getFormat()); - assertEquals(false, component.isNice()); + assertFalse(component.isNice()); tag.doEndTag(); @@ -432,13 +464,13 @@ public class DateTagTest extends AbstractTagTest { freshTag.setPageContext(pageContext); assertTrue("Tag state after doEndTag() and explicit tag state clearing is inequal to new Tag with pageContext/parent set. " + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", - strutsBodyTagsAreReflectionEqual(tag, freshTag)); + strutsBodyTagsAreReflectionEqual(tag, freshTag)); } public void testSetId() throws Exception { String format = "yyyy/MM/dd hh:mm:ss"; - Date now = new Date(); - String formatted = new SimpleDateFormat(format).format(now); + LocalDateTime now = LocalDateTime.now(); + String formatted = DateTimeFormatter.ofPattern(format).format(now); context.put("myDate", now); tag.setName("myDate"); @@ -454,13 +486,13 @@ public class DateTagTest extends AbstractTagTest { freshTag.setPageContext(pageContext); assertFalse("Tag state after doEndTag() under default tag clear state is equal to new Tag with pageContext/parent set. " + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", - strutsBodyTagsAreReflectionEqual(tag, freshTag)); + strutsBodyTagsAreReflectionEqual(tag, freshTag)); } public void testSetId_clearTagStateSet() throws Exception { String format = "yyyy/MM/dd hh:mm:ss"; - Date now = new Date(); - String formatted = new SimpleDateFormat(format).format(now); + LocalDateTime now = LocalDateTime.now(); + String formatted = DateTimeFormatter.ofPattern(format).format(now); context.put("myDate", now); tag.setPerformClearTagStateForTagPoolingServers(true); // Explicitly request tag state clearing. @@ -479,7 +511,7 @@ public class DateTagTest extends AbstractTagTest { freshTag.setPageContext(pageContext); assertTrue("Tag state after doEndTag() and explicit tag state clearing is inequal to new Tag with pageContext/parent set. " + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", - strutsBodyTagsAreReflectionEqual(tag, freshTag)); + strutsBodyTagsAreReflectionEqual(tag, freshTag)); } public void testFutureNiceHour() throws Exception { @@ -501,7 +533,7 @@ public class DateTagTest extends AbstractTagTest { freshTag.setPageContext(pageContext); assertFalse("Tag state after doEndTag() under default tag clear state is equal to new Tag with pageContext/parent set. " + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", - strutsBodyTagsAreReflectionEqual(tag, freshTag)); + strutsBodyTagsAreReflectionEqual(tag, freshTag)); } public void testFutureNiceHour_clearTagStateSet() throws Exception { @@ -526,7 +558,7 @@ public class DateTagTest extends AbstractTagTest { freshTag.setPageContext(pageContext); assertTrue("Tag state after doEndTag() and explicit tag state clearing is inequal to new Tag with pageContext/parent set. " + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", - strutsBodyTagsAreReflectionEqual(tag, freshTag)); + strutsBodyTagsAreReflectionEqual(tag, freshTag)); } public void testPastNiceHour() throws Exception { @@ -548,7 +580,7 @@ public class DateTagTest extends AbstractTagTest { freshTag.setPageContext(pageContext); assertFalse("Tag state after doEndTag() under default tag clear state is equal to new Tag with pageContext/parent set. " + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", - strutsBodyTagsAreReflectionEqual(tag, freshTag)); + strutsBodyTagsAreReflectionEqual(tag, freshTag)); } public void testPastNiceHour_clearTagStateSet() throws Exception { @@ -573,7 +605,7 @@ public class DateTagTest extends AbstractTagTest { freshTag.setPageContext(pageContext); assertTrue("Tag state after doEndTag() and explicit tag state clearing is inequal to new Tag with pageContext/parent set. " + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", - strutsBodyTagsAreReflectionEqual(tag, freshTag)); + strutsBodyTagsAreReflectionEqual(tag, freshTag)); } public void testFutureNiceHourMinSec() throws Exception { @@ -596,7 +628,7 @@ public class DateTagTest extends AbstractTagTest { freshTag.setPageContext(pageContext); assertFalse("Tag state after doEndTag() under default tag clear state is equal to new Tag with pageContext/parent set. " + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", - strutsBodyTagsAreReflectionEqual(tag, freshTag)); + strutsBodyTagsAreReflectionEqual(tag, freshTag)); } public void testFutureNiceHourMinSec_clearTagStateSet() throws Exception { @@ -622,7 +654,7 @@ public class DateTagTest extends AbstractTagTest { freshTag.setPageContext(pageContext); assertTrue("Tag state after doEndTag() and explicit tag state clearing is inequal to new Tag with pageContext/parent set. " + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", - strutsBodyTagsAreReflectionEqual(tag, freshTag)); + strutsBodyTagsAreReflectionEqual(tag, freshTag)); } public void testPastNiceHourMin() throws Exception { @@ -645,7 +677,7 @@ public class DateTagTest extends AbstractTagTest { freshTag.setPageContext(pageContext); assertFalse("Tag state after doEndTag() under default tag clear state is equal to new Tag with pageContext/parent set. " + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", - strutsBodyTagsAreReflectionEqual(tag, freshTag)); + strutsBodyTagsAreReflectionEqual(tag, freshTag)); } public void testPastNiceHourMin_clearTagStateSet() throws Exception { @@ -671,7 +703,7 @@ public class DateTagTest extends AbstractTagTest { freshTag.setPageContext(pageContext); assertTrue("Tag state after doEndTag() and explicit tag state clearing is inequal to new Tag with pageContext/parent set. " + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", - strutsBodyTagsAreReflectionEqual(tag, freshTag)); + strutsBodyTagsAreReflectionEqual(tag, freshTag)); } public void testFutureLessOneMin() throws Exception { @@ -693,7 +725,7 @@ public class DateTagTest extends AbstractTagTest { freshTag.setPageContext(pageContext); assertFalse("Tag state after doEndTag() under default tag clear state is equal to new Tag with pageContext/parent set. " + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", - strutsBodyTagsAreReflectionEqual(tag, freshTag)); + strutsBodyTagsAreReflectionEqual(tag, freshTag)); } public void testFutureLessOneMin_clearTagStateSet() throws Exception { @@ -718,7 +750,7 @@ public class DateTagTest extends AbstractTagTest { freshTag.setPageContext(pageContext); assertTrue("Tag state after doEndTag() and explicit tag state clearing is inequal to new Tag with pageContext/parent set. " + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", - strutsBodyTagsAreReflectionEqual(tag, freshTag)); + strutsBodyTagsAreReflectionEqual(tag, freshTag)); } public void testFutureLessOneHour() throws Exception { @@ -740,7 +772,7 @@ public class DateTagTest extends AbstractTagTest { freshTag.setPageContext(pageContext); assertFalse("Tag state after doEndTag() under default tag clear state is equal to new Tag with pageContext/parent set. " + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", - strutsBodyTagsAreReflectionEqual(tag, freshTag)); + strutsBodyTagsAreReflectionEqual(tag, freshTag)); } public void testFutureLessOneHour_clearTagStateSet() throws Exception { @@ -765,7 +797,7 @@ public class DateTagTest extends AbstractTagTest { freshTag.setPageContext(pageContext); assertTrue("Tag state after doEndTag() and explicit tag state clearing is inequal to new Tag with pageContext/parent set. " + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", - strutsBodyTagsAreReflectionEqual(tag, freshTag)); + strutsBodyTagsAreReflectionEqual(tag, freshTag)); } public void testFutureLessOneYear() throws Exception { @@ -787,7 +819,7 @@ public class DateTagTest extends AbstractTagTest { freshTag.setPageContext(pageContext); assertFalse("Tag state after doEndTag() under default tag clear state is equal to new Tag with pageContext/parent set. " + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", - strutsBodyTagsAreReflectionEqual(tag, freshTag)); + strutsBodyTagsAreReflectionEqual(tag, freshTag)); } public void testFutureLessOneYear_clearTagStateSet() throws Exception { @@ -812,7 +844,7 @@ public class DateTagTest extends AbstractTagTest { freshTag.setPageContext(pageContext); assertTrue("Tag state after doEndTag() and explicit tag state clearing is inequal to new Tag with pageContext/parent set. " + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", - strutsBodyTagsAreReflectionEqual(tag, freshTag)); + strutsBodyTagsAreReflectionEqual(tag, freshTag)); } public void testFutureTwoYears() throws Exception { @@ -838,7 +870,7 @@ public class DateTagTest extends AbstractTagTest { freshTag.setPageContext(pageContext); assertFalse("Tag state after doEndTag() under default tag clear state is equal to new Tag with pageContext/parent set. " + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", - strutsBodyTagsAreReflectionEqual(tag, freshTag)); + strutsBodyTagsAreReflectionEqual(tag, freshTag)); } public void testFutureTwoYears_clearTagStateSet() throws Exception { @@ -867,7 +899,7 @@ public class DateTagTest extends AbstractTagTest { freshTag.setPageContext(pageContext); assertTrue("Tag state after doEndTag() and explicit tag state clearing is inequal to new Tag with pageContext/parent set. " + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", - strutsBodyTagsAreReflectionEqual(tag, freshTag)); + strutsBodyTagsAreReflectionEqual(tag, freshTag)); } public void testNoDateObjectInContext() throws Exception { @@ -884,7 +916,7 @@ public class DateTagTest extends AbstractTagTest { freshTag.setPageContext(pageContext); assertFalse("Tag state after doEndTag() under default tag clear state is equal to new Tag with pageContext/parent set. " + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", - strutsBodyTagsAreReflectionEqual(tag, freshTag)); + strutsBodyTagsAreReflectionEqual(tag, freshTag)); } public void testNoDateObjectInContext_clearTagStateSet() throws Exception { @@ -904,7 +936,7 @@ public class DateTagTest extends AbstractTagTest { freshTag.setPageContext(pageContext); assertTrue("Tag state after doEndTag() and explicit tag state clearing is inequal to new Tag with pageContext/parent set. " + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", - strutsBodyTagsAreReflectionEqual(tag, freshTag)); + strutsBodyTagsAreReflectionEqual(tag, freshTag)); } /** @@ -912,10 +944,8 @@ public class DateTagTest extends AbstractTagTest { * since that tag does not have its own unit tests, and it also appears to be * a broken tag. The code coverage tests can be moved if the tag is fixed, or * removed if the tag is dropped. - * - * @throws Exception */ - public void testDateTextFieldTag_artificialCoverageTest() throws Exception { + public void testDateTextFieldTag_artificialCoverageTest() throws JspException { final String format = "yyyy/MM/dd hh:mm:ss"; DateTextFieldTag dateTextFieldTag = createDateTextFieldTag(); dateTextFieldTag.setFormat(format); @@ -939,20 +969,40 @@ public class DateTagTest extends AbstractTagTest { freshTag.setPageContext(pageContext); assertTrue("Tag state after doEndTag() and explicit tag state clearing is inequal to new Tag with pageContext/parent set. " + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", - strutsBodyTagsAreReflectionEqual(dateTextFieldTag, freshTag)); + strutsBodyTagsAreReflectionEqual(dateTextFieldTag, freshTag)); + } + + public void testNewJava8Format() throws Exception { + String format = "EEEE MMMM dd, hh:mm a"; + LocalDateTime now = LocalDateTime.now(); + String formatted = DateTimeFormatter.ofPattern(format, ActionContext.getContext().getLocale()).format(now); + context.put("myDate", now); + + tag.setName("myDate"); + tag.setNice(false); + tag.setFormat(format); + tag.doStartTag(); + tag.doEndTag(); + assertEquals(formatted, writer.toString()); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + DateTag freshTag = new DateTag(); + freshTag.setPageContext(pageContext); + assertFalse("Tag state after doEndTag() under default tag clear state is equal to new Tag with pageContext/parent set. " + + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", + strutsBodyTagsAreReflectionEqual(tag, freshTag)); } /** * Utility method to create a new {@link DateTextFieldTag} instance for code coverage tests. - * + * <p> * Note: There is no datetextfield.ftl template for the tag, so it does not appear that it can - * actually be used in practice. We can perform basic coverage tests from within this - * unit test class until the {@link DateTextFieldTag} is fixed or removed. - * + * actually be used in practice. We can perform basic coverage tests from within this + * unit test class until the {@link DateTextFieldTag} is fixed or removed. + * * @return a basic {@link DateTextFieldTag} instance - * @throws Exception */ - private DateTextFieldTag createDateTextFieldTag() throws Exception { + private DateTextFieldTag createDateTextFieldTag() { DateTextFieldTag tag = new DateTextFieldTag(); tag.setPageContext(pageContext); tag.setName("myDate");