From cb0d0e770a63a415d280bdfe0e4f27b2cb2c883e Mon Sep 17 00:00:00 2001 From: JCgH4164838Gh792C124B5 <43964333+JCgH4164838Gh792C124B5@users.noreply.github.com> Date: Sat, 30 Oct 2021 15:17:03 -0400 Subject: [PATCH 1/7] WW-5124 - Proposed fix for Struts JSP tag behaviour on application servers that use tag pooling. - Prior to this change, on application serves such as Glassfish, tag pools that re-use tag instances demonstrated incorrect behaviour, due to previous / old tag state still being present. - Added new clearTagStateForTagPoolingServers() to StrutsBodyTagSupport. It is called in doEndTag(), and descendants that override doEndTag() should call the ancestor method or directly call clearTagStateForTagPoolingServers(). - Unit test support methods were added to StrutsInternalTestCase and AbstractTagTest. - Basic sanity checks for existing unit tests were added where feasible. They reflection-compare a tag's state after doEndTag() is called with that of a new instance, to help catch if future changes miss calls in the clearTagStateForTagPoolingServers() hierarchy. - Removed some unused imports, added some missing override annotations to classes that were modified as part of this change. # Conflicts: # core/src/main/java/org/apache/struts2/views/jsp/StrutsBodyTagSupport.java # core/src/main/java/org/apache/struts2/views/jsp/ui/AnchorTag.java # core/src/main/java/org/apache/struts2/views/jsp/ui/CheckboxTag.java # core/src/main/java/org/apache/struts2/views/jsp/ui/SubmitTag.java # core/src/test/java/org/apache/struts2/StrutsInternalTestCase.java # core/src/test/java/org/apache/struts2/views/jsp/ActionTagTest.java # core/src/test/java/org/apache/struts2/views/jsp/PropertyTagTest.java # core/src/test/java/org/apache/struts2/views/jsp/TextTagTest.java # core/src/test/java/org/apache/struts2/views/jsp/ui/FormTagTest.java - Manually attempted to resolved conflicts. --- .../apache/struts2/views/jsp/ActionTag.java | 13 + .../org/apache/struts2/views/jsp/BeanTag.java | 9 + .../views/jsp/ComponentTagSupport.java | 11 +- .../struts2/views/jsp/ContextBeanTag.java | 8 + .../org/apache/struts2/views/jsp/DateTag.java | 11 + .../apache/struts2/views/jsp/ElseIfTag.java | 9 + .../org/apache/struts2/views/jsp/I18nTag.java | 9 + .../org/apache/struts2/views/jsp/IfTag.java | 9 + .../apache/struts2/views/jsp/IncludeTag.java | 9 + .../apache/struts2/views/jsp/IteratorTag.java | 15 + .../apache/struts2/views/jsp/NumberTag.java | 17 + .../apache/struts2/views/jsp/ParamTag.java | 11 + .../apache/struts2/views/jsp/PropertyTag.java | 14 + .../org/apache/struts2/views/jsp/PushTag.java | 9 + .../org/apache/struts2/views/jsp/SetTag.java | 11 + .../views/jsp/StrutsBodyTagSupport.java | 35 ++- .../org/apache/struts2/views/jsp/TextTag.java | 13 + .../org/apache/struts2/views/jsp/URLTag.java | 22 ++ .../jsp/iterator/IteratorGeneratorTag.java | 14 + .../views/jsp/iterator/SortIteratorTag.java | 13 + .../views/jsp/iterator/SubsetIteratorTag.java | 17 +- .../views/jsp/ui/AbstractClosingTag.java | 8 + .../views/jsp/ui/AbstractDoubleListTag.java | 45 +++ .../struts2/views/jsp/ui/AbstractListTag.java | 15 + .../struts2/views/jsp/ui/AbstractUITag.java | 47 +++ .../struts2/views/jsp/ui/ActionErrorTag.java | 9 + .../views/jsp/ui/ActionMessageTag.java | 10 +- .../struts2/views/jsp/ui/AnchorTag.java | 24 +- .../struts2/views/jsp/ui/CheckboxTag.java | 9 + .../struts2/views/jsp/ui/ComboBoxTag.java | 14 + .../views/jsp/ui/DateTextFieldTag.java | 14 +- .../struts2/views/jsp/ui/FieldErrorTag.java | 11 +- .../apache/struts2/views/jsp/ui/FileTag.java | 10 + .../apache/struts2/views/jsp/ui/FormTag.java | 21 ++ .../views/jsp/ui/InputTransferSelectTag.java | 23 ++ .../apache/struts2/views/jsp/ui/LabelTag.java | 9 + .../struts2/views/jsp/ui/OptGroupTag.java | 16 + .../views/jsp/ui/OptionTransferSelectTag.java | 35 +++ .../struts2/views/jsp/ui/PasswordTag.java | 9 + .../apache/struts2/views/jsp/ui/ResetTag.java | 11 + .../struts2/views/jsp/ui/SelectTag.java | 12 + .../struts2/views/jsp/ui/SubmitTag.java | 12 + .../struts2/views/jsp/ui/TextFieldTag.java | 12 + .../struts2/views/jsp/ui/TextareaTag.java | 11 + .../struts2/views/jsp/ui/UpDownSelectTag.java | 14 + .../struts2/StrutsInternalTestCase.java | 26 +- .../struts2/views/jsp/AbstractTagTest.java | 25 ++ .../struts2/views/jsp/ActionTagTest.java | 78 +++++ .../struts2/views/jsp/AnchorTagTest.java | 239 +++++++++++++- .../views/jsp/AppendIteratorTagTest.java | 41 +++ .../apache/struts2/views/jsp/BeanTagTest.java | 7 + .../struts2/views/jsp/ElseIfTagTest.java | 29 ++ .../apache/struts2/views/jsp/ElseTagTest.java | 24 ++ .../apache/struts2/views/jsp/I18nTagTest.java | 8 + .../apache/struts2/views/jsp/IfTagTest.java | 138 ++++++++ .../struts2/views/jsp/IncludeTagTest.java | 39 ++- .../views/jsp/IteratorGeneratorTagTest.java | 36 +++ .../struts2/views/jsp/IteratorTagTest.java | 98 ++++-- .../views/jsp/MergeIteratorTagTest.java | 40 +++ .../struts2/views/jsp/NumberTagTest.java | 25 ++ .../struts2/views/jsp/PropertyTagTest.java | 191 ++++++++--- .../apache/struts2/views/jsp/PushTagTest.java | 7 + .../apache/struts2/views/jsp/SetTagTest.java | 68 ++++ .../views/jsp/SortIteratorTagTest.java | 24 ++ .../views/jsp/SubsetIteratorTagTest.java | 85 +++++ .../apache/struts2/views/jsp/TextTagTest.java | 138 +++++++- .../apache/struts2/views/jsp/URLTagTest.java | 290 ++++++++++++++++- .../views/jsp/ui/ActionErrorTagTest.java | 45 +++ .../views/jsp/ui/ActionMessageTagTest.java | 47 ++- .../struts2/views/jsp/ui/AnchorTest.java | 28 ++ .../views/jsp/ui/CheckboxListTest.java | 29 ++ .../struts2/views/jsp/ui/CheckboxTest.java | 52 ++- .../struts2/views/jsp/ui/ComboBoxTest.java | 28 ++ .../struts2/views/jsp/ui/ComponentTest.java | 32 +- .../struts2/views/jsp/ui/DateTagTest.java | 121 +++++++ .../struts2/views/jsp/ui/DebugTagTest.java | 28 ++ .../views/jsp/ui/DoubleSelectTest.java | 28 +- .../views/jsp/ui/FieldErrorTagTest.java | 148 +++++++++ .../apache/struts2/views/jsp/ui/FileTest.java | 8 + .../struts2/views/jsp/ui/FormTagTest.java | 297 +++++++++++++++++- .../struts2/views/jsp/ui/HeadTagTest.java | 7 + .../struts2/views/jsp/ui/HiddenTest.java | 33 +- .../jsp/ui/InputTransferSelectTagTest.java | 7 + .../struts2/views/jsp/ui/JspTemplateTest.java | 7 + .../struts2/views/jsp/ui/LabelTest.java | 57 ++++ .../struts2/views/jsp/ui/OptGroupTest.java | 136 ++++++++ .../jsp/ui/OptionTransferSelectTagTest.java | 49 +++ .../struts2/views/jsp/ui/PasswordTest.java | 7 + .../struts2/views/jsp/ui/RadioTest.java | 56 ++++ .../struts2/views/jsp/ui/ResetTest.java | 71 +++++ .../struts2/views/jsp/ui/SelectTest.java | 119 +++++++ .../struts2/views/jsp/ui/SubmitTest.java | 78 +++++ .../struts2/views/jsp/ui/TextareaTest.java | 8 + .../struts2/views/jsp/ui/TextfieldTest.java | 113 +++++++ .../struts2/views/jsp/ui/TokenTagTest.java | 7 + .../struts2/views/jsp/ui/TooltipTest.java | 134 ++++++++ .../views/jsp/ui/UpDownSelectTagTest.java | 78 +++++ .../views/jsp/ui/ValidationStylesTest.java | 35 +++ 98 files changed, 4132 insertions(+), 97 deletions(-) diff --git a/core/src/main/java/org/apache/struts2/views/jsp/ActionTag.java b/core/src/main/java/org/apache/struts2/views/jsp/ActionTag.java index 948808bb1..b298941eb 100644 --- a/core/src/main/java/org/apache/struts2/views/jsp/ActionTag.java +++ b/core/src/main/java/org/apache/struts2/views/jsp/ActionTag.java @@ -39,10 +39,12 @@ public class ActionTag extends ContextBeanTag { protected boolean flush = true; protected boolean rethrowException; + @Override public Component getBean(ValueStack stack, HttpServletRequest req, HttpServletResponse res) { return new ActionComponent(stack, req, res); } + @Override protected void populateParams() { super.populateParams(); @@ -88,4 +90,15 @@ public class ActionTag extends ContextBeanTag { this.rethrowException = rethrowException; } + @Override + public void clearTagStateForTagPoolingServers() { + super.clearTagStateForTagPoolingServers(); + this.name = null; + this.namespace = null; + this.executeResult = false; + this.ignoreContextParams = false; + this.flush = true; + this.rethrowException = false; + } + } diff --git a/core/src/main/java/org/apache/struts2/views/jsp/BeanTag.java b/core/src/main/java/org/apache/struts2/views/jsp/BeanTag.java index 7b2c3a587..a0535cdd9 100644 --- a/core/src/main/java/org/apache/struts2/views/jsp/BeanTag.java +++ b/core/src/main/java/org/apache/struts2/views/jsp/BeanTag.java @@ -39,10 +39,12 @@ public class BeanTag extends ContextBeanTag { protected String name; + @Override public Component getBean(ValueStack stack, HttpServletRequest req, HttpServletResponse res) { return new Bean(stack); } + @Override protected void populateParams() { super.populateParams(); @@ -52,4 +54,11 @@ public class BeanTag extends ContextBeanTag { public void setName(String name) { this.name = name; } + + @Override + public void clearTagStateForTagPoolingServers() { + super.clearTagStateForTagPoolingServers(); + this.name = null; + } + } diff --git a/core/src/main/java/org/apache/struts2/views/jsp/ComponentTagSupport.java b/core/src/main/java/org/apache/struts2/views/jsp/ComponentTagSupport.java index 9dd463cb6..ee7a9b650 100644 --- a/core/src/main/java/org/apache/struts2/views/jsp/ComponentTagSupport.java +++ b/core/src/main/java/org/apache/struts2/views/jsp/ComponentTagSupport.java @@ -35,12 +35,14 @@ public abstract class ComponentTagSupport extends StrutsBodyTagSupport { public abstract Component getBean(ValueStack stack, HttpServletRequest req, HttpServletResponse res); + @Override public int doEndTag() throws JspException { component.end(pageContext.getOut(), getBody()); - component = null; + clearTagStateForTagPoolingServers(); // Moved the component reference clear into this method call. return EVAL_PAGE; } + @Override public int doStartTag() throws JspException { ValueStack stack = getStack(); component = getBean(stack, (HttpServletRequest) pageContext.getRequest(), (HttpServletResponse) pageContext.getResponse()); @@ -63,4 +65,11 @@ public abstract class ComponentTagSupport extends StrutsBodyTagSupport { public Component getComponent() { return component; } + + @Override + protected void clearTagStateForTagPoolingServers() { + super.clearTagStateForTagPoolingServers(); + component = null; + } + } diff --git a/core/src/main/java/org/apache/struts2/views/jsp/ContextBeanTag.java b/core/src/main/java/org/apache/struts2/views/jsp/ContextBeanTag.java index 470fae5e0..790e65ca7 100644 --- a/core/src/main/java/org/apache/struts2/views/jsp/ContextBeanTag.java +++ b/core/src/main/java/org/apache/struts2/views/jsp/ContextBeanTag.java @@ -24,6 +24,7 @@ import org.apache.struts2.components.ContextBean; public abstract class ContextBeanTag extends ComponentTagSupport { private String var; + @Override protected void populateParams() { super.populateParams(); @@ -34,4 +35,11 @@ public abstract class ContextBeanTag extends ComponentTagSupport { public void setVar(String var) { this.var = var; } + + @Override + public void clearTagStateForTagPoolingServers() { + super.clearTagStateForTagPoolingServers(); + this.var = null; + } + } diff --git a/core/src/main/java/org/apache/struts2/views/jsp/DateTag.java b/core/src/main/java/org/apache/struts2/views/jsp/DateTag.java index 73b62f1a7..a9dabc8b4 100644 --- a/core/src/main/java/org/apache/struts2/views/jsp/DateTag.java +++ b/core/src/main/java/org/apache/struts2/views/jsp/DateTag.java @@ -37,10 +37,12 @@ public class DateTag extends ContextBeanTag { protected boolean nice; protected String timezone; + @Override public Component getBean(ValueStack stack, HttpServletRequest req, HttpServletResponse res) { return new Date(stack); } + @Override protected void populateParams() { super.populateParams(); Date d = (Date)component; @@ -66,4 +68,13 @@ public class DateTag extends ContextBeanTag { this.timezone = timezone; } + @Override + public void clearTagStateForTagPoolingServers() { + super.clearTagStateForTagPoolingServers(); + this.name = null; + this.format = null; + this.nice = false; + this.timezone = null; + } + } diff --git a/core/src/main/java/org/apache/struts2/views/jsp/ElseIfTag.java b/core/src/main/java/org/apache/struts2/views/jsp/ElseIfTag.java index 999f8c6ca..acc438f18 100644 --- a/core/src/main/java/org/apache/struts2/views/jsp/ElseIfTag.java +++ b/core/src/main/java/org/apache/struts2/views/jsp/ElseIfTag.java @@ -35,10 +35,12 @@ public class ElseIfTag extends ComponentTagSupport { protected String test; + @Override public Component getBean(ValueStack stack, HttpServletRequest req, HttpServletResponse res) { return new ElseIf(stack); } + @Override protected void populateParams() { ((ElseIf) getComponent()).setTest(test); } @@ -46,4 +48,11 @@ public class ElseIfTag extends ComponentTagSupport { public void setTest(String test) { this.test = test; } + + @Override + public void clearTagStateForTagPoolingServers() { + super.clearTagStateForTagPoolingServers(); + this.test = null; + } + } diff --git a/core/src/main/java/org/apache/struts2/views/jsp/I18nTag.java b/core/src/main/java/org/apache/struts2/views/jsp/I18nTag.java index de1a1ee16..f58c4d248 100644 --- a/core/src/main/java/org/apache/struts2/views/jsp/I18nTag.java +++ b/core/src/main/java/org/apache/struts2/views/jsp/I18nTag.java @@ -35,10 +35,12 @@ public class I18nTag extends ComponentTagSupport { protected String name; + @Override public Component getBean(ValueStack stack, HttpServletRequest req, HttpServletResponse res) { return new I18n(stack); } + @Override protected void populateParams() { super.populateParams(); @@ -48,4 +50,11 @@ public class I18nTag extends ComponentTagSupport { public void setName(String name) { this.name = name; } + + @Override + public void clearTagStateForTagPoolingServers() { + super.clearTagStateForTagPoolingServers(); + this.name = null; + } + } diff --git a/core/src/main/java/org/apache/struts2/views/jsp/IfTag.java b/core/src/main/java/org/apache/struts2/views/jsp/IfTag.java index 4f4e56eff..5a2373f6c 100644 --- a/core/src/main/java/org/apache/struts2/views/jsp/IfTag.java +++ b/core/src/main/java/org/apache/struts2/views/jsp/IfTag.java @@ -35,10 +35,12 @@ public class IfTag extends ComponentTagSupport { String test; + @Override public Component getBean(ValueStack stack, HttpServletRequest req, HttpServletResponse res) { return new If(stack); } + @Override protected void populateParams() { ((If) getComponent()).setTest(test); } @@ -46,4 +48,11 @@ public class IfTag extends ComponentTagSupport { public void setTest(String test) { this.test = test; } + + @Override + public void clearTagStateForTagPoolingServers() { + super.clearTagStateForTagPoolingServers(); + this.test = null; + } + } diff --git a/core/src/main/java/org/apache/struts2/views/jsp/IncludeTag.java b/core/src/main/java/org/apache/struts2/views/jsp/IncludeTag.java index 1b811bbac..c63474315 100644 --- a/core/src/main/java/org/apache/struts2/views/jsp/IncludeTag.java +++ b/core/src/main/java/org/apache/struts2/views/jsp/IncludeTag.java @@ -35,10 +35,12 @@ public class IncludeTag extends ComponentTagSupport { protected String value; + @Override public Component getBean(ValueStack stack, HttpServletRequest req, HttpServletResponse res) { return new Include(stack, req, res); } + @Override protected void populateParams() { super.populateParams(); @@ -48,4 +50,11 @@ public class IncludeTag extends ComponentTagSupport { public void setValue(String value) { this.value = value; } + + @Override + public void clearTagStateForTagPoolingServers() { + super.clearTagStateForTagPoolingServers(); + this.value = null; + } + } diff --git a/core/src/main/java/org/apache/struts2/views/jsp/IteratorTag.java b/core/src/main/java/org/apache/struts2/views/jsp/IteratorTag.java index 397257ea2..d46f257a7 100644 --- a/core/src/main/java/org/apache/struts2/views/jsp/IteratorTag.java +++ b/core/src/main/java/org/apache/struts2/views/jsp/IteratorTag.java @@ -39,10 +39,12 @@ public class IteratorTag extends ContextBeanTag { protected String end; protected String step; + @Override public Component getBean(ValueStack stack, HttpServletRequest req, HttpServletResponse res) { return new IteratorComponent(stack); } + @Override protected void populateParams() { super.populateParams(); @@ -74,11 +76,14 @@ public class IteratorTag extends ContextBeanTag { this.step = step; } + @Override public int doEndTag() throws JspException { component = null; + clearTagStateForTagPoolingServers(); return EVAL_PAGE; } + @Override public int doAfterBody() throws JspException { boolean again = component.end(pageContext.getOut(), getBody()); @@ -96,4 +101,14 @@ public class IteratorTag extends ContextBeanTag { } } + @Override + public void clearTagStateForTagPoolingServers() { + super.clearTagStateForTagPoolingServers(); + this.statusAttr = null; + this.value = null; + this.begin = null; + this.end = null; + this.step = null; + } + } diff --git a/core/src/main/java/org/apache/struts2/views/jsp/NumberTag.java b/core/src/main/java/org/apache/struts2/views/jsp/NumberTag.java index a74f2aa27..23084d9ad 100644 --- a/core/src/main/java/org/apache/struts2/views/jsp/NumberTag.java +++ b/core/src/main/java/org/apache/struts2/views/jsp/NumberTag.java @@ -43,10 +43,12 @@ public class NumberTag extends ContextBeanTag { private Boolean parseIntegerOnly; private String roundingMode; + @Override public Component getBean(ValueStack stack, HttpServletRequest req, HttpServletResponse res) { return new Number(stack); } + @Override protected void populateParams() { super.populateParams(); Number n = (Number) component; @@ -133,4 +135,19 @@ public class NumberTag extends ContextBeanTag { this.roundingMode = roundingMode; } + @Override + public void clearTagStateForTagPoolingServers() { + super.clearTagStateForTagPoolingServers(); + this.name = null; + this.currency = null; + this.type = null; + this.groupingUsed = null; + this.maximumFractionDigits = null; + this.maximumIntegerDigits = null; + this.minimumFractionDigits = null; + this.minimumIntegerDigits = null; + this.parseIntegerOnly = null; + this.roundingMode = null; + } + } diff --git a/core/src/main/java/org/apache/struts2/views/jsp/ParamTag.java b/core/src/main/java/org/apache/struts2/views/jsp/ParamTag.java index 3f1fe6015..006bbe6eb 100644 --- a/core/src/main/java/org/apache/struts2/views/jsp/ParamTag.java +++ b/core/src/main/java/org/apache/struts2/views/jsp/ParamTag.java @@ -36,10 +36,12 @@ public class ParamTag extends ComponentTagSupport { protected String value; protected boolean suppressEmptyParameters; + @Override public Component getBean(ValueStack stack, HttpServletRequest req, HttpServletResponse res) { return new Param(stack); } + @Override protected void populateParams() { super.populateParams(); @@ -60,4 +62,13 @@ public class ParamTag extends ComponentTagSupport { public void setSuppressEmptyParameters(boolean suppressEmptyParameters) { this.suppressEmptyParameters = suppressEmptyParameters; } + + @Override + public void clearTagStateForTagPoolingServers() { + super.clearTagStateForTagPoolingServers(); + this.name = null; + this.value = null; + this.suppressEmptyParameters = false; + } + } diff --git a/core/src/main/java/org/apache/struts2/views/jsp/PropertyTag.java b/core/src/main/java/org/apache/struts2/views/jsp/PropertyTag.java index 12abe6bbb..99a1c10a7 100644 --- a/core/src/main/java/org/apache/struts2/views/jsp/PropertyTag.java +++ b/core/src/main/java/org/apache/struts2/views/jsp/PropertyTag.java @@ -40,10 +40,12 @@ public class PropertyTag extends ComponentTagSupport { private boolean escapeXml = false; private boolean escapeCsv = false; + @Override public Component getBean(ValueStack stack, HttpServletRequest req, HttpServletResponse res) { return new Property(stack); } + @Override protected void populateParams() { super.populateParams(); @@ -83,4 +85,16 @@ public class PropertyTag extends ComponentTagSupport { public void setEscapeXml(boolean escapeXml) { this.escapeXml = escapeXml; } + + @Override + public void clearTagStateForTagPoolingServers() { + super.clearTagStateForTagPoolingServers(); + this.defaultValue = null; + this.value = null; + this.escapeHtml = true; + this.escapeJavaScript = false; + this.escapeXml = false; + this.escapeCsv = false; + } + } diff --git a/core/src/main/java/org/apache/struts2/views/jsp/PushTag.java b/core/src/main/java/org/apache/struts2/views/jsp/PushTag.java index 1a48b767d..d575255e5 100644 --- a/core/src/main/java/org/apache/struts2/views/jsp/PushTag.java +++ b/core/src/main/java/org/apache/struts2/views/jsp/PushTag.java @@ -35,10 +35,12 @@ public class PushTag extends ComponentTagSupport { protected String value; + @Override public Component getBean(ValueStack stack, HttpServletRequest req, HttpServletResponse res) { return new Push(stack); } + @Override protected void populateParams() { super.populateParams(); @@ -48,4 +50,11 @@ public class PushTag extends ComponentTagSupport { public void setValue(String value) { this.value = value; } + + @Override + public void clearTagStateForTagPoolingServers() { + super.clearTagStateForTagPoolingServers(); + this.value = null; + } + } diff --git a/core/src/main/java/org/apache/struts2/views/jsp/SetTag.java b/core/src/main/java/org/apache/struts2/views/jsp/SetTag.java index 581720300..910498108 100644 --- a/core/src/main/java/org/apache/struts2/views/jsp/SetTag.java +++ b/core/src/main/java/org/apache/struts2/views/jsp/SetTag.java @@ -37,10 +37,12 @@ public class SetTag extends ContextBeanTag { protected String value; protected boolean trimBody = true; + @Override public Component getBean(ValueStack stack, HttpServletRequest req, HttpServletResponse res) { return new Set(stack); } + @Override protected void populateParams() { super.populateParams(); @@ -77,4 +79,13 @@ public class SetTag extends ContextBeanTag { return (bodyContent == null ? null : bodyContent.getString()); } } + + @Override + public void clearTagStateForTagPoolingServers() { + super.clearTagStateForTagPoolingServers(); + this.scope = null; + this.value = null; + this.trimBody = true; + } + } diff --git a/core/src/main/java/org/apache/struts2/views/jsp/StrutsBodyTagSupport.java b/core/src/main/java/org/apache/struts2/views/jsp/StrutsBodyTagSupport.java index 2a89b0e11..597073c04 100644 --- a/core/src/main/java/org/apache/struts2/views/jsp/StrutsBodyTagSupport.java +++ b/core/src/main/java/org/apache/struts2/views/jsp/StrutsBodyTagSupport.java @@ -20,11 +20,12 @@ package org.apache.struts2.views.jsp; import com.opensymphony.xwork2.util.TextParseUtil; import com.opensymphony.xwork2.util.ValueStack; +import java.io.PrintWriter; +import javax.servlet.jsp.JspException; +import javax.servlet.jsp.tagext.BodyTagSupport; import org.apache.struts2.util.ComponentUtils; import org.apache.struts2.util.FastByteArrayOutputStream; -import javax.servlet.jsp.tagext.BodyTagSupport; -import java.io.PrintWriter; /** * Contains common functonalities for Struts JSP Tags. @@ -72,4 +73,34 @@ public class StrutsBodyTagSupport extends BodyTagSupport { return bodyContent.getString().trim(); } } + + @Override + public int doEndTag() throws JspException { + clearTagStateForTagPoolingServers(); + return super.doEndTag(); + } + + /** + * Provide a mechanism to clear tag state, to handle servlet container JSP tag pooling + * behaviour with some servers, such as Glassfish. + * + * Usage: Override this method in descendant classes to clear any state that might cause issues should the + * servlet container re-use a cached instance of the tag object. If the descendant class does not + * declare any new field members then it should not be strictly necessary to call this method there. + * Typically that means calling the ancestor's {@link ComponentTagSupport#clearTagStateForTagPoolingServers()} + * method first, then resetting instance variables at the current level to their default state. + * + * Note: If the descendant overrides {@link StrutsBodyTagSupport#doEndTag()}, and does not call + * super.doEndTag(), then the descendant should call this method in the descendant doEndTag() method + * to ensure consistent clearing of tag state. + */ + protected void clearTagStateForTagPoolingServers() { + // Default implementation. + this.setBodyContent(null); // Always clear the tag body (if any) after tag completion. + this.setId(null); // Always clear the tag id (if any) after tag completion. + // Note: The pageContext and parent Tag state are NOT cleared, only the "user-defined" tag state should be cleared. + // Calling setPageContext(null) and setParent(null) appears too dangerous to consider, and the container + // should always set them, even if a tag instance from a pool is re-used. + } + } diff --git a/core/src/main/java/org/apache/struts2/views/jsp/TextTag.java b/core/src/main/java/org/apache/struts2/views/jsp/TextTag.java index 8f93ad61f..4c8dc0cf1 100644 --- a/core/src/main/java/org/apache/struts2/views/jsp/TextTag.java +++ b/core/src/main/java/org/apache/struts2/views/jsp/TextTag.java @@ -39,10 +39,12 @@ public class TextTag extends ContextBeanTag { private boolean escapeXml = false; private boolean escapeCsv = false; + @Override public Component getBean(ValueStack stack, HttpServletRequest req, HttpServletResponse res) { return new Text(stack); } + @Override protected void populateParams() { super.populateParams(); @@ -74,4 +76,15 @@ public class TextTag extends ContextBeanTag { this.escapeCsv = escapeCsv; } + @Override + public void clearTagStateForTagPoolingServers() { + super.clearTagStateForTagPoolingServers(); + this.name = null; + this.searchValueStack = null; + this.escapeHtml = false; + this.escapeJavaScript = false; + this.escapeXml = false; + this.escapeCsv = false; + } + } diff --git a/core/src/main/java/org/apache/struts2/views/jsp/URLTag.java b/core/src/main/java/org/apache/struts2/views/jsp/URLTag.java index baf632340..7c0f5652f 100644 --- a/core/src/main/java/org/apache/struts2/views/jsp/URLTag.java +++ b/core/src/main/java/org/apache/struts2/views/jsp/URLTag.java @@ -48,10 +48,12 @@ public class URLTag extends ContextBeanTag { protected String anchor; protected String forceAddSchemeHostAndPort; + @Override public Component getBean(ValueStack stack, HttpServletRequest req, HttpServletResponse res) { return new URL(stack, req, res); } + @Override protected void populateParams() { super.populateParams(); @@ -136,4 +138,24 @@ public class URLTag extends ContextBeanTag { public void setForceAddSchemeHostAndPort(String forceAddSchemeHostAndPort) { this.forceAddSchemeHostAndPort = forceAddSchemeHostAndPort; } + + @Override + public void clearTagStateForTagPoolingServers() { + super.clearTagStateForTagPoolingServers(); + this.includeParams = null; + this.scheme = null; + this.value = null; + this.action = null; + this.namespace = null; + this.method = null; + this.encode = null; + this.includeContext = null; + this.escapeAmp = null; + this.portletMode = null; + this.windowState = null; + this.portletUrlType = null; + this.anchor = null; + this.forceAddSchemeHostAndPort = null; + } + } diff --git a/core/src/main/java/org/apache/struts2/views/jsp/iterator/IteratorGeneratorTag.java b/core/src/main/java/org/apache/struts2/views/jsp/iterator/IteratorGeneratorTag.java index 6255ea98a..e988c8017 100644 --- a/core/src/main/java/org/apache/struts2/views/jsp/iterator/IteratorGeneratorTag.java +++ b/core/src/main/java/org/apache/struts2/views/jsp/iterator/IteratorGeneratorTag.java @@ -176,6 +176,7 @@ public class IteratorGeneratorTag extends StrutsBodyTagSupport { this.var = var; } + @Override public int doStartTag() throws JspException { // value @@ -230,11 +231,24 @@ public class IteratorGeneratorTag extends StrutsBodyTagSupport { return EVAL_BODY_INCLUDE; } + @Override public int doEndTag() throws JspException { // pop resulting iterator from stack at end tag getStack().pop(); iteratorGenerator = null; // clean up + clearTagStateForTagPoolingServers(); // Clean-up, including iteratorGenerator reference. return EVAL_PAGE; } + + @Override + public void clearTagStateForTagPoolingServers() { + super.clearTagStateForTagPoolingServers(); + this.countAttr = null; + this.separatorAttr = null; + this.valueAttr = null; + this.converterAttr = null; + this.var = null; + this.iteratorGenerator = null; + } } diff --git a/core/src/main/java/org/apache/struts2/views/jsp/iterator/SortIteratorTag.java b/core/src/main/java/org/apache/struts2/views/jsp/iterator/SortIteratorTag.java index a268b7fcf..8165045f2 100644 --- a/core/src/main/java/org/apache/struts2/views/jsp/iterator/SortIteratorTag.java +++ b/core/src/main/java/org/apache/struts2/views/jsp/iterator/SortIteratorTag.java @@ -110,6 +110,7 @@ public class SortIteratorTag extends StrutsBodyTagSupport { this.var = var; } + @Override public int doStartTag() throws JspException { // Source Object srcToSort; @@ -144,13 +145,25 @@ public class SortIteratorTag extends StrutsBodyTagSupport { return EVAL_BODY_INCLUDE; } + @Override public int doEndTag() throws JspException { int returnVal = super.doEndTag(); // pop sorted list from stack at the end of tag getStack().pop(); sortIteratorFilter = null; + // The super.doEndTag() above should ensure clearTagStateForTagPoolingServers() is called correctly, + // which should clean-up the sortIteratorFilter reference. return returnVal; } + + @Override + public void clearTagStateForTagPoolingServers() { + super.clearTagStateForTagPoolingServers(); + this.comparatorAttr = null; + this.sourceAttr = null; + this.var = null; + this.sortIteratorFilter = null; + } } diff --git a/core/src/main/java/org/apache/struts2/views/jsp/iterator/SubsetIteratorTag.java b/core/src/main/java/org/apache/struts2/views/jsp/iterator/SubsetIteratorTag.java index b1b6dc592..6f19afbea 100644 --- a/core/src/main/java/org/apache/struts2/views/jsp/iterator/SubsetIteratorTag.java +++ b/core/src/main/java/org/apache/struts2/views/jsp/iterator/SubsetIteratorTag.java @@ -193,6 +193,7 @@ public class SubsetIteratorTag extends StrutsBodyTagSupport { this.var = var; } + @Override public int doStartTag() throws JspException { // source @@ -272,12 +273,24 @@ public class SubsetIteratorTag extends StrutsBodyTagSupport { return EVAL_BODY_INCLUDE; } + @Override public int doEndTag() throws JspException { - + // pop resulting subset iterator from stack at end tag getStack().pop(); - subsetIteratorFilter = null; + clearTagStateForTagPoolingServers(); // Clean-up, including subsetIteratorFilter reference. return EVAL_PAGE; } + + @Override + public void clearTagStateForTagPoolingServers() { + super.clearTagStateForTagPoolingServers(); + this.countAttr = null; + this.sourceAttr = null; + this.startAttr = null; + this.deciderAttr = null; + this.var = null; + this.subsetIteratorFilter = null; + } } diff --git a/core/src/main/java/org/apache/struts2/views/jsp/ui/AbstractClosingTag.java b/core/src/main/java/org/apache/struts2/views/jsp/ui/AbstractClosingTag.java index 8fc0834eb..3af662248 100644 --- a/core/src/main/java/org/apache/struts2/views/jsp/ui/AbstractClosingTag.java +++ b/core/src/main/java/org/apache/struts2/views/jsp/ui/AbstractClosingTag.java @@ -23,6 +23,7 @@ import org.apache.struts2.components.ClosingUIBean; public abstract class AbstractClosingTag extends AbstractUITag { protected String openTemplate; + @Override protected void populateParams() { super.populateParams(); @@ -32,4 +33,11 @@ public abstract class AbstractClosingTag extends AbstractUITag { public void setOpenTemplate(String openTemplate) { this.openTemplate = openTemplate; } + + @Override + public void clearTagStateForTagPoolingServers() { + super.clearTagStateForTagPoolingServers(); + this.openTemplate = null; + } + } diff --git a/core/src/main/java/org/apache/struts2/views/jsp/ui/AbstractDoubleListTag.java b/core/src/main/java/org/apache/struts2/views/jsp/ui/AbstractDoubleListTag.java index 83bbdb7f0..21c09833d 100644 --- a/core/src/main/java/org/apache/struts2/views/jsp/ui/AbstractDoubleListTag.java +++ b/core/src/main/java/org/apache/struts2/views/jsp/ui/AbstractDoubleListTag.java @@ -66,6 +66,7 @@ public abstract class AbstractDoubleListTag extends AbstractRequiredListTag { protected String doubleAccesskey; + @Override protected void populateParams() { super.populateParams(); @@ -382,4 +383,48 @@ public abstract class AbstractDoubleListTag extends AbstractRequiredListTag { public void setDoubleAccesskey(String doubleAccesskey) { this.doubleAccesskey = doubleAccesskey; } + + @Override + public void clearTagStateForTagPoolingServers() { + super.clearTagStateForTagPoolingServers(); + this.doubleList = null; + this.doubleListKey = null; + this.doubleListValue = null; + this.doubleListCssClass = null; + this.doubleListCssStyle = null; + this.doubleListTitle = null; + this.doubleName = null; + this.doubleValue = null; + this.formName = null; + this.emptyOption = null; + this.headerKey = null; + this.headerValue = null; + this.multiple = null; + this.size = null; + this.doubleId = null; + this.doubleDisabled = null; + this.doubleMultiple = null; + this.doubleSize = null; + this.doubleHeaderKey = null; + this.doubleHeaderValue = null; + this.doubleEmptyOption = null; + this.doubleCssClass = null; + this.doubleCssStyle = null; + this.doubleOnclick = null; + this.doubleOndblclick = null; + this.doubleOnmousedown = null; + this.doubleOnmouseup = null; + this.doubleOnmouseover = null; + this.doubleOnmousemove = null; + this.doubleOnmouseout = null; + this.doubleOnfocus = null; + this.doubleOnblur = null; + this.doubleOnkeypress = null; + this.doubleOnkeydown = null; + this.doubleOnkeyup = null; + this.doubleOnselect = null; + this.doubleOnchange = null; + this.doubleAccesskey = null; + } + } diff --git a/core/src/main/java/org/apache/struts2/views/jsp/ui/AbstractListTag.java b/core/src/main/java/org/apache/struts2/views/jsp/ui/AbstractListTag.java index b357bcbba..747c4c9a8 100644 --- a/core/src/main/java/org/apache/struts2/views/jsp/ui/AbstractListTag.java +++ b/core/src/main/java/org/apache/struts2/views/jsp/ui/AbstractListTag.java @@ -30,6 +30,7 @@ public abstract class AbstractListTag extends AbstractUITag { protected String listCssStyle; protected String listTitle; + @Override protected void populateParams() { super.populateParams(); @@ -75,4 +76,18 @@ public abstract class AbstractListTag extends AbstractUITag { public void setListTitle(String listTitle) { this.listTitle = listTitle; } + + @Override + public void clearTagStateForTagPoolingServers() { + super.clearTagStateForTagPoolingServers(); + this.list = null; + this.listKey = null; + this.listValue = null; + this.listValueKey = null; + this.listLabelKey = null; + this.listCssClass = null; + this.listCssStyle = null; + this.listTitle = null; + } + } diff --git a/core/src/main/java/org/apache/struts2/views/jsp/ui/AbstractUITag.java b/core/src/main/java/org/apache/struts2/views/jsp/ui/AbstractUITag.java index 6c4323805..316954f88 100644 --- a/core/src/main/java/org/apache/struts2/views/jsp/ui/AbstractUITag.java +++ b/core/src/main/java/org/apache/struts2/views/jsp/ui/AbstractUITag.java @@ -316,4 +316,51 @@ public abstract class AbstractUITag extends ComponentTagSupport implements Dynam dynamicAttributes.put(localName, String.valueOf(value)); } + @Override + public void clearTagStateForTagPoolingServers() { + super.clearTagStateForTagPoolingServers(); + this.cssClass = null; + this.cssErrorClass = null; + this.cssStyle = null; + this.cssErrorStyle = null; + this.title = null; + this.disabled = null; + this.label = null; + this.labelSeparator = null; + this.labelposition = null; + this.requiredPosition = null; + this.errorPosition = null; + this.name = null; + this.requiredLabel = null; + this.tabindex = null; + this.value = null; + this.template = null; + this.theme = null; + this.templateDir = null; + this.onclick = null; + this.ondblclick = null; + this.onmousedown = null; + this.onmouseup = null; + this.onmouseover = null; + this.onmousemove = null; + this.onmouseout = null; + this.onfocus = null; + this.onblur = null; + this.onkeypress = null; + this.onkeydown = null; + this.onkeyup = null; + this.onselect = null; + this.onchange = null; + this.accesskey = null; + this.id = null; + this.key = null; + this.tooltip = null; + this.tooltipConfig = null; + this.javascriptTooltip = null; + this.tooltipDelay = null; + this.tooltipCssClass = null; + this.tooltipIconPath = null; + this.dynamicAttributes.clear(); + } + } diff --git a/core/src/main/java/org/apache/struts2/views/jsp/ui/ActionErrorTag.java b/core/src/main/java/org/apache/struts2/views/jsp/ui/ActionErrorTag.java index e1b7ef63b..4c9c875e6 100644 --- a/core/src/main/java/org/apache/struts2/views/jsp/ui/ActionErrorTag.java +++ b/core/src/main/java/org/apache/struts2/views/jsp/ui/ActionErrorTag.java @@ -36,10 +36,12 @@ public class ActionErrorTag extends AbstractUITag { private boolean escape = true; + @Override public Component getBean(ValueStack stack, HttpServletRequest req, HttpServletResponse res) { return new ActionError(stack, req, res); } + @Override protected void populateParams() { super.populateParams(); @@ -50,4 +52,11 @@ public class ActionErrorTag extends AbstractUITag { public void setEscape(boolean escape) { this.escape = escape; } + + @Override + public void clearTagStateForTagPoolingServers() { + super.clearTagStateForTagPoolingServers(); + this.escape = true; + } + } diff --git a/core/src/main/java/org/apache/struts2/views/jsp/ui/ActionMessageTag.java b/core/src/main/java/org/apache/struts2/views/jsp/ui/ActionMessageTag.java index 439f9550e..7b6879739 100644 --- a/core/src/main/java/org/apache/struts2/views/jsp/ui/ActionMessageTag.java +++ b/core/src/main/java/org/apache/struts2/views/jsp/ui/ActionMessageTag.java @@ -23,7 +23,6 @@ import javax.servlet.http.HttpServletResponse; import org.apache.struts2.components.ActionMessage; import org.apache.struts2.components.Component; -import org.apache.struts2.components.ActionError; import com.opensymphony.xwork2.util.ValueStack; @@ -37,10 +36,12 @@ public class ActionMessageTag extends AbstractUITag { private boolean escape = true; + @Override public Component getBean(ValueStack stack, HttpServletRequest req, HttpServletResponse res) { return new ActionMessage(stack, req, res); } + @Override protected void populateParams() { super.populateParams(); @@ -51,4 +52,11 @@ public class ActionMessageTag extends AbstractUITag { public void setEscape(boolean escape) { this.escape = escape; } + + @Override + public void clearTagStateForTagPoolingServers() { + super.clearTagStateForTagPoolingServers(); + this.escape = true; + } + } diff --git a/core/src/main/java/org/apache/struts2/views/jsp/ui/AnchorTag.java b/core/src/main/java/org/apache/struts2/views/jsp/ui/AnchorTag.java index d3645c169..4d0fda5b2 100644 --- a/core/src/main/java/org/apache/struts2/views/jsp/ui/AnchorTag.java +++ b/core/src/main/java/org/apache/struts2/views/jsp/ui/AnchorTag.java @@ -49,10 +49,12 @@ public class AnchorTag extends AbstractClosingTag { protected String forceAddSchemeHostAndPort; protected boolean escapeHtmlBody = true; // Default - escape HTML body + @Override public Component getBean(ValueStack stack, HttpServletRequest req, HttpServletResponse res) { return new Anchor(stack, req, res); } + @Override protected void populateParams() { super.populateParams(); @@ -120,6 +122,7 @@ public class AnchorTag extends AbstractClosingTag { this.scheme = scheme; } + @Override public void setValue(String value) { this.value = value; } @@ -154,6 +157,25 @@ public class AnchorTag extends AbstractClosingTag { public void setEscapeHtmlBody(boolean escapeHtmlBody) { this.escapeHtmlBody = escapeHtmlBody; } + + @Override + public void clearTagStateForTagPoolingServers() { + super.clearTagStateForTagPoolingServers(); + this.href = null; + this.includeParams = null; + this.scheme = null; + this.action = null; + this.namespace = null; + this.method = null; + this.encode = null; + this.includeContext = null; + this.escapeAmp = null; + this.portletMode = null; + this.windowState = null; + this.portletUrlType = null; + this.anchor = null; + this.forceAddSchemeHostAndPort = null; + } + } - diff --git a/core/src/main/java/org/apache/struts2/views/jsp/ui/CheckboxTag.java b/core/src/main/java/org/apache/struts2/views/jsp/ui/CheckboxTag.java index 5cfa22fbc..4230b9e11 100644 --- a/core/src/main/java/org/apache/struts2/views/jsp/ui/CheckboxTag.java +++ b/core/src/main/java/org/apache/struts2/views/jsp/ui/CheckboxTag.java @@ -35,10 +35,12 @@ public class CheckboxTag extends AbstractUITag { protected String fieldValue; protected String submitUnchecked; + @Override public Component getBean(ValueStack stack, HttpServletRequest req, HttpServletResponse res) { return new Checkbox(stack, req, res); } + @Override protected void populateParams() { super.populateParams(); @@ -53,4 +55,11 @@ public class CheckboxTag extends AbstractUITag { public void setSubmitUnchecked(String aValue) { this.submitUnchecked = aValue; } + + @Override + public void clearTagStateForTagPoolingServers() { + super.clearTagStateForTagPoolingServers(); + this.fieldValue = null; + } + } diff --git a/core/src/main/java/org/apache/struts2/views/jsp/ui/ComboBoxTag.java b/core/src/main/java/org/apache/struts2/views/jsp/ui/ComboBoxTag.java index 877ff03e4..76b4ec9bf 100644 --- a/core/src/main/java/org/apache/struts2/views/jsp/ui/ComboBoxTag.java +++ b/core/src/main/java/org/apache/struts2/views/jsp/ui/ComboBoxTag.java @@ -60,10 +60,12 @@ public class ComboBoxTag extends TextFieldTag { this.listValue = listValue; } + @Override public Component getBean(ValueStack stack, HttpServletRequest req, HttpServletResponse res) { return new ComboBox(stack, req, res); } + @Override protected void populateParams() { super.populateParams(); @@ -78,4 +80,16 @@ public class ComboBoxTag extends TextFieldTag { public void setList(String list) { this.list = list; } + + @Override + public void clearTagStateForTagPoolingServers() { + super.clearTagStateForTagPoolingServers(); + this.list = null; + this.listKey = null; + this.listValue = null; + this.headerKey = null; + this.headerValue = null; + this.emptyOption = null; + } + } diff --git a/core/src/main/java/org/apache/struts2/views/jsp/ui/DateTextFieldTag.java b/core/src/main/java/org/apache/struts2/views/jsp/ui/DateTextFieldTag.java index b4d190757..666c7b4bf 100644 --- a/core/src/main/java/org/apache/struts2/views/jsp/ui/DateTextFieldTag.java +++ b/core/src/main/java/org/apache/struts2/views/jsp/ui/DateTextFieldTag.java @@ -35,10 +35,12 @@ public class DateTextFieldTag extends AbstractUITag { protected String format; + @Override public Component getBean(ValueStack stack, HttpServletRequest req, HttpServletResponse res) { return new DateTextField(stack, req, res); } + @Override protected void populateParams() { super.populateParams(); @@ -46,8 +48,14 @@ public class DateTextFieldTag extends AbstractUITag { textField.setFormat(format); } - public void setFormat(String format) { - this.format = format; - } + public void setFormat(String format) { + this.format = format; + } + + @Override + public void clearTagStateForTagPoolingServers() { + super.clearTagStateForTagPoolingServers(); + this.format = null; + } } diff --git a/core/src/main/java/org/apache/struts2/views/jsp/ui/FieldErrorTag.java b/core/src/main/java/org/apache/struts2/views/jsp/ui/FieldErrorTag.java index b5a834484..44ad8adab 100644 --- a/core/src/main/java/org/apache/struts2/views/jsp/ui/FieldErrorTag.java +++ b/core/src/main/java/org/apache/struts2/views/jsp/ui/FieldErrorTag.java @@ -37,10 +37,12 @@ public class FieldErrorTag extends AbstractUITag { protected boolean escape = true; + @Override public Component getBean(ValueStack stack, HttpServletRequest req, HttpServletResponse res) { return new FieldError(stack, req, res); } + @Override protected void populateParams() { super.populateParams(); @@ -56,5 +58,12 @@ public class FieldErrorTag extends AbstractUITag { public void setEscape(boolean escape) { this.escape = escape; } -} + @Override + public void clearTagStateForTagPoolingServers() { + super.clearTagStateForTagPoolingServers(); + this.fieldName = null; + this.escape = true; + } + +} diff --git a/core/src/main/java/org/apache/struts2/views/jsp/ui/FileTag.java b/core/src/main/java/org/apache/struts2/views/jsp/ui/FileTag.java index bbee234e8..d97aa4df2 100644 --- a/core/src/main/java/org/apache/struts2/views/jsp/ui/FileTag.java +++ b/core/src/main/java/org/apache/struts2/views/jsp/ui/FileTag.java @@ -36,10 +36,12 @@ public class FileTag extends AbstractUITag { protected String accept; protected String size; + @Override public Component getBean(ValueStack stack, HttpServletRequest req, HttpServletResponse res) { return new File(stack, req, res); } + @Override protected void populateParams() { super.populateParams(); @@ -55,4 +57,12 @@ public class FileTag extends AbstractUITag { public void setSize(String size) { this.size = size; } + + @Override + public void clearTagStateForTagPoolingServers() { + super.clearTagStateForTagPoolingServers(); + this.accept = null; + this.size = null; + } + } diff --git a/core/src/main/java/org/apache/struts2/views/jsp/ui/FormTag.java b/core/src/main/java/org/apache/struts2/views/jsp/ui/FormTag.java index b7ded8d9c..41b8d275c 100644 --- a/core/src/main/java/org/apache/struts2/views/jsp/ui/FormTag.java +++ b/core/src/main/java/org/apache/struts2/views/jsp/ui/FormTag.java @@ -47,10 +47,12 @@ public class FormTag extends AbstractClosingTag { protected String focusElement; protected boolean includeContext = true; + @Override public Component getBean(ValueStack stack, HttpServletRequest req, HttpServletResponse res) { return new Form(stack, req, res); } + @Override protected void populateParams() { super.populateParams(); Form form = ((Form) component); @@ -121,4 +123,23 @@ public class FormTag extends AbstractClosingTag { public void setIncludeContext(boolean includeContext) { this.includeContext = includeContext; } + + @Override + public void clearTagStateForTagPoolingServers() { + super.clearTagStateForTagPoolingServers(); + this.action = null; + this.target = null; + this.enctype = null; + this.method = null; + this.namespace = null; + this.validate = null; + this.onsubmit = null; + this.onreset = null; + this.portletMode = null; + this.windowState = null; + this.acceptcharset = null; + this.focusElement = null; + this.includeContext = true; + } + } diff --git a/core/src/main/java/org/apache/struts2/views/jsp/ui/InputTransferSelectTag.java b/core/src/main/java/org/apache/struts2/views/jsp/ui/InputTransferSelectTag.java index da8cb2da1..99922ff46 100644 --- a/core/src/main/java/org/apache/struts2/views/jsp/ui/InputTransferSelectTag.java +++ b/core/src/main/java/org/apache/struts2/views/jsp/ui/InputTransferSelectTag.java @@ -53,10 +53,12 @@ public class InputTransferSelectTag extends AbstractListTag { protected String headerKey; protected String headerValue; + @Override public Component getBean(ValueStack stack, HttpServletRequest req, HttpServletResponse res) { return new InputTransferSelect(stack, req, res); } + @Override protected void populateParams() { super.populateParams(); @@ -200,4 +202,25 @@ public class InputTransferSelectTag extends AbstractListTag { public void setHeaderValue(String headerValue) { this.headerValue = headerValue; } + + @Override + public void clearTagStateForTagPoolingServers() { + super.clearTagStateForTagPoolingServers(); + this.size = null; + this.multiple = null; + this.allowRemoveAll = null; + this.allowUpDown = null; + this.leftTitle = null; + this.rightTitle = null; + this.buttonCssClass = null; + this.buttonCssStyle = null; + this.addLabel = null; + this.removeLabel = null; + this.removeAllLabel = null; + this.upLabel = null; + this.downLabel = null; + this.headerKey = null; + this.headerValue = null; + } + } diff --git a/core/src/main/java/org/apache/struts2/views/jsp/ui/LabelTag.java b/core/src/main/java/org/apache/struts2/views/jsp/ui/LabelTag.java index 19611a0fe..85a458cd8 100644 --- a/core/src/main/java/org/apache/struts2/views/jsp/ui/LabelTag.java +++ b/core/src/main/java/org/apache/struts2/views/jsp/ui/LabelTag.java @@ -35,10 +35,12 @@ public class LabelTag extends AbstractUITag { protected String forAttr; + @Override public Component getBean(ValueStack stack, HttpServletRequest req, HttpServletResponse res) { return new Label(stack, req, res); } + @Override protected void populateParams() { super.populateParams(); @@ -48,4 +50,11 @@ public class LabelTag extends AbstractUITag { public void setFor(String aFor) { this.forAttr = aFor; } + + @Override + public void clearTagStateForTagPoolingServers() { + super.clearTagStateForTagPoolingServers(); + this.forAttr = null; + } + } diff --git a/core/src/main/java/org/apache/struts2/views/jsp/ui/OptGroupTag.java b/core/src/main/java/org/apache/struts2/views/jsp/ui/OptGroupTag.java index bd90ff5a3..8e9ba1ba2 100644 --- a/core/src/main/java/org/apache/struts2/views/jsp/ui/OptGroupTag.java +++ b/core/src/main/java/org/apache/struts2/views/jsp/ui/OptGroupTag.java @@ -40,10 +40,12 @@ public class OptGroupTag extends ComponentTagSupport { protected String listCssStyle; protected String listTitle; + @Override public Component getBean(ValueStack stack, HttpServletRequest req, HttpServletResponse res) { return new OptGroup(stack, req, res); } + @Override protected void populateParams() { super.populateParams(); @@ -89,4 +91,18 @@ public class OptGroupTag extends ComponentTagSupport { public void setListTitle(String listTitle) { this.listTitle = listTitle; } + + @Override + public void clearTagStateForTagPoolingServers() { + super.clearTagStateForTagPoolingServers(); + this.list = null; + this.label = null; + this.disabled = null; + this.listKey = null; + this.listValue = null; + this.listCssClass = null; + this.listCssStyle = null; + this.listTitle = null; + } + } diff --git a/core/src/main/java/org/apache/struts2/views/jsp/ui/OptionTransferSelectTag.java b/core/src/main/java/org/apache/struts2/views/jsp/ui/OptionTransferSelectTag.java index 73aabc38b..da9a097c3 100644 --- a/core/src/main/java/org/apache/struts2/views/jsp/ui/OptionTransferSelectTag.java +++ b/core/src/main/java/org/apache/struts2/views/jsp/ui/OptionTransferSelectTag.java @@ -66,10 +66,12 @@ public class OptionTransferSelectTag extends AbstractDoubleListTag { protected String upDownOnRightOnclick; + @Override public Component getBean(ValueStack stack, HttpServletRequest req, HttpServletResponse res) { return new OptionTransferSelect(stack, req, res); } + @Override protected void populateParams() { super.populateParams(); @@ -342,4 +344,37 @@ public class OptionTransferSelectTag extends AbstractDoubleListTag { public String getSelectAllOnclick() { return this.selectAllOnclick; } + + @Override + public void clearTagStateForTagPoolingServers() { + super.clearTagStateForTagPoolingServers(); + this.allowAddToLeft = null; + this.allowAddToRight = null; + this.allowAddAllToLeft = null; + this.allowAddAllToRight = null; + this.allowSelectAll = null; + this.allowUpDownOnLeft = null; + this.allowUpDownOnRight = null; + this.leftTitle = null; + this.rightTitle = null; + this.buttonCssClass = null; + this.buttonCssStyle = null; + this.addToLeftLabel = null; + this.addToRightLabel = null; + this.addAllToLeftLabel = null; + this.addAllToRightLabel = null; + this.selectAllLabel = null; + this.leftUpLabel = null; + this.leftDownLabel = null; + this.rightUpLabel = null; + this.rightDownLabel = null; + this.addToLeftOnclick = null; + this.addToRightOnclick = null; + this.addAllToLeftOnclick = null; + this.addAllToRightOnclick = null; + this.selectAllOnclick = null; + this.upDownOnLeftOnclick = null; + this.upDownOnRightOnclick = null; + } + } diff --git a/core/src/main/java/org/apache/struts2/views/jsp/ui/PasswordTag.java b/core/src/main/java/org/apache/struts2/views/jsp/ui/PasswordTag.java index cf3f73d90..3a6b807f3 100644 --- a/core/src/main/java/org/apache/struts2/views/jsp/ui/PasswordTag.java +++ b/core/src/main/java/org/apache/struts2/views/jsp/ui/PasswordTag.java @@ -35,10 +35,12 @@ public class PasswordTag extends TextFieldTag { protected String showPassword; + @Override public Component getBean(ValueStack stack, HttpServletRequest req, HttpServletResponse res) { return new Password(stack, req, res); } + @Override protected void populateParams() { super.populateParams(); @@ -52,4 +54,11 @@ public class PasswordTag extends TextFieldTag { public void setShowPassword(String showPassword) { this.showPassword = showPassword; } + + @Override + public void clearTagStateForTagPoolingServers() { + super.clearTagStateForTagPoolingServers(); + this.showPassword = null; + } + } diff --git a/core/src/main/java/org/apache/struts2/views/jsp/ui/ResetTag.java b/core/src/main/java/org/apache/struts2/views/jsp/ui/ResetTag.java index 339b0ec08..bda98da93 100644 --- a/core/src/main/java/org/apache/struts2/views/jsp/ui/ResetTag.java +++ b/core/src/main/java/org/apache/struts2/views/jsp/ui/ResetTag.java @@ -37,10 +37,12 @@ public class ResetTag extends AbstractUITag { protected String type; protected String src; + @Override public Component getBean(ValueStack stack, HttpServletRequest req, HttpServletResponse res) { return new Reset(stack, req, res); } + @Override protected void populateParams() { super.populateParams(); @@ -67,4 +69,13 @@ public class ResetTag extends AbstractUITag { this.src = src; } + @Override + public void clearTagStateForTagPoolingServers() { + super.clearTagStateForTagPoolingServers(); + this.action = null; + this.method = null; + this.type = null; + this.src = null; + } + } diff --git a/core/src/main/java/org/apache/struts2/views/jsp/ui/SelectTag.java b/core/src/main/java/org/apache/struts2/views/jsp/ui/SelectTag.java index cbd71e67e..dd71eceae 100644 --- a/core/src/main/java/org/apache/struts2/views/jsp/ui/SelectTag.java +++ b/core/src/main/java/org/apache/struts2/views/jsp/ui/SelectTag.java @@ -39,10 +39,12 @@ public class SelectTag extends AbstractRequiredListTag { protected String multiple; protected String size; + @Override public Component getBean(ValueStack stack, HttpServletRequest req, HttpServletResponse res) { return new Select(stack, req, res); } + @Override protected void populateParams() { super.populateParams(); @@ -74,4 +76,14 @@ public class SelectTag extends AbstractRequiredListTag { this.size = size; } + @Override + public void clearTagStateForTagPoolingServers() { + super.clearTagStateForTagPoolingServers(); + this.emptyOption = null; + this.headerKey = null; + this.headerValue = null; + this.multiple = null; + this.size = null; + } + } diff --git a/core/src/main/java/org/apache/struts2/views/jsp/ui/SubmitTag.java b/core/src/main/java/org/apache/struts2/views/jsp/ui/SubmitTag.java index a86571051..01ca56f34 100644 --- a/core/src/main/java/org/apache/struts2/views/jsp/ui/SubmitTag.java +++ b/core/src/main/java/org/apache/struts2/views/jsp/ui/SubmitTag.java @@ -39,10 +39,12 @@ public class SubmitTag extends AbstractClosingTag { protected String src; protected boolean escapeHtmlBody = true; // Default - escape HTML body + @Override public Component getBean(ValueStack stack, HttpServletRequest req, HttpServletResponse res) { return new Submit(stack, req, res); } + @Override protected void populateParams() { super.populateParams(); @@ -84,4 +86,14 @@ public class SubmitTag extends AbstractClosingTag { public void setEscapeHtmlBody(boolean escapeHtmlBody) { this.escapeHtmlBody = escapeHtmlBody; } + + @Override + public void clearTagStateForTagPoolingServers() { + super.clearTagStateForTagPoolingServers(); + this.action = null; + this.method = null; + this.type = null; + this.src = null; + } + } diff --git a/core/src/main/java/org/apache/struts2/views/jsp/ui/TextFieldTag.java b/core/src/main/java/org/apache/struts2/views/jsp/ui/TextFieldTag.java index 4f7d2de09..71a5d4916 100644 --- a/core/src/main/java/org/apache/struts2/views/jsp/ui/TextFieldTag.java +++ b/core/src/main/java/org/apache/struts2/views/jsp/ui/TextFieldTag.java @@ -37,10 +37,12 @@ public class TextFieldTag extends AbstractUITag { protected String size; protected String type; + @Override public Component getBean(ValueStack stack, HttpServletRequest req, HttpServletResponse res) { return new TextField(stack, req, res); } + @Override protected void populateParams() { super.populateParams(); @@ -66,4 +68,14 @@ public class TextFieldTag extends AbstractUITag { public void setType(String type) { this.type = type; } + + @Override + public void clearTagStateForTagPoolingServers() { + super.clearTagStateForTagPoolingServers(); + this.maxlength = null; + this.readonly = null; + this.size = null; + this.type = null; + } + } diff --git a/core/src/main/java/org/apache/struts2/views/jsp/ui/TextareaTag.java b/core/src/main/java/org/apache/struts2/views/jsp/ui/TextareaTag.java index 0efbe0188..d1a509f1b 100644 --- a/core/src/main/java/org/apache/struts2/views/jsp/ui/TextareaTag.java +++ b/core/src/main/java/org/apache/struts2/views/jsp/ui/TextareaTag.java @@ -40,10 +40,12 @@ public class TextareaTag extends AbstractUITag { protected String maxlength; protected String minlength; + @Override public Component getBean(ValueStack stack, HttpServletRequest req, HttpServletResponse res) { return new TextArea(stack, req, res); } + @Override protected void populateParams() { super.populateParams(); @@ -80,4 +82,13 @@ public class TextareaTag extends AbstractUITag { this.minlength = minlength; } + @Override + public void clearTagStateForTagPoolingServers() { + super.clearTagStateForTagPoolingServers(); + this.cols = null; + this.readonly = null; + this.rows = null; + this.wrap = null; + } + } diff --git a/core/src/main/java/org/apache/struts2/views/jsp/ui/UpDownSelectTag.java b/core/src/main/java/org/apache/struts2/views/jsp/ui/UpDownSelectTag.java index 925a6223c..f7b36478a 100644 --- a/core/src/main/java/org/apache/struts2/views/jsp/ui/UpDownSelectTag.java +++ b/core/src/main/java/org/apache/struts2/views/jsp/ui/UpDownSelectTag.java @@ -42,10 +42,12 @@ public class UpDownSelectTag extends SelectTag { protected String selectAllLabel; + @Override public Component getBean(ValueStack stack, HttpServletRequest req, HttpServletResponse res) { return new UpDownSelect(stack, req, res); } + @Override protected void populateParams() { super.populateParams(); @@ -118,4 +120,16 @@ public class UpDownSelectTag extends SelectTag { public void setSelectAllLabel(String selectAllLabel) { this.selectAllLabel = selectAllLabel; } + + @Override + public void clearTagStateForTagPoolingServers() { + super.clearTagStateForTagPoolingServers(); + this.allowMoveUp = null; + this.allowMoveDown = null; + this.allowSelectAll = null; + this.moveUpLabel = null; + this.moveDownLabel = null; + this.selectAllLabel = null; + } + } diff --git a/core/src/test/java/org/apache/struts2/StrutsInternalTestCase.java b/core/src/test/java/org/apache/struts2/StrutsInternalTestCase.java index dfc2dc3a4..4dc7e78df 100644 --- a/core/src/test/java/org/apache/struts2/StrutsInternalTestCase.java +++ b/core/src/test/java/org/apache/struts2/StrutsInternalTestCase.java @@ -19,12 +19,10 @@ package org.apache.struts2; import com.opensymphony.xwork2.XWorkTestCase; +import org.apache.commons.lang3.builder.EqualsBuilder; import org.apache.struts2.dispatcher.Dispatcher; import org.apache.struts2.util.StrutsTestCaseHelper; import org.apache.struts2.views.jsp.StrutsMockServletContext; - -import java.text.SimpleDateFormat; -import java.util.Date; import java.util.HashMap; import java.util.Map; @@ -78,4 +76,26 @@ public abstract class StrutsInternalTestCase extends XWorkTestCase { StrutsTestCaseHelper.tearDown(); } + /** + * Compare if two objects are considered equal according to their fields as accessed + * via reflection. + * + * Utilizes {@link EqualsBuilder#reflectionEquals(java.lang.Object, java.lang.Object, boolean)} to perform + * the check, and compares transient fields as well. This may fail when run while a security manager is + * active, due to a need to user reflection. + * + * + * @param obj1 the first {@link Object} to compare against the other. + * @param obj2 the second {@link Object} to compare against the other. + * @return true if the objects are equal based on field comparisons by reflection, false otherwise. + */ + protected boolean objectsAreReflectionEqual(Object obj1, Object obj2) { + boolean result = false; + if (obj1 == obj2) { + result = true; + } else if (obj1 != null && obj2 != null) { + result = EqualsBuilder.reflectionEquals(obj1, obj2, true); + } + return result; + } } diff --git a/core/src/test/java/org/apache/struts2/views/jsp/AbstractTagTest.java b/core/src/test/java/org/apache/struts2/views/jsp/AbstractTagTest.java index f31ccc40c..4179fde27 100644 --- a/core/src/test/java/org/apache/struts2/views/jsp/AbstractTagTest.java +++ b/core/src/test/java/org/apache/struts2/views/jsp/AbstractTagTest.java @@ -27,6 +27,7 @@ import java.util.Map; import javax.servlet.http.HttpServletResponse; import javax.servlet.jsp.JspWriter; +import org.apache.commons.lang3.builder.EqualsBuilder; import org.apache.struts2.ServletActionContext; import org.apache.struts2.StrutsInternalTestCase; import org.apache.struts2.TestAction; @@ -74,6 +75,7 @@ public abstract class AbstractTagTest extends StrutsInternalTestCase { return new TestAction(); } + @Override protected void setUp() throws Exception { super.setUp(); createMocks(); @@ -129,6 +131,7 @@ public abstract class AbstractTagTest extends StrutsInternalTestCase { .bind(); } + @Override protected void tearDown() throws Exception { super.tearDown(); pageContext.verify(); @@ -144,4 +147,26 @@ public abstract class AbstractTagTest extends StrutsInternalTestCase { servletContext = null; mockContainer = null; } + + /** + * Compare if two component tags are considered equal according to their fields as accessed + * via reflection. + * + * Utilizes {@link EqualsBuilder#reflectionEquals(java.lang.Object, java.lang.Object, boolean)} to perform + * the check, and compares transient fields as well. This may fail when run while a security manager is + * active, due to a need to user reflection. + * + * This method may be useful for checking if the state of a tag is what is expected after a given set of operations, + * or after clearing state such as for calls involving {@link StrutsBodyTagSupport#clearTagStateForTagPoolingServers()} + * has taken place following {@link StrutsBodyTagSupport#doEndTag()} processing. When making comparisons, keep in mind the + * pageContext and parent Tag state are not cleared by clearTagStateForTagPoolingServers(). + * + * @param tag1 the first {@link StrutsBodyTagSupport} to compare against the other. + * @param tag2 the second {@link StrutsBodyTagSupport} to compare against the other. + * @return true if the Tags are equal based on field comparisons by reflection, false otherwise. + */ + protected boolean strutsBodyTagsAreReflectionEqual(StrutsBodyTagSupport tag1, StrutsBodyTagSupport tag2) { + return objectsAreReflectionEqual(tag1, tag2); + } + } diff --git a/core/src/test/java/org/apache/struts2/views/jsp/ActionTagTest.java b/core/src/test/java/org/apache/struts2/views/jsp/ActionTagTest.java index 895639019..ff38a19d6 100644 --- a/core/src/test/java/org/apache/struts2/views/jsp/ActionTagTest.java +++ b/core/src/test/java/org/apache/struts2/views/jsp/ActionTagTest.java @@ -66,6 +66,13 @@ public class ActionTagTest extends AbstractTagTest { ex.printStackTrace(); fail(); } + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + ActionTag freshTag = new ActionTag(); + freshTag.setPageContext(pageContext); + assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", + strutsBodyTagsAreReflectionEqual(tag, freshTag)); } public void testSimple() { @@ -98,6 +105,14 @@ public class ActionTagTest extends AbstractTagTest { ex.printStackTrace(); fail(); } + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + ActionTag freshTag = new ActionTag(); + freshTag.setPageContext(pageContext); + assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", + strutsBodyTagsAreReflectionEqual(tag, freshTag)); + } public void testSimpleWithoutServletActionContext() { @@ -136,6 +151,14 @@ public class ActionTagTest extends AbstractTagTest { ex.printStackTrace(); fail(); } + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + ActionTag freshTag = new ActionTag(); + freshTag.setPageContext(pageContext); + assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", + strutsBodyTagsAreReflectionEqual(tag, freshTag)); + } public void testActionWithExecuteResult() throws Exception { @@ -157,6 +180,14 @@ public class ActionTagTest extends AbstractTagTest { assertTrue(stack.getContext().containsKey(ServletActionContext.PAGE_CONTEXT)); assertTrue(stack.getContext().get(ServletActionContext.PAGE_CONTEXT) instanceof PageContext); assertTrue(result.isExecuted()); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + ActionTag freshTag = new ActionTag(); + freshTag.setPageContext(pageContext); + assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", + strutsBodyTagsAreReflectionEqual(tag, freshTag)); + } public void testActionWithoutExecuteResult() throws Exception { @@ -178,6 +209,13 @@ public class ActionTagTest extends AbstractTagTest { assertTrue(stack.getContext().containsKey(ServletActionContext.PAGE_CONTEXT)); assertTrue(stack.getContext().get(ServletActionContext.PAGE_CONTEXT) instanceof PageContext); assertNull(result); // result is never executed, hence never set into invocation + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + ActionTag freshTag = new ActionTag(); + freshTag.setPageContext(pageContext); + assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", + strutsBodyTagsAreReflectionEqual(tag, freshTag)); } public void testExecuteButResetReturnSameInvocation() throws Exception { @@ -199,6 +237,13 @@ public class ActionTagTest extends AbstractTagTest { tag.doEndTag(); assertSame(oldInvocation, ActionContext.getContext().getActionInvocation()); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + ActionTag freshTag = new ActionTag(); + freshTag.setPageContext(pageContext); + assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", + strutsBodyTagsAreReflectionEqual(tag, freshTag)); } public void testIngoreContextParamsFalse() throws Exception { @@ -224,6 +269,14 @@ public class ActionTagTest extends AbstractTagTest { ActionInvocation ai = component.getProxy().getInvocation(); ActionContext ac = ai.getInvocationContext(); assertEquals(1, ac.getParameters().keySet().size()); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + ActionTag freshTag = new ActionTag(); + freshTag.setPageContext(pageContext); + assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", + strutsBodyTagsAreReflectionEqual(tag, freshTag)); + } public void testIngoreContextParamsTrue() throws Exception { @@ -249,6 +302,13 @@ public class ActionTagTest extends AbstractTagTest { ActionInvocation ai = component.getProxy().getInvocation(); ActionContext ac = ai.getInvocationContext(); assertEquals(0, ac.getParameters().keySet().size()); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + ActionTag freshTag = new ActionTag(); + freshTag.setPageContext(pageContext); + assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", + strutsBodyTagsAreReflectionEqual(tag, freshTag)); } public void testNoNameDefined() throws Exception { @@ -265,6 +325,8 @@ public class ActionTagTest extends AbstractTagTest { } catch (StrutsException e) { assertEquals("tag 'actioncomponent', field 'name': Action name is required. Example: updatePerson", e.getMessage()); } + + // The doEndTag() call is expected not to complete. Cannot perform basic sanity check of clearTagStateForTagPoolingServers() behaviour. } // FIXME: Logging the error seems to cause the standard Maven build to fail @@ -278,6 +340,13 @@ public class ActionTagTest extends AbstractTagTest { tag.doStartTag(); tag.doEndTag(); // will just log it to ERROR but we run the code to test that it works somehow + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + ActionTag freshTag = new ActionTag(); + freshTag.setPageContext(pageContext); + assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", + strutsBodyTagsAreReflectionEqual(tag, freshTag)); } public void testActionMethodWithExecuteResult() throws Exception { @@ -300,8 +369,16 @@ public class ActionTagTest extends AbstractTagTest { assertTrue(stack.getContext().containsKey(ServletActionContext.PAGE_CONTEXT)); assertTrue(stack.getContext().get(ServletActionContext.PAGE_CONTEXT) instanceof PageContext); assertTrue(result.isExecuted()); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + ActionTag freshTag = new ActionTag(); + freshTag.setPageContext(pageContext); + assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", + strutsBodyTagsAreReflectionEqual(tag, freshTag)); } + @Override protected void setUp() throws Exception { super.setUp(); initDispatcher(new HashMap() {{ @@ -310,6 +387,7 @@ public class ActionTagTest extends AbstractTagTest { createMocks(); } + @Override protected void tearDown() throws Exception { super.tearDown(); } diff --git a/core/src/test/java/org/apache/struts2/views/jsp/AnchorTagTest.java b/core/src/test/java/org/apache/struts2/views/jsp/AnchorTagTest.java index acf5d3c65..ebff0e1dc 100644 --- a/core/src/test/java/org/apache/struts2/views/jsp/AnchorTagTest.java +++ b/core/src/test/java/org/apache/struts2/views/jsp/AnchorTagTest.java @@ -30,8 +30,6 @@ import javax.servlet.jsp.JspWriter; import org.apache.struts2.views.jsp.ui.AnchorTag; import org.apache.struts2.views.jsp.ui.StrutsBodyContent; -import org.apache.struts2.components.URL; -import org.apache.struts2.components.Anchor; /** @@ -51,6 +49,13 @@ public class AnchorTagTest extends AbstractUITagTest { ex.printStackTrace(); fail(); } + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + AnchorTag freshTag = new AnchorTag(); + freshTag.setPageContext(pageContext); + assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", + strutsBodyTagsAreReflectionEqual(tag, freshTag)); } public void testAddParameters() { @@ -67,6 +72,13 @@ public class AnchorTagTest extends AbstractUITagTest { ex.printStackTrace(); fail(); } + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + AnchorTag freshTag = new AnchorTag(); + freshTag.setPageContext(pageContext); + assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", + strutsBodyTagsAreReflectionEqual(tag, freshTag)); } /** @@ -147,6 +159,13 @@ public class AnchorTagTest extends AbstractUITagTest { assertEquals(wrapWithAnchor("testAction.action?id1=paramId1&id2=tagId2&" + "amp;tagId=tagValue&urlParam1=urlValue1&urlParam2=urlValue2&param1=param1value&param2=param2value"), writer.toString()); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + AnchorTag freshTag = new AnchorTag(); + freshTag.setPageContext(pageContext); + assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", + strutsBodyTagsAreReflectionEqual(tag, freshTag)); } /** @@ -171,6 +190,12 @@ public class AnchorTagTest extends AbstractUITagTest { param1.doStartTag(); param1.doEndTag(); + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + ParamTag freshParamTag = new ParamTag(); + freshParamTag.setPageContext(pageContext); + assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", + strutsBodyTagsAreReflectionEqual(param1, freshParamTag)); //String[] stack.getContext().put("param2value", new String[]{"d", "e"}); @@ -181,6 +206,10 @@ public class AnchorTagTest extends AbstractUITagTest { param2.doStartTag(); param2.doEndTag(); + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", + strutsBodyTagsAreReflectionEqual(param2, freshParamTag)); //ValueHolder[] stack.getContext().put("param3value", new URLTagTest.ValueHolder[]{ @@ -192,6 +221,11 @@ public class AnchorTagTest extends AbstractUITagTest { param3.doStartTag(); param3.doEndTag(); + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", + strutsBodyTagsAreReflectionEqual(param3, freshParamTag)); + tag.doEndTag(); String result = writer.toString(); @@ -202,6 +236,13 @@ public class AnchorTagTest extends AbstractUITagTest { assertTrue(result.contains("p3=f")); assertTrue(result.contains("p3=g")); assertTrue(result.contains("p0=z")); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + AnchorTag freshTag = new AnchorTag(); + freshTag.setPageContext(pageContext); + assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", + strutsBodyTagsAreReflectionEqual(tag, freshTag)); } /** @@ -253,6 +294,26 @@ public class AnchorTagTest extends AbstractUITagTest { tag.doEndTag(); assertEquals(wrapWithAnchor("testAction.action?id1=paramId1&id2=tagId2&tagId=tagValue&param1=param1value&param2=param2value"), writer.toString()); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + ParamTag freshParamTag = new ParamTag(); + freshParamTag.setPageContext(pageContext); + assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", + strutsBodyTagsAreReflectionEqual(param1, freshParamTag)); + assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", + strutsBodyTagsAreReflectionEqual(param2, freshParamTag)); + assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", + strutsBodyTagsAreReflectionEqual(param3, freshParamTag)); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + AnchorTag freshTag = new AnchorTag(); + freshTag.setPageContext(pageContext); + assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", + strutsBodyTagsAreReflectionEqual(tag, freshTag)); } public void testIncludeParamsDefaultToGET() throws Exception { @@ -272,6 +333,13 @@ public class AnchorTagTest extends AbstractUITagTest { tag.doEndTag(); assertEquals(wrapWithAnchor("TestAction.acton?one=oneVal&two=twoVal&three=threeVal"), writer.toString()); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + AnchorTag freshTag = new AnchorTag(); + freshTag.setPageContext(pageContext); + assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", + strutsBodyTagsAreReflectionEqual(tag, freshTag)); } public void testActionURL2() throws Exception { @@ -306,7 +374,24 @@ public class AnchorTagTest extends AbstractUITagTest { assertTrue(result.contains("param0=value0")); assertTrue(result.contains("param1=value1")); assertTrue(result.contains("param2=value2")); - assertTrue(result.contains("/TestAction.action")); + assertTrue(result.contains("/TestAction.action")); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + ParamTag freshParamTag = new ParamTag(); + freshParamTag.setPageContext(pageContext); + assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", + strutsBodyTagsAreReflectionEqual(param1, freshParamTag)); + assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", + strutsBodyTagsAreReflectionEqual(param2, freshParamTag)); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + AnchorTag freshTag = new AnchorTag(); + freshTag.setPageContext(pageContext); + assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", + strutsBodyTagsAreReflectionEqual(tag, freshTag)); } public void testEvaluateValue() throws Exception { @@ -318,6 +403,13 @@ public class AnchorTagTest extends AbstractUITagTest { tag.doStartTag(); tag.doEndTag(); assertEquals(wrapWithAnchor("test"), writer.toString()); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + AnchorTag freshTag = new AnchorTag(); + freshTag.setPageContext(pageContext); + assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", + strutsBodyTagsAreReflectionEqual(tag, freshTag)); } public void testHttps() throws Exception { @@ -330,6 +422,13 @@ public class AnchorTagTest extends AbstractUITagTest { tag.doStartTag(); tag.doEndTag(); assertEquals(wrapWithAnchor("list-members.action"), writer.toString()); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + AnchorTag freshTag = new AnchorTag(); + freshTag.setPageContext(pageContext); + assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", + strutsBodyTagsAreReflectionEqual(tag, freshTag)); } public void testAnchor() throws Exception { @@ -343,6 +442,13 @@ public class AnchorTagTest extends AbstractUITagTest { tag.doStartTag(); tag.doEndTag(); assertEquals(wrapWithAnchor("list-members.action#test"), writer.toString()); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + AnchorTag freshTag = new AnchorTag(); + freshTag.setPageContext(pageContext); + assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", + strutsBodyTagsAreReflectionEqual(tag, freshTag)); } public void testParamPrecedence() throws Exception { @@ -365,6 +471,20 @@ public class AnchorTagTest extends AbstractUITagTest { anchor.doEndTag(); assertEquals(wrapWithAnchor("/context/someAction.action?id=33&name=John"), writer.getBuffer().toString()); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + ParamTag freshParamTag = new ParamTag(); + freshParamTag.setPageContext(pageContext); + assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", + strutsBodyTagsAreReflectionEqual(paramTag, freshParamTag)); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + AnchorTag freshTag = new AnchorTag(); + freshTag.setPageContext(pageContext); + assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", + strutsBodyTagsAreReflectionEqual(tag, freshTag)); } public void testParamPrecedenceWithAnchor() throws Exception { @@ -388,6 +508,20 @@ public class AnchorTagTest extends AbstractUITagTest { anchorTag.doEndTag(); assertEquals(wrapWithAnchor("/context/someAction.action?id=33&name=John#testAnchor"), writer.getBuffer().toString()); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + ParamTag freshParamTag = new ParamTag(); + freshParamTag.setPageContext(pageContext); + assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", + strutsBodyTagsAreReflectionEqual(paramTag, freshParamTag)); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + AnchorTag freshTag = new AnchorTag(); + freshTag.setPageContext(pageContext); + assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", + strutsBodyTagsAreReflectionEqual(tag, freshTag)); } @@ -396,6 +530,13 @@ public class AnchorTagTest extends AbstractUITagTest { tag.doStartTag(); tag.doEndTag(); assertEquals(wrapWithAnchor("/public/about/team.jsp"), writer.toString()); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + AnchorTag freshTag = new AnchorTag(); + freshTag.setPageContext(pageContext); + assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", + strutsBodyTagsAreReflectionEqual(tag, freshTag)); } public void testRequestURIActionIncludeNone() throws Exception { @@ -408,6 +549,13 @@ public class AnchorTagTest extends AbstractUITagTest { tag.doEndTag(); assertEquals(wrapWithAnchor("/team.action"), writer.toString()); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + AnchorTag freshTag = new AnchorTag(); + freshTag.setPageContext(pageContext); + assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", + strutsBodyTagsAreReflectionEqual(tag, freshTag)); } public void testRequestURIActionIncludeGet() throws Exception { @@ -420,6 +568,13 @@ public class AnchorTagTest extends AbstractUITagTest { tag.doEndTag(); assertEquals(wrapWithAnchor("/team.action?section=team&company=acme+inc"), writer.toString()); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + AnchorTag freshTag = new AnchorTag(); + freshTag.setPageContext(pageContext); + assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", + strutsBodyTagsAreReflectionEqual(tag, freshTag)); } public void testRequestURIActionIncludeGetDoNotEscapeAmp() throws Exception { @@ -433,6 +588,13 @@ public class AnchorTagTest extends AbstractUITagTest { tag.doEndTag(); assertEquals(wrapWithAnchor("/team.action?section=team&company=acme+inc"), writer.toString()); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + AnchorTag freshTag = new AnchorTag(); + freshTag.setPageContext(pageContext); + assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", + strutsBodyTagsAreReflectionEqual(tag, freshTag)); } public void testRequestURINoActionIncludeNone() throws Exception { @@ -445,6 +607,13 @@ public class AnchorTagTest extends AbstractUITagTest { tag.doEndTag(); assertEquals(wrapWithAnchor("/public/about"), writer.toString()); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + AnchorTag freshTag = new AnchorTag(); + freshTag.setPageContext(pageContext); + assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", + strutsBodyTagsAreReflectionEqual(tag, freshTag)); } public void testNoActionIncludeGet() throws Exception { @@ -457,6 +626,13 @@ public class AnchorTagTest extends AbstractUITagTest { tag.doEndTag(); assertEquals(wrapWithAnchor("/public/about?section=team&company=acme+inc"), writer.toString()); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + AnchorTag freshTag = new AnchorTag(); + freshTag.setPageContext(pageContext); + assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", + strutsBodyTagsAreReflectionEqual(tag, freshTag)); } public void testRequestURIActionIncludeAll() throws Exception { @@ -483,6 +659,20 @@ public class AnchorTagTest extends AbstractUITagTest { assertTrue(result.contains("section=team")); assertTrue(result.contains("company=acme+inc")); assertTrue(result.contains("year=2006")); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + ParamTag freshParamTag = new ParamTag(); + freshParamTag.setPageContext(pageContext); + assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", + strutsBodyTagsAreReflectionEqual(paramTag, freshParamTag)); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + AnchorTag freshTag = new AnchorTag(); + freshTag.setPageContext(pageContext); + assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", + strutsBodyTagsAreReflectionEqual(tag, freshTag)); } public void testRequestURINoActionIncludeAll() throws Exception { @@ -509,6 +699,20 @@ public class AnchorTagTest extends AbstractUITagTest { assertTrue(result.contains("section=team")); assertTrue(result.contains("company=acme+inc")); assertTrue(result.contains("year=2006")); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + ParamTag freshParamTag = new ParamTag(); + freshParamTag.setPageContext(pageContext); + assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", + strutsBodyTagsAreReflectionEqual(paramTag, freshParamTag)); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + AnchorTag freshTag = new AnchorTag(); + freshTag.setPageContext(pageContext); + assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", + strutsBodyTagsAreReflectionEqual(tag, freshTag)); } public void testUnknownIncludeParam() throws Exception { @@ -519,6 +723,13 @@ public class AnchorTagTest extends AbstractUITagTest { tag.doStartTag(); tag.doEndTag(); assertEquals(wrapWithAnchor("/public/about"), writer.toString()); // should not add any request parameters + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + AnchorTag freshTag = new AnchorTag(); + freshTag.setPageContext(pageContext); + assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", + strutsBodyTagsAreReflectionEqual(tag, freshTag)); } public void testRequestURIWithAnchor() throws Exception { @@ -531,6 +742,13 @@ public class AnchorTagTest extends AbstractUITagTest { tag.doEndTag(); assertEquals(wrapWithAnchor("/company.action?company=acme+inc"), writer.toString()); // will always chop anchor if using requestURI + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + AnchorTag freshTag = new AnchorTag(); + freshTag.setPageContext(pageContext); + assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", + strutsBodyTagsAreReflectionEqual(tag, freshTag)); } public void testIncludeContext() throws Exception { @@ -542,6 +760,13 @@ public class AnchorTagTest extends AbstractUITagTest { tag.doEndTag(); assertEquals(wrapWithAnchor("/myapp/company.action"), writer.toString()); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + AnchorTag freshTag = new AnchorTag(); + freshTag.setPageContext(pageContext); + assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", + strutsBodyTagsAreReflectionEqual(tag, freshTag)); } public void testForceAddSchemeHostAndPort() throws Exception { @@ -551,12 +776,20 @@ public class AnchorTagTest extends AbstractUITagTest { tag.doEndTag(); assertEquals(wrapWithAnchor("http://localhost/company.action"), writer.toString()); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + AnchorTag freshTag = new AnchorTag(); + freshTag.setPageContext(pageContext); + assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", + strutsBodyTagsAreReflectionEqual(tag, freshTag)); } private String wrapWithAnchor(String href) { return MessageFormat.format("", href); } + @Override protected void setUp() throws Exception { super.setUp(); diff --git a/core/src/test/java/org/apache/struts2/views/jsp/AppendIteratorTagTest.java b/core/src/test/java/org/apache/struts2/views/jsp/AppendIteratorTagTest.java index 64112c911..6ae0756cc 100644 --- a/core/src/test/java/org/apache/struts2/views/jsp/AppendIteratorTagTest.java +++ b/core/src/test/java/org/apache/struts2/views/jsp/AppendIteratorTagTest.java @@ -82,6 +82,26 @@ public class AppendIteratorTagTest extends AbstractTagTest { assertTrue(appendedIterator.hasNext()); assertEquals(appendedIterator.next(), "C"); assertFalse(appendedIterator.hasNext()); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + ParamTag freshParamTag = new ParamTag(); + freshParamTag.setPageContext(pageContext); + assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", + strutsBodyTagsAreReflectionEqual(iterator1ParamTag, freshParamTag)); + assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", + strutsBodyTagsAreReflectionEqual(iterator2ParamTag, freshParamTag)); + assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", + strutsBodyTagsAreReflectionEqual(iterator3ParamTag, freshParamTag)); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + AppendIteratorTag freshTag = new AppendIteratorTag(); + freshTag.setPageContext(pageContext); + assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", + strutsBodyTagsAreReflectionEqual(tag, freshTag)); } public void testAppendingIteratorsUsingListAsSource() throws Exception { @@ -133,10 +153,31 @@ public class AppendIteratorTagTest extends AbstractTagTest { assertTrue(appendedIterator.hasNext()); assertEquals(appendedIterator.next(), "C"); assertFalse(appendedIterator.hasNext()); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + ParamTag freshParamTag = new ParamTag(); + freshParamTag.setPageContext(pageContext); + assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", + strutsBodyTagsAreReflectionEqual(iterator1ParamTag, freshParamTag)); + assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", + strutsBodyTagsAreReflectionEqual(iterator2ParamTag, freshParamTag)); + assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", + strutsBodyTagsAreReflectionEqual(iterator3ParamTag, freshParamTag)); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + AppendIteratorTag freshTag = new AppendIteratorTag(); + freshTag.setPageContext(pageContext); + assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", + strutsBodyTagsAreReflectionEqual(tag, freshTag)); } + @Override public Action getAction() { return new ActionSupport() { public List getMyList1() { diff --git a/core/src/test/java/org/apache/struts2/views/jsp/BeanTagTest.java b/core/src/test/java/org/apache/struts2/views/jsp/BeanTagTest.java index 168ffe563..5d8d43a9c 100644 --- a/core/src/test/java/org/apache/struts2/views/jsp/BeanTagTest.java +++ b/core/src/test/java/org/apache/struts2/views/jsp/BeanTagTest.java @@ -46,5 +46,12 @@ public class BeanTagTest extends AbstractUITagTest { request.verify(); pageContext.verify(); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + BeanTag freshTag = new BeanTag(); + freshTag.setPageContext(pageContext); + assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", + strutsBodyTagsAreReflectionEqual(tag, freshTag)); } } diff --git a/core/src/test/java/org/apache/struts2/views/jsp/ElseIfTagTest.java b/core/src/test/java/org/apache/struts2/views/jsp/ElseIfTagTest.java index 007cc82e6..c5b8648ee 100644 --- a/core/src/test/java/org/apache/struts2/views/jsp/ElseIfTagTest.java +++ b/core/src/test/java/org/apache/struts2/views/jsp/ElseIfTagTest.java @@ -50,6 +50,13 @@ public class ElseIfTagTest extends StrutsInternalTestCase { tag.doEndTag(); assertEquals(result, TagSupport.EVAL_BODY_INCLUDE); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + ElseIfTag freshTag = new ElseIfTag(); + freshTag.setPageContext(pageContext); + assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", + objectsAreReflectionEqual(tag, freshTag)); } public void testIfIsFalseElseIfIsFalse() throws Exception { @@ -63,6 +70,13 @@ public class ElseIfTagTest extends StrutsInternalTestCase { tag.doEndTag(); assertEquals(result, TagSupport.SKIP_BODY); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + ElseIfTag freshTag = new ElseIfTag(); + freshTag.setPageContext(pageContext); + assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", + objectsAreReflectionEqual(tag, freshTag)); } public void testIfIsTrueElseIfIsTrue() throws Exception { @@ -76,6 +90,13 @@ public class ElseIfTagTest extends StrutsInternalTestCase { tag.doEndTag(); assertEquals(result, TagSupport.SKIP_BODY); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + ElseIfTag freshTag = new ElseIfTag(); + freshTag.setPageContext(pageContext); + assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", + objectsAreReflectionEqual(tag, freshTag)); } public void testIfIsTrueElseIfIsFalse() throws Exception { @@ -89,9 +110,17 @@ public class ElseIfTagTest extends StrutsInternalTestCase { tag.doEndTag(); assertEquals(result, TagSupport.SKIP_BODY); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + ElseIfTag freshTag = new ElseIfTag(); + freshTag.setPageContext(pageContext); + assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", + objectsAreReflectionEqual(tag, freshTag)); } + @Override protected void setUp() throws Exception { super.setUp(); stack = ActionContext.getContext().getValueStack(); diff --git a/core/src/test/java/org/apache/struts2/views/jsp/ElseTagTest.java b/core/src/test/java/org/apache/struts2/views/jsp/ElseTagTest.java index e39304ab2..270ac77cd 100644 --- a/core/src/test/java/org/apache/struts2/views/jsp/ElseTagTest.java +++ b/core/src/test/java/org/apache/struts2/views/jsp/ElseTagTest.java @@ -54,6 +54,13 @@ public class ElseTagTest extends StrutsInternalTestCase { fail(); } assertEquals(TagSupport.EVAL_BODY_INCLUDE, result); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + ElseTag freshTag = new ElseTag(); + freshTag.setPageContext(pageContext); + assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", + objectsAreReflectionEqual(elseTag, freshTag)); } public void testTestNull() { @@ -63,12 +70,20 @@ public class ElseTagTest extends StrutsInternalTestCase { try { result = elseTag.doStartTag(); + elseTag.doEndTag(); } catch (JspException e) { e.printStackTrace(); fail(); } assertEquals(TagSupport.SKIP_BODY, result); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + ElseTag freshTag = new ElseTag(); + freshTag.setPageContext(pageContext); + assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", + objectsAreReflectionEqual(elseTag, freshTag)); } public void testTestTrue() { @@ -79,14 +94,23 @@ public class ElseTagTest extends StrutsInternalTestCase { try { result = elseTag.doStartTag(); + elseTag.doEndTag(); } catch (JspException e) { e.printStackTrace(); fail(); } assertEquals(TagSupport.SKIP_BODY, result); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + ElseTag freshTag = new ElseTag(); + freshTag.setPageContext(pageContext); + assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", + objectsAreReflectionEqual(elseTag, freshTag)); } + @Override protected void setUp() throws Exception { super.setUp(); // create the needed objects diff --git a/core/src/test/java/org/apache/struts2/views/jsp/I18nTagTest.java b/core/src/test/java/org/apache/struts2/views/jsp/I18nTagTest.java index 6b5ac867a..39659e8b6 100644 --- a/core/src/test/java/org/apache/struts2/views/jsp/I18nTagTest.java +++ b/core/src/test/java/org/apache/struts2/views/jsp/I18nTagTest.java @@ -35,6 +35,7 @@ public class I18nTagTest extends StrutsInternalTestCase { MockPageContext pageContext; ValueStack stack; + @Override protected void setUp() throws Exception { super.setUp(); // create the needed objects @@ -76,6 +77,13 @@ public class I18nTagTest extends StrutsInternalTestCase { e.printStackTrace(); fail(); } + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + I18nTag freshTag = new I18nTag(); + freshTag.setPageContext(pageContext); + assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", + objectsAreReflectionEqual(tag, freshTag)); } /** diff --git a/core/src/test/java/org/apache/struts2/views/jsp/IfTagTest.java b/core/src/test/java/org/apache/struts2/views/jsp/IfTagTest.java index 4537e9a58..31b9e4dc6 100644 --- a/core/src/test/java/org/apache/struts2/views/jsp/IfTagTest.java +++ b/core/src/test/java/org/apache/struts2/views/jsp/IfTagTest.java @@ -65,6 +65,13 @@ public class IfTagTest extends StrutsInternalTestCase { e.printStackTrace(); fail(); } + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + IfTag freshTag = new IfTag(); + freshTag.setPageContext(pageContext); + assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", + objectsAreReflectionEqual(tag, freshTag)); } public void testTestError() { @@ -93,6 +100,13 @@ public class IfTagTest extends StrutsInternalTestCase { e.printStackTrace(); fail(); } + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + IfTag freshTag = new IfTag(); + freshTag.setPageContext(pageContext); + assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", + objectsAreReflectionEqual(tag, freshTag)); } public void testTestFalse() { @@ -121,6 +135,13 @@ public class IfTagTest extends StrutsInternalTestCase { e.printStackTrace(); fail(); } + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + IfTag freshTag = new IfTag(); + freshTag.setPageContext(pageContext); + assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", + objectsAreReflectionEqual(tag, freshTag)); } public void testTestTrue() { @@ -150,6 +171,13 @@ public class IfTagTest extends StrutsInternalTestCase { e.printStackTrace(); fail(); } + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + IfTag freshTag = new IfTag(); + freshTag.setPageContext(pageContext); + assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", + objectsAreReflectionEqual(tag, freshTag)); } @@ -168,6 +196,20 @@ public class IfTagTest extends StrutsInternalTestCase { assertEquals(TagSupport.EVAL_BODY_INCLUDE, r1); assertEquals(TagSupport.SKIP_BODY, r2); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + IfTag freshTag = new IfTag(); + freshTag.setPageContext(pageContext); + assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", + objectsAreReflectionEqual(ifTag, freshTag)); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + ElseTag freshTag2 = new ElseTag(); + freshTag2.setPageContext(pageContext); + assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", + objectsAreReflectionEqual(elseTag, freshTag2)); } public void testIfElse2() throws Exception { @@ -185,6 +227,20 @@ public class IfTagTest extends StrutsInternalTestCase { assertEquals(TagSupport.SKIP_BODY, r1); assertEquals(TagSupport.EVAL_BODY_INCLUDE, r2); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + IfTag freshTag = new IfTag(); + freshTag.setPageContext(pageContext); + assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", + objectsAreReflectionEqual(ifTag, freshTag)); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + ElseTag freshTag2 = new ElseTag(); + freshTag2.setPageContext(pageContext); + assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", + objectsAreReflectionEqual(elseTag, freshTag2)); } public void testIfElseIf() throws Exception { @@ -217,6 +273,26 @@ public class IfTagTest extends StrutsInternalTestCase { assertEquals(TagSupport.SKIP_BODY, r2); assertEquals(TagSupport.EVAL_BODY_INCLUDE, r3); assertEquals(TagSupport.SKIP_BODY, r4); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + IfTag freshTag = new IfTag(); + freshTag.setPageContext(pageContext); + assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", + objectsAreReflectionEqual(ifTag, freshTag)); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + ElseIfTag freshTag2 = new ElseIfTag(); + freshTag2.setPageContext(pageContext); + assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", + objectsAreReflectionEqual(elseIfTag1, freshTag2)); + assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", + objectsAreReflectionEqual(elseIfTag2, freshTag2)); + assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", + objectsAreReflectionEqual(elseIfTag3, freshTag2)); } public void testIfElseIfElse() throws Exception { @@ -255,6 +331,33 @@ public class IfTagTest extends StrutsInternalTestCase { assertEquals(TagSupport.SKIP_BODY, r3); assertEquals(TagSupport.SKIP_BODY, r4); assertEquals(TagSupport.EVAL_BODY_INCLUDE, r5); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + IfTag freshTag = new IfTag(); + freshTag.setPageContext(pageContext); + assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", + objectsAreReflectionEqual(ifTag, freshTag)); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + ElseIfTag freshTag2 = new ElseIfTag(); + freshTag2.setPageContext(pageContext); + assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", + objectsAreReflectionEqual(elseIfTag1, freshTag2)); + assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", + objectsAreReflectionEqual(elseIfTag2, freshTag2)); + assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", + objectsAreReflectionEqual(elseIfTag3, freshTag2)); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + ElseTag freshTag3 = new ElseTag(); + freshTag3.setPageContext(pageContext); + assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", + objectsAreReflectionEqual(elseTag, freshTag3)); } @@ -283,6 +386,23 @@ public class IfTagTest extends StrutsInternalTestCase { assertEquals(TagSupport.EVAL_PAGE, r4); assertEquals(TagSupport.SKIP_BODY, r5); assertEquals(TagSupport.EVAL_PAGE, r6); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + IfTag freshTag = new IfTag(); + freshTag.setPageContext(pageContext); + assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", + objectsAreReflectionEqual(ifTag, freshTag)); + assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", + objectsAreReflectionEqual(nestedIfTag, freshTag)); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + ElseTag freshTag2 = new ElseTag(); + freshTag2.setPageContext(pageContext); + assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", + objectsAreReflectionEqual(elseTag, freshTag2)); } public void testNestedIfElse2() throws Exception { @@ -310,11 +430,29 @@ public class IfTagTest extends StrutsInternalTestCase { assertEquals(TagSupport.EVAL_PAGE, r4); assertEquals(TagSupport.SKIP_BODY, r5); assertEquals(TagSupport.EVAL_PAGE, r6); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + IfTag freshTag = new IfTag(); + freshTag.setPageContext(pageContext); + assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", + objectsAreReflectionEqual(ifTag, freshTag)); + assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", + objectsAreReflectionEqual(nestedIfTag, freshTag)); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + ElseTag freshTag2 = new ElseTag(); + freshTag2.setPageContext(pageContext); + assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", + objectsAreReflectionEqual(elseTag, freshTag2)); } + @Override protected void setUp() throws Exception { super.setUp(); // create the needed objects diff --git a/core/src/test/java/org/apache/struts2/views/jsp/IncludeTagTest.java b/core/src/test/java/org/apache/struts2/views/jsp/IncludeTagTest.java index 45830854f..69d134292 100644 --- a/core/src/test/java/org/apache/struts2/views/jsp/IncludeTagTest.java +++ b/core/src/test/java/org/apache/struts2/views/jsp/IncludeTagTest.java @@ -65,6 +65,13 @@ public class IncludeTagTest extends AbstractTagTest { assertEquals("", writer.toString()); verify(mockRequestDispatcher); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + IncludeTag freshTag = new IncludeTag(); + freshTag.setPageContext(pageContext); + assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", + strutsBodyTagsAreReflectionEqual(tag, freshTag)); } public void testIncludeWithParameters() throws Exception { @@ -86,6 +93,13 @@ public class IncludeTagTest extends AbstractTagTest { assertEquals("", writer.toString()); verify(mockRequestDispatcher); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + IncludeTag freshTag = new IncludeTag(); + freshTag.setPageContext(pageContext); + assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", + strutsBodyTagsAreReflectionEqual(tag, freshTag)); } public void testIncludeRelative2Dots() throws Exception { @@ -105,7 +119,14 @@ public class IncludeTagTest extends AbstractTagTest { assertEquals("/car/view.jsp", request.getRequestDispatherString()); assertEquals("", writer.toString()); - verify(mockRequestDispatcher); + verify(mockRequestDispatcher); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + IncludeTag freshTag = new IncludeTag(); + freshTag.setPageContext(pageContext); + assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", + strutsBodyTagsAreReflectionEqual(tag, freshTag)); } public void testIncludeSetUseResponseEncodingTrue() throws Exception { @@ -133,6 +154,13 @@ public class IncludeTagTest extends AbstractTagTest { assertEquals("", writer.toString()); // Nothing gets written for mock-include verify(mockRequestDispatcher); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + IncludeTag freshTag = new IncludeTag(); + freshTag.setPageContext(pageContext); + assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", + strutsBodyTagsAreReflectionEqual(tag, freshTag)); } public void testIncludeSetUseResponseEncodingFalse() throws Exception { @@ -160,8 +188,16 @@ public class IncludeTagTest extends AbstractTagTest { assertEquals("", writer.toString()); // Nothing gets written for mock-include verify(mockRequestDispatcher); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + IncludeTag freshTag = new IncludeTag(); + freshTag.setPageContext(pageContext); + assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", + strutsBodyTagsAreReflectionEqual(tag, freshTag)); } + @Override protected void setUp() throws Exception { super.setUp(); request.setupGetRequestDispatcher(new MockRequestDispatcher()); @@ -174,6 +210,7 @@ public class IncludeTagTest extends AbstractTagTest { tag.setPageContext(pageContext); } + @Override protected void tearDown() throws Exception { super.tearDown(); tag = null; diff --git a/core/src/test/java/org/apache/struts2/views/jsp/IteratorGeneratorTagTest.java b/core/src/test/java/org/apache/struts2/views/jsp/IteratorGeneratorTagTest.java index a5efc523e..cf53dd14c 100644 --- a/core/src/test/java/org/apache/struts2/views/jsp/IteratorGeneratorTagTest.java +++ b/core/src/test/java/org/apache/struts2/views/jsp/IteratorGeneratorTagTest.java @@ -65,6 +65,13 @@ public class IteratorGeneratorTagTest extends AbstractTagTest { assertNotSame(afterTopOfStack, topOfStack); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + IteratorGeneratorTag freshTag = new IteratorGeneratorTag(); + freshTag.setPageContext(pageContext); + assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", + strutsBodyTagsAreReflectionEqual(tag, freshTag)); } public void testGeneratorWithSeparator() throws Exception { @@ -97,6 +104,13 @@ public class IteratorGeneratorTagTest extends AbstractTagTest { assertFalse(((Iterator)topOfStack).hasNext()); assertNotSame(afterTopOfStack, topOfStack); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + IteratorGeneratorTag freshTag = new IteratorGeneratorTag(); + freshTag.setPageContext(pageContext); + assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", + strutsBodyTagsAreReflectionEqual(tag, freshTag)); } public void testGeneratorWithConverter() throws Exception { @@ -129,6 +143,13 @@ public class IteratorGeneratorTagTest extends AbstractTagTest { assertFalse(((Iterator)topOfStack).hasNext()); assertNotSame(afterTopOfStack, topOfStack); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + IteratorGeneratorTag freshTag = new IteratorGeneratorTag(); + freshTag.setPageContext(pageContext); + assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", + strutsBodyTagsAreReflectionEqual(tag, freshTag)); } public void testGeneratorWithId() throws Exception { @@ -159,6 +180,13 @@ public class IteratorGeneratorTagTest extends AbstractTagTest { assertEquals(((Iterator)pageContextIterator).next(), "eee"); assertFalse(((Iterator)pageContextIterator).hasNext()); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + IteratorGeneratorTag freshTag = new IteratorGeneratorTag(); + freshTag.setPageContext(pageContext); + assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", + strutsBodyTagsAreReflectionEqual(tag, freshTag)); } public void testGeneratorWithCount() throws Exception { @@ -186,9 +214,17 @@ public class IteratorGeneratorTagTest extends AbstractTagTest { assertFalse(((Iterator)topOfStack).hasNext()); assertNotSame(topOfStack, afterTopOfStack); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + IteratorGeneratorTag freshTag = new IteratorGeneratorTag(); + freshTag.setPageContext(pageContext); + assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", + strutsBodyTagsAreReflectionEqual(tag, freshTag)); } + @Override public Action getAction() { return new ActionSupport() { public Converter getMyConverter() { diff --git a/core/src/test/java/org/apache/struts2/views/jsp/IteratorTagTest.java b/core/src/test/java/org/apache/struts2/views/jsp/IteratorTagTest.java index df13f164e..a473931cf 100644 --- a/core/src/test/java/org/apache/struts2/views/jsp/IteratorTagTest.java +++ b/core/src/test/java/org/apache/struts2/views/jsp/IteratorTagTest.java @@ -59,7 +59,7 @@ public class IteratorTagTest extends AbstractUITagTest { // one int result = tag.doStartTag(); - assertEquals(result, TagSupport.EVAL_BODY_INCLUDE); + assertEquals(TagSupport.EVAL_BODY_INCLUDE, result); assertEquals(stack.peek(), "one"); assertEquals(stack.getContext().get("myId"), "one"); @@ -68,37 +68,44 @@ public class IteratorTagTest extends AbstractUITagTest { // two result = tag.doAfterBody(); - assertEquals(result, TagSupport.EVAL_BODY_AGAIN); + assertEquals(TagSupport.EVAL_BODY_AGAIN, result); assertEquals(stack.peek(), "two"); assertEquals(stack.getContext().get("myId"), "two"); // three result = tag.doAfterBody(); - assertEquals(result, TagSupport.EVAL_BODY_AGAIN); + assertEquals(TagSupport.EVAL_BODY_AGAIN, result); assertEquals(stack.peek(), "three"); assertEquals(stack.getContext().get("myId"), "three"); // four result = tag.doAfterBody(); - assertEquals(result, TagSupport.EVAL_BODY_AGAIN); + assertEquals(TagSupport.EVAL_BODY_AGAIN, result); assertEquals(stack.peek(), "four"); assertEquals(stack.getContext().get("myId"), "four"); // five result = tag.doAfterBody(); - assertEquals(result, TagSupport.EVAL_BODY_AGAIN); + assertEquals(TagSupport.EVAL_BODY_AGAIN, result); assertEquals(stack.peek(), "five"); assertEquals(stack.getContext().get("myId"), "five"); result = tag.doAfterBody(); - assertEquals(result, TagSupport.SKIP_BODY); + assertEquals(TagSupport.SKIP_BODY, result); result = tag.doEndTag(); - assertEquals(result, TagSupport.EVAL_PAGE); + assertEquals(TagSupport.EVAL_PAGE, result); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + IteratorTag freshTag = new IteratorTag(); + freshTag.setPageContext(pageContext); + assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", + strutsBodyTagsAreReflectionEqual(tag, freshTag)); } public void testIteratingWithIdSpecifiedAndNullElementOnCollection() throws Exception { @@ -117,7 +124,7 @@ public class IteratorTagTest extends AbstractUITagTest { // one int result = tag.doStartTag(); - assertEquals(result, TagSupport.EVAL_BODY_INCLUDE); + assertEquals(TagSupport.EVAL_BODY_INCLUDE, result); assertEquals(stack.peek(), "one"); assertEquals(stack.getContext().get("myId"), "one"); @@ -126,22 +133,29 @@ public class IteratorTagTest extends AbstractUITagTest { // two result = tag.doAfterBody(); - assertEquals(result, TagSupport.EVAL_BODY_AGAIN); + assertEquals(TagSupport.EVAL_BODY_AGAIN, result); assertNull(stack.peek()); assertNull(stack.getContext().get("myId")); // three result = tag.doAfterBody(); - assertEquals(result, TagSupport.EVAL_BODY_AGAIN); + assertEquals(TagSupport.EVAL_BODY_AGAIN, result); assertEquals(stack.peek(), "three"); assertEquals(stack.getContext().get("myId"), "three"); result = tag.doAfterBody(); - assertEquals(result, TagSupport.SKIP_BODY); + assertEquals(TagSupport.SKIP_BODY, result); result = tag.doEndTag(); - assertEquals(result, TagSupport.EVAL_PAGE); + assertEquals(TagSupport.EVAL_PAGE, result); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + IteratorTag freshTag = new IteratorTag(); + freshTag.setPageContext(pageContext); + assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", + strutsBodyTagsAreReflectionEqual(tag, freshTag)); } @@ -232,6 +246,22 @@ public class IteratorTagTest extends AbstractUITagTest { assertEquals(TagSupport.SKIP_BODY, result); assertEquals(3, stack.size()); + + try { + result = tag.doEndTag(); + } catch (JspException e) { + e.printStackTrace(); + fail(); + } + + assertEquals(TagSupport.EVAL_PAGE, result); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + IteratorTag freshTag = new IteratorTag(); + freshTag.setPageContext(pageContext); + assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", + strutsBodyTagsAreReflectionEqual(tag, freshTag)); } public void testStatus() { @@ -252,7 +282,7 @@ public class IteratorTagTest extends AbstractUITagTest { fail(); } - assertEquals(result, TagSupport.EVAL_BODY_INCLUDE); + assertEquals(TagSupport.EVAL_BODY_INCLUDE, result); assertEquals("test1", stack.getRoot().peek()); assertEquals(4, stack.size()); @@ -272,7 +302,7 @@ public class IteratorTagTest extends AbstractUITagTest { fail(); } - assertEquals(result, TagSupport.EVAL_BODY_AGAIN); + assertEquals(TagSupport.EVAL_BODY_AGAIN, result); assertEquals("test2", stack.getRoot().peek()); assertEquals(4, stack.size()); @@ -292,7 +322,7 @@ public class IteratorTagTest extends AbstractUITagTest { fail(); } - assertEquals(result, TagSupport.EVAL_BODY_AGAIN); + assertEquals(TagSupport.EVAL_BODY_AGAIN, result); assertEquals("test3", stack.getRoot().peek()); assertEquals(4, stack.size()); @@ -304,6 +334,22 @@ public class IteratorTagTest extends AbstractUITagTest { assertEquals(3, status.getCount()); assertTrue(status.isOdd()); assertFalse(status.isEven()); + + try { + result = tag.doEndTag(); + } catch (JspException e) { + e.printStackTrace(); + fail(); + } + + assertEquals(TagSupport.EVAL_PAGE, result); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + IteratorTag freshTag = new IteratorTag(); + freshTag.setPageContext(pageContext); + assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", + strutsBodyTagsAreReflectionEqual(tag, freshTag)); } public void testEmptyArray() { @@ -661,7 +707,7 @@ public class IteratorTagTest extends AbstractUITagTest { List values = new ArrayList(); try { int result = tag.doStartTag(); - assertEquals(result, TagSupport.EVAL_BODY_INCLUDE); + assertEquals(TagSupport.EVAL_BODY_INCLUDE, result); values.add(stack.getRoot().peek()); } catch (JspException e) { e.printStackTrace(); @@ -676,6 +722,7 @@ public class IteratorTagTest extends AbstractUITagTest { ListUtils.isEqualList(Arrays.asList(expectedValues), values); } + @Override protected void setUp() throws Exception { super.setUp(); @@ -700,7 +747,7 @@ public class IteratorTagTest extends AbstractUITagTest { fail(); } - assertEquals(result, TagSupport.EVAL_BODY_INCLUDE); + assertEquals(TagSupport.EVAL_BODY_INCLUDE, result); assertEquals("test1", stack.getRoot().peek()); assertEquals(4, stack.size()); @@ -711,7 +758,7 @@ public class IteratorTagTest extends AbstractUITagTest { fail(); } - assertEquals(result, TagSupport.EVAL_BODY_AGAIN); + assertEquals(TagSupport.EVAL_BODY_AGAIN, result); assertEquals("test2", stack.getRoot().peek()); assertEquals(4, stack.size()); @@ -722,7 +769,7 @@ public class IteratorTagTest extends AbstractUITagTest { fail(); } - assertEquals(result, TagSupport.EVAL_BODY_AGAIN); + assertEquals(TagSupport.EVAL_BODY_AGAIN, result); assertEquals("test3", stack.getRoot().peek()); assertEquals(4, stack.size()); @@ -733,7 +780,7 @@ public class IteratorTagTest extends AbstractUITagTest { fail(); } - assertEquals(result, TagSupport.SKIP_BODY); + assertEquals(TagSupport.SKIP_BODY, result); assertEquals(3, stack.size()); } @@ -747,13 +794,22 @@ public class IteratorTagTest extends AbstractUITagTest { fail(); } - assertEquals(result, TagSupport.SKIP_BODY); + assertEquals(TagSupport.SKIP_BODY, result); try { result = tag.doEndTag(); } catch (JspException e) { e.printStackTrace(); fail(); } + + assertEquals(TagSupport.EVAL_PAGE, result); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + IteratorTag freshTag = new IteratorTag(); + freshTag.setPageContext(pageContext); + assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", + strutsBodyTagsAreReflectionEqual(tag, freshTag)); } class Foo { diff --git a/core/src/test/java/org/apache/struts2/views/jsp/MergeIteratorTagTest.java b/core/src/test/java/org/apache/struts2/views/jsp/MergeIteratorTagTest.java index fd3dad1ec..811f4de44 100644 --- a/core/src/test/java/org/apache/struts2/views/jsp/MergeIteratorTagTest.java +++ b/core/src/test/java/org/apache/struts2/views/jsp/MergeIteratorTagTest.java @@ -82,6 +82,26 @@ public class MergeIteratorTagTest extends AbstractTagTest { assertTrue(mergedIterator.hasNext()); assertEquals(mergedIterator.next(), "C"); assertFalse(mergedIterator.hasNext()); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + ParamTag freshParamTag = new ParamTag(); + freshParamTag.setPageContext(pageContext); + assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", + strutsBodyTagsAreReflectionEqual(iterator1ParamTag, freshParamTag)); + assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", + strutsBodyTagsAreReflectionEqual(iterator2ParamTag, freshParamTag)); + assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", + strutsBodyTagsAreReflectionEqual(iterator3ParamTag, freshParamTag)); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + MergeIteratorTag freshTag = new MergeIteratorTag(); + freshTag.setPageContext(pageContext); + assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", + strutsBodyTagsAreReflectionEqual(tag, freshTag)); } @@ -134,6 +154,26 @@ public class MergeIteratorTagTest extends AbstractTagTest { assertTrue(mergedIterator.hasNext()); assertEquals(mergedIterator.next(), "C"); assertFalse(mergedIterator.hasNext()); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + ParamTag freshParamTag = new ParamTag(); + freshParamTag.setPageContext(pageContext); + assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", + strutsBodyTagsAreReflectionEqual(iterator1ParamTag, freshParamTag)); + assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", + strutsBodyTagsAreReflectionEqual(iterator2ParamTag, freshParamTag)); + assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", + strutsBodyTagsAreReflectionEqual(iterator3ParamTag, freshParamTag)); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + MergeIteratorTag freshTag = new MergeIteratorTag(); + freshTag.setPageContext(pageContext); + assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", + strutsBodyTagsAreReflectionEqual(tag, freshTag)); } diff --git a/core/src/test/java/org/apache/struts2/views/jsp/NumberTagTest.java b/core/src/test/java/org/apache/struts2/views/jsp/NumberTagTest.java index 6056a94cd..9a414545e 100644 --- a/core/src/test/java/org/apache/struts2/views/jsp/NumberTagTest.java +++ b/core/src/test/java/org/apache/struts2/views/jsp/NumberTagTest.java @@ -44,6 +44,13 @@ public class NumberTagTest extends AbstractTagTest { // then assertEquals("120", writer.toString()); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + NumberTag freshTag = new NumberTag(); + freshTag.setPageContext(pageContext); + assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", + strutsBodyTagsAreReflectionEqual(tag, freshTag)); } public void testSimpleCurrencyUSFormat() throws Exception { @@ -64,6 +71,12 @@ public class NumberTagTest extends AbstractTagTest { // then assertEquals("$120.00", writer.toString()); + + NumberTag freshTag = new NumberTag(); + freshTag.setPageContext(pageContext); + assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", + strutsBodyTagsAreReflectionEqual(tag, freshTag)); } public void testSimpleCurrencyPLFormat() throws Exception { @@ -89,6 +102,12 @@ public class NumberTagTest extends AbstractTagTest { String expected = format.format(120.0f); assertEquals(expected, writer.toString()); + + NumberTag freshTag = new NumberTag(); + freshTag.setPageContext(pageContext); + assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", + strutsBodyTagsAreReflectionEqual(tag, freshTag)); } public void testSimpleRoundingCeiling() throws Exception { @@ -114,6 +133,12 @@ public class NumberTagTest extends AbstractTagTest { String expected = format.format(120.45f); assertEquals(expected, writer.toString()); + + NumberTag freshTag = new NumberTag(); + freshTag.setPageContext(pageContext); + assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", + strutsBodyTagsAreReflectionEqual(tag, freshTag)); } } diff --git a/core/src/test/java/org/apache/struts2/views/jsp/PropertyTagTest.java b/core/src/test/java/org/apache/struts2/views/jsp/PropertyTagTest.java index f37431af2..8b074222e 100644 --- a/core/src/test/java/org/apache/struts2/views/jsp/PropertyTagTest.java +++ b/core/src/test/java/org/apache/struts2/views/jsp/PropertyTagTest.java @@ -65,6 +65,20 @@ public class PropertyTagTest extends StrutsInternalTestCase { request.verify(); jspWriter.verify(); pageContext.verify(); + + try { + tag.doEndTag(); + } catch (JspException e) { + e.printStackTrace(); + fail(); + } + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + PropertyTag freshTag = new PropertyTag(); + freshTag.setPageContext(pageContext); + assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", + objectsAreReflectionEqual(tag, freshTag)); } public void testNull() { @@ -94,6 +108,20 @@ public class PropertyTagTest extends StrutsInternalTestCase { request.verify(); jspWriter.verify(); pageContext.verify(); + + try { + tag.doEndTag(); + } catch (JspException e) { + e.printStackTrace(); + fail(); + } + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + PropertyTag freshTag = new PropertyTag(); + freshTag.setPageContext(pageContext); + assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", + objectsAreReflectionEqual(tag, freshTag)); } public void testSimple() { @@ -124,6 +152,20 @@ public class PropertyTagTest extends StrutsInternalTestCase { request.verify(); jspWriter.verify(); pageContext.verify(); + + try { + tag.doEndTag(); + } catch (JspException e) { + e.printStackTrace(); + fail(); + } + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + PropertyTag freshTag = new PropertyTag(); + freshTag.setPageContext(pageContext); + assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", + objectsAreReflectionEqual(tag, freshTag)); } public void testTopOfStack() { @@ -153,6 +195,20 @@ public class PropertyTagTest extends StrutsInternalTestCase { request.verify(); jspWriter.verify(); pageContext.verify(); + + try { + tag.doEndTag(); + } catch (JspException e) { + e.printStackTrace(); + fail(); + } + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + PropertyTag freshTag = new PropertyTag(); + freshTag.setPageContext(pageContext); + assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", + objectsAreReflectionEqual(tag, freshTag)); } @@ -176,6 +232,13 @@ public class PropertyTagTest extends StrutsInternalTestCase { tag.setValue("%{formatTitle()}"); tag.doStartTag(); tag.doEndTag(); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + PropertyTag freshTag = new PropertyTag(); + freshTag.setPageContext(pageContext); + assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", + objectsAreReflectionEqual(tag, freshTag)); } // verify test @@ -198,15 +261,20 @@ public class PropertyTagTest extends StrutsInternalTestCase { pageContext.setRequest(request); // test - { - PropertyTag tag = new PropertyTag(); - tag.setEscapeHtml(false); - tag.setEscapeJavaScript(true); - tag.setPageContext(pageContext); - tag.setValue("%{formatTitle()}"); - tag.doStartTag(); - tag.doEndTag(); - } + {PropertyTag tag = new PropertyTag(); + tag.setEscapeHtml(false); + tag.setEscapeJavaScript(true); + tag.setPageContext(pageContext); + tag.setValue("%{formatTitle()}"); + tag.doStartTag(); + tag.doEndTag(); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + PropertyTag freshTag = new PropertyTag(); + freshTag.setPageContext(pageContext); + assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", + objectsAreReflectionEqual(tag, freshTag));} // verify test request.verify(); @@ -228,15 +296,20 @@ public class PropertyTagTest extends StrutsInternalTestCase { pageContext.setRequest(request); // test - { - PropertyTag tag = new PropertyTag(); - tag.setEscapeHtml(false); - tag.setEscapeXml(true); - tag.setPageContext(pageContext); - tag.setValue("%{formatTitle()}"); - tag.doStartTag(); - tag.doEndTag(); - } + {PropertyTag tag = new PropertyTag(); + tag.setEscapeHtml(false); + tag.setEscapeXml(true); + tag.setPageContext(pageContext); + tag.setValue("%{formatTitle()}"); + tag.doStartTag(); + tag.doEndTag(); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + PropertyTag freshTag = new PropertyTag(); + freshTag.setPageContext(pageContext); + assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", + objectsAreReflectionEqual(tag, freshTag));} // verify test request.verify(); @@ -258,15 +331,20 @@ public class PropertyTagTest extends StrutsInternalTestCase { pageContext.setRequest(request); // test - { - PropertyTag tag = new PropertyTag(); - tag.setEscapeHtml(false); - tag.setEscapeCsv(true); - tag.setPageContext(pageContext); - tag.setValue("%{formatTitle()}"); - tag.doStartTag(); - tag.doEndTag(); - } + {PropertyTag tag = new PropertyTag(); + tag.setEscapeHtml(false); + tag.setEscapeCsv(true); + tag.setPageContext(pageContext); + tag.setValue("%{formatTitle()}"); + tag.doStartTag(); + tag.doEndTag(); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + PropertyTag freshTag = new PropertyTag(); + freshTag.setPageContext(pageContext); + assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", + objectsAreReflectionEqual(tag, freshTag));} // verify test request.verify(); @@ -288,13 +366,18 @@ public class PropertyTagTest extends StrutsInternalTestCase { pageContext.setRequest(request); // test - { - PropertyTag tag = new PropertyTag(); - tag.setPageContext(pageContext); - tag.setValue("formatTitle()"); - tag.doStartTag(); - tag.doEndTag(); - } + {PropertyTag tag = new PropertyTag(); + tag.setPageContext(pageContext); + tag.setValue("formatTitle()"); + tag.doStartTag(); + tag.doEndTag(); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + PropertyTag freshTag = new PropertyTag(); + freshTag.setPageContext(pageContext); + assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", + objectsAreReflectionEqual(tag, freshTag));} // verify test request.verify(); @@ -316,13 +399,18 @@ public class PropertyTagTest extends StrutsInternalTestCase { pageContext.setRequest(request); // test - { - PropertyTag tag = new PropertyTag(); - tag.setPageContext(pageContext); - tag.setValue("formatTitle()"); - tag.doStartTag(); - tag.doEndTag(); - } + {PropertyTag tag = new PropertyTag(); + tag.setPageContext(pageContext); + tag.setValue("formatTitle()"); + tag.doStartTag(); + tag.doEndTag(); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + PropertyTag freshTag = new PropertyTag(); + freshTag.setPageContext(pageContext); + assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", + objectsAreReflectionEqual(tag, freshTag));} // verify test request.verify(); @@ -344,13 +432,18 @@ public class PropertyTagTest extends StrutsInternalTestCase { pageContext.setRequest(request); // test - { - PropertyTag tag = new PropertyTag(); - tag.setPageContext(pageContext); - tag.setValue("%{formatTitle()}"); - tag.doStartTag(); - tag.doEndTag(); - } + {PropertyTag tag = new PropertyTag(); + tag.setPageContext(pageContext); + tag.setValue("%{formatTitle()}"); + tag.doStartTag(); + tag.doEndTag(); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + PropertyTag freshTag = new PropertyTag(); + freshTag.setPageContext(pageContext); + assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", + objectsAreReflectionEqual(tag, freshTag));} // verify test request.verify(); @@ -359,6 +452,7 @@ public class PropertyTagTest extends StrutsInternalTestCase { } + @Override protected void setUp() throws Exception { super.setUp(); stack = ActionContext.getContext().getValueStack(); @@ -381,6 +475,7 @@ public class PropertyTagTest extends StrutsInternalTestCase { return "Foo is: " + title; } + @Override public String toString() { return formatTitle(); } diff --git a/core/src/test/java/org/apache/struts2/views/jsp/PushTagTest.java b/core/src/test/java/org/apache/struts2/views/jsp/PushTagTest.java index 78de86f01..80fb7324b 100644 --- a/core/src/test/java/org/apache/struts2/views/jsp/PushTagTest.java +++ b/core/src/test/java/org/apache/struts2/views/jsp/PushTagTest.java @@ -43,5 +43,12 @@ public class PushTagTest extends AbstractUITagTest { e.printStackTrace(); fail(); } + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + PushTag freshTag = new PushTag(); + freshTag.setPageContext(pageContext); + assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", + strutsBodyTagsAreReflectionEqual(tag, freshTag)); } } diff --git a/core/src/test/java/org/apache/struts2/views/jsp/SetTagTest.java b/core/src/test/java/org/apache/struts2/views/jsp/SetTagTest.java index 5edfae401..7e8aba387 100644 --- a/core/src/test/java/org/apache/struts2/views/jsp/SetTagTest.java +++ b/core/src/test/java/org/apache/struts2/views/jsp/SetTagTest.java @@ -39,6 +39,13 @@ public class SetTagTest extends AbstractUITagTest { tag.doEndTag(); assertEquals("chewie", servletContext.getAttribute("foo")); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + SetTag freshTag = new SetTag(); + freshTag.setPageContext(pageContext); + assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", + strutsBodyTagsAreReflectionEqual(tag, freshTag)); } public void testPageScope() throws JspException { @@ -49,6 +56,13 @@ public class SetTagTest extends AbstractUITagTest { tag.doEndTag(); assertEquals("chewie", pageContext.getAttribute("foo")); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + SetTag freshTag = new SetTag(); + freshTag.setPageContext(pageContext); + assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", + strutsBodyTagsAreReflectionEqual(tag, freshTag)); } public void testRequestScope() throws JspException { @@ -58,6 +72,13 @@ public class SetTagTest extends AbstractUITagTest { tag.doStartTag(); tag.doEndTag(); assertEquals("chewie", request.getAttribute("foo")); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + SetTag freshTag = new SetTag(); + freshTag.setPageContext(pageContext); + assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", + strutsBodyTagsAreReflectionEqual(tag, freshTag)); } public void testSessionScope() throws JspException { @@ -68,6 +89,13 @@ public class SetTagTest extends AbstractUITagTest { tag.doEndTag(); assertEquals("chewie", session.get("foo")); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + SetTag freshTag = new SetTag(); + freshTag.setPageContext(pageContext); + assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", + strutsBodyTagsAreReflectionEqual(tag, freshTag)); } public void testStrutsScope() throws JspException { @@ -76,6 +104,13 @@ public class SetTagTest extends AbstractUITagTest { tag.doStartTag(); tag.doEndTag(); assertEquals("chewie", context.get("foo")); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + SetTag freshTag = new SetTag(); + freshTag.setPageContext(pageContext); + assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", + strutsBodyTagsAreReflectionEqual(tag, freshTag)); } public void testStrutsScope2() throws JspException { @@ -83,6 +118,13 @@ public class SetTagTest extends AbstractUITagTest { tag.doStartTag(); tag.doEndTag(); assertEquals(chewie, context.get("chewie")); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + SetTag freshTag = new SetTag(); + freshTag.setPageContext(pageContext); + assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", + strutsBodyTagsAreReflectionEqual(tag, freshTag)); } public void testSetTrimBody() throws JspException, IOException { @@ -100,6 +142,13 @@ public class SetTagTest extends AbstractUITagTest { tag.doEndTag(); assertEquals(trimmedBeginEndSpaceString, context.get("foo")); + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + SetTag freshTag = new SetTag(); + freshTag.setPageContext(pageContext); + assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", + strutsBodyTagsAreReflectionEqual(tag, freshTag)); + tag.setName("foo"); tag.setValue(null); tag.setTrimBody(true); @@ -110,6 +159,12 @@ public class SetTagTest extends AbstractUITagTest { tag.doEndTag(); assertEquals(trimmedBeginEndSpaceString, context.get("foo")); + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + freshTag.setPageContext(pageContext); + assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", + strutsBodyTagsAreReflectionEqual(tag, freshTag)); + tag.setName("foo"); tag.setValue(null); tag.setTrimBody(false); @@ -119,6 +174,12 @@ public class SetTagTest extends AbstractUITagTest { tag.doStartTag(); tag.doEndTag(); assertEquals(beginEndSpaceString, context.get("foo")); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + freshTag.setPageContext(pageContext); + assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", + strutsBodyTagsAreReflectionEqual(tag, freshTag)); } public void testEmptyBody() throws JspException { @@ -133,6 +194,13 @@ public class SetTagTest extends AbstractUITagTest { tag.doStartTag(); tag.doEndTag(); assertEquals(emptyBody, context.get(variableName)); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + SetTag freshTag = new SetTag(); + freshTag.setPageContext(pageContext); + assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", + strutsBodyTagsAreReflectionEqual(tag, freshTag)); } protected void setUp() throws Exception { diff --git a/core/src/test/java/org/apache/struts2/views/jsp/SortIteratorTagTest.java b/core/src/test/java/org/apache/struts2/views/jsp/SortIteratorTagTest.java index eef012c72..3efb4eaa1 100644 --- a/core/src/test/java/org/apache/struts2/views/jsp/SortIteratorTagTest.java +++ b/core/src/test/java/org/apache/struts2/views/jsp/SortIteratorTagTest.java @@ -67,6 +67,13 @@ public class SortIteratorTagTest extends AbstractTagTest { assertFalse(sortedIterator.hasNext()); tag.doEndTag(); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + SortIteratorTag freshTag = new SortIteratorTag(); + freshTag.setPageContext(pageContext); + assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", + strutsBodyTagsAreReflectionEqual(tag, freshTag)); } public void testSortWithIdIteratorAvailableInStackTop() throws Exception { @@ -104,6 +111,13 @@ public class SortIteratorTagTest extends AbstractTagTest { } tag.doEndTag(); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + SortIteratorTag freshTag = new SortIteratorTag(); + freshTag.setPageContext(pageContext); + assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", + strutsBodyTagsAreReflectionEqual(tag, freshTag)); } @@ -141,6 +155,13 @@ public class SortIteratorTagTest extends AbstractTagTest { } tag.doEndTag(); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + SortIteratorTag freshTag = new SortIteratorTag(); + freshTag.setPageContext(pageContext); + assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", + strutsBodyTagsAreReflectionEqual(tag, freshTag)); } public void testSortWithIllegalSource() throws Exception { @@ -159,6 +180,8 @@ public class SortIteratorTagTest extends AbstractTagTest { // ok assertTrue(true); } + + // The doEndTag() call is expected not to complete. Cannot perform basic sanity check of clearTagStateForTagPoolingServers() behaviour. } public void testSortWithIllegalComparator() throws Exception { @@ -178,6 +201,7 @@ public class SortIteratorTagTest extends AbstractTagTest { assertTrue(true); } + // The doEndTag() call is expected not to complete. Cannot perform basic sanity check of clearTagStateForTagPoolingServers() behaviour. } public Action getAction() { diff --git a/core/src/test/java/org/apache/struts2/views/jsp/SubsetIteratorTagTest.java b/core/src/test/java/org/apache/struts2/views/jsp/SubsetIteratorTagTest.java index 2bed2901a..1d7a439f2 100644 --- a/core/src/test/java/org/apache/struts2/views/jsp/SubsetIteratorTagTest.java +++ b/core/src/test/java/org/apache/struts2/views/jsp/SubsetIteratorTagTest.java @@ -51,6 +51,13 @@ public class SubsetIteratorTagTest extends AbstractTagTest { assertEquals(subsetIterator.next(), new Integer(3)); assertEquals(subsetIterator.next(), new Integer(4)); assertEquals(subsetIterator.next(), new Integer(5)); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + SubsetIteratorTag freshTag = new SubsetIteratorTag(); + freshTag.setPageContext(pageContext); + assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", + strutsBodyTagsAreReflectionEqual(tag, freshTag)); } { // Array as Source @@ -67,6 +74,13 @@ public class SubsetIteratorTagTest extends AbstractTagTest { assertEquals(subsetIterator.next(), new Integer(3)); assertEquals(subsetIterator.next(), new Integer(4)); assertEquals(subsetIterator.next(), new Integer(5)); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + SubsetIteratorTag freshTag = new SubsetIteratorTag(); + freshTag.setPageContext(pageContext); + assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", + strutsBodyTagsAreReflectionEqual(tag, freshTag)); } } @@ -83,6 +97,13 @@ public class SubsetIteratorTagTest extends AbstractTagTest { assertEquals(subsetIterator.next(), new Integer(4)); assertEquals(subsetIterator.next(), new Integer(5)); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + SubsetIteratorTag freshTag = new SubsetIteratorTag(); + freshTag.setPageContext(pageContext); + assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", + strutsBodyTagsAreReflectionEqual(tag, freshTag)); } { // Array as source @@ -97,6 +118,13 @@ public class SubsetIteratorTagTest extends AbstractTagTest { assertEquals(subsetIterator.next(), new Integer(4)); assertEquals(subsetIterator.next(), new Integer(5)); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + SubsetIteratorTag freshTag = new SubsetIteratorTag(); + freshTag.setPageContext(pageContext); + assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", + strutsBodyTagsAreReflectionEqual(tag, freshTag)); } } @@ -114,6 +142,13 @@ public class SubsetIteratorTagTest extends AbstractTagTest { assertEquals(subsetIterator.next(), new Integer(1)); assertEquals(subsetIterator.next(), new Integer(2)); assertEquals(subsetIterator.next(), new Integer(3)); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + SubsetIteratorTag freshTag = new SubsetIteratorTag(); + freshTag.setPageContext(pageContext); + assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", + strutsBodyTagsAreReflectionEqual(tag, freshTag)); } { // array as source @@ -129,6 +164,13 @@ public class SubsetIteratorTagTest extends AbstractTagTest { assertEquals(subsetIterator.next(), new Integer(1)); assertEquals(subsetIterator.next(), new Integer(2)); assertEquals(subsetIterator.next(), new Integer(3)); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + SubsetIteratorTag freshTag = new SubsetIteratorTag(); + freshTag.setPageContext(pageContext); + assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", + strutsBodyTagsAreReflectionEqual(tag, freshTag)); } } @@ -146,6 +188,13 @@ public class SubsetIteratorTagTest extends AbstractTagTest { assertEquals(subsetIterator.next(), new Integer("4")); assertEquals(subsetIterator.next(), new Integer("5")); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + SubsetIteratorTag freshTag = new SubsetIteratorTag(); + freshTag.setPageContext(pageContext); + assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", + strutsBodyTagsAreReflectionEqual(tag, freshTag)); } { // Array as source @@ -161,6 +210,13 @@ public class SubsetIteratorTagTest extends AbstractTagTest { assertEquals(subsetIterator.next(), new Integer("4")); assertEquals(subsetIterator.next(), new Integer("5")); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + SubsetIteratorTag freshTag = new SubsetIteratorTag(); + freshTag.setPageContext(pageContext); + assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", + strutsBodyTagsAreReflectionEqual(tag, freshTag)); } } @@ -185,6 +241,13 @@ public class SubsetIteratorTagTest extends AbstractTagTest { assertEquals(subsetIterator2.next(), new Integer(3)); assertEquals(subsetIterator2.next(), new Integer(4)); assertEquals(subsetIterator2.next(), new Integer(5)); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + SubsetIteratorTag freshTag = new SubsetIteratorTag(); + freshTag.setPageContext(pageContext); + assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", + strutsBodyTagsAreReflectionEqual(tag, freshTag)); } { // Array as source @@ -207,6 +270,13 @@ public class SubsetIteratorTagTest extends AbstractTagTest { assertEquals(subsetIterator2.next(), new Integer(3)); assertEquals(subsetIterator2.next(), new Integer(4)); assertEquals(subsetIterator2.next(), new Integer(5)); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + SubsetIteratorTag freshTag = new SubsetIteratorTag(); + freshTag.setPageContext(pageContext); + assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", + strutsBodyTagsAreReflectionEqual(tag, freshTag)); } } @@ -223,6 +293,13 @@ public class SubsetIteratorTagTest extends AbstractTagTest { assertEquals(subsetIterator.next(), new Integer(2)); assertEquals(subsetIterator.next(), new Integer(4)); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + SubsetIteratorTag freshTag = new SubsetIteratorTag(); + freshTag.setPageContext(pageContext); + assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", + strutsBodyTagsAreReflectionEqual(tag, freshTag)); } { // Array As source @@ -237,11 +314,19 @@ public class SubsetIteratorTagTest extends AbstractTagTest { assertEquals(subsetIterator.next(), new Integer(2)); assertEquals(subsetIterator.next(), new Integer(4)); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + SubsetIteratorTag freshTag = new SubsetIteratorTag(); + freshTag.setPageContext(pageContext); + assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", + strutsBodyTagsAreReflectionEqual(tag, freshTag)); } } + @Override public Action getAction() { return new ActionSupport() { public List getMyList() { diff --git a/core/src/test/java/org/apache/struts2/views/jsp/TextTagTest.java b/core/src/test/java/org/apache/struts2/views/jsp/TextTagTest.java index 29b56271c..99e0bf565 100644 --- a/core/src/test/java/org/apache/struts2/views/jsp/TextTagTest.java +++ b/core/src/test/java/org/apache/struts2/views/jsp/TextTagTest.java @@ -50,6 +50,7 @@ public class TextTagTest extends AbstractTagTest { private TextTag tag; + @Override public Action getAction() { TestAction action = new TestAction(); action.setFoo(fooValue); @@ -71,6 +72,13 @@ public class TextTagTest extends AbstractTagTest { assertEquals(startStatus, BodyTag.EVAL_BODY_BUFFERED); assertEquals("Sample Of Default Message", writer.toString()); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + TextTag freshTag = new TextTag(); + freshTag.setPageContext(pageContext); + assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", + strutsBodyTagsAreReflectionEqual(tag, freshTag)); } public void testExpressionsEvaluated() throws Exception { @@ -80,6 +88,13 @@ public class TextTagTest extends AbstractTagTest { tag.doStartTag(); tag.doEndTag(); assertEquals(value, writer.toString()); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + TextTag freshTag = new TextTag(); + freshTag.setPageContext(pageContext); + assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", + strutsBodyTagsAreReflectionEqual(tag, freshTag)); } public void testCorrectI18NKey() throws Exception { @@ -89,6 +104,13 @@ public class TextTagTest extends AbstractTagTest { tag.doStartTag(); tag.doEndTag(); assertEquals(value, writer.toString()); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + TextTag freshTag = new TextTag(); + freshTag.setPageContext(pageContext); + assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", + strutsBodyTagsAreReflectionEqual(tag, freshTag)); } public void testCorrectI18NKey2() throws Exception { @@ -98,6 +120,13 @@ public class TextTagTest extends AbstractTagTest { tag.doStartTag(); tag.doEndTag(); assertEquals(value, writer.toString()); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + TextTag freshTag = new TextTag(); + freshTag.setPageContext(pageContext); + assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", + strutsBodyTagsAreReflectionEqual(tag, freshTag)); } public void testMessageFormatWorks() throws Exception { @@ -121,6 +150,13 @@ public class TextTagTest extends AbstractTagTest { ((Text) tag.component).addParameter(param3); tag.doEndTag(); assertEquals(expected, writer.toString()); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + TextTag freshTag = new TextTag(); + freshTag.setPageContext(pageContext); + assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", + strutsBodyTagsAreReflectionEqual(tag, freshTag)); } public void testSimpleKeyValueWorks() throws JspException { @@ -130,6 +166,13 @@ public class TextTagTest extends AbstractTagTest { tag.doStartTag(); tag.doEndTag(); assertEquals(value, writer.toString()); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + TextTag freshTag = new TextTag(); + freshTag.setPageContext(pageContext); + assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", + strutsBodyTagsAreReflectionEqual(tag, freshTag)); } private Locale getForeignLocale() { @@ -169,6 +212,14 @@ public class TextTagTest extends AbstractTagTest { tag.doStartTag(); tag.doEndTag(); assertEquals(value1, writer.toString()); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + TextTag freshTag = new TextTag(); + freshTag.setPageContext(pageContext); + assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", + strutsBodyTagsAreReflectionEqual(tag, freshTag)); + final StringBuffer buffer = writer.getBuffer(); buffer.delete(0, buffer.length()); ValueStack newStack = container.getInstance(ValueStackFactory.class).createValueStack(); @@ -176,10 +227,16 @@ public class TextTagTest extends AbstractTagTest { newStack.push(container.inject(TestAction1.class)); request.setAttribute(ServletActionContext.STRUTS_VALUESTACK_KEY, newStack); assertNotSame(ActionContext.getContext().getValueStack().peek(), newStack.peek()); - + tag.setName(key); // Required as WW-5124 fix clears tag state. tag.doStartTag(); tag.doEndTag(); assertEquals(value2, writer.toString()); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + freshTag.setPageContext(pageContext); + assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", + strutsBodyTagsAreReflectionEqual(tag, freshTag)); } public void testTextTagUsesLocaleFromValueStack() throws JspException { @@ -198,6 +255,13 @@ public class TextTagTest extends AbstractTagTest { tag.doEndTag(); assertEquals(value_default, writer.toString()); + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + TextTag freshTag = new TextTag(); + freshTag.setPageContext(pageContext); + assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", + strutsBodyTagsAreReflectionEqual(tag, freshTag)); + final StringBuffer buffer = writer.getBuffer(); buffer.delete(0, buffer.length()); String value_int = getLocalizedMessage(foreignLocale); @@ -207,9 +271,16 @@ public class TextTagTest extends AbstractTagTest { assertNotSame(newStack.getActionContext().getLocale(), ActionContext.getContext().getLocale()); request.setAttribute(ServletActionContext.STRUTS_VALUESTACK_KEY, newStack); assertEquals(ActionContext.getContext().getValueStack().peek(), newStack.peek()); + tag.setName(key); // Required as WW-5124 fix clears tag state. tag.doStartTag(); tag.doEndTag(); assertEquals(value_int, writer.toString()); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + freshTag.setPageContext(pageContext); + assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", + strutsBodyTagsAreReflectionEqual(tag, freshTag)); } public void testWithNoMessageAndBodyIsNotEmptyBodyIsReturned() throws Exception { @@ -223,6 +294,13 @@ public class TextTagTest extends AbstractTagTest { tag.doStartTag(); tag.doEndTag(); assertEquals(bodyText, writer.toString()); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + TextTag freshTag = new TextTag(); + freshTag.setPageContext(pageContext); + assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", + strutsBodyTagsAreReflectionEqual(tag, freshTag)); } public void testWithNoMessageAndNoDefaultKeyReturned() throws JspException { @@ -231,6 +309,13 @@ public class TextTagTest extends AbstractTagTest { tag.doStartTag(); tag.doEndTag(); assertEquals(key, writer.toString()); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + TextTag freshTag = new TextTag(); + freshTag.setPageContext(pageContext); + assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", + strutsBodyTagsAreReflectionEqual(tag, freshTag)); } public void testNoNameDefined() throws Exception { @@ -242,6 +327,8 @@ public class TextTagTest extends AbstractTagTest { } catch (StrutsException e) { assertEquals(msg, e.getMessage()); } + + // The doEndTag() call is expected not to complete. Cannot perform basic sanity check of clearTagStateForTagPoolingServers() behaviour. } public void testBlankNameDefined() throws Exception { @@ -249,6 +336,13 @@ public class TextTagTest extends AbstractTagTest { tag.doStartTag(); tag.doEndTag(); assertEquals("", writer.toString()); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + TextTag freshTag = new TextTag(); + freshTag.setPageContext(pageContext); + assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", + strutsBodyTagsAreReflectionEqual(tag, freshTag)); } public void testPutId() throws Exception { @@ -259,6 +353,13 @@ public class TextTagTest extends AbstractTagTest { tag.doEndTag(); assertEquals("", writer.toString()); assertEquals("No foo here", stack.findString("myId")); // is in stack now + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + TextTag freshTag = new TextTag(); + freshTag.setPageContext(pageContext); + assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", + strutsBodyTagsAreReflectionEqual(tag, freshTag)); } public void testEscapeHtml() throws Exception { @@ -269,6 +370,13 @@ public class TextTagTest extends AbstractTagTest { tag.doStartTag(); tag.doEndTag(); assertEquals(value, writer.toString()); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + TextTag freshTag = new TextTag(); + freshTag.setPageContext(pageContext); + assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", + strutsBodyTagsAreReflectionEqual(tag, freshTag)); } public void testEscapeXml() throws Exception { @@ -279,6 +387,13 @@ public class TextTagTest extends AbstractTagTest { tag.doStartTag(); tag.doEndTag(); assertEquals(value, writer.toString()); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + TextTag freshTag = new TextTag(); + freshTag.setPageContext(pageContext); + assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", + strutsBodyTagsAreReflectionEqual(tag, freshTag)); } public void testEscapeJavaScript() throws Exception { @@ -289,6 +404,13 @@ public class TextTagTest extends AbstractTagTest { tag.doStartTag(); tag.doEndTag(); assertEquals(value, writer.toString()); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + TextTag freshTag = new TextTag(); + freshTag.setPageContext(pageContext); + assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", + strutsBodyTagsAreReflectionEqual(tag, freshTag)); } public void testEscapeCsv() throws Exception { @@ -299,8 +421,21 @@ public class TextTagTest extends AbstractTagTest { tag.doStartTag(); tag.doEndTag(); assertEquals(value, writer.toString()); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + TextTag freshTag = new TextTag(); + freshTag.setPageContext(pageContext); + assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", + strutsBodyTagsAreReflectionEqual(tag, freshTag)); } + /** + * todo remove ActionContext set after LocalizedTextUtil is fixed to not use ThreadLocal + * + * @throws Exception + */ + @Override protected void setUp() throws Exception { super.setUp(); tag = new TextTag(); @@ -308,6 +443,7 @@ public class TextTagTest extends AbstractTagTest { ActionContext.of(stack.getContext()).bind(); } + @Override protected void tearDown() throws Exception { super.tearDown(); } diff --git a/core/src/test/java/org/apache/struts2/views/jsp/URLTagTest.java b/core/src/test/java/org/apache/struts2/views/jsp/URLTagTest.java index 7b6117d27..b34788c84 100644 --- a/core/src/test/java/org/apache/struts2/views/jsp/URLTagTest.java +++ b/core/src/test/java/org/apache/struts2/views/jsp/URLTagTest.java @@ -144,6 +144,28 @@ public class URLTagTest extends AbstractUITagTest { assertEquals(parameters.get("tagId"), "tagValue"); assertEquals(parameters.get("param1"), "param1value"); assertEquals(parameters.get("param2"), "param2value"); + + tag.doEndTag(); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + ParamTag freshParamTag = new ParamTag(); + freshParamTag.setPageContext(pageContext); + assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", + strutsBodyTagsAreReflectionEqual(param1, freshParamTag)); + assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", + strutsBodyTagsAreReflectionEqual(param2, freshParamTag)); + assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", + strutsBodyTagsAreReflectionEqual(param3, freshParamTag)); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + URLTag freshTag = new URLTag(); + freshTag.setPageContext(pageContext); + assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", + strutsBodyTagsAreReflectionEqual(tag, freshTag)); } /** @@ -168,6 +190,13 @@ public class URLTagTest extends AbstractUITagTest { tag.doEndTag(); assertEquals("/TestAction.action?p0=z&p1=a&p1=b&p2=d&p2=e&p3=f&p3=g", writer.toString()); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + URLTag freshTag = new URLTag(); + freshTag.setPageContext(pageContext); + assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", + strutsBodyTagsAreReflectionEqual(tag, freshTag)); } /** @@ -202,7 +231,6 @@ public class URLTagTest extends AbstractUITagTest { param3.setName("id1"); param3.setValue("%{'paramId1'}"); - tag.doStartTag(); param1.doStartTag(); param1.doEndTag(); @@ -220,6 +248,28 @@ public class URLTagTest extends AbstractUITagTest { assertEquals(parameters.get("tagId"), "tagValue"); assertEquals(parameters.get("param1"), "param1value"); assertEquals(parameters.get("param2"), "param2value"); + + tag.doEndTag(); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + ParamTag freshParamTag = new ParamTag(); + freshParamTag.setPageContext(pageContext); + assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", + strutsBodyTagsAreReflectionEqual(param1, freshParamTag)); + assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", + strutsBodyTagsAreReflectionEqual(param2, freshParamTag)); + assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", + strutsBodyTagsAreReflectionEqual(param3, freshParamTag)); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + URLTag freshTag = new URLTag(); + freshTag.setPageContext(pageContext); + assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", + strutsBodyTagsAreReflectionEqual(tag, freshTag)); } public void testIncludeParamsDefaultToGET() throws Exception { @@ -245,6 +295,13 @@ public class URLTagTest extends AbstractUITagTest { assertEquals(parameters.get("one"), "oneVal"); assertEquals(parameters.get("two"), "twoVal"); assertEquals(parameters.get("three"), "threeVal"); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + URLTag freshTag = new URLTag(); + freshTag.setPageContext(pageContext); + assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", + strutsBodyTagsAreReflectionEqual(tag, freshTag)); } public void testActionURL() throws Exception { @@ -253,6 +310,13 @@ public class URLTagTest extends AbstractUITagTest { tag.doStartTag(); tag.doEndTag(); assertEquals("TestAction.action", writer.toString()); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + URLTag freshTag = new URLTag(); + freshTag.setPageContext(pageContext); + assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", + strutsBodyTagsAreReflectionEqual(tag, freshTag)); } public void testAddParameters() throws Exception { @@ -266,6 +330,13 @@ public class URLTagTest extends AbstractUITagTest { tag.component.addParameter("param2", "value2"); tag.doEndTag(); assertEquals("/TestAction.action?param0=value0&param1=value1&param2=value2", writer.toString()); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + URLTag freshTag = new URLTag(); + freshTag.setPageContext(pageContext); + assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", + strutsBodyTagsAreReflectionEqual(tag, freshTag)); } public void testEvaluateValue() throws Exception { @@ -277,6 +348,13 @@ public class URLTagTest extends AbstractUITagTest { tag.doStartTag(); tag.doEndTag(); assertEquals("test", writer.toString()); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + URLTag freshTag = new URLTag(); + freshTag.setPageContext(pageContext); + assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", + strutsBodyTagsAreReflectionEqual(tag, freshTag)); } public void testHttps() throws Exception { @@ -289,6 +367,13 @@ public class URLTagTest extends AbstractUITagTest { tag.doStartTag(); tag.doEndTag(); assertEquals("list-members.action", writer.toString()); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + URLTag freshTag = new URLTag(); + freshTag.setPageContext(pageContext); + assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", + strutsBodyTagsAreReflectionEqual(tag, freshTag)); } public void testAnchor() throws Exception { @@ -302,6 +387,13 @@ public class URLTagTest extends AbstractUITagTest { tag.doStartTag(); tag.doEndTag(); assertEquals("list-members.action#test", writer.toString()); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + URLTag freshTag = new URLTag(); + freshTag.setPageContext(pageContext); + assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", + strutsBodyTagsAreReflectionEqual(tag, freshTag)); } public void testParamPrecedence() throws Exception { @@ -324,6 +416,20 @@ public class URLTagTest extends AbstractUITagTest { urlTag.doEndTag(); assertEquals("/context/someAction.action?id=33&name=John", writer.getBuffer().toString()); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + ParamTag freshParamTag = new ParamTag(); + freshParamTag.setPageContext(pageContext); + assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", + strutsBodyTagsAreReflectionEqual(paramTag, freshParamTag)); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + URLTag freshTag = new URLTag(); + freshTag.setPageContext(pageContext); + assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", + strutsBodyTagsAreReflectionEqual(tag, freshTag)); } public void testParamPrecedenceWithAnchor() throws Exception { @@ -347,6 +453,20 @@ public class URLTagTest extends AbstractUITagTest { urlTag.doEndTag(); assertEquals("/context/someAction.action?id=33&name=John#testAnchor", writer.getBuffer().toString()); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + ParamTag freshParamTag = new ParamTag(); + freshParamTag.setPageContext(pageContext); + assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", + strutsBodyTagsAreReflectionEqual(paramTag, freshParamTag)); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + URLTag freshTag = new URLTag(); + freshTag.setPageContext(pageContext); + assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", + strutsBodyTagsAreReflectionEqual(tag, freshTag)); } public void testPutId() throws Exception { @@ -357,6 +477,13 @@ public class URLTagTest extends AbstractUITagTest { tag.doEndTag(); assertEquals("", writer.toString()); assertEquals("/public/about", stack.findString("myId")); // is in stack now + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + URLTag freshTag = new URLTag(); + freshTag.setPageContext(pageContext); + assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", + strutsBodyTagsAreReflectionEqual(tag, freshTag)); } public void testUsingValueOnly() throws Exception { @@ -364,6 +491,13 @@ public class URLTagTest extends AbstractUITagTest { tag.doStartTag(); tag.doEndTag(); assertEquals("/public/about/team.jsp", writer.toString()); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + URLTag freshTag = new URLTag(); + freshTag.setPageContext(pageContext); + assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", + strutsBodyTagsAreReflectionEqual(tag, freshTag)); } public void testRequestURIActionIncludeNone() throws Exception { @@ -376,6 +510,13 @@ public class URLTagTest extends AbstractUITagTest { tag.doEndTag(); assertEquals("/team.action", writer.toString()); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + URLTag freshTag = new URLTag(); + freshTag.setPageContext(pageContext); + assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", + strutsBodyTagsAreReflectionEqual(tag, freshTag)); } public void testRequestURIActionIncludeGet() throws Exception { @@ -388,6 +529,13 @@ public class URLTagTest extends AbstractUITagTest { tag.doEndTag(); assertEquals("/team.action?section=team&company=acme+inc", writer.toString()); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + URLTag freshTag = new URLTag(); + freshTag.setPageContext(pageContext); + assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", + strutsBodyTagsAreReflectionEqual(tag, freshTag)); } public void testRequestURIActionIncludeGetDoNotEscapeAmp() throws Exception { @@ -401,6 +549,13 @@ public class URLTagTest extends AbstractUITagTest { tag.doEndTag(); assertEquals("/team.action?section=team&company=acme+inc", writer.toString()); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + URLTag freshTag = new URLTag(); + freshTag.setPageContext(pageContext); + assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", + strutsBodyTagsAreReflectionEqual(tag, freshTag)); } public void testRequestURINoActionIncludeNone() throws Exception { @@ -413,6 +568,13 @@ public class URLTagTest extends AbstractUITagTest { tag.doEndTag(); assertEquals("/public/about", writer.toString()); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + URLTag freshTag = new URLTag(); + freshTag.setPageContext(pageContext); + assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", + strutsBodyTagsAreReflectionEqual(tag, freshTag)); } public void testNoActionIncludeGet() throws Exception { @@ -425,6 +587,13 @@ public class URLTagTest extends AbstractUITagTest { tag.doEndTag(); assertEquals("/public/about?section=team&company=acme+inc", writer.toString()); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + URLTag freshTag = new URLTag(); + freshTag.setPageContext(pageContext); + assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", + strutsBodyTagsAreReflectionEqual(tag, freshTag)); } public void testRequestURIActionIncludeAll() throws Exception { @@ -447,6 +616,20 @@ public class URLTagTest extends AbstractUITagTest { tag.doEndTag(); assertEquals("/team.action?section=team&company=acme+inc&year=2006", writer.toString()); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + ParamTag freshParamTag = new ParamTag(); + freshParamTag.setPageContext(pageContext); + assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", + strutsBodyTagsAreReflectionEqual(paramTag, freshParamTag)); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + URLTag freshTag = new URLTag(); + freshTag.setPageContext(pageContext); + assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", + strutsBodyTagsAreReflectionEqual(tag, freshTag)); } public void testRequestURINoActionIncludeAll() throws Exception { @@ -469,6 +652,20 @@ public class URLTagTest extends AbstractUITagTest { tag.doEndTag(); assertEquals("/public/about?section=team&company=acme+inc&year=2006", writer.toString()); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + ParamTag freshParamTag = new ParamTag(); + freshParamTag.setPageContext(pageContext); + assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", + strutsBodyTagsAreReflectionEqual(paramTag, freshParamTag)); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + URLTag freshTag = new URLTag(); + freshTag.setPageContext(pageContext); + assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", + strutsBodyTagsAreReflectionEqual(tag, freshTag)); } public void testUnknownIncludeParam() throws Exception { @@ -479,6 +676,13 @@ public class URLTagTest extends AbstractUITagTest { tag.doStartTag(); tag.doEndTag(); assertEquals("/public/about", writer.toString()); // should not add any request parameters + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + URLTag freshTag = new URLTag(); + freshTag.setPageContext(pageContext); + assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", + strutsBodyTagsAreReflectionEqual(tag, freshTag)); } public void testRequestURIWithAnchor() throws Exception { @@ -491,6 +695,13 @@ public class URLTagTest extends AbstractUITagTest { tag.doEndTag(); assertEquals("/company.action?company=acme+inc", writer.toString()); // will always chop anchor if using requestURI + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + URLTag freshTag = new URLTag(); + freshTag.setPageContext(pageContext); + assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", + strutsBodyTagsAreReflectionEqual(tag, freshTag)); } public void testIncludeContext() throws Exception { @@ -502,6 +713,13 @@ public class URLTagTest extends AbstractUITagTest { tag.doEndTag(); assertEquals("/myapp/company.action", writer.toString()); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + URLTag freshTag = new URLTag(); + freshTag.setPageContext(pageContext); + assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", + strutsBodyTagsAreReflectionEqual(tag, freshTag)); } public void testForceAddSchemeHostAndPort() throws Exception { @@ -511,6 +729,13 @@ public class URLTagTest extends AbstractUITagTest { tag.doEndTag(); assertEquals("http://localhost/company.action", writer.toString()); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + URLTag freshTag = new URLTag(); + freshTag.setPageContext(pageContext); + assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", + strutsBodyTagsAreReflectionEqual(tag, freshTag)); } public void testEmptyActionCustomMapper() throws Exception { @@ -587,6 +812,13 @@ public class URLTagTest extends AbstractUITagTest { tag.doEndTag(); assertEquals("/hello.action-red", writer.toString()); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + URLTag freshTag = new URLTag(); + freshTag.setPageContext(pageContext); + assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", + strutsBodyTagsAreReflectionEqual(tag, freshTag)); writer = new StringWriter(); jspWriter = new StrutsMockJspWriter(writer); @@ -596,6 +828,12 @@ public class URLTagTest extends AbstractUITagTest { tag.doEndTag(); assertEquals("/hello.action-blue", writer.toString()); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + freshTag.setPageContext(pageContext); + assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", + strutsBodyTagsAreReflectionEqual(tag, freshTag)); writer = new StringWriter(); jspWriter = new StrutsMockJspWriter(writer); @@ -606,7 +844,11 @@ public class URLTagTest extends AbstractUITagTest { assertEquals("/hello.action-red", writer.toString()); - + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + freshTag.setPageContext(pageContext); + assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", + strutsBodyTagsAreReflectionEqual(tag, freshTag)); } public void testEmbeddedParamTagExpressionGetsEvaluatedCorrectly() throws Exception { @@ -632,6 +874,20 @@ public class URLTagTest extends AbstractUITagTest { tag.doEndTag(); assertEquals("/team.action?section=team&company=acme+inc&title=test", writer.toString()); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + ParamTag freshParamTag = new ParamTag(); + freshParamTag.setPageContext(pageContext); + assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", + strutsBodyTagsAreReflectionEqual(paramTag, freshParamTag)); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + URLTag freshTag = new URLTag(); + freshTag.setPageContext(pageContext); + assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", + strutsBodyTagsAreReflectionEqual(tag, freshTag)); } public void testAccessToStackInternalsGetsHandledCorrectly() throws Exception { @@ -668,6 +924,13 @@ public class URLTagTest extends AbstractUITagTest { "aae%24%7B%23session%5B%22bar%22%5D%7D=1%24%7B%23session%5B%22bar%22%5D%7D" , writer.toString() ); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + URLTag freshTag = new URLTag(); + freshTag.setPageContext(pageContext); + assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", + strutsBodyTagsAreReflectionEqual(tag, freshTag)); } public void testIncludeEmptyParameters() throws Exception { @@ -723,6 +986,29 @@ public class URLTagTest extends AbstractUITagTest { tag.doEndTag(); assertEquals("/company.action?paramWithSetValue=¶mWithSetBody=", writer.toString()); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + ParamTag freshParamTag = new ParamTag(); + freshParamTag.setPageContext(pageContext); + assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", + strutsBodyTagsAreReflectionEqual(param1, freshParamTag)); + assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", + strutsBodyTagsAreReflectionEqual(param2, freshParamTag)); + assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", + strutsBodyTagsAreReflectionEqual(param3, freshParamTag)); + assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", + strutsBodyTagsAreReflectionEqual(param4, freshParamTag)); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + URLTag freshTag = new URLTag(); + freshTag.setPageContext(pageContext); + assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", + strutsBodyTagsAreReflectionEqual(tag, freshTag)); } protected void setUp() throws Exception { diff --git a/core/src/test/java/org/apache/struts2/views/jsp/ui/ActionErrorTagTest.java b/core/src/test/java/org/apache/struts2/views/jsp/ui/ActionErrorTagTest.java index b16e6c847..f0bdcbc7f 100644 --- a/core/src/test/java/org/apache/struts2/views/jsp/ui/ActionErrorTagTest.java +++ b/core/src/test/java/org/apache/struts2/views/jsp/ui/ActionErrorTagTest.java @@ -45,6 +45,13 @@ public class ActionErrorTagTest extends AbstractUITagTest { //assertEquals("", writer.toString()); verify(ActionErrorTagTest.class.getResource("actionerror-1.txt")); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + ActionErrorTag freshTag = new ActionErrorTag(); + freshTag.setPageContext(pageContext); + assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", + strutsBodyTagsAreReflectionEqual(tag, freshTag)); } public void testActionErrorsEscape() throws Exception { @@ -61,6 +68,13 @@ public class ActionErrorTagTest extends AbstractUITagTest { assertEquals(normalize("", true), normalize(writer.toString(), true)); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + ActionErrorTag freshTag = new ActionErrorTag(); + freshTag.setPageContext(pageContext); + assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", + strutsBodyTagsAreReflectionEqual(tag, freshTag)); } public void testActionErrorsDontEscape() throws Exception { @@ -77,6 +91,13 @@ public class ActionErrorTagTest extends AbstractUITagTest { assertEquals(normalize("", true), normalize(writer.toString(), true)); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + ActionErrorTag freshTag = new ActionErrorTag(); + freshTag.setPageContext(pageContext); + assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", + strutsBodyTagsAreReflectionEqual(tag, freshTag)); } public void testHaveActionErrors() throws Exception { @@ -89,6 +110,13 @@ public class ActionErrorTagTest extends AbstractUITagTest { tag.doEndTag(); verify(ActionErrorTagTest.class.getResource("actionerror-2.txt")); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + ActionErrorTag freshTag = new ActionErrorTag(); + freshTag.setPageContext(pageContext); + assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", + strutsBodyTagsAreReflectionEqual(tag, freshTag)); } public void testNullError() throws Exception { @@ -102,6 +130,13 @@ public class ActionErrorTagTest extends AbstractUITagTest { tag.doEndTag(); verify(ActionErrorTagTest.class.getResource("actionerror-2.txt")); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + ActionErrorTag freshTag = new ActionErrorTag(); + freshTag.setPageContext(pageContext); + assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", + strutsBodyTagsAreReflectionEqual(tag, freshTag)); } public void testEmptyErrorList() throws Exception { @@ -115,9 +150,17 @@ public class ActionErrorTagTest extends AbstractUITagTest { tag.doEndTag(); assertTrue(StringUtils.isBlank(writer.toString())); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + ActionErrorTag freshTag = new ActionErrorTag(); + freshTag.setPageContext(pageContext); + assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", + strutsBodyTagsAreReflectionEqual(tag, freshTag)); } + @Override public Action getAction() { return new InternalActionSupport(); } @@ -138,10 +181,12 @@ public class ActionErrorTagTest extends AbstractUITagTest { yesActionErrors = aYesActionErrors; } + @Override public boolean hasActionErrors() { return yesActionErrors; } + @Override public Collection getActionErrors() { if (justNullElement) { return Arrays.asList(null); diff --git a/core/src/test/java/org/apache/struts2/views/jsp/ui/ActionMessageTagTest.java b/core/src/test/java/org/apache/struts2/views/jsp/ui/ActionMessageTagTest.java index 15ec1af13..8819db8bf 100644 --- a/core/src/test/java/org/apache/struts2/views/jsp/ui/ActionMessageTagTest.java +++ b/core/src/test/java/org/apache/struts2/views/jsp/ui/ActionMessageTagTest.java @@ -45,6 +45,13 @@ public class ActionMessageTagTest extends AbstractUITagTest { tag.doEndTag(); verify(ActionMessageTagTest.class.getResource("actionmessage-1.txt")); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + ActionMessageTag freshTag = new ActionMessageTag(); + freshTag.setPageContext(pageContext); + assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", + strutsBodyTagsAreReflectionEqual(tag, freshTag)); } public void testActionMessageEscape() throws Exception { @@ -61,6 +68,13 @@ public class ActionMessageTagTest extends AbstractUITagTest { assertEquals(normalize("", true), normalize(writer.toString(), true)); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + ActionMessageTag freshTag = new ActionMessageTag(); + freshTag.setPageContext(pageContext); + assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", + strutsBodyTagsAreReflectionEqual(tag, freshTag)); } public void testActionErrorsDontEscape() throws Exception { @@ -77,6 +91,13 @@ public class ActionMessageTagTest extends AbstractUITagTest { assertEquals(normalize("", true), normalize(writer.toString(), true)); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + ActionMessageTag freshTag = new ActionMessageTag(); + freshTag.setPageContext(pageContext); + assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", + strutsBodyTagsAreReflectionEqual(tag, freshTag)); } @@ -90,6 +111,13 @@ public class ActionMessageTagTest extends AbstractUITagTest { tag.doEndTag(); verify(ActionMessageTagTest.class.getResource("actionmessage-2.txt")); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + ActionMessageTag freshTag = new ActionMessageTag(); + freshTag.setPageContext(pageContext); + assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", + strutsBodyTagsAreReflectionEqual(tag, freshTag)); } public void testYesActionMessagesWithEmptyMessages() throws Exception { @@ -102,7 +130,14 @@ public class ActionMessageTagTest extends AbstractUITagTest { tag.doStartTag(); tag.doEndTag(); - assertTrue(StringUtils.isBlank(writer.toString())); + assertTrue(StringUtils.isBlank(writer.toString())); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + ActionMessageTag freshTag = new ActionMessageTag(); + freshTag.setPageContext(pageContext); + assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", + strutsBodyTagsAreReflectionEqual(tag, freshTag)); } public void testNullMessage() throws Exception { @@ -116,8 +151,16 @@ public class ActionMessageTagTest extends AbstractUITagTest { tag.doEndTag(); verify(ActionMessageTagTest.class.getResource("actionmessage-2.txt")); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + ActionMessageTag freshTag = new ActionMessageTag(); + freshTag.setPageContext(pageContext); + assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", + strutsBodyTagsAreReflectionEqual(tag, freshTag)); } + @Override public Action getAction() { return new InternalActionSupport(); } @@ -142,6 +185,7 @@ public class ActionMessageTagTest extends AbstractUITagTest { this.justNullElement = justNullElement; } + @Override public Collection getActionMessages() { if (justNullElement) { return Arrays.asList(null); @@ -157,6 +201,7 @@ public class ActionMessageTagTest extends AbstractUITagTest { } } + @Override public boolean hasActionMessages() { return canHaveActionMessage; } diff --git a/core/src/test/java/org/apache/struts2/views/jsp/ui/AnchorTest.java b/core/src/test/java/org/apache/struts2/views/jsp/ui/AnchorTest.java index c031f3945..25bc1e549 100644 --- a/core/src/test/java/org/apache/struts2/views/jsp/ui/AnchorTest.java +++ b/core/src/test/java/org/apache/struts2/views/jsp/ui/AnchorTest.java @@ -47,6 +47,13 @@ public class AnchorTest extends AbstractUITagTest { tag.doEndTag(); verifyResource("href-1.txt"); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + AnchorTag freshTag = new AnchorTag(); + freshTag.setPageContext(pageContext); + assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", + strutsBodyTagsAreReflectionEqual(tag, freshTag)); } public void testSimpleBadQuote() throws Exception { @@ -58,6 +65,13 @@ public class AnchorTest extends AbstractUITagTest { tag.doEndTag(); verifyResource("href-2.txt"); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + AnchorTag freshTag = new AnchorTag(); + freshTag.setPageContext(pageContext); + assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", + strutsBodyTagsAreReflectionEqual(tag, freshTag)); } public void testDynamicAttribute() throws Exception { @@ -72,6 +86,13 @@ public class AnchorTest extends AbstractUITagTest { tag.doEndTag(); verifyResource("Anchor-2.txt"); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + AnchorTag freshTag = new AnchorTag(); + freshTag.setPageContext(pageContext); + assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", + strutsBodyTagsAreReflectionEqual(tag, freshTag)); } public void testDynamicAttributeAsExpression() throws Exception { @@ -86,6 +107,13 @@ public class AnchorTest extends AbstractUITagTest { tag.doEndTag(); verifyResource("Anchor-3.txt"); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + AnchorTag freshTag = new AnchorTag(); + freshTag.setPageContext(pageContext); + assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", + strutsBodyTagsAreReflectionEqual(tag, freshTag)); } private void createAction() { diff --git a/core/src/test/java/org/apache/struts2/views/jsp/ui/CheckboxListTest.java b/core/src/test/java/org/apache/struts2/views/jsp/ui/CheckboxListTest.java index 1f72445b9..dcc964c20 100644 --- a/core/src/test/java/org/apache/struts2/views/jsp/ui/CheckboxListTest.java +++ b/core/src/test/java/org/apache/struts2/views/jsp/ui/CheckboxListTest.java @@ -40,6 +40,7 @@ public class CheckboxListTest extends AbstractUITagTest { * @return A Map of PropertyHolders values bound to {@link org.apache.struts2.views.jsp.AbstractUITagTest.PropertyHolder#getName()} * as key. */ + @Override protected Map initializedGenericTagTestProperties() { Map result = super.initializedGenericTagTestProperties(); new PropertyHolder("value", "hello").addToMap(result); @@ -98,6 +99,13 @@ public class CheckboxListTest extends AbstractUITagTest { tag.doEndTag(); verify(CheckboxListTag.class.getResource("CheckboxList-2.txt")); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + CheckboxListTag freshTag = new CheckboxListTag(); + freshTag.setPageContext(pageContext); + assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", + strutsBodyTagsAreReflectionEqual(tag, freshTag)); } public void testMultipleWithDisabledOn() throws Exception { @@ -125,6 +133,13 @@ public class CheckboxListTest extends AbstractUITagTest { tag.doEndTag(); verify(CheckboxListTag.class.getResource("CheckboxList-3.txt")); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + CheckboxListTag freshTag = new CheckboxListTag(); + freshTag.setPageContext(pageContext); + assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", + strutsBodyTagsAreReflectionEqual(tag, freshTag)); } public void testSimple() throws Exception { @@ -150,6 +165,13 @@ public class CheckboxListTest extends AbstractUITagTest { tag.doEndTag(); verify(CheckboxListTag.class.getResource("CheckboxList-1.txt")); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + CheckboxListTag freshTag = new CheckboxListTag(); + freshTag.setPageContext(pageContext); + assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", + strutsBodyTagsAreReflectionEqual(tag, freshTag)); } public void testSimpleWithDisableOn() throws Exception { @@ -174,5 +196,12 @@ public class CheckboxListTest extends AbstractUITagTest { tag.doEndTag(); verify(CheckboxListTag.class.getResource("CheckboxList-4.txt")); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + CheckboxListTag freshTag = new CheckboxListTag(); + freshTag.setPageContext(pageContext); + assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", + strutsBodyTagsAreReflectionEqual(tag, freshTag)); } } diff --git a/core/src/test/java/org/apache/struts2/views/jsp/ui/CheckboxTest.java b/core/src/test/java/org/apache/struts2/views/jsp/ui/CheckboxTest.java index 256e639b5..ac507ac52 100644 --- a/core/src/test/java/org/apache/struts2/views/jsp/ui/CheckboxTest.java +++ b/core/src/test/java/org/apache/struts2/views/jsp/ui/CheckboxTest.java @@ -19,8 +19,6 @@ package org.apache.struts2.views.jsp.ui; import java.util.Map; -import java.util.HashMap; -import java.util.Collections; import org.apache.struts2.TestAction; import org.apache.struts2.views.jsp.AbstractUITagTest; @@ -41,6 +39,7 @@ public class CheckboxTest extends AbstractUITagTest { * @return A Map of PropertyHolders values bound to {@link org.apache.struts2.views.jsp.AbstractUITagTest.PropertyHolder#getName()} * as key. */ + @Override protected Map initializedGenericTagTestProperties() { Map result = super.initializedGenericTagTestProperties(); new PropertyHolder("value", "true").addToMap(result); @@ -74,6 +73,13 @@ public class CheckboxTest extends AbstractUITagTest { tag.doEndTag(); verify(CheckboxTag.class.getResource("Checkbox-1.txt")); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + CheckboxTag freshTag = new CheckboxTag(); + freshTag.setPageContext(pageContext); + assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", + strutsBodyTagsAreReflectionEqual(tag, freshTag)); } public void testCheckedWithTopLabelPosition() throws Exception { @@ -94,6 +100,13 @@ public class CheckboxTest extends AbstractUITagTest { tag.doEndTag(); verify(CheckboxTag.class.getResource("Checkbox-4.txt")); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + CheckboxTag freshTag = new CheckboxTag(); + freshTag.setPageContext(pageContext); + assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", + strutsBodyTagsAreReflectionEqual(tag, freshTag)); } public void testCheckedWithLeftLabelPosition() throws Exception { @@ -114,6 +127,13 @@ public class CheckboxTest extends AbstractUITagTest { tag.doEndTag(); verify(CheckboxTag.class.getResource("Checkbox-5.txt")); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + CheckboxTag freshTag = new CheckboxTag(); + freshTag.setPageContext(pageContext); + assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", + strutsBodyTagsAreReflectionEqual(tag, freshTag)); } public void testCheckedWithError() throws Exception { @@ -136,6 +156,13 @@ public class CheckboxTest extends AbstractUITagTest { tag.doEndTag(); verify(CheckboxTag.class.getResource("Checkbox-3.txt")); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + CheckboxTag freshTag = new CheckboxTag(); + freshTag.setPageContext(pageContext); + assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", + strutsBodyTagsAreReflectionEqual(tag, freshTag)); } public void testCheckedWithErrorStyle() throws Exception { @@ -158,6 +185,13 @@ public class CheckboxTest extends AbstractUITagTest { tag.doEndTag(); verify(CheckboxTag.class.getResource("Checkbox-33.txt")); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + CheckboxTag freshTag = new CheckboxTag(); + freshTag.setPageContext(pageContext); + assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", + strutsBodyTagsAreReflectionEqual(tag, freshTag)); } public void testUnchecked() throws Exception { @@ -175,6 +209,13 @@ public class CheckboxTest extends AbstractUITagTest { tag.doEndTag(); verify(CheckboxTag.class.getResource("Checkbox-2.txt")); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + CheckboxTag freshTag = new CheckboxTag(); + freshTag.setPageContext(pageContext); + assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", + strutsBodyTagsAreReflectionEqual(tag, freshTag)); } public void testDisabled() throws Exception { @@ -193,6 +234,13 @@ public class CheckboxTest extends AbstractUITagTest { tag.doEndTag(); verify(CheckboxTag.class.getResource("Checkbox-6.txt")); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + CheckboxTag freshTag = new CheckboxTag(); + freshTag.setPageContext(pageContext); + assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", + strutsBodyTagsAreReflectionEqual(tag, freshTag)); } public void testSubmitUncheckedAsFalse() throws Exception { diff --git a/core/src/test/java/org/apache/struts2/views/jsp/ui/ComboBoxTest.java b/core/src/test/java/org/apache/struts2/views/jsp/ui/ComboBoxTest.java index a3f50278b..20302c4f1 100644 --- a/core/src/test/java/org/apache/struts2/views/jsp/ui/ComboBoxTest.java +++ b/core/src/test/java/org/apache/struts2/views/jsp/ui/ComboBoxTest.java @@ -79,6 +79,13 @@ public class ComboBoxTest extends AbstractUITagTest { tag.doEndTag(); verify(ComboBoxTag.class.getResource("ComboBox-1.txt")); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + ComboBoxTag freshTag = new ComboBoxTag(); + freshTag.setPageContext(pageContext); + assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", + strutsBodyTagsAreReflectionEqual(tag, freshTag)); } public void testWithEmptyOptionAndHeader() throws Exception { @@ -106,6 +113,13 @@ public class ComboBoxTest extends AbstractUITagTest { tag.doEndTag(); verify(ComboBoxTag.class.getResource("ComboBox-2.txt")); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + ComboBoxTag freshTag = new ComboBoxTag(); + freshTag.setPageContext(pageContext); + assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", + strutsBodyTagsAreReflectionEqual(tag, freshTag)); } public void testWithMap() throws Exception { @@ -133,6 +147,13 @@ public class ComboBoxTest extends AbstractUITagTest { tag.doEndTag(); verify(ComboBoxTag.class.getResource("ComboBox-3.txt")); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + ComboBoxTag freshTag = new ComboBoxTag(); + freshTag.setPageContext(pageContext); + assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", + strutsBodyTagsAreReflectionEqual(tag, freshTag)); } public void testJsCallNamingUsesEscapedId() throws Exception { @@ -154,6 +175,13 @@ public class ComboBoxTest extends AbstractUITagTest { tag.doEndTag(); verify(ComboBoxTag.class.getResource("ComboBox-4.txt")); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + ComboBoxTag freshTag = new ComboBoxTag(); + freshTag.setPageContext(pageContext); + assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", + strutsBodyTagsAreReflectionEqual(tag, freshTag)); } } diff --git a/core/src/test/java/org/apache/struts2/views/jsp/ui/ComponentTest.java b/core/src/test/java/org/apache/struts2/views/jsp/ui/ComponentTest.java index 78765d89f..f0d816986 100644 --- a/core/src/test/java/org/apache/struts2/views/jsp/ui/ComponentTest.java +++ b/core/src/test/java/org/apache/struts2/views/jsp/ui/ComponentTest.java @@ -19,7 +19,6 @@ package org.apache.struts2.views.jsp.ui; import org.apache.struts2.TestAction; -import org.apache.struts2.components.Component; import org.apache.struts2.views.jsp.AbstractUITagTest; @@ -46,6 +45,13 @@ public class ComponentTest extends AbstractUITagTest { tag.doEndTag(); verify(ComponentTag.class.getResource("Component-2.txt")); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + TextFieldTag freshTag = new TextFieldTag(); + freshTag.setPageContext(pageContext); + assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", + strutsBodyTagsAreReflectionEqual(tag, freshTag)); } public void testIdIsEvaludatedAgainstStack2() throws Exception { @@ -63,6 +69,13 @@ public class ComponentTest extends AbstractUITagTest { tag.doEndTag(); verify(ComponentTag.class.getResource("Component-3.txt")); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + TextFieldTag freshTag = new TextFieldTag(); + freshTag.setPageContext(pageContext); + assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", + strutsBodyTagsAreReflectionEqual(tag, freshTag)); } @@ -83,6 +96,13 @@ public class ComponentTest extends AbstractUITagTest { tag.doEndTag(); verify(ComponentTag.class.getResource("Component-1.txt")); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + ComponentTag freshTag = new ComponentTag(); + freshTag.setPageContext(pageContext); + assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", + strutsBodyTagsAreReflectionEqual(tag, freshTag)); } /** @@ -111,6 +131,13 @@ public class ComponentTest extends AbstractUITagTest { // System.out.println(writer); verify(ComponentTag.class.getResource("Component-param.txt")); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + ComponentTag freshTag = new ComponentTag(); + freshTag.setPageContext(pageContext); + assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", + strutsBodyTagsAreReflectionEqual(tag, freshTag)); } public void testTagAttributeExclusion() throws Exception { @@ -122,6 +149,9 @@ public class ComponentTest extends AbstractUITagTest { tag.doStartTag(); assertTrue(tag.includeContext); + + // Calling tag.doEndTag() results in an exception. + // Aa a result, a basic sanity check of clearTagStateForTagPoolingServers() cannot be called. } } 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 ccf506384..4a5be78bd 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 @@ -54,6 +54,13 @@ public class DateTagTest extends AbstractTagTest { 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); + assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", + strutsBodyTagsAreReflectionEqual(tag, freshTag)); } public void testCustomGlobalFormatFormat() throws Exception { @@ -86,6 +93,13 @@ public class DateTagTest extends AbstractTagTest { 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); + assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", + strutsBodyTagsAreReflectionEqual(tag, freshTag)); } public void testCustomFormatWithTimezoneAsExpression() throws Exception { @@ -104,6 +118,13 @@ public class DateTagTest extends AbstractTagTest { 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); + assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", + strutsBodyTagsAreReflectionEqual(tag, freshTag)); } public void testCustomFormatCalendar() throws Exception { @@ -118,6 +139,13 @@ public class DateTagTest extends AbstractTagTest { 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); + assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", + strutsBodyTagsAreReflectionEqual(tag, freshTag)); } public void testCustomFormatLong() throws Exception { @@ -133,6 +161,13 @@ public class DateTagTest extends AbstractTagTest { 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); + assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", + strutsBodyTagsAreReflectionEqual(tag, freshTag)); } public void testCustomFormatLocalDateTime() throws Exception { @@ -174,6 +209,13 @@ public class DateTagTest extends AbstractTagTest { 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); + assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", + strutsBodyTagsAreReflectionEqual(tag, freshTag)); } public void testCustomFormatAndComponent() throws Exception { @@ -197,6 +239,13 @@ public class DateTagTest extends AbstractTagTest { tag.doEndTag(); assertEquals(formatted, writer.toString()); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + DateTag freshTag = new DateTag(); + freshTag.setPageContext(pageContext); + assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", + strutsBodyTagsAreReflectionEqual(tag, freshTag)); } public void testSetId() throws Exception { @@ -212,6 +261,13 @@ public class DateTagTest extends AbstractTagTest { tag.doStartTag(); tag.doEndTag(); assertEquals(formatted, context.get("myId")); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + DateTag freshTag = new DateTag(); + freshTag.setPageContext(pageContext); + assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", + strutsBodyTagsAreReflectionEqual(tag, freshTag)); } public void testFutureNiceHour() throws Exception { @@ -227,6 +283,13 @@ public class DateTagTest extends AbstractTagTest { tag.doStartTag(); tag.doEndTag(); assertEquals("in one hour", writer.toString()); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + DateTag freshTag = new DateTag(); + freshTag.setPageContext(pageContext); + assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", + strutsBodyTagsAreReflectionEqual(tag, freshTag)); } public void testPastNiceHour() throws Exception { @@ -242,6 +305,13 @@ public class DateTagTest extends AbstractTagTest { tag.doStartTag(); tag.doEndTag(); assertEquals("one hour ago", writer.toString()); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + DateTag freshTag = new DateTag(); + freshTag.setPageContext(pageContext); + assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", + strutsBodyTagsAreReflectionEqual(tag, freshTag)); } public void testFutureNiceHourMinSec() throws Exception { @@ -258,6 +328,13 @@ public class DateTagTest extends AbstractTagTest { tag.doStartTag(); tag.doEndTag(); assertEquals("in 2 hours, 33 minutes", writer.toString()); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + DateTag freshTag = new DateTag(); + freshTag.setPageContext(pageContext); + assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", + strutsBodyTagsAreReflectionEqual(tag, freshTag)); } public void testPastNiceHourMin() throws Exception { @@ -274,6 +351,13 @@ public class DateTagTest extends AbstractTagTest { tag.doStartTag(); tag.doEndTag(); assertEquals("4 hours, 55 minutes ago", writer.toString()); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + DateTag freshTag = new DateTag(); + freshTag.setPageContext(pageContext); + assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", + strutsBodyTagsAreReflectionEqual(tag, freshTag)); } public void testFutureLessOneMin() throws Exception { @@ -289,6 +373,13 @@ public class DateTagTest extends AbstractTagTest { tag.doStartTag(); tag.doEndTag(); assertEquals("in an instant", writer.toString()); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + DateTag freshTag = new DateTag(); + freshTag.setPageContext(pageContext); + assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", + strutsBodyTagsAreReflectionEqual(tag, freshTag)); } public void testFutureLessOneHour() throws Exception { @@ -304,6 +395,13 @@ public class DateTagTest extends AbstractTagTest { tag.doStartTag(); tag.doEndTag(); assertEquals("in 36 minutes", writer.toString()); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + DateTag freshTag = new DateTag(); + freshTag.setPageContext(pageContext); + assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", + strutsBodyTagsAreReflectionEqual(tag, freshTag)); } public void testFutureLessOneYear() throws Exception { @@ -319,6 +417,13 @@ public class DateTagTest extends AbstractTagTest { tag.doStartTag(); tag.doEndTag(); assertEquals("in 40 days", writer.toString()); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + DateTag freshTag = new DateTag(); + freshTag.setPageContext(pageContext); + assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", + strutsBodyTagsAreReflectionEqual(tag, freshTag)); } public void testFutureTwoYears() throws Exception { @@ -338,6 +443,13 @@ public class DateTagTest extends AbstractTagTest { // hmmm the Date component isn't the best to calculate the excat difference so we'll just check // that it starts with in 2 years assertTrue(writer.toString().startsWith("in 2 years")); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + DateTag freshTag = new DateTag(); + freshTag.setPageContext(pageContext); + assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", + strutsBodyTagsAreReflectionEqual(tag, freshTag)); } public void testNoDateObjectInContext() throws Exception { @@ -348,14 +460,23 @@ public class DateTagTest extends AbstractTagTest { tag.doEndTag(); //should return a blank assertEquals("", writer.toString()); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + DateTag freshTag = new DateTag(); + freshTag.setPageContext(pageContext); + assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", + strutsBodyTagsAreReflectionEqual(tag, freshTag)); } + @Override protected void setUp() throws Exception { super.setUp(); tag = new DateTag(); tag.setPageContext(pageContext); } + @Override protected void tearDown() throws Exception { super.tearDown(); tag = null; diff --git a/core/src/test/java/org/apache/struts2/views/jsp/ui/DebugTagTest.java b/core/src/test/java/org/apache/struts2/views/jsp/ui/DebugTagTest.java index fa4729555..50ef1f6bd 100644 --- a/core/src/test/java/org/apache/struts2/views/jsp/ui/DebugTagTest.java +++ b/core/src/test/java/org/apache/struts2/views/jsp/ui/DebugTagTest.java @@ -57,6 +57,13 @@ public class DebugTagTest extends AbstractUITagTest { assertTrue("Nonce value not included", result.contains("nonce=\"r4nd0m\"")); assertTrue(StringUtils.isNotEmpty(result)); assertTrue("Property 'checkStackProperty' should be in Debug Tag output", StringUtils.contains(result, "checkStackProperty")); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + DebugTag freshTag = new DebugTag(); + freshTag.setPageContext(pageContext); + assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", + strutsBodyTagsAreReflectionEqual(tag, freshTag)); } public void testDevModeDisabled() throws Exception { @@ -65,6 +72,13 @@ public class DebugTagTest extends AbstractUITagTest { tag.doStartTag(); tag.doEndTag(); assertTrue("nothing to see here, devMode=false", StringUtils.isEmpty(writer.toString())); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + DebugTag freshTag = new DebugTag(); + freshTag.setPageContext(pageContext); + assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", + strutsBodyTagsAreReflectionEqual(tag, freshTag)); } public void testTagAttributeOverrideDevModeTrue() throws Exception { @@ -76,6 +90,13 @@ public class DebugTagTest extends AbstractUITagTest { String result = writer.toString(); assertTrue(StringUtils.isNotEmpty(result)); assertTrue("Property 'checkStackProperty' should be in Debug Tag output", StringUtils.contains(result, "checkStackProperty")); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + DebugTag freshTag = new DebugTag(); + freshTag.setPageContext(pageContext); + assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", + strutsBodyTagsAreReflectionEqual(tag, freshTag)); } public void testTagAttributeOverrideDevModeFalse() throws Exception { @@ -85,6 +106,13 @@ public class DebugTagTest extends AbstractUITagTest { tag.doStartTag(); tag.doEndTag(); assertTrue("nothing to see here, devMode=false and overrideDevMode=false", StringUtils.isEmpty(writer.toString())); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + DebugTag freshTag = new DebugTag(); + freshTag.setPageContext(pageContext); + assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", + strutsBodyTagsAreReflectionEqual(tag, freshTag)); } private void setDevMode(final boolean devMode) { diff --git a/core/src/test/java/org/apache/struts2/views/jsp/ui/DoubleSelectTest.java b/core/src/test/java/org/apache/struts2/views/jsp/ui/DoubleSelectTest.java index 536a5d996..a91dc7ce1 100644 --- a/core/src/test/java/org/apache/struts2/views/jsp/ui/DoubleSelectTest.java +++ b/core/src/test/java/org/apache/struts2/views/jsp/ui/DoubleSelectTest.java @@ -94,6 +94,13 @@ public class DoubleSelectTest extends AbstractUITagTest { tag.doEndTag(); verify(SelectTag.class.getResource("DoubleSelect-1.txt")); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + DoubleSelectTag freshTag = new DoubleSelectTag(); + freshTag.setPageContext(pageContext); + assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", + strutsBodyTagsAreReflectionEqual(tag, freshTag)); } public void testOnchange() throws Exception { @@ -158,6 +165,13 @@ public class DoubleSelectTest extends AbstractUITagTest { tag.doEndTag(); verify(SelectTag.class.getResource("DoubleSelect-4.txt")); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + DoubleSelectTag freshTag = new DoubleSelectTag(); + freshTag.setPageContext(pageContext); + assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", + strutsBodyTagsAreReflectionEqual(tag, freshTag)); } @@ -221,7 +235,12 @@ public class DoubleSelectTest extends AbstractUITagTest { verify(SelectTag.class.getResource("DoubleSelect-2.txt")); - + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + DoubleSelectTag freshTag = new DoubleSelectTag(); + freshTag.setPageContext(pageContext); + assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", + strutsBodyTagsAreReflectionEqual(tag, freshTag)); } public void testDoubleWithDotName() throws Exception { @@ -279,6 +298,13 @@ public class DoubleSelectTest extends AbstractUITagTest { tag.doEndTag(); verify(SelectTag.class.getResource("DoubleSelect-3.txt")); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + DoubleSelectTag freshTag = new DoubleSelectTag(); + freshTag.setPageContext(pageContext); + assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", + strutsBodyTagsAreReflectionEqual(tag, freshTag)); } public void testGenericSimple() throws Exception { diff --git a/core/src/test/java/org/apache/struts2/views/jsp/ui/FieldErrorTagTest.java b/core/src/test/java/org/apache/struts2/views/jsp/ui/FieldErrorTagTest.java index b1e9b5bad..6c984299b 100644 --- a/core/src/test/java/org/apache/struts2/views/jsp/ui/FieldErrorTagTest.java +++ b/core/src/test/java/org/apache/struts2/views/jsp/ui/FieldErrorTagTest.java @@ -46,6 +46,13 @@ public class FieldErrorTagTest extends AbstractUITagTest { tag.doEndTag(); verify(FieldErrorTagTest.class.getResource("fielderror-1.txt")); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + FieldErrorTag freshTag = new FieldErrorTag(); + freshTag.setPageContext(pageContext); + assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", + strutsBodyTagsAreReflectionEqual(tag, freshTag)); } public void testWithoutParamsWithoutFieldErrors() throws Exception { @@ -56,6 +63,13 @@ public class FieldErrorTagTest extends AbstractUITagTest { tag.doEndTag(); verify(FieldErrorTagTest.class.getResource("fielderror-2.txt")); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + FieldErrorTag freshTag = new FieldErrorTag(); + freshTag.setPageContext(pageContext); + assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", + strutsBodyTagsAreReflectionEqual(tag, freshTag)); } public void testFieldErrorsEscape() throws Exception { @@ -72,6 +86,13 @@ public class FieldErrorTagTest extends AbstractUITagTest { assertEquals(normalize("
  • <p>hey</p>
", true), normalize(writer.toString(), true)); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + FieldErrorTag freshTag = new FieldErrorTag(); + freshTag.setPageContext(pageContext); + assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", + strutsBodyTagsAreReflectionEqual(tag, freshTag)); } public void testFieldErrorsDontEscape() throws Exception { @@ -88,6 +109,13 @@ public class FieldErrorTagTest extends AbstractUITagTest { assertEquals(normalize("
  • hey

", true), normalize(writer.toString(), true)); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + FieldErrorTag freshTag = new FieldErrorTag(); + freshTag.setPageContext(pageContext); + assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", + strutsBodyTagsAreReflectionEqual(tag, freshTag)); } public void testWithParamsWithFieldErrors1() throws Exception { @@ -111,6 +139,23 @@ public class FieldErrorTagTest extends AbstractUITagTest { tag.doEndTag(); verify(FieldErrorTagTest.class.getResource("fielderror-3.txt")); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + ParamTag freshParamTag = new ParamTag(); + freshParamTag.setPageContext(pageContext); + assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", + strutsBodyTagsAreReflectionEqual(pTag1, freshParamTag)); + assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", + strutsBodyTagsAreReflectionEqual(pTag2, freshParamTag)); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + FieldErrorTag freshTag = new FieldErrorTag(); + freshTag.setPageContext(pageContext); + assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", + strutsBodyTagsAreReflectionEqual(tag, freshTag)); } public void testWithFieldName() throws Exception { @@ -122,6 +167,13 @@ public class FieldErrorTagTest extends AbstractUITagTest { tag.doEndTag(); verify(FieldErrorTagTest.class.getResource("fielderror-6.txt")); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + FieldErrorTag freshTag = new FieldErrorTag(); + freshTag.setPageContext(pageContext); + assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", + strutsBodyTagsAreReflectionEqual(tag, freshTag)); } public void testWithParamsWithFieldErrors2() throws Exception { @@ -144,6 +196,23 @@ public class FieldErrorTagTest extends AbstractUITagTest { tag.doEndTag(); verify(FieldErrorTagTest.class.getResource("fielderror-4.txt")); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + ParamTag freshParamTag = new ParamTag(); + freshParamTag.setPageContext(pageContext); + assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", + strutsBodyTagsAreReflectionEqual(pTag1, freshParamTag)); + assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", + strutsBodyTagsAreReflectionEqual(pTag2, freshParamTag)); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + FieldErrorTag freshTag = new FieldErrorTag(); + freshTag.setPageContext(pageContext); + assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", + strutsBodyTagsAreReflectionEqual(tag, freshTag)); } @@ -161,6 +230,20 @@ public class FieldErrorTagTest extends AbstractUITagTest { tag.doEndTag(); verify(FieldErrorTagTest.class.getResource("fielderror-5.txt")); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + ParamTag freshParamTag = new ParamTag(); + freshParamTag.setPageContext(pageContext); + assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", + strutsBodyTagsAreReflectionEqual(pTag1, freshParamTag)); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + FieldErrorTag freshTag = new FieldErrorTag(); + freshTag.setPageContext(pageContext); + assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", + strutsBodyTagsAreReflectionEqual(tag, freshTag)); } public void testWithParamsWithoutFieldErrors1() throws Exception { @@ -182,6 +265,23 @@ public class FieldErrorTagTest extends AbstractUITagTest { tag.doEndTag(); verify(FieldErrorTagTest.class.getResource("fielderror-2.txt")); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + ParamTag freshParamTag = new ParamTag(); + freshParamTag.setPageContext(pageContext); + assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", + strutsBodyTagsAreReflectionEqual(pTag1, freshParamTag)); + assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", + strutsBodyTagsAreReflectionEqual(pTag2, freshParamTag)); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + FieldErrorTag freshTag = new FieldErrorTag(); + freshTag.setPageContext(pageContext); + assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", + strutsBodyTagsAreReflectionEqual(tag, freshTag)); } public void testWithParamsWithoutFieldErrors2() throws Exception { @@ -203,6 +303,23 @@ public class FieldErrorTagTest extends AbstractUITagTest { tag.doEndTag(); verify(FieldErrorTagTest.class.getResource("fielderror-2.txt")); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + ParamTag freshParamTag = new ParamTag(); + freshParamTag.setPageContext(pageContext); + assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", + strutsBodyTagsAreReflectionEqual(pTag1, freshParamTag)); + assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", + strutsBodyTagsAreReflectionEqual(pTag2, freshParamTag)); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + FieldErrorTag freshTag = new FieldErrorTag(); + freshTag.setPageContext(pageContext); + assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", + strutsBodyTagsAreReflectionEqual(tag, freshTag)); } @@ -220,6 +337,20 @@ public class FieldErrorTagTest extends AbstractUITagTest { tag.doEndTag(); verify(FieldErrorTagTest.class.getResource("fielderror-2.txt")); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + ParamTag freshParamTag = new ParamTag(); + freshParamTag.setPageContext(pageContext); + assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", + strutsBodyTagsAreReflectionEqual(pTag1, freshParamTag)); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + FieldErrorTag freshTag = new FieldErrorTag(); + freshTag.setPageContext(pageContext); + assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", + strutsBodyTagsAreReflectionEqual(tag, freshTag)); } public void testWithNullFieldErrors() throws Exception { @@ -237,9 +368,24 @@ public class FieldErrorTagTest extends AbstractUITagTest { tag.doEndTag(); verify(FieldErrorTagTest.class.getResource("fielderror-2.txt")); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + ParamTag freshParamTag = new ParamTag(); + freshParamTag.setPageContext(pageContext); + assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", + strutsBodyTagsAreReflectionEqual(pTag1, freshParamTag)); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + FieldErrorTag freshTag = new FieldErrorTag(); + freshTag.setPageContext(pageContext); + assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", + strutsBodyTagsAreReflectionEqual(tag, freshTag)); } + @Override public Action getAction() { return new InternalAction(); } @@ -258,6 +404,7 @@ public class FieldErrorTagTest extends AbstractUITagTest { this.returnNullForFieldErrors = returnNullForFieldErrors; } + @Override public Map> getFieldErrors() { if (haveFieldErrors) { List err1 = new ArrayList(); @@ -280,6 +427,7 @@ public class FieldErrorTagTest extends AbstractUITagTest { } } + @Override public boolean hasFieldErrors() { return haveFieldErrors; } diff --git a/core/src/test/java/org/apache/struts2/views/jsp/ui/FileTest.java b/core/src/test/java/org/apache/struts2/views/jsp/ui/FileTest.java index 3e1a6be13..483d7f406 100644 --- a/core/src/test/java/org/apache/struts2/views/jsp/ui/FileTest.java +++ b/core/src/test/java/org/apache/struts2/views/jsp/ui/FileTest.java @@ -49,6 +49,13 @@ public class FileTest extends AbstractUITagTest { tag.doEndTag(); verify(TextFieldTag.class.getResource("File-1.txt")); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + FileTag freshTag = new FileTag(); + freshTag.setPageContext(pageContext); + assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", + strutsBodyTagsAreReflectionEqual(tag, freshTag)); } /** @@ -59,6 +66,7 @@ public class FileTest extends AbstractUITagTest { * @return A Map of PropertyHolders values bound to {@link org.apache.struts2.views.jsp.AbstractUITagTest.PropertyHolder#getName()} * as key. */ + @Override protected Map initializedGenericTagTestProperties() { Map result = super.initializedGenericTagTestProperties(); new PropertyHolder("accept", "someAccepted").addToMap(result); diff --git a/core/src/test/java/org/apache/struts2/views/jsp/ui/FormTagTest.java b/core/src/test/java/org/apache/struts2/views/jsp/ui/FormTagTest.java index ef3484c4e..d5a56448e 100644 --- a/core/src/test/java/org/apache/struts2/views/jsp/ui/FormTagTest.java +++ b/core/src/test/java/org/apache/struts2/views/jsp/ui/FormTagTest.java @@ -58,6 +58,13 @@ public class FormTagTest extends AbstractUITagTest { tag.doEndTag(); verify(FormTag.class.getResource("Formtag-26.txt")); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + FormTag freshTag = new FormTag(); + freshTag.setPageContext(pageContext); + assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", + strutsBodyTagsAreReflectionEqual(tag, freshTag)); } public void testFormWithActionAttributeContainingBothActionAndMethod() throws Exception { @@ -74,6 +81,13 @@ public class FormTagTest extends AbstractUITagTest { tag.doEndTag(); verify(FormTag.class.getResource("Formtag-9.txt")); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + FormTag freshTag = new FormTag(); + freshTag.setPageContext(pageContext); + assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", + strutsBodyTagsAreReflectionEqual(tag, freshTag)); } public void testFormWithoutContext() throws Exception { @@ -89,6 +103,13 @@ public class FormTagTest extends AbstractUITagTest { verify(FormTag.class.getResource("Formtag-14.txt")); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + FormTag freshTag = new FormTag(); + freshTag.setPageContext(pageContext); + assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", + strutsBodyTagsAreReflectionEqual(tag, freshTag)); } public void testFormWithContext() throws Exception { @@ -103,6 +124,13 @@ public class FormTagTest extends AbstractUITagTest { verify(FormTag.class.getResource("Formtag-13.txt")); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + FormTag freshTag = new FormTag(); + freshTag.setPageContext(pageContext); + assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", + strutsBodyTagsAreReflectionEqual(tag, freshTag)); } public void testFormWithActionAttributeContainingBothActionAndDMIMethod() throws Exception { @@ -122,7 +150,14 @@ public class FormTagTest extends AbstractUITagTest { tag.doEndTag(); verify(FormTag.class.getResource("Formtag-23.txt")); - } + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + FormTag freshTag = new FormTag(); + freshTag.setPageContext(pageContext); + assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", + strutsBodyTagsAreReflectionEqual(tag, freshTag)); + } public void testFormWithFocusElement() throws Exception { FormTag tag = new FormTag(); @@ -134,6 +169,13 @@ public class FormTagTest extends AbstractUITagTest { tag.doEndTag(); verify(FormTag.class.getResource("Formtag-12.txt")); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + FormTag freshTag = new FormTag(); + freshTag.setPageContext(pageContext); + assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", + strutsBodyTagsAreReflectionEqual(tag, freshTag)); } public void testFormWithActionAttributeContainingBothActionAndMethodAndNamespace() throws Exception { @@ -152,6 +194,13 @@ public class FormTagTest extends AbstractUITagTest { tag.doEndTag(); verify(FormTag.class.getResource("Formtag-10.txt")); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + FormTag freshTag = new FormTag(); + freshTag.setPageContext(pageContext); + assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", + strutsBodyTagsAreReflectionEqual(tag, freshTag)); } @@ -177,6 +226,13 @@ public class FormTagTest extends AbstractUITagTest { tag.doEndTag(); verify(FormTag.class.getResource("Formtag-1.txt")); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + FormTag freshTag = new FormTag(); + freshTag.setPageContext(pageContext); + assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", + strutsBodyTagsAreReflectionEqual(tag, freshTag)); } public void testFormId() throws Exception { @@ -196,6 +252,13 @@ public class FormTagTest extends AbstractUITagTest { tag.doEndTag(); verify(FormTag.class.getResource("Formtag-29.txt")); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + FormTag freshTag = new FormTag(); + freshTag.setPageContext(pageContext); + assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", + strutsBodyTagsAreReflectionEqual(tag, freshTag)); } public void testFormNoNameOrId() throws Exception { @@ -218,6 +281,13 @@ public class FormTagTest extends AbstractUITagTest { tag.doEndTag(); verify(FormTag.class.getResource("Formtag-25.txt")); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + FormTag freshTag = new FormTag(); + freshTag.setPageContext(pageContext); + assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", + strutsBodyTagsAreReflectionEqual(tag, freshTag)); } /** @@ -252,6 +322,20 @@ public class FormTagTest extends AbstractUITagTest { tag.doEndTag(); verify(FormTag.class.getResource("Formtag-2.txt")); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + UpDownSelectTag freshParamTag = new UpDownSelectTag(); + freshParamTag.setPageContext(pageContext); + assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", + strutsBodyTagsAreReflectionEqual(t, freshParamTag)); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + FormTag freshTag = new FormTag(); + freshTag.setPageContext(pageContext); + assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", + strutsBodyTagsAreReflectionEqual(tag, freshTag)); } @@ -286,6 +370,20 @@ public class FormTagTest extends AbstractUITagTest { tag.doEndTag(); verify(FormTag.class.getResource("Formtag-11.txt")); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + UpDownSelectTag freshParamTag = new UpDownSelectTag(); + freshParamTag.setPageContext(pageContext); + assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", + strutsBodyTagsAreReflectionEqual(t, freshParamTag)); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + FormTag freshTag = new FormTag(); + freshTag.setPageContext(pageContext); + assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", + strutsBodyTagsAreReflectionEqual(tag, freshTag)); } /** @@ -318,6 +416,20 @@ public class FormTagTest extends AbstractUITagTest { tag.doEndTag(); verify(FormTag.class.getResource("Formtag-22.txt")); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + UpDownSelectTag freshParamTag = new UpDownSelectTag(); + freshParamTag.setPageContext(pageContext); + assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", + strutsBodyTagsAreReflectionEqual(t, freshParamTag)); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + FormTag freshTag = new FormTag(); + freshTag.setPageContext(pageContext); + assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", + strutsBodyTagsAreReflectionEqual(tag, freshTag)); } /** @@ -350,6 +462,20 @@ public class FormTagTest extends AbstractUITagTest { tag.doEndTag(); verify(FormTag.class.getResource("Formtag-24.txt")); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + UpDownSelectTag freshParamTag = new UpDownSelectTag(); + freshParamTag.setPageContext(pageContext); + assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", + strutsBodyTagsAreReflectionEqual(t, freshParamTag)); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + FormTag freshTag = new FormTag(); + freshTag.setPageContext(pageContext); + assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", + strutsBodyTagsAreReflectionEqual(tag, freshTag)); } private void prepareMockInvocation() throws Exception { @@ -394,6 +520,20 @@ public class FormTagTest extends AbstractUITagTest { tag.doEndTag(); verify(FormTag.class.getResource("Formtag-6.txt")); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + UpDownSelectTag freshParamTag = new UpDownSelectTag(); + freshParamTag.setPageContext(pageContext); + assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", + strutsBodyTagsAreReflectionEqual(t, freshParamTag)); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + FormTag freshTag = new FormTag(); + freshTag.setPageContext(pageContext); + assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", + strutsBodyTagsAreReflectionEqual(tag, freshTag)); } @@ -428,6 +568,13 @@ public class FormTagTest extends AbstractUITagTest { tag.doEndTag(); verify(FormTag.class.getResource("Formtag-5.txt")); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + FormTag freshTag = new FormTag(); + freshTag.setPageContext(pageContext); + assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", + strutsBodyTagsAreReflectionEqual(tag, freshTag)); } /** @@ -449,6 +596,13 @@ public class FormTagTest extends AbstractUITagTest { tag.doEndTag(); verify(FormTag.class.getResource("Formtag-5.txt")); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + FormTag freshTag = new FormTag(); + freshTag.setPageContext(pageContext); + assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", + strutsBodyTagsAreReflectionEqual(tag, freshTag)); } public void testFormWithNamespaceDefaulting() throws Exception { @@ -467,6 +621,13 @@ public class FormTagTest extends AbstractUITagTest { tag.doEndTag(); verify(FormTag.class.getResource("Formtag-3.txt")); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + FormTag freshTag = new FormTag(); + freshTag.setPageContext(pageContext); + assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", + strutsBodyTagsAreReflectionEqual(tag, freshTag)); } public void testFormTagForStackOverflowException1() throws Exception { @@ -492,6 +653,20 @@ public class FormTagTest extends AbstractUITagTest { form1.doEndTag(); assertNull(form1.getComponent()); // component is removed after end tag + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + FormTag freshFormTag = new FormTag(); + freshFormTag.setPageContext(pageContext); + assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", + strutsBodyTagsAreReflectionEqual(form1, freshFormTag)); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + ActionTag freshTag = new ActionTag(); + freshTag.setPageContext(pageContext); + assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", + strutsBodyTagsAreReflectionEqual(tag, freshTag)); } public void testFormTagForStackOverflowException2() throws Exception { @@ -527,6 +702,23 @@ public class FormTagTest extends AbstractUITagTest { form1.doEndTag(); assertNull(form1.getComponent()); // component is removed after end tag + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + FormTag freshFormTag = new FormTag(); + freshFormTag.setPageContext(pageContext); + assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", + strutsBodyTagsAreReflectionEqual(form1, freshFormTag)); + assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", + strutsBodyTagsAreReflectionEqual(form2, freshFormTag)); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + ActionTag freshTag = new ActionTag(); + freshTag.setPageContext(pageContext); + assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", + strutsBodyTagsAreReflectionEqual(tag, freshTag)); } @@ -573,6 +765,26 @@ public class FormTagTest extends AbstractUITagTest { form1.doEndTag(); assertNull(form1.getComponent()); // component is removed after end tag + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + FormTag freshFormTag = new FormTag(); + freshFormTag.setPageContext(pageContext); + assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", + strutsBodyTagsAreReflectionEqual(form1, freshFormTag)); + assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", + strutsBodyTagsAreReflectionEqual(form2, freshFormTag)); + assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", + strutsBodyTagsAreReflectionEqual(form3, freshFormTag)); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + ActionTag freshTag = new ActionTag(); + freshTag.setPageContext(pageContext); + assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", + strutsBodyTagsAreReflectionEqual(tag, freshTag)); } @@ -588,6 +800,13 @@ public class FormTagTest extends AbstractUITagTest { form.doEndTag(); assertNull(form.getComponent()); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + FormTag freshTag = new FormTag(); + freshTag.setPageContext(pageContext); + assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", + strutsBodyTagsAreReflectionEqual(form, freshTag)); } @@ -602,6 +821,13 @@ public class FormTagTest extends AbstractUITagTest { tag.doEndTag(); verify(FormTag.class.getResource("Formtag-4.txt")); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + FormTag freshTag = new FormTag(); + freshTag.setPageContext(pageContext); + assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", + strutsBodyTagsAreReflectionEqual(tag, freshTag)); } public void testFormWithStaticAction() throws Exception { @@ -616,6 +842,13 @@ public class FormTagTest extends AbstractUITagTest { tag.doEndTag(); verify(FormTag.class.getResource("Formtag-7.txt")); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + FormTag freshTag = new FormTag(); + freshTag.setPageContext(pageContext); + assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", + strutsBodyTagsAreReflectionEqual(tag, freshTag)); } public void testFormWithActionAndExtension() throws Exception { @@ -632,6 +865,12 @@ public class FormTagTest extends AbstractUITagTest { verify(FormTag.class.getResource("Formtag-8.txt")); + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + FormTag freshTag = new FormTag(); + freshTag.setPageContext(pageContext); + assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", + strutsBodyTagsAreReflectionEqual(tag, freshTag)); } public void testFormWithTopLabelPosition() throws Exception { @@ -652,6 +891,20 @@ public class FormTagTest extends AbstractUITagTest { form.doEndTag(); verify(FormTag.class.getResource("Formtag-27.txt")); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + FormTag freshFormTag = new FormTag(); + freshFormTag.setPageContext(pageContext); + assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", + strutsBodyTagsAreReflectionEqual(form, freshFormTag)); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + TextFieldTag freshTag = new TextFieldTag(); + freshTag.setPageContext(pageContext); + assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", + strutsBodyTagsAreReflectionEqual(text, freshTag)); } public void testFormWithTopLabelPositionWithElementOverride() throws Exception { @@ -673,6 +926,20 @@ public class FormTagTest extends AbstractUITagTest { form.doEndTag(); verify(FormTag.class.getResource("Formtag-27.txt")); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + FormTag freshFormTag = new FormTag(); + freshFormTag.setPageContext(pageContext); + assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", + strutsBodyTagsAreReflectionEqual(form, freshFormTag)); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + TextFieldTag freshTag = new TextFieldTag(); + freshTag.setPageContext(pageContext); + assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", + strutsBodyTagsAreReflectionEqual(text, freshTag)); } public void testFormWithTopLabelPositionCssXhtml() throws Exception { @@ -693,6 +960,20 @@ public class FormTagTest extends AbstractUITagTest { form.doEndTag(); verify(FormTag.class.getResource("Formtag-28.txt")); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + FormTag freshFormTag = new FormTag(); + freshFormTag.setPageContext(pageContext); + assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", + strutsBodyTagsAreReflectionEqual(form, freshFormTag)); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + TextFieldTag freshTag = new TextFieldTag(); + freshTag.setPageContext(pageContext); + assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", + strutsBodyTagsAreReflectionEqual(text, freshTag)); } public void testFormWithTopLabelPositionWithElementOverrideCssXhtml() throws Exception { @@ -714,6 +995,20 @@ public class FormTagTest extends AbstractUITagTest { form.doEndTag(); verify(FormTag.class.getResource("Formtag-28.txt")); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + FormTag freshFormTag = new FormTag(); + freshFormTag.setPageContext(pageContext); + assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", + strutsBodyTagsAreReflectionEqual(form, freshFormTag)); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + TextFieldTag freshTag = new TextFieldTag(); + freshTag.setPageContext(pageContext); + assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", + strutsBodyTagsAreReflectionEqual(text, freshTag)); } @Override diff --git a/core/src/test/java/org/apache/struts2/views/jsp/ui/HeadTagTest.java b/core/src/test/java/org/apache/struts2/views/jsp/ui/HeadTagTest.java index a0c0ff296..493515fba 100644 --- a/core/src/test/java/org/apache/struts2/views/jsp/ui/HeadTagTest.java +++ b/core/src/test/java/org/apache/struts2/views/jsp/ui/HeadTagTest.java @@ -39,5 +39,12 @@ public class HeadTagTest extends AbstractUITagTest { tag.doEndTag(); verify(HeadTagTest.class.getResource("HeadTagTest-1.txt")); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + HeadTag freshTag = new HeadTag(); + freshTag.setPageContext(pageContext); + assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", + strutsBodyTagsAreReflectionEqual(tag, freshTag)); } } diff --git a/core/src/test/java/org/apache/struts2/views/jsp/ui/HiddenTest.java b/core/src/test/java/org/apache/struts2/views/jsp/ui/HiddenTest.java index 41f895045..c2b062852 100644 --- a/core/src/test/java/org/apache/struts2/views/jsp/ui/HiddenTest.java +++ b/core/src/test/java/org/apache/struts2/views/jsp/ui/HiddenTest.java @@ -26,6 +26,8 @@ import org.apache.struts2.views.jsp.AbstractUITagTest; import java.util.HashMap; import java.util.Map; +/** + */ public class HiddenTest extends AbstractUITagTest { public void testSimple() throws Exception { @@ -42,6 +44,13 @@ public class HiddenTest extends AbstractUITagTest { tag.doEndTag(); verify(TextFieldTag.class.getResource("Hidden-1.txt")); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + HiddenTag freshTag = new HiddenTag(); + freshTag.setPageContext(pageContext); + assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", + strutsBodyTagsAreReflectionEqual(tag, freshTag)); } public void testDisabled() throws Exception { @@ -59,6 +68,13 @@ public class HiddenTest extends AbstractUITagTest { tag.doEndTag(); verify(TextFieldTag.class.getResource("Hidden-2.txt")); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + HiddenTag freshTag = new HiddenTag(); + freshTag.setPageContext(pageContext); + assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", + strutsBodyTagsAreReflectionEqual(tag, freshTag)); } public void testDynamicAttributesWithActionInvocation() throws Exception { @@ -83,6 +99,13 @@ public class HiddenTest extends AbstractUITagTest { assertNotSame(stack.pop(), tag); verify(TextFieldTag.class.getResource("Hidden-3.txt")); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + HiddenTag freshTag = new HiddenTag(); + freshTag.setPageContext(pageContext); + assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", + strutsBodyTagsAreReflectionEqual(tag, freshTag)); } public void testDynamicAttributesWithStack() throws Exception { @@ -103,6 +126,13 @@ public class HiddenTest extends AbstractUITagTest { assertNotSame(stack.pop(), tag); verify(TextFieldTag.class.getResource("Hidden-3.txt")); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + HiddenTag freshTag = new HiddenTag(); + freshTag.setPageContext(pageContext); + assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", + strutsBodyTagsAreReflectionEqual(tag, freshTag)); } /** @@ -111,8 +141,9 @@ public class HiddenTest extends AbstractUITagTest { * String, String[])} as properties to verify.
This implementation extends testdata from AbstractUITag. * * @return A Map of PropertyHolders values bound to {@link org.apache.struts2.views.jsp.AbstractUITagTest.PropertyHolder#getName()} - * as key. + * as key. */ + @Override protected Map initializedGenericTagTestProperties() { Map result = new HashMap(); new PropertyHolder("name", "someName").addToMap(result); diff --git a/core/src/test/java/org/apache/struts2/views/jsp/ui/InputTransferSelectTagTest.java b/core/src/test/java/org/apache/struts2/views/jsp/ui/InputTransferSelectTagTest.java index ee60cd80e..eb938798c 100644 --- a/core/src/test/java/org/apache/struts2/views/jsp/ui/InputTransferSelectTagTest.java +++ b/core/src/test/java/org/apache/struts2/views/jsp/ui/InputTransferSelectTagTest.java @@ -49,5 +49,12 @@ public class InputTransferSelectTagTest extends AbstractUITagTest { //System.out.println(writer.toString()); verify(InputTransferSelectTagTest.class.getResource("inputtransferselect-1.txt")); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + InputTransferSelectTag freshTag = new InputTransferSelectTag(); + freshTag.setPageContext(pageContext); + assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", + strutsBodyTagsAreReflectionEqual(tag, freshTag)); } } diff --git a/core/src/test/java/org/apache/struts2/views/jsp/ui/JspTemplateTest.java b/core/src/test/java/org/apache/struts2/views/jsp/ui/JspTemplateTest.java index 645343766..9add2d1e5 100644 --- a/core/src/test/java/org/apache/struts2/views/jsp/ui/JspTemplateTest.java +++ b/core/src/test/java/org/apache/struts2/views/jsp/ui/JspTemplateTest.java @@ -47,5 +47,12 @@ public class JspTemplateTest extends AbstractUITagTest { tag.doStartTag(); tag.doEndTag(); rdMock.verify(); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + CheckboxTag freshTag = new CheckboxTag(); + freshTag.setPageContext(pageContext); + assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", + strutsBodyTagsAreReflectionEqual(tag, freshTag)); } } diff --git a/core/src/test/java/org/apache/struts2/views/jsp/ui/LabelTest.java b/core/src/test/java/org/apache/struts2/views/jsp/ui/LabelTest.java index 720358c9d..6d5689f49 100644 --- a/core/src/test/java/org/apache/struts2/views/jsp/ui/LabelTest.java +++ b/core/src/test/java/org/apache/struts2/views/jsp/ui/LabelTest.java @@ -44,6 +44,13 @@ public class LabelTest extends AbstractUITagTest { tag.doEndTag(); verify(LabelTest.class.getResource("Label-1.txt")); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + LabelTag freshTag = new LabelTag(); + freshTag.setPageContext(pageContext); + assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", + strutsBodyTagsAreReflectionEqual(tag, freshTag)); } public void testSimpleWithLabelposition() throws Exception { @@ -61,6 +68,13 @@ public class LabelTest extends AbstractUITagTest { tag.doEndTag(); verify(LabelTest.class.getResource("Label-3.txt")); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + LabelTag freshTag = new LabelTag(); + freshTag.setPageContext(pageContext); + assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", + strutsBodyTagsAreReflectionEqual(tag, freshTag)); } /** @@ -71,6 +85,7 @@ public class LabelTest extends AbstractUITagTest { * @return A Map of PropertyHolders values bound to {@link org.apache.struts2.views.jsp.AbstractUITagTest.PropertyHolder#getName()} * as key. */ + @Override protected Map initializedGenericTagTestProperties() { Map result = new HashMap(); new PropertyHolder("title", "someTitle").addToMap(result); @@ -95,6 +110,13 @@ public class LabelTest extends AbstractUITagTest { tag.doEndTag(); verify(LabelTest.class.getResource("Label-5.txt")); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + LabelTag freshTag = new LabelTag(); + freshTag.setPageContext(pageContext); + assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", + strutsBodyTagsAreReflectionEqual(tag, freshTag)); } public void testGenericSimple() throws Exception { @@ -126,6 +148,13 @@ public class LabelTest extends AbstractUITagTest { tag.doEndTag(); verify(LabelTest.class.getResource("Label-2.txt")); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + LabelTag freshTag = new LabelTag(); + freshTag.setPageContext(pageContext); + assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", + strutsBodyTagsAreReflectionEqual(tag, freshTag)); } public void testWithKeyValueFromStack() throws Exception { @@ -147,6 +176,13 @@ public class LabelTest extends AbstractUITagTest { tag.doEndTag(); verify(LabelTest.class.getResource("Label-4.txt")); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + LabelTag freshTag = new LabelTag(); + freshTag.setPageContext(pageContext); + assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", + strutsBodyTagsAreReflectionEqual(tag, freshTag)); } public void testWithJustKeyValueFromStack() throws Exception { @@ -166,6 +202,13 @@ public class LabelTest extends AbstractUITagTest { tag.doEndTag(); verify(LabelTest.class.getResource("Label-6.txt")); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + LabelTag freshTag = new LabelTag(); + freshTag.setPageContext(pageContext); + assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", + strutsBodyTagsAreReflectionEqual(tag, freshTag)); } public void testWithCssErrorClass() throws Exception { @@ -186,6 +229,13 @@ public class LabelTest extends AbstractUITagTest { tag.doEndTag(); verify(LabelTest.class.getResource("Label-7.txt")); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + LabelTag freshTag = new LabelTag(); + freshTag.setPageContext(pageContext); + assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", + strutsBodyTagsAreReflectionEqual(tag, freshTag)); } public void testWithCssErrorStyle() throws Exception { @@ -206,6 +256,13 @@ public class LabelTest extends AbstractUITagTest { tag.doEndTag(); verify(LabelTest.class.getResource("Label-8.txt")); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + LabelTag freshTag = new LabelTag(); + freshTag.setPageContext(pageContext); + assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", + strutsBodyTagsAreReflectionEqual(tag, freshTag)); } } diff --git a/core/src/test/java/org/apache/struts2/views/jsp/ui/OptGroupTest.java b/core/src/test/java/org/apache/struts2/views/jsp/ui/OptGroupTest.java index 5a2b35153..b4a6484d4 100644 --- a/core/src/test/java/org/apache/struts2/views/jsp/ui/OptGroupTest.java +++ b/core/src/test/java/org/apache/struts2/views/jsp/ui/OptGroupTest.java @@ -52,6 +52,23 @@ public class OptGroupTest extends AbstractUITagTest { //System.out.println(writer.toString()); verify(SelectTag.class.getResource("OptGroup-1.txt")); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + SelectTag freshTag = new SelectTag(); + freshTag.setPageContext(pageContext); + assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", + strutsBodyTagsAreReflectionEqual(selectTag, freshTag)); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + OptGroupTag freshOptGroupTag = new OptGroupTag(); + freshOptGroupTag.setPageContext(pageContext); + assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", + strutsBodyTagsAreReflectionEqual(optGroupTag1, freshOptGroupTag)); + assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", + strutsBodyTagsAreReflectionEqual(optGroupTag2, freshOptGroupTag)); } @@ -84,6 +101,23 @@ public class OptGroupTest extends AbstractUITagTest { //System.out.println(writer.toString()); verify(SelectTag.class.getResource("OptGroup-2.txt")); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + SelectTag freshTag = new SelectTag(); + freshTag.setPageContext(pageContext); + assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", + strutsBodyTagsAreReflectionEqual(selectTag, freshTag)); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + OptGroupTag freshOptGroupTag = new OptGroupTag(); + freshOptGroupTag.setPageContext(pageContext); + assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", + strutsBodyTagsAreReflectionEqual(optGroupTag1, freshOptGroupTag)); + assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", + strutsBodyTagsAreReflectionEqual(optGroupTag2, freshOptGroupTag)); } @@ -116,6 +150,23 @@ public class OptGroupTest extends AbstractUITagTest { //System.out.println(writer.toString()); verify(SelectTag.class.getResource("OptGroup-3.txt")); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + SelectTag freshTag = new SelectTag(); + freshTag.setPageContext(pageContext); + assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", + strutsBodyTagsAreReflectionEqual(selectTag, freshTag)); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + OptGroupTag freshOptGroupTag = new OptGroupTag(); + freshOptGroupTag.setPageContext(pageContext); + assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", + strutsBodyTagsAreReflectionEqual(optGroupTag1, freshOptGroupTag)); + assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", + strutsBodyTagsAreReflectionEqual(optGroupTag2, freshOptGroupTag)); } public void testOptGroupWithMultipleSelectIntKey() throws Exception { @@ -147,6 +198,23 @@ public class OptGroupTest extends AbstractUITagTest { //System.out.println(writer.toString()); verify(SelectTag.class.getResource("OptGroup-7.txt")); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + SelectTag freshTag = new SelectTag(); + freshTag.setPageContext(pageContext); + assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", + strutsBodyTagsAreReflectionEqual(selectTag, freshTag)); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + OptGroupTag freshOptGroupTag = new OptGroupTag(); + freshOptGroupTag.setPageContext(pageContext); + assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", + strutsBodyTagsAreReflectionEqual(optGroupTag1, freshOptGroupTag)); + assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", + strutsBodyTagsAreReflectionEqual(optGroupTag2, freshOptGroupTag)); } public void testOptGroupNumbers() throws Exception { @@ -183,6 +251,23 @@ public class OptGroupTest extends AbstractUITagTest { //System.out.println(writer.toString()); verify(SelectTag.class.getResource("OptGroup-4.txt")); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + SelectTag freshTag = new SelectTag(); + freshTag.setPageContext(pageContext); + assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", + strutsBodyTagsAreReflectionEqual(selectTag, freshTag)); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + OptGroupTag freshOptGroupTag = new OptGroupTag(); + freshOptGroupTag.setPageContext(pageContext); + assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", + strutsBodyTagsAreReflectionEqual(optGroupTag1, freshOptGroupTag)); + assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", + strutsBodyTagsAreReflectionEqual(optGroupTag2, freshOptGroupTag)); } public void testOptGroupForHtmlEncoding() throws Exception { @@ -214,6 +299,23 @@ public class OptGroupTest extends AbstractUITagTest { //System.out.println(writer.toString()); verify(SelectTag.class.getResource("OptGroup-5.txt")); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + SelectTag freshTag = new SelectTag(); + freshTag.setPageContext(pageContext); + assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", + strutsBodyTagsAreReflectionEqual(selectTag, freshTag)); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + OptGroupTag freshOptGroupTag = new OptGroupTag(); + freshOptGroupTag.setPageContext(pageContext); + assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", + strutsBodyTagsAreReflectionEqual(optGroupTag1, freshOptGroupTag)); + assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", + strutsBodyTagsAreReflectionEqual(optGroupTag2, freshOptGroupTag)); } public void testOptGroupWithValueKey() throws Exception { @@ -251,6 +353,23 @@ public class OptGroupTest extends AbstractUITagTest { //System.out.println(writer.toString()); verify(SelectTag.class.getResource("OptGroup-6.txt")); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + SelectTag freshTag = new SelectTag(); + freshTag.setPageContext(pageContext); + assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", + strutsBodyTagsAreReflectionEqual(selectTag, freshTag)); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + OptGroupTag freshOptGroupTag = new OptGroupTag(); + freshOptGroupTag.setPageContext(pageContext); + assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", + strutsBodyTagsAreReflectionEqual(optGroupTag1, freshOptGroupTag)); + assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", + strutsBodyTagsAreReflectionEqual(optGroupTag2, freshOptGroupTag)); } public void testOptGroupListAttributes() throws Exception { @@ -288,5 +407,22 @@ public class OptGroupTest extends AbstractUITagTest { //System.out.println(writer.toString()); verify(SelectTag.class.getResource("OptGroup-8.txt")); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + SelectTag freshTag = new SelectTag(); + freshTag.setPageContext(pageContext); + assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", + strutsBodyTagsAreReflectionEqual(selectTag, freshTag)); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + OptGroupTag freshOptGroupTag = new OptGroupTag(); + freshOptGroupTag.setPageContext(pageContext); + assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", + strutsBodyTagsAreReflectionEqual(optGroupTag1, freshOptGroupTag)); + assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", + strutsBodyTagsAreReflectionEqual(optGroupTag2, freshOptGroupTag)); } } diff --git a/core/src/test/java/org/apache/struts2/views/jsp/ui/OptionTransferSelectTagTest.java b/core/src/test/java/org/apache/struts2/views/jsp/ui/OptionTransferSelectTagTest.java index d7e8bb1aa..31463e5f9 100644 --- a/core/src/test/java/org/apache/struts2/views/jsp/ui/OptionTransferSelectTagTest.java +++ b/core/src/test/java/org/apache/struts2/views/jsp/ui/OptionTransferSelectTagTest.java @@ -92,6 +92,13 @@ public class OptionTransferSelectTagTest extends AbstractUITagTest { //System.out.println(writer.toString()); verify(OptionTransferSelectTagTest.class.getResource("optiontransferselect-1.txt")); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + OptionTransferSelectTag freshTag = new OptionTransferSelectTag(); + freshTag.setPageContext(pageContext); + assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", + strutsBodyTagsAreReflectionEqual(tag, freshTag)); } public void testWithPartialSelectedOnBothSides() throws Exception { @@ -165,6 +172,13 @@ public class OptionTransferSelectTagTest extends AbstractUITagTest { //System.out.println(writer.toString()); verify(OptionTransferSelectTagTest.class.getResource("optiontransferselect-2.txt")); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + OptionTransferSelectTag freshTag = new OptionTransferSelectTag(); + freshTag.setPageContext(pageContext); + assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", + strutsBodyTagsAreReflectionEqual(tag, freshTag)); } public void testWithoutHeaderOnBothSides() throws Exception { @@ -232,6 +246,13 @@ public class OptionTransferSelectTagTest extends AbstractUITagTest { //System.out.println(writer.toString()); verify(OptionTransferSelectTagTest.class.getResource("optiontransferselect-3.txt")); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + OptionTransferSelectTag freshTag = new OptionTransferSelectTag(); + freshTag.setPageContext(pageContext); + assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", + strutsBodyTagsAreReflectionEqual(tag, freshTag)); } public void testWithoutHeaderOnOneSide() throws Exception { @@ -302,6 +323,13 @@ public class OptionTransferSelectTagTest extends AbstractUITagTest { //System.out.println(writer.toString()); verify(OptionTransferSelectTagTest.class.getResource("optiontransferselect-4.txt")); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + OptionTransferSelectTag freshTag = new OptionTransferSelectTag(); + freshTag.setPageContext(pageContext); + assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", + strutsBodyTagsAreReflectionEqual(tag, freshTag)); } public void testWithoutEmptyOptionOnBothSides() throws Exception { @@ -375,6 +403,13 @@ public class OptionTransferSelectTagTest extends AbstractUITagTest { //System.out.println(writer.toString()); verify(OptionTransferSelectTagTest.class.getResource("optiontransferselect-5.txt")); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + OptionTransferSelectTag freshTag = new OptionTransferSelectTag(); + freshTag.setPageContext(pageContext); + assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", + strutsBodyTagsAreReflectionEqual(tag, freshTag)); } public void testWithoutEmptyOptionOnOneSide() throws Exception { @@ -448,6 +483,13 @@ public class OptionTransferSelectTagTest extends AbstractUITagTest { //System.out.println(writer.toString()); verify(OptionTransferSelectTagTest.class.getResource("optiontransferselect-6.txt")); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + OptionTransferSelectTag freshTag = new OptionTransferSelectTag(); + freshTag.setPageContext(pageContext); + assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", + strutsBodyTagsAreReflectionEqual(tag, freshTag)); } public void testDisableSomeButtons() throws Exception { @@ -524,5 +566,12 @@ public class OptionTransferSelectTagTest extends AbstractUITagTest { //System.out.println(writer.toString()); verify(OptionTransferSelectTagTest.class.getResource("optiontransferselect-7.txt")); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + OptionTransferSelectTag freshTag = new OptionTransferSelectTag(); + freshTag.setPageContext(pageContext); + assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", + strutsBodyTagsAreReflectionEqual(tag, freshTag)); } } diff --git a/core/src/test/java/org/apache/struts2/views/jsp/ui/PasswordTest.java b/core/src/test/java/org/apache/struts2/views/jsp/ui/PasswordTest.java index b3de7e291..91628a742 100644 --- a/core/src/test/java/org/apache/struts2/views/jsp/ui/PasswordTest.java +++ b/core/src/test/java/org/apache/struts2/views/jsp/ui/PasswordTest.java @@ -40,6 +40,13 @@ public class PasswordTest extends AbstractUITagTest { tag.doEndTag(); verify(PasswordTag.class.getResource("Password-1.txt")); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + PasswordTag freshTag = new PasswordTag(); + freshTag.setPageContext(pageContext); + assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", + strutsBodyTagsAreReflectionEqual(tag, freshTag)); } public void testGenericSimple() throws Exception { diff --git a/core/src/test/java/org/apache/struts2/views/jsp/ui/RadioTest.java b/core/src/test/java/org/apache/struts2/views/jsp/ui/RadioTest.java index 1caa5a5bd..c03cfc6d3 100644 --- a/core/src/test/java/org/apache/struts2/views/jsp/ui/RadioTest.java +++ b/core/src/test/java/org/apache/struts2/views/jsp/ui/RadioTest.java @@ -50,6 +50,13 @@ public class RadioTest extends AbstractUITagTest { tag.doEndTag(); verify(RadioTag.class.getResource("Radio-3.txt")); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + RadioTag freshTag = new RadioTag(); + freshTag.setPageContext(pageContext); + assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", + strutsBodyTagsAreReflectionEqual(tag, freshTag)); } public void testMapChecked() throws Exception { @@ -74,6 +81,13 @@ public class RadioTest extends AbstractUITagTest { tag.doEndTag(); verify(RadioTag.class.getResource("Radio-2.txt")); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + RadioTag freshTag = new RadioTag(); + freshTag.setPageContext(pageContext); + assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", + strutsBodyTagsAreReflectionEqual(tag, freshTag)); } public void testMapCheckedNull() throws Exception { @@ -96,6 +110,13 @@ public class RadioTest extends AbstractUITagTest { tag.doEndTag(); verify(RadioTag.class.getResource("Radio-4.txt")); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + RadioTag freshTag = new RadioTag(); + freshTag.setPageContext(pageContext); + assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", + strutsBodyTagsAreReflectionEqual(tag, freshTag)); } public void testSimple() throws Exception { @@ -119,6 +140,13 @@ public class RadioTest extends AbstractUITagTest { tag.doEndTag(); verify(RadioTag.class.getResource("Radio-1.txt")); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + RadioTag freshTag = new RadioTag(); + freshTag.setPageContext(pageContext); + assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", + strutsBodyTagsAreReflectionEqual(tag, freshTag)); } public void testSimpleWithStringMap() throws Exception { @@ -134,6 +162,13 @@ public class RadioTest extends AbstractUITagTest { tag.doEndTag(); verify(RadioTag.class.getResource("Radio-6.txt")); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + RadioTag freshTag = new RadioTag(); + freshTag.setPageContext(pageContext); + assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", + strutsBodyTagsAreReflectionEqual(tag, freshTag)); } public void testSimpleWithLabelSeparator() throws Exception { @@ -158,6 +193,13 @@ public class RadioTest extends AbstractUITagTest { tag.doEndTag(); verify(RadioTag.class.getResource("Radio-5.txt")); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + RadioTag freshTag = new RadioTag(); + freshTag.setPageContext(pageContext); + assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", + strutsBodyTagsAreReflectionEqual(tag, freshTag)); } public void testGenericSimple() throws Exception { @@ -194,6 +236,13 @@ public class RadioTest extends AbstractUITagTest { tag.doEndTag(); verify(RadioTag.class.getResource("Radio-7.txt")); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + RadioTag freshTag = new RadioTag(); + freshTag.setPageContext(pageContext); + assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", + strutsBodyTagsAreReflectionEqual(tag, freshTag)); } public void testNotExistingListValueKey() throws Exception { @@ -209,6 +258,13 @@ public class RadioTest extends AbstractUITagTest { tag.doEndTag(); verify(SelectTag.class.getResource("Radio-8.txt")); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + RadioTag freshTag = new RadioTag(); + freshTag.setPageContext(pageContext); + assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", + strutsBodyTagsAreReflectionEqual(tag, freshTag)); } private void prepareTagGeneric(RadioTag tag) { diff --git a/core/src/test/java/org/apache/struts2/views/jsp/ui/ResetTest.java b/core/src/test/java/org/apache/struts2/views/jsp/ui/ResetTest.java index 03ee9e960..d3194757c 100644 --- a/core/src/test/java/org/apache/struts2/views/jsp/ui/ResetTest.java +++ b/core/src/test/java/org/apache/struts2/views/jsp/ui/ResetTest.java @@ -45,6 +45,13 @@ public class ResetTest extends AbstractUITagTest { tag.doEndTag(); verify(TextFieldTag.class.getResource("Reset-2.txt")); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + ResetTag freshTag = new ResetTag(); + freshTag.setPageContext(pageContext); + assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", + strutsBodyTagsAreReflectionEqual(tag, freshTag)); } public void testSimple() throws Exception { @@ -62,6 +69,13 @@ public class ResetTest extends AbstractUITagTest { tag.doEndTag(); verify(TextFieldTag.class.getResource("Reset-1.txt")); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + ResetTag freshTag = new ResetTag(); + freshTag.setPageContext(pageContext); + assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", + strutsBodyTagsAreReflectionEqual(tag, freshTag)); } public void testButtonSimple() throws Exception { @@ -79,6 +93,13 @@ public class ResetTest extends AbstractUITagTest { tag.doEndTag(); verify(TextFieldTag.class.getResource("Reset-3.txt")); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + ResetTag freshTag = new ResetTag(); + freshTag.setPageContext(pageContext); + assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", + strutsBodyTagsAreReflectionEqual(tag, freshTag)); } public void testButtonWithLabel() throws Exception { @@ -96,6 +117,13 @@ public class ResetTest extends AbstractUITagTest { tag.doEndTag(); verify(TextFieldTag.class.getResource("Reset-4.txt")); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + ResetTag freshTag = new ResetTag(); + freshTag.setPageContext(pageContext); + assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", + strutsBodyTagsAreReflectionEqual(tag, freshTag)); } public void testImageSimple() throws Exception { @@ -113,6 +141,13 @@ public class ResetTest extends AbstractUITagTest { tag.doEndTag(); verify(TextFieldTag.class.getResource("Reset-5.txt")); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + ResetTag freshTag = new ResetTag(); + freshTag.setPageContext(pageContext); + assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", + strutsBodyTagsAreReflectionEqual(tag, freshTag)); } public void testImageWithSrc() throws Exception { @@ -131,6 +166,13 @@ public class ResetTest extends AbstractUITagTest { tag.doEndTag(); verify(TextFieldTag.class.getResource("Reset-6.txt")); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + ResetTag freshTag = new ResetTag(); + freshTag.setPageContext(pageContext); + assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", + strutsBodyTagsAreReflectionEqual(tag, freshTag)); } public void testImageWithExpressionSrc() throws Exception { @@ -149,6 +191,13 @@ public class ResetTest extends AbstractUITagTest { tag.doEndTag(); verify(TextFieldTag.class.getResource("Reset-6.txt")); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + ResetTag freshTag = new ResetTag(); + freshTag.setPageContext(pageContext); + assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", + strutsBodyTagsAreReflectionEqual(tag, freshTag)); } public void testSimpleThemeImageUsingActionAndMethod() throws Exception { @@ -168,6 +217,13 @@ public class ResetTest extends AbstractUITagTest { tag.doEndTag(); verify(TextFieldTag.class.getResource("Reset-7.txt")); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + ResetTag freshTag = new ResetTag(); + freshTag.setPageContext(pageContext); + assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", + strutsBodyTagsAreReflectionEqual(tag, freshTag)); } public void testSimpleThemeImageUsingActionOnly() throws Exception { @@ -187,6 +243,13 @@ public class ResetTest extends AbstractUITagTest { tag.doEndTag(); verify(TextFieldTag.class.getResource("Reset-8.txt")); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + ResetTag freshTag = new ResetTag(); + freshTag.setPageContext(pageContext); + assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", + strutsBodyTagsAreReflectionEqual(tag, freshTag)); } public void testSimpleThemeImageUsingMethodOnly() throws Exception { @@ -206,6 +269,13 @@ public class ResetTest extends AbstractUITagTest { tag.doEndTag(); verify(TextFieldTag.class.getResource("Reset-9.txt")); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + ResetTag freshTag = new ResetTag(); + freshTag.setPageContext(pageContext); + assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", + strutsBodyTagsAreReflectionEqual(tag, freshTag)); } /** @@ -216,6 +286,7 @@ public class ResetTest extends AbstractUITagTest { * @return A Map of PropertyHolders values bound to {@link org.apache.struts2.views.jsp.AbstractUITagTest.PropertyHolder#getName()} * as key. */ + @Override protected Map initializedGenericTagTestProperties() { Map result = new HashMap(); new PropertyHolder("title", "someTitle").addToMap(result); diff --git a/core/src/test/java/org/apache/struts2/views/jsp/ui/SelectTest.java b/core/src/test/java/org/apache/struts2/views/jsp/ui/SelectTest.java index c30b8f5ab..ad8a7e378 100644 --- a/core/src/test/java/org/apache/struts2/views/jsp/ui/SelectTest.java +++ b/core/src/test/java/org/apache/struts2/views/jsp/ui/SelectTest.java @@ -46,6 +46,13 @@ public class SelectTest extends AbstractUITagTest { tag.doEndTag(); verify(SelectTag.class.getResource("Select-8.txt")); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + SelectTag freshTag = new SelectTag(); + freshTag.setPageContext(pageContext); + assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", + strutsBodyTagsAreReflectionEqual(tag, freshTag)); } /** @@ -87,6 +94,13 @@ public class SelectTest extends AbstractUITagTest { tag.doEndTag(); verify(SelectTag.class.getResource("Select-10.txt")); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + SelectTag freshTag = new SelectTag(); + freshTag.setPageContext(pageContext); + assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", + strutsBodyTagsAreReflectionEqual(tag, freshTag)); } @@ -130,6 +144,13 @@ public class SelectTest extends AbstractUITagTest { tag.doEndTag(); verify(SelectTag.class.getResource("Select-3.txt")); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + SelectTag freshTag = new SelectTag(); + freshTag.setPageContext(pageContext); + assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", + strutsBodyTagsAreReflectionEqual(tag, freshTag)); } public void testInteger() throws Exception { @@ -169,6 +190,13 @@ public class SelectTest extends AbstractUITagTest { tag.doEndTag(); verify(SelectTag.class.getResource("Select-14.txt")); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + SelectTag freshTag = new SelectTag(); + freshTag.setPageContext(pageContext); + assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", + strutsBodyTagsAreReflectionEqual(tag, freshTag)); } public void testNumericString() throws Exception { @@ -209,6 +237,13 @@ public class SelectTest extends AbstractUITagTest { tag.doEndTag(); verify(SelectTag.class.getResource("Select-15.txt")); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + SelectTag freshTag = new SelectTag(); + freshTag.setPageContext(pageContext); + assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", + strutsBodyTagsAreReflectionEqual(tag, freshTag)); } public class BigDecimalObject { @@ -345,6 +380,13 @@ public class SelectTest extends AbstractUITagTest { tag.doEndTag(); verify(SelectTag.class.getResource("Select-4.txt")); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + SelectTag freshTag = new SelectTag(); + freshTag.setPageContext(pageContext); + assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", + strutsBodyTagsAreReflectionEqual(tag, freshTag)); } public void testMultiple() throws Exception { @@ -377,6 +419,13 @@ public class SelectTest extends AbstractUITagTest { tag.doEndTag(); verify(SelectTag.class.getResource("Select-2.txt")); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + SelectTag freshTag = new SelectTag(); + freshTag.setPageContext(pageContext); + assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", + strutsBodyTagsAreReflectionEqual(tag, freshTag)); } /** @@ -415,6 +464,13 @@ public class SelectTest extends AbstractUITagTest { tag.doEndTag(); verify(SelectTag.class.getResource("Select-12.txt")); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + SelectTag freshTag = new SelectTag(); + freshTag.setPageContext(pageContext); + assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", + strutsBodyTagsAreReflectionEqual(tag, freshTag)); } public void testSimple() throws Exception { @@ -445,6 +501,13 @@ public class SelectTest extends AbstractUITagTest { tag.doEndTag(); verify(SelectTag.class.getResource("Select-1.txt")); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + SelectTag freshTag = new SelectTag(); + freshTag.setPageContext(pageContext); + assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", + strutsBodyTagsAreReflectionEqual(tag, freshTag)); } public void testSimpleWithNulls() throws Exception { @@ -475,6 +538,13 @@ public class SelectTest extends AbstractUITagTest { tag.doEndTag(); verify(SelectTag.class.getResource("Select-9.txt")); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + SelectTag freshTag = new SelectTag(); + freshTag.setPageContext(pageContext); + assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", + strutsBodyTagsAreReflectionEqual(tag, freshTag)); } public void testExtended() throws Exception { @@ -505,6 +575,13 @@ public class SelectTest extends AbstractUITagTest { tag.doEndTag(); verify(SelectTag.class.getResource("Select-7.txt")); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + SelectTag freshTag = new SelectTag(); + freshTag.setPageContext(pageContext); + assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", + strutsBodyTagsAreReflectionEqual(tag, freshTag)); } public void testGenericSimple() throws Exception { @@ -533,6 +610,13 @@ public class SelectTest extends AbstractUITagTest { tag.doEndTag(); verify(SelectTag.class.getResource("Select-5.txt")); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + SelectTag freshTag = new SelectTag(); + freshTag.setPageContext(pageContext); + assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", + strutsBodyTagsAreReflectionEqual(tag, freshTag)); } public void testMultipleOff() throws Exception { @@ -549,6 +633,13 @@ public class SelectTest extends AbstractUITagTest { tag.doEndTag(); verify(SelectTag.class.getResource("Select-6.txt")); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + SelectTag freshTag = new SelectTag(); + freshTag.setPageContext(pageContext); + assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", + strutsBodyTagsAreReflectionEqual(tag, freshTag)); } @@ -584,6 +675,13 @@ public class SelectTest extends AbstractUITagTest { tag.doEndTag(); verify(SelectTag.class.getResource("Select-11.txt")); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + SelectTag freshTag = new SelectTag(); + freshTag.setPageContext(pageContext); + assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", + strutsBodyTagsAreReflectionEqual(tag, freshTag)); } public void testSimpleIntegerWithValueWorkaround() throws Exception { @@ -619,6 +717,13 @@ public class SelectTest extends AbstractUITagTest { tag.doEndTag(); verify(SelectTag.class.getResource("Select-11.txt")); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + SelectTag freshTag = new SelectTag(); + freshTag.setPageContext(pageContext); + assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", + strutsBodyTagsAreReflectionEqual(tag, freshTag)); } public void testEnumList() throws Exception { @@ -635,6 +740,13 @@ public class SelectTest extends AbstractUITagTest { tag.doEndTag(); verify(SelectTag.class.getResource("Select-13.txt")); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + SelectTag freshTag = new SelectTag(); + freshTag.setPageContext(pageContext); + assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", + strutsBodyTagsAreReflectionEqual(tag, freshTag)); } public void testNotExistingListValueKey() throws Exception { @@ -650,6 +762,13 @@ public class SelectTest extends AbstractUITagTest { tag.doEndTag(); verify(SelectTag.class.getResource("Select-16.txt")); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + SelectTag freshTag = new SelectTag(); + freshTag.setPageContext(pageContext); + assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", + strutsBodyTagsAreReflectionEqual(tag, freshTag)); } public class IdName { diff --git a/core/src/test/java/org/apache/struts2/views/jsp/ui/SubmitTest.java b/core/src/test/java/org/apache/struts2/views/jsp/ui/SubmitTest.java index b1c7da721..2ebe68c60 100644 --- a/core/src/test/java/org/apache/struts2/views/jsp/ui/SubmitTest.java +++ b/core/src/test/java/org/apache/struts2/views/jsp/ui/SubmitTest.java @@ -50,6 +50,13 @@ public class SubmitTest extends AbstractUITagTest { tag.doEndTag(); verify(TextFieldTag.class.getResource("Submit-10.txt")); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + SubmitTag freshTag = new SubmitTag(); + freshTag.setPageContext(pageContext); + assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", + strutsBodyTagsAreReflectionEqual(tag, freshTag)); } public void testDefaultValues() throws Exception { @@ -66,6 +73,13 @@ public class SubmitTest extends AbstractUITagTest { tag.doEndTag(); verify(TextFieldTag.class.getResource("Submit-2.txt")); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + SubmitTag freshTag = new SubmitTag(); + freshTag.setPageContext(pageContext); + assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", + strutsBodyTagsAreReflectionEqual(tag, freshTag)); } public void testSimple() throws Exception { @@ -84,6 +98,13 @@ public class SubmitTest extends AbstractUITagTest { tag.doEndTag(); verify(TextFieldTag.class.getResource("Submit-1.txt")); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + SubmitTag freshTag = new SubmitTag(); + freshTag.setPageContext(pageContext); + assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", + strutsBodyTagsAreReflectionEqual(tag, freshTag)); } public void testButtonSimple() throws Exception { @@ -102,6 +123,13 @@ public class SubmitTest extends AbstractUITagTest { tag.doEndTag(); verify(TextFieldTag.class.getResource("Submit-3.txt")); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + SubmitTag freshTag = new SubmitTag(); + freshTag.setPageContext(pageContext); + assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", + strutsBodyTagsAreReflectionEqual(tag, freshTag)); } public void testButtonWithLabel() throws Exception { @@ -119,6 +147,13 @@ public class SubmitTest extends AbstractUITagTest { tag.doEndTag(); verify(TextFieldTag.class.getResource("Submit-4.txt")); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + SubmitTag freshTag = new SubmitTag(); + freshTag.setPageContext(pageContext); + assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", + strutsBodyTagsAreReflectionEqual(tag, freshTag)); } public void testImageSimple() throws Exception { @@ -136,6 +171,13 @@ public class SubmitTest extends AbstractUITagTest { tag.doEndTag(); verify(TextFieldTag.class.getResource("Submit-5.txt")); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + SubmitTag freshTag = new SubmitTag(); + freshTag.setPageContext(pageContext); + assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", + strutsBodyTagsAreReflectionEqual(tag, freshTag)); } public void testImageWithSrc() throws Exception { @@ -154,6 +196,13 @@ public class SubmitTest extends AbstractUITagTest { tag.doEndTag(); verify(TextFieldTag.class.getResource("Submit-6.txt")); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + SubmitTag freshTag = new SubmitTag(); + freshTag.setPageContext(pageContext); + assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", + strutsBodyTagsAreReflectionEqual(tag, freshTag)); } public void testSimpleThemeImageUsingActionAndMethod() throws Exception { @@ -173,6 +222,13 @@ public class SubmitTest extends AbstractUITagTest { tag.doEndTag(); verify(TextFieldTag.class.getResource("Submit-7.txt")); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + SubmitTag freshTag = new SubmitTag(); + freshTag.setPageContext(pageContext); + assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", + strutsBodyTagsAreReflectionEqual(tag, freshTag)); } public void testSimpleThemeImageUsingActionOnly() throws Exception { @@ -192,6 +248,13 @@ public class SubmitTest extends AbstractUITagTest { tag.doEndTag(); verify(TextFieldTag.class.getResource("Submit-8.txt")); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + SubmitTag freshTag = new SubmitTag(); + freshTag.setPageContext(pageContext); + assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", + strutsBodyTagsAreReflectionEqual(tag, freshTag)); } public void testSimpleThemeImageUsingMethodOnly() throws Exception { @@ -211,6 +274,13 @@ public class SubmitTest extends AbstractUITagTest { tag.doEndTag(); verify(TextFieldTag.class.getResource("Submit-9.txt")); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + SubmitTag freshTag = new SubmitTag(); + freshTag.setPageContext(pageContext); + assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", + strutsBodyTagsAreReflectionEqual(tag, freshTag)); } public void testSimpleThemeInput() throws Exception { @@ -230,6 +300,13 @@ public class SubmitTest extends AbstractUITagTest { tag.doEndTag(); assertEquals("", writer.toString().trim()); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + SubmitTag freshTag = new SubmitTag(); + freshTag.setPageContext(pageContext); + assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", + strutsBodyTagsAreReflectionEqual(tag, freshTag)); } /** @@ -240,6 +317,7 @@ public class SubmitTest extends AbstractUITagTest { * @return A Map of PropertyHolders values bound to {@link org.apache.struts2.views.jsp.AbstractUITagTest.PropertyHolder#getName()} * as key. */ + @Override protected Map initializedGenericTagTestProperties() { Map result = new HashMap(); new PropertyHolder("title", "someTitle").addToMap(result); diff --git a/core/src/test/java/org/apache/struts2/views/jsp/ui/TextareaTest.java b/core/src/test/java/org/apache/struts2/views/jsp/ui/TextareaTest.java index ddd050608..c52435b79 100644 --- a/core/src/test/java/org/apache/struts2/views/jsp/ui/TextareaTest.java +++ b/core/src/test/java/org/apache/struts2/views/jsp/ui/TextareaTest.java @@ -52,6 +52,13 @@ public class TextareaTest extends AbstractUITagTest { tag.doEndTag(); verify(TextareaTag.class.getResource("Textarea-1.txt")); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + TextareaTag freshTag = new TextareaTag(); + freshTag.setPageContext(pageContext); + assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", + strutsBodyTagsAreReflectionEqual(tag, freshTag)); } public void testNoColsAndRows() throws Exception { @@ -86,6 +93,7 @@ public class TextareaTest extends AbstractUITagTest { * @return A Map of PropertyHolders values bound to {@link org.apache.struts2.views.jsp.AbstractUITagTest.PropertyHolder#getName()} * as key. */ + @Override protected Map initializedGenericTagTestProperties() { Map result = super.initializedGenericTagTestProperties(); new PropertyHolder("cols", "10").addToMap(result); diff --git a/core/src/test/java/org/apache/struts2/views/jsp/ui/TextfieldTest.java b/core/src/test/java/org/apache/struts2/views/jsp/ui/TextfieldTest.java index bd52b8ad9..568484aab 100644 --- a/core/src/test/java/org/apache/struts2/views/jsp/ui/TextfieldTest.java +++ b/core/src/test/java/org/apache/struts2/views/jsp/ui/TextfieldTest.java @@ -39,6 +39,7 @@ public class TextfieldTest extends AbstractUITagTest { * @return A Map of PropertyHolders values bound to {@link org.apache.struts2.views.jsp.AbstractUITagTest.PropertyHolder#getName()} * as key. */ + @Override protected Map initializedGenericTagTestProperties() { Map result = super.initializedGenericTagTestProperties(); new PropertyHolder("maxlength", "10").addToMap(result); @@ -74,6 +75,13 @@ public class TextfieldTest extends AbstractUITagTest { tag.doEndTag(); verify(TextFieldTag.class.getResource("Textfield-2.txt")); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + TextFieldTag freshTag = new TextFieldTag(); + freshTag.setPageContext(pageContext); + assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", + strutsBodyTagsAreReflectionEqual(tag, freshTag)); } public void testNoLabelJsp() throws Exception { @@ -91,6 +99,13 @@ public class TextfieldTest extends AbstractUITagTest { tag.doEndTag(); verify(TextFieldTag.class.getResource("Textfield-3.txt")); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + TextFieldTag freshTag = new TextFieldTag(); + freshTag.setPageContext(pageContext); + assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", + strutsBodyTagsAreReflectionEqual(tag, freshTag)); } public void testLabelSeparatorJsp() throws Exception { @@ -110,6 +125,13 @@ public class TextfieldTest extends AbstractUITagTest { tag.doEndTag(); verify(TextFieldTag.class.getResource("Textfield-4.txt")); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + TextFieldTag freshTag = new TextFieldTag(); + freshTag.setPageContext(pageContext); + assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", + strutsBodyTagsAreReflectionEqual(tag, freshTag)); } public void testNoLabelFtl() throws Exception { @@ -144,6 +166,13 @@ public class TextfieldTest extends AbstractUITagTest { tag.doEndTag(); verify(TextFieldTag.class.getResource("Textfield-1.txt")); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + TextFieldTag freshTag = new TextFieldTag(); + freshTag.setPageContext(pageContext); + assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", + strutsBodyTagsAreReflectionEqual(tag, freshTag)); } public void testWW5125() throws Exception { @@ -157,6 +186,13 @@ public class TextfieldTest extends AbstractUITagTest { tag.setName(fieldName); tag.doStartTag(); tag.doEndTag(); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + TextFieldTag freshTag = new TextFieldTag(); + freshTag.setPageContext(pageContext); + assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", + strutsBodyTagsAreReflectionEqual(tag, freshTag)); } verify(TextFieldTag.class.getResource("Textfield-WW-5125.txt")); @@ -177,6 +213,13 @@ public class TextfieldTest extends AbstractUITagTest { tag.doEndTag(); verify(TextFieldTag.class.getResource("Textfield-5.txt")); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + TextFieldTag freshTag = new TextFieldTag(); + freshTag.setPageContext(pageContext); + assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", + strutsBodyTagsAreReflectionEqual(tag, freshTag)); } public void testSimple_recursionTestNoValue() throws Exception { @@ -193,6 +236,13 @@ public class TextfieldTest extends AbstractUITagTest { tag.doEndTag(); verify(TextFieldTag.class.getResource("Textfield-6.txt")); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + TextFieldTag freshTag = new TextFieldTag(); + freshTag.setPageContext(pageContext); + assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", + strutsBodyTagsAreReflectionEqual(tag, freshTag)); } public void testHtml5EmailTag() throws Exception { @@ -210,6 +260,13 @@ public class TextfieldTest extends AbstractUITagTest { tag.doEndTag(); verify(TextFieldTag.class.getResource("Textfield-7.txt")); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + TextFieldTag freshTag = new TextFieldTag(); + freshTag.setPageContext(pageContext); + assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", + strutsBodyTagsAreReflectionEqual(tag, freshTag)); } public void testErrorPositionBottom() throws Exception { @@ -230,6 +287,13 @@ public class TextfieldTest extends AbstractUITagTest { tag.doEndTag(); verify(TextFieldTag.class.getResource("Textfield-8.txt")); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + TextFieldTag freshTag = new TextFieldTag(); + freshTag.setPageContext(pageContext); + assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", + strutsBodyTagsAreReflectionEqual(tag, freshTag)); } public void testErrorPositionTop() throws Exception { @@ -250,6 +314,13 @@ public class TextfieldTest extends AbstractUITagTest { tag.doEndTag(); verify(TextFieldTag.class.getResource("Textfield-9.txt")); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + TextFieldTag freshTag = new TextFieldTag(); + freshTag.setPageContext(pageContext); + assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", + strutsBodyTagsAreReflectionEqual(tag, freshTag)); } public void testRequiredLabelPositionDefault() throws Exception { @@ -268,6 +339,13 @@ public class TextfieldTest extends AbstractUITagTest { tag.doEndTag(); verify(TextFieldTag.class.getResource("Textfield-12.txt")); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + TextFieldTag freshTag = new TextFieldTag(); + freshTag.setPageContext(pageContext); + assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", + strutsBodyTagsAreReflectionEqual(tag, freshTag)); } public void testRequiredLabelPositionRight() throws Exception { @@ -287,6 +365,13 @@ public class TextfieldTest extends AbstractUITagTest { tag.doEndTag(); verify(TextFieldTag.class.getResource("Textfield-12.txt")); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + TextFieldTag freshTag = new TextFieldTag(); + freshTag.setPageContext(pageContext); + assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", + strutsBodyTagsAreReflectionEqual(tag, freshTag)); } public void testRequiredLabelPositionLeft() throws Exception { @@ -306,6 +391,13 @@ public class TextfieldTest extends AbstractUITagTest { tag.doEndTag(); verify(TextFieldTag.class.getResource("Textfield-13.txt")); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + TextFieldTag freshTag = new TextFieldTag(); + freshTag.setPageContext(pageContext); + assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", + strutsBodyTagsAreReflectionEqual(tag, freshTag)); } public void testErrorPositionBottomCssXhtmlTheme() throws Exception { @@ -327,6 +419,13 @@ public class TextfieldTest extends AbstractUITagTest { tag.doEndTag(); verify(TextFieldTag.class.getResource("Textfield-10.txt")); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + TextFieldTag freshTag = new TextFieldTag(); + freshTag.setPageContext(pageContext); + assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", + strutsBodyTagsAreReflectionEqual(tag, freshTag)); } public void testErrorPositionTopCssXhtmlTheme() throws Exception { @@ -348,6 +447,13 @@ public class TextfieldTest extends AbstractUITagTest { tag.doEndTag(); verify(TextFieldTag.class.getResource("Textfield-11.txt")); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + TextFieldTag freshTag = new TextFieldTag(); + freshTag.setPageContext(pageContext); + assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", + strutsBodyTagsAreReflectionEqual(tag, freshTag)); } public void testNameEvaluation() throws Exception { @@ -363,6 +469,13 @@ public class TextfieldTest extends AbstractUITagTest { tag.doEndTag(); verify(TextFieldTag.class.getResource("Textfield-14.txt")); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + TextFieldTag freshTag = new TextFieldTag(); + freshTag.setPageContext(pageContext); + assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", + strutsBodyTagsAreReflectionEqual(tag, freshTag)); } diff --git a/core/src/test/java/org/apache/struts2/views/jsp/ui/TokenTagTest.java b/core/src/test/java/org/apache/struts2/views/jsp/ui/TokenTagTest.java index 1d2b42f3f..a2eb22fdb 100644 --- a/core/src/test/java/org/apache/struts2/views/jsp/ui/TokenTagTest.java +++ b/core/src/test/java/org/apache/struts2/views/jsp/ui/TokenTagTest.java @@ -87,6 +87,13 @@ public class TokenTagTest extends AbstractUITagTest { assertNotNull(token); final String sessionTokenName = TokenHelper.buildTokenSessionAttributeName(tokenName); assertEquals(token, pageContext.getSession().getAttribute(sessionTokenName)); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + TokenTag freshTag = new TokenTag(); + freshTag.setPageContext(pageContext); + assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", + strutsBodyTagsAreReflectionEqual(tag, freshTag)); } catch (JspException e) { e.printStackTrace(); fail(); diff --git a/core/src/test/java/org/apache/struts2/views/jsp/ui/TooltipTest.java b/core/src/test/java/org/apache/struts2/views/jsp/ui/TooltipTest.java index 8c8d8e1c8..6a8578023 100644 --- a/core/src/test/java/org/apache/struts2/views/jsp/ui/TooltipTest.java +++ b/core/src/test/java/org/apache/struts2/views/jsp/ui/TooltipTest.java @@ -64,6 +64,20 @@ public class TooltipTest extends AbstractUITagTest { formTag.doEndTag(); verify(TooltipTest.class.getResource("tooltip-1.txt")); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + TextFieldTag freshTag = new TextFieldTag(); + freshTag.setPageContext(pageContext); + assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", + strutsBodyTagsAreReflectionEqual(tag, freshTag)); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + FormTag freshFormTag = new FormTag(); + freshFormTag.setPageContext(pageContext); + assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", + strutsBodyTagsAreReflectionEqual(formTag, freshFormTag)); } public void testWithoutFormOverridingNoJS() throws Exception { @@ -98,6 +112,20 @@ public class TooltipTest extends AbstractUITagTest { formTag.doEndTag(); verify(TooltipTest.class.getResource("tooltip-4.txt")); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + TextFieldTag freshTag = new TextFieldTag(); + freshTag.setPageContext(pageContext); + assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", + strutsBodyTagsAreReflectionEqual(tag, freshTag)); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + FormTag freshFormTag = new FormTag(); + freshFormTag.setPageContext(pageContext); + assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", + strutsBodyTagsAreReflectionEqual(formTag, freshFormTag)); } public void testWithoutFormOverridingNew() throws Exception { @@ -130,6 +158,20 @@ public class TooltipTest extends AbstractUITagTest { formTag.doEndTag(); verify(TooltipTest.class.getResource("tooltip-1.txt")); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + TextFieldTag freshTag = new TextFieldTag(); + freshTag.setPageContext(pageContext); + assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", + strutsBodyTagsAreReflectionEqual(tag, freshTag)); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + FormTag freshFormTag = new FormTag(); + freshFormTag.setPageContext(pageContext); + assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", + strutsBodyTagsAreReflectionEqual(formTag, freshFormTag)); } public void testWithFormOverriding() throws Exception { @@ -162,6 +204,20 @@ public class TooltipTest extends AbstractUITagTest { formTag.doEndTag(); verify(TooltipTest.class.getResource("tooltip-2.txt")); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + TextFieldTag freshTag = new TextFieldTag(); + freshTag.setPageContext(pageContext); + assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", + strutsBodyTagsAreReflectionEqual(tag, freshTag)); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + FormTag freshFormTag = new FormTag(); + freshFormTag.setPageContext(pageContext); + assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", + strutsBodyTagsAreReflectionEqual(formTag, freshFormTag)); } public void testWithFormOverridingNew() throws Exception { @@ -192,6 +248,20 @@ public class TooltipTest extends AbstractUITagTest { formTag.doEndTag(); verify(TooltipTest.class.getResource("tooltip-2.txt")); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + TextFieldTag freshTag = new TextFieldTag(); + freshTag.setPageContext(pageContext); + assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", + strutsBodyTagsAreReflectionEqual(tag, freshTag)); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + FormTag freshFormTag = new FormTag(); + freshFormTag.setPageContext(pageContext); + assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", + strutsBodyTagsAreReflectionEqual(formTag, freshFormTag)); } public void testWithPartialFormOverriding() throws Exception { @@ -230,6 +300,20 @@ public class TooltipTest extends AbstractUITagTest { formTag.doEndTag(); verify(TooltipTest.class.getResource("tooltip-3.txt")); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + TextFieldTag freshTag = new TextFieldTag(); + freshTag.setPageContext(pageContext); + assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", + strutsBodyTagsAreReflectionEqual(tag, freshTag)); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + FormTag freshFormTag = new FormTag(); + freshFormTag.setPageContext(pageContext); + assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", + strutsBodyTagsAreReflectionEqual(formTag, freshFormTag)); } public void testWithPartialFormOverridingNew() throws Exception { @@ -265,6 +349,20 @@ public class TooltipTest extends AbstractUITagTest { formTag.doEndTag(); verify(TooltipTest.class.getResource("tooltip-3.txt")); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + TextFieldTag freshTag = new TextFieldTag(); + freshTag.setPageContext(pageContext); + assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", + strutsBodyTagsAreReflectionEqual(tag, freshTag)); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + FormTag freshFormTag = new FormTag(); + freshFormTag.setPageContext(pageContext); + assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", + strutsBodyTagsAreReflectionEqual(formTag, freshFormTag)); } public void testUsingParamValueToSetConfigurations() throws Exception { @@ -313,6 +411,20 @@ public class TooltipTest extends AbstractUITagTest { formTag.doEndTag(); verify(TooltipTest.class.getResource("tooltip-3.txt")); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + TextFieldTag freshTag = new TextFieldTag(); + freshTag.setPageContext(pageContext); + assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", + strutsBodyTagsAreReflectionEqual(tag, freshTag)); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + FormTag freshFormTag = new FormTag(); + freshFormTag.setPageContext(pageContext); + assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", + strutsBodyTagsAreReflectionEqual(formTag, freshFormTag)); } @@ -365,8 +477,30 @@ public class TooltipTest extends AbstractUITagTest { System.out.println(writer.toString()); verify(TooltipTest.class.getResource("tooltip-3.txt")); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + TextFieldTag freshTag = new TextFieldTag(); + freshTag.setPageContext(pageContext); + assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", + strutsBodyTagsAreReflectionEqual(tag, freshTag)); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + ParamTag freshParamTag = new ParamTag(); + freshParamTag.setPageContext(pageContext); + assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", + strutsBodyTagsAreReflectionEqual(textFieldParamTag, freshParamTag)); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + FormTag freshFormTag = new FormTag(); + freshFormTag.setPageContext(pageContext); + assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", + strutsBodyTagsAreReflectionEqual(formTag, freshFormTag)); } + @Override public void setUp() throws Exception { super.setUp(); diff --git a/core/src/test/java/org/apache/struts2/views/jsp/ui/UpDownSelectTagTest.java b/core/src/test/java/org/apache/struts2/views/jsp/ui/UpDownSelectTagTest.java index f35fa18f1..f71fa2826 100644 --- a/core/src/test/java/org/apache/struts2/views/jsp/ui/UpDownSelectTagTest.java +++ b/core/src/test/java/org/apache/struts2/views/jsp/ui/UpDownSelectTagTest.java @@ -48,6 +48,13 @@ public class UpDownSelectTagTest extends AbstractUITagTest { tag.doEndTag(); verify(UpDownSelectTagTest.class.getResource("updownselecttag-1.txt")); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + UpDownSelectTag freshTag = new UpDownSelectTag(); + freshTag.setPageContext(pageContext); + assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", + strutsBodyTagsAreReflectionEqual(tag, freshTag)); } public void testWithPartialSelected() throws Exception { @@ -66,6 +73,13 @@ public class UpDownSelectTagTest extends AbstractUITagTest { tag.doEndTag(); verify(UpDownSelectTagTest.class.getResource("updownselecttag-2.txt")); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + UpDownSelectTag freshTag = new UpDownSelectTag(); + freshTag.setPageContext(pageContext); + assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", + strutsBodyTagsAreReflectionEqual(tag, freshTag)); } public void testWithHeaderAndEmptyOption() throws Exception { @@ -84,6 +98,13 @@ public class UpDownSelectTagTest extends AbstractUITagTest { tag.doEndTag(); verify(UpDownSelectTagTest.class.getResource("updownselecttag-3.txt")); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + UpDownSelectTag freshTag = new UpDownSelectTag(); + freshTag.setPageContext(pageContext); + assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", + strutsBodyTagsAreReflectionEqual(tag, freshTag)); } public void testWithHeaderOnly() throws Exception { @@ -102,6 +123,13 @@ public class UpDownSelectTagTest extends AbstractUITagTest { tag.doEndTag(); verify(UpDownSelectTagTest.class.getResource("updownselecttag-4.txt")); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + UpDownSelectTag freshTag = new UpDownSelectTag(); + freshTag.setPageContext(pageContext); + assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", + strutsBodyTagsAreReflectionEqual(tag, freshTag)); } public void testWithEmptyOptionOnly() throws Exception { @@ -118,6 +146,13 @@ public class UpDownSelectTagTest extends AbstractUITagTest { tag.doEndTag(); verify(UpDownSelectTagTest.class.getResource("updownselecttag-5.txt")); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + UpDownSelectTag freshTag = new UpDownSelectTag(); + freshTag.setPageContext(pageContext); + assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", + strutsBodyTagsAreReflectionEqual(tag, freshTag)); } @@ -136,6 +171,13 @@ public class UpDownSelectTagTest extends AbstractUITagTest { tag.doEndTag(); verify(UpDownSelectTagTest.class.getResource("updownselecttag-6.txt")); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + UpDownSelectTag freshTag = new UpDownSelectTag(); + freshTag.setPageContext(pageContext); + assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", + strutsBodyTagsAreReflectionEqual(tag, freshTag)); } public void testDisableMoveUpButton() throws Exception { @@ -152,6 +194,13 @@ public class UpDownSelectTagTest extends AbstractUITagTest { tag.doEndTag(); verify(UpDownSelectTagTest.class.getResource("updownselecttag-7.txt")); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + UpDownSelectTag freshTag = new UpDownSelectTag(); + freshTag.setPageContext(pageContext); + assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", + strutsBodyTagsAreReflectionEqual(tag, freshTag)); } public void testDisableMoveDownButton() throws Exception { @@ -168,6 +217,13 @@ public class UpDownSelectTagTest extends AbstractUITagTest { tag.doEndTag(); verify(UpDownSelectTagTest.class.getResource("updownselecttag-8.txt")); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + UpDownSelectTag freshTag = new UpDownSelectTag(); + freshTag.setPageContext(pageContext); + assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", + strutsBodyTagsAreReflectionEqual(tag, freshTag)); } public void testChangeSelectAllButtonText() throws Exception { @@ -184,6 +240,13 @@ public class UpDownSelectTagTest extends AbstractUITagTest { tag.doEndTag(); verify(UpDownSelectTagTest.class.getResource("updownselecttag-9.txt")); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + UpDownSelectTag freshTag = new UpDownSelectTag(); + freshTag.setPageContext(pageContext); + assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", + strutsBodyTagsAreReflectionEqual(tag, freshTag)); } public void testChangeMoveUpButtonText() throws Exception { @@ -200,6 +263,13 @@ public class UpDownSelectTagTest extends AbstractUITagTest { tag.doEndTag(); verify(UpDownSelectTagTest.class.getResource("updownselecttag-10.txt")); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + UpDownSelectTag freshTag = new UpDownSelectTag(); + freshTag.setPageContext(pageContext); + assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", + strutsBodyTagsAreReflectionEqual(tag, freshTag)); } public void testChangeMoveDownButtonText() throws Exception { @@ -216,6 +286,13 @@ public class UpDownSelectTagTest extends AbstractUITagTest { tag.doEndTag(); verify(UpDownSelectTagTest.class.getResource("updownselecttag-11.txt")); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + UpDownSelectTag freshTag = new UpDownSelectTag(); + freshTag.setPageContext(pageContext); + assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", + strutsBodyTagsAreReflectionEqual(tag, freshTag)); } public void testGenericSimple() throws Exception { @@ -237,6 +314,7 @@ public class UpDownSelectTagTest extends AbstractUITagTest { // =============================== + @Override public Action getAction() { return new ActionSupport() { diff --git a/core/src/test/java/org/apache/struts2/views/jsp/ui/ValidationStylesTest.java b/core/src/test/java/org/apache/struts2/views/jsp/ui/ValidationStylesTest.java index 07f54916a..de7632455 100644 --- a/core/src/test/java/org/apache/struts2/views/jsp/ui/ValidationStylesTest.java +++ b/core/src/test/java/org/apache/struts2/views/jsp/ui/ValidationStylesTest.java @@ -30,6 +30,13 @@ public class ValidationStylesTest extends AbstractUITagTest { tag.doEndTag(); verify(ValidationStylesTest.class.getResource("validationstyles-1.txt")); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + TextFieldTag freshTag = new TextFieldTag(); + freshTag.setPageContext(pageContext); + assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", + strutsBodyTagsAreReflectionEqual(tag, freshTag)); } public void testErrorStyle() throws Exception { @@ -38,6 +45,13 @@ public class ValidationStylesTest extends AbstractUITagTest { tag.doEndTag(); verify(ValidationStylesTest.class.getResource("validationstyles-2.txt")); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + TextFieldTag freshTag = new TextFieldTag(); + freshTag.setPageContext(pageContext); + assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", + strutsBodyTagsAreReflectionEqual(tag, freshTag)); } public void testErrorClass() throws Exception { @@ -46,6 +60,13 @@ public class ValidationStylesTest extends AbstractUITagTest { tag.doEndTag(); verify(ValidationStylesTest.class.getResource("validationstyles-3.txt")); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + TextFieldTag freshTag = new TextFieldTag(); + freshTag.setPageContext(pageContext); + assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", + strutsBodyTagsAreReflectionEqual(tag, freshTag)); } public void testStyleAndErrorStyle() throws Exception { @@ -55,6 +76,13 @@ public class ValidationStylesTest extends AbstractUITagTest { tag.doEndTag(); verify(ValidationStylesTest.class.getResource("validationstyles-2.txt")); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + TextFieldTag freshTag = new TextFieldTag(); + freshTag.setPageContext(pageContext); + assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", + strutsBodyTagsAreReflectionEqual(tag, freshTag)); } public void testStyleAndErrorClass() throws Exception { @@ -64,6 +92,13 @@ public class ValidationStylesTest extends AbstractUITagTest { tag.doEndTag(); verify(ValidationStylesTest.class.getResource("validationstyles-3.txt")); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + TextFieldTag freshTag = new TextFieldTag(); + freshTag.setPageContext(pageContext); + assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", + strutsBodyTagsAreReflectionEqual(tag, freshTag)); } @Override From d08f4af635d6eee2141cde6ecf9df26c08a8639f Mon Sep 17 00:00:00 2001 From: JCgH4164838Gh792C124B5 <43964333+JCgH4164838Gh792C124B5@users.noreply.github.com> Date: Sat, 30 Oct 2021 16:08:51 -0400 Subject: [PATCH 2/7] Update: - Introduced performClearTagStateForTagPoolingServers flag to S2 Tags and compontents to make the tag state clearing optional. By default, the value is false, so the default behaviour should be identical to before. When set to true, it should only apply to a particular tag, providing a granular control to the developer. - Made clearTagStateForTagPoolingServers() calls consistently protected. - Updated and added unit tests to test behaviour with the clear tag state set both false and true. # Conflicts: # core/src/main/java/org/apache/struts2/views/jsp/ui/AnchorTag.java # core/src/main/java/org/apache/struts2/views/jsp/ui/CheckboxTag.java # core/src/main/java/org/apache/struts2/views/jsp/ui/SubmitTag.java # core/src/test/java/org/apache/struts2/views/jsp/TextTagTest.java # core/src/test/java/org/apache/struts2/views/jsp/URLTagTest.java # core/src/test/java/org/apache/struts2/views/jsp/ui/DoubleSelectTest.java # core/src/test/java/org/apache/struts2/views/jsp/ui/FormTagTest.java - Manually attempted to resolve conflicsts. --- .../apache/struts2/components/Component.java | 21 + .../apache/struts2/views/jsp/ActionTag.java | 13 +- .../org/apache/struts2/views/jsp/BeanTag.java | 13 +- .../views/jsp/ComponentTagSupport.java | 27 +- .../struts2/views/jsp/ContextBeanTag.java | 13 +- .../org/apache/struts2/views/jsp/DateTag.java | 13 +- .../apache/struts2/views/jsp/ElseIfTag.java | 14 +- .../org/apache/struts2/views/jsp/ElseTag.java | 9 + .../org/apache/struts2/views/jsp/I18nTag.java | 13 +- .../org/apache/struts2/views/jsp/IfTag.java | 14 +- .../apache/struts2/views/jsp/IncludeTag.java | 13 +- .../apache/struts2/views/jsp/IteratorTag.java | 15 +- .../apache/struts2/views/jsp/NumberTag.java | 15 +- .../apache/struts2/views/jsp/ParamTag.java | 13 +- .../apache/struts2/views/jsp/PropertyTag.java | 13 +- .../org/apache/struts2/views/jsp/PushTag.java | 13 +- .../org/apache/struts2/views/jsp/SetTag.java | 15 +- .../views/jsp/StrutsBodyTagSupport.java | 42 +- .../org/apache/struts2/views/jsp/TextTag.java | 15 +- .../org/apache/struts2/views/jsp/URLTag.java | 15 +- .../views/jsp/iterator/AppendIteratorTag.java | 8 + .../jsp/iterator/IteratorGeneratorTag.java | 11 +- .../views/jsp/iterator/MergeIteratorTag.java | 9 + .../views/jsp/iterator/SortIteratorTag.java | 11 +- .../views/jsp/iterator/SubsetIteratorTag.java | 11 +- .../views/jsp/ui/AbstractClosingTag.java | 15 +- .../views/jsp/ui/AbstractDoubleListTag.java | 15 +- .../struts2/views/jsp/ui/AbstractListTag.java | 15 +- .../views/jsp/ui/AbstractRequiredListTag.java | 8 + .../struts2/views/jsp/ui/AbstractUITag.java | 16 +- .../struts2/views/jsp/ui/ActionErrorTag.java | 15 +- .../views/jsp/ui/ActionMessageTag.java | 15 +- .../struts2/views/jsp/ui/AnchorTag.java | 13 +- .../struts2/views/jsp/ui/CheckboxListTag.java | 9 + .../struts2/views/jsp/ui/CheckboxTag.java | 13 +- .../struts2/views/jsp/ui/ComboBoxTag.java | 15 +- .../struts2/views/jsp/ui/ComponentTag.java | 9 + .../views/jsp/ui/DateTextFieldTag.java | 15 +- .../apache/struts2/views/jsp/ui/DebugTag.java | 8 + .../struts2/views/jsp/ui/DoubleSelectTag.java | 10 + .../struts2/views/jsp/ui/FieldErrorTag.java | 15 +- .../apache/struts2/views/jsp/ui/FileTag.java | 15 +- .../apache/struts2/views/jsp/ui/FormTag.java | 15 +- .../apache/struts2/views/jsp/ui/HeadTag.java | 9 + .../struts2/views/jsp/ui/HiddenTag.java | 9 + .../views/jsp/ui/InputTransferSelectTag.java | 15 +- .../apache/struts2/views/jsp/ui/LabelTag.java | 15 +- .../struts2/views/jsp/ui/OptGroupTag.java | 13 +- .../views/jsp/ui/OptionTransferSelectTag.java | 15 +- .../struts2/views/jsp/ui/PasswordTag.java | 15 +- .../apache/struts2/views/jsp/ui/RadioTag.java | 9 + .../apache/struts2/views/jsp/ui/ResetTag.java | 15 +- .../struts2/views/jsp/ui/SelectTag.java | 15 +- .../struts2/views/jsp/ui/SubmitTag.java | 13 +- .../struts2/views/jsp/ui/TextFieldTag.java | 15 +- .../struts2/views/jsp/ui/TextareaTag.java | 15 +- .../apache/struts2/views/jsp/ui/TokenTag.java | 10 + .../struts2/views/jsp/ui/UpDownSelectTag.java | 13 +- .../struts2/views/jsp/AbstractTagTest.java | 18 + .../struts2/views/jsp/ActionTagTest.java | 361 ++++- .../struts2/views/jsp/AnchorTagTest.java | 916 ++++++++++++- .../views/jsp/AppendIteratorTagTest.java | 176 ++- .../apache/struts2/views/jsp/BeanTagTest.java | 36 +- .../struts2/views/jsp/ElseIfTagTest.java | 116 +- .../apache/struts2/views/jsp/ElseTagTest.java | 106 +- .../apache/struts2/views/jsp/I18nTagTest.java | 54 +- .../apache/struts2/views/jsp/IfTagTest.java | 535 +++++++- .../struts2/views/jsp/IncludeTagTest.java | 173 ++- .../views/jsp/IteratorGeneratorTagTest.java | 210 ++- .../struts2/views/jsp/IteratorTagTest.java | 302 ++++- .../views/jsp/MergeIteratorTagTest.java | 175 ++- .../struts2/views/jsp/NumberTagTest.java | 136 +- .../struts2/views/jsp/PropertyTagTest.java | 496 ++++++- .../apache/struts2/views/jsp/PushTagTest.java | 32 +- .../apache/struts2/views/jsp/SetTagTest.java | 217 ++- .../views/jsp/SortIteratorTagTest.java | 137 +- .../views/jsp/SubsetIteratorTagTest.java | 334 ++++- .../apache/struts2/views/jsp/TextTagTest.java | 532 +++++++- .../apache/struts2/views/jsp/URLTagTest.java | 1191 ++++++++++++++++- .../views/jsp/ui/ActionErrorTagTest.java | 154 ++- .../views/jsp/ui/ActionMessageTagTest.java | 154 ++- .../struts2/views/jsp/ui/AnchorTest.java | 98 +- .../views/jsp/ui/CheckboxListTest.java | 150 ++- .../struts2/views/jsp/ui/CheckboxTest.java | 224 +++- .../struts2/views/jsp/ui/ComboBoxTest.java | 146 +- .../struts2/views/jsp/ui/ComponentTest.java | 132 +- .../struts2/views/jsp/ui/DateTagTest.java | 470 ++++++- .../struts2/views/jsp/ui/DebugTagTest.java | 90 +- .../views/jsp/ui/DoubleSelectTest.java | 292 +++- .../views/jsp/ui/FieldErrorTagTest.java | 461 ++++++- .../apache/struts2/views/jsp/ui/FileTest.java | 31 +- .../struts2/views/jsp/ui/FormTagTest.java | 1168 +++++++++++++++- .../struts2/views/jsp/ui/HeadTagTest.java | 23 +- .../struts2/views/jsp/ui/HiddenTest.java | 125 +- .../jsp/ui/InputTransferSelectTagTest.java | 33 +- .../struts2/views/jsp/ui/JspTemplateTest.java | 26 + .../struts2/views/jsp/ui/LabelTest.java | 247 +++- .../struts2/views/jsp/ui/OptGroupTest.java | 515 ++++++- .../jsp/ui/OptionTransferSelectTagTest.java | 580 +++++++- .../struts2/views/jsp/ui/PasswordTest.java | 28 +- .../struts2/views/jsp/ui/RadioTest.java | 268 +++- .../struts2/views/jsp/ui/ResetTest.java | 300 ++++- .../struts2/views/jsp/ui/SelectTest.java | 692 +++++++++- .../struts2/views/jsp/ui/SubmitTest.java | 334 ++++- .../struts2/views/jsp/ui/TextareaTest.java | 38 +- .../struts2/views/jsp/ui/TextfieldTest.java | 487 ++++++- .../struts2/views/jsp/ui/TokenTagTest.java | 59 +- .../struts2/views/jsp/ui/TooltipTest.java | 567 +++++++- .../views/jsp/ui/UpDownSelectTagTest.java | 312 ++++- .../views/jsp/ui/ValidationStylesTest.java | 102 +- 110 files changed, 14774 insertions(+), 586 deletions(-) diff --git a/core/src/main/java/org/apache/struts2/components/Component.java b/core/src/main/java/org/apache/struts2/components/Component.java index e20b4f5e8..37d38fd2d 100644 --- a/core/src/main/java/org/apache/struts2/components/Component.java +++ b/core/src/main/java/org/apache/struts2/components/Component.java @@ -71,6 +71,7 @@ public class Component { protected Map parameters; protected ActionMapper actionMapper; protected boolean throwExceptionOnELFailure; + protected boolean performClearTagStateForTagPoolingServers = false; private UrlHelper urlHelper; /** @@ -571,4 +572,24 @@ public class Component { return standardAttributes; } + /** + * Request that the tag state be cleared during {@link org.apache.struts2.views.jsp.StrutsBodyTagSupport#doEndTag()} processing, + * which may help with certain edge cases with tag logic running on servers that implement JSP Tag Pooling. + * + * Note: All Tag classes that extend {@link org.apache.struts2.views.jsp.StrutsBodyTagSupport} must implement a setter for + * this attribute (same name), and it must be defined at the Tag class level. + * Defining a setter in the superclass alone is insufficient (results in "Cannot find a setter method for the attribute"). + * + * See {@link org.apache.struts2.views.jsp.StrutsBodyTagSupport#clearTagStateForTagPoolingServers() for additional details. + * + * @param performClearTagStateForTagPoolingServers true if tag state should be cleared, false otherwise. + */ + @StrutsTagAttribute(description="Whether to clear all tag state during doEndTag() processing (if applicable)", type="Boolean", defaultValue="false", required = false) + public void setPerformClearTagStateForTagPoolingServers(boolean performClearTagStateForTagPoolingServers) { + this.performClearTagStateForTagPoolingServers = performClearTagStateForTagPoolingServers; + } + + public boolean getPerformClearTagStateForTagPoolingServers() { + return this.performClearTagStateForTagPoolingServers; + } } diff --git a/core/src/main/java/org/apache/struts2/views/jsp/ActionTag.java b/core/src/main/java/org/apache/struts2/views/jsp/ActionTag.java index b298941eb..7478a1258 100644 --- a/core/src/main/java/org/apache/struts2/views/jsp/ActionTag.java +++ b/core/src/main/java/org/apache/struts2/views/jsp/ActionTag.java @@ -91,7 +91,18 @@ public class ActionTag extends ContextBeanTag { } @Override - public void clearTagStateForTagPoolingServers() { + /** + * Must declare the setter at the descendant Tag class level in order for the tag handler to locate the method. + */ + public void setPerformClearTagStateForTagPoolingServers(boolean performClearTagStateForTagPoolingServers) { + super.setPerformClearTagStateForTagPoolingServers(performClearTagStateForTagPoolingServers); + } + + @Override + protected void clearTagStateForTagPoolingServers() { + if (getPerformClearTagStateForTagPoolingServers() == false) { + return; // If flag is false (default setting), do not perform any state clearing. + } super.clearTagStateForTagPoolingServers(); this.name = null; this.namespace = null; diff --git a/core/src/main/java/org/apache/struts2/views/jsp/BeanTag.java b/core/src/main/java/org/apache/struts2/views/jsp/BeanTag.java index a0535cdd9..363078be3 100644 --- a/core/src/main/java/org/apache/struts2/views/jsp/BeanTag.java +++ b/core/src/main/java/org/apache/struts2/views/jsp/BeanTag.java @@ -56,7 +56,18 @@ public class BeanTag extends ContextBeanTag { } @Override - public void clearTagStateForTagPoolingServers() { + /** + * Must declare the setter at the descendant Tag class level in order for the tag handler to locate the method. + */ + public void setPerformClearTagStateForTagPoolingServers(boolean performClearTagStateForTagPoolingServers) { + super.setPerformClearTagStateForTagPoolingServers(performClearTagStateForTagPoolingServers); + } + + @Override + protected void clearTagStateForTagPoolingServers() { + if (getPerformClearTagStateForTagPoolingServers() == false) { + return; // If flag is false (default setting), do not perform any state clearing. + } super.clearTagStateForTagPoolingServers(); this.name = null; } diff --git a/core/src/main/java/org/apache/struts2/views/jsp/ComponentTagSupport.java b/core/src/main/java/org/apache/struts2/views/jsp/ComponentTagSupport.java index ee7a9b650..73bba2ea6 100644 --- a/core/src/main/java/org/apache/struts2/views/jsp/ComponentTagSupport.java +++ b/core/src/main/java/org/apache/struts2/views/jsp/ComponentTagSupport.java @@ -38,7 +38,8 @@ public abstract class ComponentTagSupport extends StrutsBodyTagSupport { @Override public int doEndTag() throws JspException { component.end(pageContext.getOut(), getBody()); - clearTagStateForTagPoolingServers(); // Moved the component reference clear into this method call. + component = null; // Always clear component reference (since clearTagStateForTagPoolingServers() is conditional). + clearTagStateForTagPoolingServers(); return EVAL_PAGE; } @@ -59,7 +60,26 @@ public abstract class ComponentTagSupport extends StrutsBodyTagSupport { } } + /** + * Define method to populate component state based on the Tag parameters. + * + * Descendants should override this method for custom behaviour, but should always call the ancestor method when doing so. + */ protected void populateParams() { + populatePerformClearTagStateForTagPoolingServersParam(); + } + + /** + * Specialized method to populate the performClearTagStateForTagPoolingServers state of the Component to match the value set in the Tag. + * + * Generally only unit tests would call this method directly, to avoid calling the whole populateParams() chain again after doStartTag() + * has been called. Doing that can break tag / component state behaviour, but unit tests still need a way to set the + * performClearTagStateForTagPoolingServers state for the component (which only comes into being after doStartTag() is called). + */ + protected void populatePerformClearTagStateForTagPoolingServersParam() { + if (component != null) { + component.setPerformClearTagStateForTagPoolingServers(super.getPerformClearTagStateForTagPoolingServers()); + } } public Component getComponent() { @@ -68,8 +88,11 @@ public abstract class ComponentTagSupport extends StrutsBodyTagSupport { @Override protected void clearTagStateForTagPoolingServers() { + if (getPerformClearTagStateForTagPoolingServers() == false) { + return; // If flag is false (default setting), do not perform any state clearing. + } super.clearTagStateForTagPoolingServers(); - component = null; + component = null; // Duplicate clear, kept for consistency. } } diff --git a/core/src/main/java/org/apache/struts2/views/jsp/ContextBeanTag.java b/core/src/main/java/org/apache/struts2/views/jsp/ContextBeanTag.java index 790e65ca7..bfebf6cf7 100644 --- a/core/src/main/java/org/apache/struts2/views/jsp/ContextBeanTag.java +++ b/core/src/main/java/org/apache/struts2/views/jsp/ContextBeanTag.java @@ -37,7 +37,18 @@ public abstract class ContextBeanTag extends ComponentTagSupport { } @Override - public void clearTagStateForTagPoolingServers() { + /** + * Must declare the setter at the descendant Tag class level in order for the tag handler to locate the method. + */ + public void setPerformClearTagStateForTagPoolingServers(boolean performClearTagStateForTagPoolingServers) { + super.setPerformClearTagStateForTagPoolingServers(performClearTagStateForTagPoolingServers); + } + + @Override + protected void clearTagStateForTagPoolingServers() { + if (getPerformClearTagStateForTagPoolingServers() == false) { + return; // If flag is false (default setting), do not perform any state clearing. + } super.clearTagStateForTagPoolingServers(); this.var = null; } diff --git a/core/src/main/java/org/apache/struts2/views/jsp/DateTag.java b/core/src/main/java/org/apache/struts2/views/jsp/DateTag.java index a9dabc8b4..70681cf98 100644 --- a/core/src/main/java/org/apache/struts2/views/jsp/DateTag.java +++ b/core/src/main/java/org/apache/struts2/views/jsp/DateTag.java @@ -69,7 +69,18 @@ public class DateTag extends ContextBeanTag { } @Override - public void clearTagStateForTagPoolingServers() { + /** + * Must declare the setter at the descendant Tag class level in order for the tag handler to locate the method. + */ + public void setPerformClearTagStateForTagPoolingServers(boolean performClearTagStateForTagPoolingServers) { + super.setPerformClearTagStateForTagPoolingServers(performClearTagStateForTagPoolingServers); + } + + @Override + protected void clearTagStateForTagPoolingServers() { + if (getPerformClearTagStateForTagPoolingServers() == false) { + return; // If flag is false (default setting), do not perform any state clearing. + } super.clearTagStateForTagPoolingServers(); this.name = null; this.format = null; diff --git a/core/src/main/java/org/apache/struts2/views/jsp/ElseIfTag.java b/core/src/main/java/org/apache/struts2/views/jsp/ElseIfTag.java index acc438f18..659a6cd23 100644 --- a/core/src/main/java/org/apache/struts2/views/jsp/ElseIfTag.java +++ b/core/src/main/java/org/apache/struts2/views/jsp/ElseIfTag.java @@ -42,6 +42,7 @@ public class ElseIfTag extends ComponentTagSupport { @Override protected void populateParams() { + super.populateParams(); ((ElseIf) getComponent()).setTest(test); } @@ -50,7 +51,18 @@ public class ElseIfTag extends ComponentTagSupport { } @Override - public void clearTagStateForTagPoolingServers() { + /** + * Must declare the setter at the descendant Tag class level in order for the tag handler to locate the method. + */ + public void setPerformClearTagStateForTagPoolingServers(boolean performClearTagStateForTagPoolingServers) { + super.setPerformClearTagStateForTagPoolingServers(performClearTagStateForTagPoolingServers); + } + + @Override + protected void clearTagStateForTagPoolingServers() { + if (getPerformClearTagStateForTagPoolingServers() == false) { + return; // If flag is false (default setting), do not perform any state clearing. + } super.clearTagStateForTagPoolingServers(); this.test = null; } diff --git a/core/src/main/java/org/apache/struts2/views/jsp/ElseTag.java b/core/src/main/java/org/apache/struts2/views/jsp/ElseTag.java index f15bab78b..343105a83 100644 --- a/core/src/main/java/org/apache/struts2/views/jsp/ElseTag.java +++ b/core/src/main/java/org/apache/struts2/views/jsp/ElseTag.java @@ -33,7 +33,16 @@ public class ElseTag extends ComponentTagSupport { private static final long serialVersionUID = 8166807953193406785L; + @Override public Component getBean(ValueStack stack, HttpServletRequest req, HttpServletResponse res) { return new Else(stack); } + + @Override + /** + * Must declare the setter at the descendant Tag class level in order for the tag handler to locate the method. + */ + public void setPerformClearTagStateForTagPoolingServers(boolean performClearTagStateForTagPoolingServers) { + super.setPerformClearTagStateForTagPoolingServers(performClearTagStateForTagPoolingServers); + } } diff --git a/core/src/main/java/org/apache/struts2/views/jsp/I18nTag.java b/core/src/main/java/org/apache/struts2/views/jsp/I18nTag.java index f58c4d248..14b46b7fc 100644 --- a/core/src/main/java/org/apache/struts2/views/jsp/I18nTag.java +++ b/core/src/main/java/org/apache/struts2/views/jsp/I18nTag.java @@ -52,7 +52,18 @@ public class I18nTag extends ComponentTagSupport { } @Override - public void clearTagStateForTagPoolingServers() { + /** + * Must declare the setter at the descendant Tag class level in order for the tag handler to locate the method. + */ + public void setPerformClearTagStateForTagPoolingServers(boolean performClearTagStateForTagPoolingServers) { + super.setPerformClearTagStateForTagPoolingServers(performClearTagStateForTagPoolingServers); + } + + @Override + protected void clearTagStateForTagPoolingServers() { + if (getPerformClearTagStateForTagPoolingServers() == false) { + return; // If flag is false (default setting), do not perform any state clearing. + } super.clearTagStateForTagPoolingServers(); this.name = null; } diff --git a/core/src/main/java/org/apache/struts2/views/jsp/IfTag.java b/core/src/main/java/org/apache/struts2/views/jsp/IfTag.java index 5a2373f6c..7621656c2 100644 --- a/core/src/main/java/org/apache/struts2/views/jsp/IfTag.java +++ b/core/src/main/java/org/apache/struts2/views/jsp/IfTag.java @@ -42,6 +42,7 @@ public class IfTag extends ComponentTagSupport { @Override protected void populateParams() { + super.populateParams(); ((If) getComponent()).setTest(test); } @@ -50,7 +51,18 @@ public class IfTag extends ComponentTagSupport { } @Override - public void clearTagStateForTagPoolingServers() { + /** + * Must declare the setter at the descendant Tag class level in order for the tag handler to locate the method. + */ + public void setPerformClearTagStateForTagPoolingServers(boolean performClearTagStateForTagPoolingServers) { + super.setPerformClearTagStateForTagPoolingServers(performClearTagStateForTagPoolingServers); + } + + @Override + protected void clearTagStateForTagPoolingServers() { + if (getPerformClearTagStateForTagPoolingServers() == false) { + return; // If flag is false (default setting), do not perform any state clearing. + } super.clearTagStateForTagPoolingServers(); this.test = null; } diff --git a/core/src/main/java/org/apache/struts2/views/jsp/IncludeTag.java b/core/src/main/java/org/apache/struts2/views/jsp/IncludeTag.java index c63474315..6ebee945a 100644 --- a/core/src/main/java/org/apache/struts2/views/jsp/IncludeTag.java +++ b/core/src/main/java/org/apache/struts2/views/jsp/IncludeTag.java @@ -52,7 +52,18 @@ public class IncludeTag extends ComponentTagSupport { } @Override - public void clearTagStateForTagPoolingServers() { + /** + * Must declare the setter at the descendant Tag class level in order for the tag handler to locate the method. + */ + public void setPerformClearTagStateForTagPoolingServers(boolean performClearTagStateForTagPoolingServers) { + super.setPerformClearTagStateForTagPoolingServers(performClearTagStateForTagPoolingServers); + } + + @Override + protected void clearTagStateForTagPoolingServers() { + if (getPerformClearTagStateForTagPoolingServers() == false) { + return; // If flag is false (default setting), do not perform any state clearing. + } super.clearTagStateForTagPoolingServers(); this.value = null; } diff --git a/core/src/main/java/org/apache/struts2/views/jsp/IteratorTag.java b/core/src/main/java/org/apache/struts2/views/jsp/IteratorTag.java index d46f257a7..f85875c32 100644 --- a/core/src/main/java/org/apache/struts2/views/jsp/IteratorTag.java +++ b/core/src/main/java/org/apache/struts2/views/jsp/IteratorTag.java @@ -101,8 +101,19 @@ public class IteratorTag extends ContextBeanTag { } } - @Override - public void clearTagStateForTagPoolingServers() { + @Override + /** + * Must declare the setter at the descendant Tag class level in order for the tag handler to locate the method. + */ + public void setPerformClearTagStateForTagPoolingServers(boolean performClearTagStateForTagPoolingServers) { + super.setPerformClearTagStateForTagPoolingServers(performClearTagStateForTagPoolingServers); + } + + @Override + protected void clearTagStateForTagPoolingServers() { + if (getPerformClearTagStateForTagPoolingServers() == false) { + return; // If flag is false (default setting), do not perform any state clearing. + } super.clearTagStateForTagPoolingServers(); this.statusAttr = null; this.value = null; diff --git a/core/src/main/java/org/apache/struts2/views/jsp/NumberTag.java b/core/src/main/java/org/apache/struts2/views/jsp/NumberTag.java index 23084d9ad..45262c63c 100644 --- a/core/src/main/java/org/apache/struts2/views/jsp/NumberTag.java +++ b/core/src/main/java/org/apache/struts2/views/jsp/NumberTag.java @@ -135,8 +135,19 @@ public class NumberTag extends ContextBeanTag { this.roundingMode = roundingMode; } - @Override - public void clearTagStateForTagPoolingServers() { + @Override + /** + * Must declare the setter at the descendant Tag class level in order for the tag handler to locate the method. + */ + public void setPerformClearTagStateForTagPoolingServers(boolean performClearTagStateForTagPoolingServers) { + super.setPerformClearTagStateForTagPoolingServers(performClearTagStateForTagPoolingServers); + } + + @Override + protected void clearTagStateForTagPoolingServers() { + if (getPerformClearTagStateForTagPoolingServers() == false) { + return; // If flag is false (default setting), do not perform any state clearing. + } super.clearTagStateForTagPoolingServers(); this.name = null; this.currency = null; diff --git a/core/src/main/java/org/apache/struts2/views/jsp/ParamTag.java b/core/src/main/java/org/apache/struts2/views/jsp/ParamTag.java index 006bbe6eb..019059367 100644 --- a/core/src/main/java/org/apache/struts2/views/jsp/ParamTag.java +++ b/core/src/main/java/org/apache/struts2/views/jsp/ParamTag.java @@ -64,7 +64,18 @@ public class ParamTag extends ComponentTagSupport { } @Override - public void clearTagStateForTagPoolingServers() { + /** + * Must declare the setter at the descendant Tag class level in order for the tag handler to locate the method. + */ + public void setPerformClearTagStateForTagPoolingServers(boolean performClearTagStateForTagPoolingServers) { + super.setPerformClearTagStateForTagPoolingServers(performClearTagStateForTagPoolingServers); + } + + @Override + protected void clearTagStateForTagPoolingServers() { + if (getPerformClearTagStateForTagPoolingServers() == false) { + return; // If flag is false (default setting), do not perform any state clearing. + } super.clearTagStateForTagPoolingServers(); this.name = null; this.value = null; diff --git a/core/src/main/java/org/apache/struts2/views/jsp/PropertyTag.java b/core/src/main/java/org/apache/struts2/views/jsp/PropertyTag.java index 99a1c10a7..7db42fcf8 100644 --- a/core/src/main/java/org/apache/struts2/views/jsp/PropertyTag.java +++ b/core/src/main/java/org/apache/struts2/views/jsp/PropertyTag.java @@ -87,7 +87,18 @@ public class PropertyTag extends ComponentTagSupport { } @Override - public void clearTagStateForTagPoolingServers() { + /** + * Must declare the setter at the descendant Tag class level in order for the tag handler to locate the method. + */ + public void setPerformClearTagStateForTagPoolingServers(boolean performClearTagStateForTagPoolingServers) { + super.setPerformClearTagStateForTagPoolingServers(performClearTagStateForTagPoolingServers); + } + + @Override + protected void clearTagStateForTagPoolingServers() { + if (getPerformClearTagStateForTagPoolingServers() == false) { + return; // If flag is false (default setting), do not perform any state clearing. + } super.clearTagStateForTagPoolingServers(); this.defaultValue = null; this.value = null; diff --git a/core/src/main/java/org/apache/struts2/views/jsp/PushTag.java b/core/src/main/java/org/apache/struts2/views/jsp/PushTag.java index d575255e5..f6d647dd3 100644 --- a/core/src/main/java/org/apache/struts2/views/jsp/PushTag.java +++ b/core/src/main/java/org/apache/struts2/views/jsp/PushTag.java @@ -52,7 +52,18 @@ public class PushTag extends ComponentTagSupport { } @Override - public void clearTagStateForTagPoolingServers() { + /** + * Must declare the setter at the descendant Tag class level in order for the tag handler to locate the method. + */ + public void setPerformClearTagStateForTagPoolingServers(boolean performClearTagStateForTagPoolingServers) { + super.setPerformClearTagStateForTagPoolingServers(performClearTagStateForTagPoolingServers); + } + + @Override + protected void clearTagStateForTagPoolingServers() { + if (getPerformClearTagStateForTagPoolingServers() == false) { + return; // If flag is false (default setting), do not perform any state clearing. + } super.clearTagStateForTagPoolingServers(); this.value = null; } diff --git a/core/src/main/java/org/apache/struts2/views/jsp/SetTag.java b/core/src/main/java/org/apache/struts2/views/jsp/SetTag.java index 910498108..c76f41cb0 100644 --- a/core/src/main/java/org/apache/struts2/views/jsp/SetTag.java +++ b/core/src/main/java/org/apache/struts2/views/jsp/SetTag.java @@ -80,8 +80,19 @@ public class SetTag extends ContextBeanTag { } } - @Override - public void clearTagStateForTagPoolingServers() { + @Override + /** + * Must declare the setter at the descendant Tag class level in order for the tag handler to locate the method. + */ + public void setPerformClearTagStateForTagPoolingServers(boolean performClearTagStateForTagPoolingServers) { + super.setPerformClearTagStateForTagPoolingServers(performClearTagStateForTagPoolingServers); + } + + @Override + protected void clearTagStateForTagPoolingServers() { + if (getPerformClearTagStateForTagPoolingServers() == false) { + return; // If flag is false (default setting), do not perform any state clearing. + } super.clearTagStateForTagPoolingServers(); this.scope = null; this.value = null; diff --git a/core/src/main/java/org/apache/struts2/views/jsp/StrutsBodyTagSupport.java b/core/src/main/java/org/apache/struts2/views/jsp/StrutsBodyTagSupport.java index 597073c04..041d34ebc 100644 --- a/core/src/main/java/org/apache/struts2/views/jsp/StrutsBodyTagSupport.java +++ b/core/src/main/java/org/apache/struts2/views/jsp/StrutsBodyTagSupport.java @@ -34,6 +34,8 @@ public class StrutsBodyTagSupport extends BodyTagSupport { private static final long serialVersionUID = -1201668454354226175L; + private boolean performClearTagStateForTagPoolingServers = false; + protected ValueStack getStack() { return TagUtils.getStack(pageContext); } @@ -80,6 +82,36 @@ public class StrutsBodyTagSupport extends BodyTagSupport { return super.doEndTag(); } + /** + * Request that the tag state be cleared during {@link StrutsBodyTagSupport#doEndTag()} processing, + * which may help with certain edge cases with tag logic running on servers that implement JSP Tag Pooling. + * + * Note: Even though the Tag classes extend this class {@link StrutsBodyTagSupport}, and this method + * {@link StrutsBodyTagSupport#setPerformClearTagStateForTagPoolingServers(boolean)} exists in the method hierarchy, + * the JSP processing requires us to explicitly override it in every Tag class in order for the Tag handler + * method to be visible to the JSP processing. + * Defining a setter in the superclass alone is insufficient (results in "Cannot find a setter method for the attribute"). + * + * See {@link StrutsBodyTagSupport#clearTagStateForTagPoolingServers()} for additional details. + * + * Warning: Setting this value to true may allow for the desired behaviour, but doing so + * may violate the JSP specification. Set to true at your own risk. + * + * @param performClearTagStateForTagPoolingServers true if tag state should be cleared, false otherwise. + */ + public void setPerformClearTagStateForTagPoolingServers(boolean performClearTagStateForTagPoolingServers) { + this.performClearTagStateForTagPoolingServers = performClearTagStateForTagPoolingServers; + } + + /** + * Allow descendant tags to check if the tag state should be cleared during {@link StrutsBodyTagSupport#doEndTag()} processing, + * + * @return true if tag state should be cleared, false (default) otherwise. + */ + protected boolean getPerformClearTagStateForTagPoolingServers() { + return this.performClearTagStateForTagPoolingServers; + } + /** * Provide a mechanism to clear tag state, to handle servlet container JSP tag pooling * behaviour with some servers, such as Glassfish. @@ -96,11 +128,19 @@ public class StrutsBodyTagSupport extends BodyTagSupport { */ protected void clearTagStateForTagPoolingServers() { // Default implementation. + if (getPerformClearTagStateForTagPoolingServers() == false) { + return; // If flag is false (default setting), do not perform any state clearing. + } this.setBodyContent(null); // Always clear the tag body (if any) after tag completion. this.setId(null); // Always clear the tag id (if any) after tag completion. // Note: The pageContext and parent Tag state are NOT cleared, only the "user-defined" tag state should be cleared. // Calling setPageContext(null) and setParent(null) appears too dangerous to consider, and the container - // should always set them, even if a tag instance from a pool is re-used. + // should always set them, even if a tag instance from a pool is re-used. Also, clearing those two + // values likely violates the JSP specification. + // Note: We intentionally do NOT reset performClearTagStateForTagPoolingServers to false here, for two reasons. + // Firstly, if a tag pool re-uses the instance, in order to qualify/match the tag parameters should be + // the same, including performClearTagStateForTagPoolingServers. Secondly, if we change the state of + // the control flag during clearing, it makes unit testing virtually impossible. } } diff --git a/core/src/main/java/org/apache/struts2/views/jsp/TextTag.java b/core/src/main/java/org/apache/struts2/views/jsp/TextTag.java index 4c8dc0cf1..d3b609e5b 100644 --- a/core/src/main/java/org/apache/struts2/views/jsp/TextTag.java +++ b/core/src/main/java/org/apache/struts2/views/jsp/TextTag.java @@ -76,8 +76,19 @@ public class TextTag extends ContextBeanTag { this.escapeCsv = escapeCsv; } - @Override - public void clearTagStateForTagPoolingServers() { + @Override + /** + * Must declare the setter at the descendant Tag class level in order for the tag handler to locate the method. + */ + public void setPerformClearTagStateForTagPoolingServers(boolean performClearTagStateForTagPoolingServers) { + super.setPerformClearTagStateForTagPoolingServers(performClearTagStateForTagPoolingServers); + } + + @Override + protected void clearTagStateForTagPoolingServers() { + if (getPerformClearTagStateForTagPoolingServers() == false) { + return; // If flag is false (default setting), do not perform any state clearing. + } super.clearTagStateForTagPoolingServers(); this.name = null; this.searchValueStack = null; diff --git a/core/src/main/java/org/apache/struts2/views/jsp/URLTag.java b/core/src/main/java/org/apache/struts2/views/jsp/URLTag.java index 7c0f5652f..445777a49 100644 --- a/core/src/main/java/org/apache/struts2/views/jsp/URLTag.java +++ b/core/src/main/java/org/apache/struts2/views/jsp/URLTag.java @@ -139,8 +139,19 @@ public class URLTag extends ContextBeanTag { this.forceAddSchemeHostAndPort = forceAddSchemeHostAndPort; } - @Override - public void clearTagStateForTagPoolingServers() { + @Override + /** + * Must declare the setter at the descendant Tag class level in order for the tag handler to locate the method. + */ + public void setPerformClearTagStateForTagPoolingServers(boolean performClearTagStateForTagPoolingServers) { + super.setPerformClearTagStateForTagPoolingServers(performClearTagStateForTagPoolingServers); + } + + @Override + protected void clearTagStateForTagPoolingServers() { + if (getPerformClearTagStateForTagPoolingServers() == false) { + return; // If flag is false (default setting), do not perform any state clearing. + } super.clearTagStateForTagPoolingServers(); this.includeParams = null; this.scheme = null; diff --git a/core/src/main/java/org/apache/struts2/views/jsp/iterator/AppendIteratorTag.java b/core/src/main/java/org/apache/struts2/views/jsp/iterator/AppendIteratorTag.java index e3f754da8..1ea16506d 100644 --- a/core/src/main/java/org/apache/struts2/views/jsp/iterator/AppendIteratorTag.java +++ b/core/src/main/java/org/apache/struts2/views/jsp/iterator/AppendIteratorTag.java @@ -37,8 +37,16 @@ public class AppendIteratorTag extends ContextBeanTag { private static final long serialVersionUID = -6017337859763283691L; + @Override public Component getBean(ValueStack stack, HttpServletRequest req, HttpServletResponse res) { return new AppendIterator(stack); } + @Override + /** + * Must declare the setter at the descendant Tag class level in order for the tag handler to locate the method. + */ + public void setPerformClearTagStateForTagPoolingServers(boolean performClearTagStateForTagPoolingServers) { + super.setPerformClearTagStateForTagPoolingServers(performClearTagStateForTagPoolingServers); + } } diff --git a/core/src/main/java/org/apache/struts2/views/jsp/iterator/IteratorGeneratorTag.java b/core/src/main/java/org/apache/struts2/views/jsp/iterator/IteratorGeneratorTag.java index e988c8017..f3af5f628 100644 --- a/core/src/main/java/org/apache/struts2/views/jsp/iterator/IteratorGeneratorTag.java +++ b/core/src/main/java/org/apache/struts2/views/jsp/iterator/IteratorGeneratorTag.java @@ -176,6 +176,12 @@ public class IteratorGeneratorTag extends StrutsBodyTagSupport { this.var = var; } + @StrutsTagAttribute(description="Whether to clear all tag state during doEndTag() processing", type="Boolean", defaultValue="false", required = false) + @Override + public void setPerformClearTagStateForTagPoolingServers(boolean performClearTagStateForTagPoolingServers) { + super.setPerformClearTagStateForTagPoolingServers(performClearTagStateForTagPoolingServers); + } + @Override public int doStartTag() throws JspException { @@ -242,7 +248,10 @@ public class IteratorGeneratorTag extends StrutsBodyTagSupport { } @Override - public void clearTagStateForTagPoolingServers() { + protected void clearTagStateForTagPoolingServers() { + if (getPerformClearTagStateForTagPoolingServers() == false) { + return; // If flag is false (default setting), do not perform any state clearing. + } super.clearTagStateForTagPoolingServers(); this.countAttr = null; this.separatorAttr = null; diff --git a/core/src/main/java/org/apache/struts2/views/jsp/iterator/MergeIteratorTag.java b/core/src/main/java/org/apache/struts2/views/jsp/iterator/MergeIteratorTag.java index 3cd7fa4f8..839030ca4 100644 --- a/core/src/main/java/org/apache/struts2/views/jsp/iterator/MergeIteratorTag.java +++ b/core/src/main/java/org/apache/struts2/views/jsp/iterator/MergeIteratorTag.java @@ -38,8 +38,17 @@ public class MergeIteratorTag extends ContextBeanTag { private static final long serialVersionUID = 4999729472466011218L; + @Override public Component getBean(ValueStack stack, HttpServletRequest req, HttpServletResponse res) { return new MergeIterator(stack); } + @Override + /** + * Must declare the setter at the descendant Tag class level in order for the tag handler to locate the method. + */ + public void setPerformClearTagStateForTagPoolingServers(boolean performClearTagStateForTagPoolingServers) { + super.setPerformClearTagStateForTagPoolingServers(performClearTagStateForTagPoolingServers); + } + } diff --git a/core/src/main/java/org/apache/struts2/views/jsp/iterator/SortIteratorTag.java b/core/src/main/java/org/apache/struts2/views/jsp/iterator/SortIteratorTag.java index 8165045f2..32e13924f 100644 --- a/core/src/main/java/org/apache/struts2/views/jsp/iterator/SortIteratorTag.java +++ b/core/src/main/java/org/apache/struts2/views/jsp/iterator/SortIteratorTag.java @@ -110,6 +110,12 @@ public class SortIteratorTag extends StrutsBodyTagSupport { this.var = var; } + @StrutsTagAttribute(description="Whether to clear all tag state during doEndTag() processing", type="Boolean", defaultValue="false", required = false) + @Override + public void setPerformClearTagStateForTagPoolingServers(boolean performClearTagStateForTagPoolingServers) { + super.setPerformClearTagStateForTagPoolingServers(performClearTagStateForTagPoolingServers); + } + @Override public int doStartTag() throws JspException { // Source @@ -159,7 +165,10 @@ public class SortIteratorTag extends StrutsBodyTagSupport { } @Override - public void clearTagStateForTagPoolingServers() { + protected void clearTagStateForTagPoolingServers() { + if (getPerformClearTagStateForTagPoolingServers() == false) { + return; // If flag is false (default setting), do not perform any state clearing. + } super.clearTagStateForTagPoolingServers(); this.comparatorAttr = null; this.sourceAttr = null; diff --git a/core/src/main/java/org/apache/struts2/views/jsp/iterator/SubsetIteratorTag.java b/core/src/main/java/org/apache/struts2/views/jsp/iterator/SubsetIteratorTag.java index 6f19afbea..f269a945d 100644 --- a/core/src/main/java/org/apache/struts2/views/jsp/iterator/SubsetIteratorTag.java +++ b/core/src/main/java/org/apache/struts2/views/jsp/iterator/SubsetIteratorTag.java @@ -193,6 +193,12 @@ public class SubsetIteratorTag extends StrutsBodyTagSupport { this.var = var; } + @StrutsTagAttribute(description="Whether to clear all tag state during doEndTag() processing", type="Boolean", defaultValue="false", required = false) + @Override + public void setPerformClearTagStateForTagPoolingServers(boolean performClearTagStateForTagPoolingServers) { + super.setPerformClearTagStateForTagPoolingServers(performClearTagStateForTagPoolingServers); + } + @Override public int doStartTag() throws JspException { @@ -284,7 +290,10 @@ public class SubsetIteratorTag extends StrutsBodyTagSupport { } @Override - public void clearTagStateForTagPoolingServers() { + protected void clearTagStateForTagPoolingServers() { + if (getPerformClearTagStateForTagPoolingServers() == false) { + return; // If flag is false (default setting), do not perform any state clearing. + } super.clearTagStateForTagPoolingServers(); this.countAttr = null; this.sourceAttr = null; diff --git a/core/src/main/java/org/apache/struts2/views/jsp/ui/AbstractClosingTag.java b/core/src/main/java/org/apache/struts2/views/jsp/ui/AbstractClosingTag.java index 3af662248..e7949db8a 100644 --- a/core/src/main/java/org/apache/struts2/views/jsp/ui/AbstractClosingTag.java +++ b/core/src/main/java/org/apache/struts2/views/jsp/ui/AbstractClosingTag.java @@ -34,8 +34,19 @@ public abstract class AbstractClosingTag extends AbstractUITag { this.openTemplate = openTemplate; } - @Override - public void clearTagStateForTagPoolingServers() { + @Override + /** + * Must declare the setter at the descendant Tag class level in order for the tag handler to locate the method. + */ + public void setPerformClearTagStateForTagPoolingServers(boolean performClearTagStateForTagPoolingServers) { + super.setPerformClearTagStateForTagPoolingServers(performClearTagStateForTagPoolingServers); + } + + @Override + protected void clearTagStateForTagPoolingServers() { + if (getPerformClearTagStateForTagPoolingServers() == false) { + return; // If flag is false (default setting), do not perform any state clearing. + } super.clearTagStateForTagPoolingServers(); this.openTemplate = null; } diff --git a/core/src/main/java/org/apache/struts2/views/jsp/ui/AbstractDoubleListTag.java b/core/src/main/java/org/apache/struts2/views/jsp/ui/AbstractDoubleListTag.java index 21c09833d..efa9db18b 100644 --- a/core/src/main/java/org/apache/struts2/views/jsp/ui/AbstractDoubleListTag.java +++ b/core/src/main/java/org/apache/struts2/views/jsp/ui/AbstractDoubleListTag.java @@ -384,8 +384,19 @@ public abstract class AbstractDoubleListTag extends AbstractRequiredListTag { this.doubleAccesskey = doubleAccesskey; } - @Override - public void clearTagStateForTagPoolingServers() { + @Override + /** + * Must declare the setter at the descendant Tag class level in order for the tag handler to locate the method. + */ + public void setPerformClearTagStateForTagPoolingServers(boolean performClearTagStateForTagPoolingServers) { + super.setPerformClearTagStateForTagPoolingServers(performClearTagStateForTagPoolingServers); + } + + @Override + protected void clearTagStateForTagPoolingServers() { + if (getPerformClearTagStateForTagPoolingServers() == false) { + return; // If flag is false (default setting), do not perform any state clearing. + } super.clearTagStateForTagPoolingServers(); this.doubleList = null; this.doubleListKey = null; diff --git a/core/src/main/java/org/apache/struts2/views/jsp/ui/AbstractListTag.java b/core/src/main/java/org/apache/struts2/views/jsp/ui/AbstractListTag.java index 747c4c9a8..a781fd997 100644 --- a/core/src/main/java/org/apache/struts2/views/jsp/ui/AbstractListTag.java +++ b/core/src/main/java/org/apache/struts2/views/jsp/ui/AbstractListTag.java @@ -77,8 +77,19 @@ public abstract class AbstractListTag extends AbstractUITag { this.listTitle = listTitle; } - @Override - public void clearTagStateForTagPoolingServers() { + @Override + /** + * Must declare the setter at the descendant Tag class level in order for the tag handler to locate the method. + */ + public void setPerformClearTagStateForTagPoolingServers(boolean performClearTagStateForTagPoolingServers) { + super.setPerformClearTagStateForTagPoolingServers(performClearTagStateForTagPoolingServers); + } + + @Override + protected void clearTagStateForTagPoolingServers() { + if (getPerformClearTagStateForTagPoolingServers() == false) { + return; // If flag is false (default setting), do not perform any state clearing. + } super.clearTagStateForTagPoolingServers(); this.list = null; this.listKey = null; diff --git a/core/src/main/java/org/apache/struts2/views/jsp/ui/AbstractRequiredListTag.java b/core/src/main/java/org/apache/struts2/views/jsp/ui/AbstractRequiredListTag.java index fd6bb84e1..c407297e0 100644 --- a/core/src/main/java/org/apache/struts2/views/jsp/ui/AbstractRequiredListTag.java +++ b/core/src/main/java/org/apache/struts2/views/jsp/ui/AbstractRequiredListTag.java @@ -22,6 +22,7 @@ import org.apache.struts2.components.ListUIBean; public abstract class AbstractRequiredListTag extends AbstractListTag { + @Override protected void populateParams() { super.populateParams(); @@ -29,4 +30,11 @@ public abstract class AbstractRequiredListTag extends AbstractListTag { listUIBean.setThrowExceptionOnNullValueAttribute(true); } + @Override + /** + * Must declare the setter at the descendant Tag class level in order for the tag handler to locate the method. + */ + public void setPerformClearTagStateForTagPoolingServers(boolean performClearTagStateForTagPoolingServers) { + super.setPerformClearTagStateForTagPoolingServers(performClearTagStateForTagPoolingServers); + } } diff --git a/core/src/main/java/org/apache/struts2/views/jsp/ui/AbstractUITag.java b/core/src/main/java/org/apache/struts2/views/jsp/ui/AbstractUITag.java index 316954f88..42f688179 100644 --- a/core/src/main/java/org/apache/struts2/views/jsp/ui/AbstractUITag.java +++ b/core/src/main/java/org/apache/struts2/views/jsp/ui/AbstractUITag.java @@ -78,6 +78,7 @@ public abstract class AbstractUITag extends ComponentTagSupport implements Dynam // dynamic attributes. protected Map dynamicAttributes = new HashMap<>(); + @Override protected void populateParams() { super.populateParams(); @@ -127,6 +128,7 @@ public abstract class AbstractUITag extends ComponentTagSupport implements Dynam uiBean.setDynamicAttributes(dynamicAttributes); } + @Override public void setId(String id) { this.id = id; } @@ -312,12 +314,24 @@ public abstract class AbstractUITag extends ComponentTagSupport implements Dynam this.labelSeparator = labelSeparator; } + @Override public void setDynamicAttribute(String uri, String localName, Object value) throws JspException { dynamicAttributes.put(localName, String.valueOf(value)); } @Override - public void clearTagStateForTagPoolingServers() { + /** + * Must declare the setter at the descendant Tag class level in order for the tag handler to locate the method. + */ + public void setPerformClearTagStateForTagPoolingServers(boolean performClearTagStateForTagPoolingServers) { + super.setPerformClearTagStateForTagPoolingServers(performClearTagStateForTagPoolingServers); + } + + @Override + protected void clearTagStateForTagPoolingServers() { + if (getPerformClearTagStateForTagPoolingServers() == false) { + return; // If flag is false (default setting), do not perform any state clearing. + } super.clearTagStateForTagPoolingServers(); this.cssClass = null; this.cssErrorClass = null; diff --git a/core/src/main/java/org/apache/struts2/views/jsp/ui/ActionErrorTag.java b/core/src/main/java/org/apache/struts2/views/jsp/ui/ActionErrorTag.java index 4c9c875e6..02f564c54 100644 --- a/core/src/main/java/org/apache/struts2/views/jsp/ui/ActionErrorTag.java +++ b/core/src/main/java/org/apache/struts2/views/jsp/ui/ActionErrorTag.java @@ -53,8 +53,19 @@ public class ActionErrorTag extends AbstractUITag { this.escape = escape; } - @Override - public void clearTagStateForTagPoolingServers() { + @Override + /** + * Must declare the setter at the descendant Tag class level in order for the tag handler to locate the method. + */ + public void setPerformClearTagStateForTagPoolingServers(boolean performClearTagStateForTagPoolingServers) { + super.setPerformClearTagStateForTagPoolingServers(performClearTagStateForTagPoolingServers); + } + + @Override + protected void clearTagStateForTagPoolingServers() { + if (getPerformClearTagStateForTagPoolingServers() == false) { + return; // If flag is false (default setting), do not perform any state clearing. + } super.clearTagStateForTagPoolingServers(); this.escape = true; } diff --git a/core/src/main/java/org/apache/struts2/views/jsp/ui/ActionMessageTag.java b/core/src/main/java/org/apache/struts2/views/jsp/ui/ActionMessageTag.java index 7b6879739..4ce77bc6c 100644 --- a/core/src/main/java/org/apache/struts2/views/jsp/ui/ActionMessageTag.java +++ b/core/src/main/java/org/apache/struts2/views/jsp/ui/ActionMessageTag.java @@ -53,8 +53,19 @@ public class ActionMessageTag extends AbstractUITag { this.escape = escape; } - @Override - public void clearTagStateForTagPoolingServers() { + @Override + /** + * Must declare the setter at the descendant Tag class level in order for the tag handler to locate the method. + */ + public void setPerformClearTagStateForTagPoolingServers(boolean performClearTagStateForTagPoolingServers) { + super.setPerformClearTagStateForTagPoolingServers(performClearTagStateForTagPoolingServers); + } + + @Override + protected void clearTagStateForTagPoolingServers() { + if (getPerformClearTagStateForTagPoolingServers() == false) { + return; // If flag is false (default setting), do not perform any state clearing. + } super.clearTagStateForTagPoolingServers(); this.escape = true; } diff --git a/core/src/main/java/org/apache/struts2/views/jsp/ui/AnchorTag.java b/core/src/main/java/org/apache/struts2/views/jsp/ui/AnchorTag.java index 4d0fda5b2..4f334ada0 100644 --- a/core/src/main/java/org/apache/struts2/views/jsp/ui/AnchorTag.java +++ b/core/src/main/java/org/apache/struts2/views/jsp/ui/AnchorTag.java @@ -158,8 +158,19 @@ public class AnchorTag extends AbstractClosingTag { this.escapeHtmlBody = escapeHtmlBody; } + /** + * Must declare the setter at the descendant Tag class level in order for the tag handler to locate the method. + */ @Override - public void clearTagStateForTagPoolingServers() { + public void setPerformClearTagStateForTagPoolingServers(boolean performClearTagStateForTagPoolingServers) { + super.setPerformClearTagStateForTagPoolingServers(performClearTagStateForTagPoolingServers); + } + + @Override + protected void clearTagStateForTagPoolingServers() { + if (getPerformClearTagStateForTagPoolingServers() == false) { + return; // If flag is false (default setting), do not perform any state clearing. + } super.clearTagStateForTagPoolingServers(); this.href = null; this.includeParams = null; diff --git a/core/src/main/java/org/apache/struts2/views/jsp/ui/CheckboxListTag.java b/core/src/main/java/org/apache/struts2/views/jsp/ui/CheckboxListTag.java index 40a6ac2f5..2e63b3c62 100644 --- a/core/src/main/java/org/apache/struts2/views/jsp/ui/CheckboxListTag.java +++ b/core/src/main/java/org/apache/struts2/views/jsp/ui/CheckboxListTag.java @@ -33,7 +33,16 @@ public class CheckboxListTag extends AbstractRequiredListTag { private static final long serialVersionUID = 4023034029558150010L; + @Override public Component getBean(ValueStack stack, HttpServletRequest req, HttpServletResponse res) { return new CheckboxList(stack, req, res); } + + @Override + /** + * Must declare the setter at the descendant Tag class level in order for the tag handler to locate the method. + */ + public void setPerformClearTagStateForTagPoolingServers(boolean performClearTagStateForTagPoolingServers) { + super.setPerformClearTagStateForTagPoolingServers(performClearTagStateForTagPoolingServers); + } } diff --git a/core/src/main/java/org/apache/struts2/views/jsp/ui/CheckboxTag.java b/core/src/main/java/org/apache/struts2/views/jsp/ui/CheckboxTag.java index 4230b9e11..242aa033b 100644 --- a/core/src/main/java/org/apache/struts2/views/jsp/ui/CheckboxTag.java +++ b/core/src/main/java/org/apache/struts2/views/jsp/ui/CheckboxTag.java @@ -56,8 +56,19 @@ public class CheckboxTag extends AbstractUITag { this.submitUnchecked = aValue; } + /** + * Must declare the setter at the descendant Tag class level in order for the tag handler to locate the method. + */ @Override - public void clearTagStateForTagPoolingServers() { + public void setPerformClearTagStateForTagPoolingServers(boolean performClearTagStateForTagPoolingServers) { + super.setPerformClearTagStateForTagPoolingServers(performClearTagStateForTagPoolingServers); + } + + @Override + protected void clearTagStateForTagPoolingServers() { + if (getPerformClearTagStateForTagPoolingServers() == false) { + return; // If flag is false (default setting), do not perform any state clearing. + } super.clearTagStateForTagPoolingServers(); this.fieldValue = null; } diff --git a/core/src/main/java/org/apache/struts2/views/jsp/ui/ComboBoxTag.java b/core/src/main/java/org/apache/struts2/views/jsp/ui/ComboBoxTag.java index 76b4ec9bf..29c03a276 100644 --- a/core/src/main/java/org/apache/struts2/views/jsp/ui/ComboBoxTag.java +++ b/core/src/main/java/org/apache/struts2/views/jsp/ui/ComboBoxTag.java @@ -81,8 +81,19 @@ public class ComboBoxTag extends TextFieldTag { this.list = list; } - @Override - public void clearTagStateForTagPoolingServers() { + @Override + /** + * Must declare the setter at the descendant Tag class level in order for the tag handler to locate the method. + */ + public void setPerformClearTagStateForTagPoolingServers(boolean performClearTagStateForTagPoolingServers) { + super.setPerformClearTagStateForTagPoolingServers(performClearTagStateForTagPoolingServers); + } + + @Override + protected void clearTagStateForTagPoolingServers() { + if (getPerformClearTagStateForTagPoolingServers() == false) { + return; // If flag is false (default setting), do not perform any state clearing. + } super.clearTagStateForTagPoolingServers(); this.list = null; this.listKey = null; diff --git a/core/src/main/java/org/apache/struts2/views/jsp/ui/ComponentTag.java b/core/src/main/java/org/apache/struts2/views/jsp/ui/ComponentTag.java index efbd813ad..48a62d457 100644 --- a/core/src/main/java/org/apache/struts2/views/jsp/ui/ComponentTag.java +++ b/core/src/main/java/org/apache/struts2/views/jsp/ui/ComponentTag.java @@ -33,7 +33,16 @@ public class ComponentTag extends AbstractUITag { private static final long serialVersionUID = 5448365363044104731L; + @Override public Component getBean(ValueStack stack, HttpServletRequest req, HttpServletResponse res) { return new GenericUIBean(stack, req, res); } + + @Override + /** + * Must declare the setter at the descendant Tag class level in order for the tag handler to locate the method. + */ + public void setPerformClearTagStateForTagPoolingServers(boolean performClearTagStateForTagPoolingServers) { + super.setPerformClearTagStateForTagPoolingServers(performClearTagStateForTagPoolingServers); + } } diff --git a/core/src/main/java/org/apache/struts2/views/jsp/ui/DateTextFieldTag.java b/core/src/main/java/org/apache/struts2/views/jsp/ui/DateTextFieldTag.java index 666c7b4bf..768864065 100644 --- a/core/src/main/java/org/apache/struts2/views/jsp/ui/DateTextFieldTag.java +++ b/core/src/main/java/org/apache/struts2/views/jsp/ui/DateTextFieldTag.java @@ -52,8 +52,19 @@ public class DateTextFieldTag extends AbstractUITag { this.format = format; } - @Override - public void clearTagStateForTagPoolingServers() { + @Override + /** + * Must declare the setter at the descendant Tag class level in order for the tag handler to locate the method. + */ + public void setPerformClearTagStateForTagPoolingServers(boolean performClearTagStateForTagPoolingServers) { + super.setPerformClearTagStateForTagPoolingServers(performClearTagStateForTagPoolingServers); + } + + @Override + protected void clearTagStateForTagPoolingServers() { + if (getPerformClearTagStateForTagPoolingServers() == false) { + return; // If flag is false (default setting), do not perform any state clearing. + } super.clearTagStateForTagPoolingServers(); this.format = null; } diff --git a/core/src/main/java/org/apache/struts2/views/jsp/ui/DebugTag.java b/core/src/main/java/org/apache/struts2/views/jsp/ui/DebugTag.java index f2a5d0965..c96d53096 100644 --- a/core/src/main/java/org/apache/struts2/views/jsp/ui/DebugTag.java +++ b/core/src/main/java/org/apache/struts2/views/jsp/ui/DebugTag.java @@ -30,8 +30,16 @@ public class DebugTag extends AbstractUITag { private static final long serialVersionUID = 3487684841317160628L; + @Override public Component getBean(ValueStack stack, HttpServletRequest req, HttpServletResponse res) { return new Debug(stack, req, res); } + @Override + /** + * Must declare the setter at the descendant Tag class level in order for the tag handler to locate the method. + */ + public void setPerformClearTagStateForTagPoolingServers(boolean performClearTagStateForTagPoolingServers) { + super.setPerformClearTagStateForTagPoolingServers(performClearTagStateForTagPoolingServers); + } } diff --git a/core/src/main/java/org/apache/struts2/views/jsp/ui/DoubleSelectTag.java b/core/src/main/java/org/apache/struts2/views/jsp/ui/DoubleSelectTag.java index 1241a67d8..ee430c9e5 100644 --- a/core/src/main/java/org/apache/struts2/views/jsp/ui/DoubleSelectTag.java +++ b/core/src/main/java/org/apache/struts2/views/jsp/ui/DoubleSelectTag.java @@ -33,10 +33,12 @@ public class DoubleSelectTag extends AbstractDoubleListTag { private static final long serialVersionUID = 7426011596359509386L; + @Override public Component getBean(ValueStack stack, HttpServletRequest req, HttpServletResponse res) { return new DoubleSelect(stack, req, res); } + @Override protected void populateParams() { super.populateParams(); @@ -48,4 +50,12 @@ public class DoubleSelectTag extends AbstractDoubleListTag { doubleSelect.setSize(size); } + + @Override + /** + * Must declare the setter at the descendant Tag class level in order for the tag handler to locate the method. + */ + public void setPerformClearTagStateForTagPoolingServers(boolean performClearTagStateForTagPoolingServers) { + super.setPerformClearTagStateForTagPoolingServers(performClearTagStateForTagPoolingServers); + } } diff --git a/core/src/main/java/org/apache/struts2/views/jsp/ui/FieldErrorTag.java b/core/src/main/java/org/apache/struts2/views/jsp/ui/FieldErrorTag.java index 44ad8adab..1d7a6e363 100644 --- a/core/src/main/java/org/apache/struts2/views/jsp/ui/FieldErrorTag.java +++ b/core/src/main/java/org/apache/struts2/views/jsp/ui/FieldErrorTag.java @@ -59,8 +59,19 @@ public class FieldErrorTag extends AbstractUITag { this.escape = escape; } - @Override - public void clearTagStateForTagPoolingServers() { + @Override + /** + * Must declare the setter at the descendant Tag class level in order for the tag handler to locate the method. + */ + public void setPerformClearTagStateForTagPoolingServers(boolean performClearTagStateForTagPoolingServers) { + super.setPerformClearTagStateForTagPoolingServers(performClearTagStateForTagPoolingServers); + } + + @Override + protected void clearTagStateForTagPoolingServers() { + if (getPerformClearTagStateForTagPoolingServers() == false) { + return; // If flag is false (default setting), do not perform any state clearing. + } super.clearTagStateForTagPoolingServers(); this.fieldName = null; this.escape = true; diff --git a/core/src/main/java/org/apache/struts2/views/jsp/ui/FileTag.java b/core/src/main/java/org/apache/struts2/views/jsp/ui/FileTag.java index d97aa4df2..ef5171d0d 100644 --- a/core/src/main/java/org/apache/struts2/views/jsp/ui/FileTag.java +++ b/core/src/main/java/org/apache/struts2/views/jsp/ui/FileTag.java @@ -58,8 +58,19 @@ public class FileTag extends AbstractUITag { this.size = size; } - @Override - public void clearTagStateForTagPoolingServers() { + @Override + /** + * Must declare the setter at the descendant Tag class level in order for the tag handler to locate the method. + */ + public void setPerformClearTagStateForTagPoolingServers(boolean performClearTagStateForTagPoolingServers) { + super.setPerformClearTagStateForTagPoolingServers(performClearTagStateForTagPoolingServers); + } + + @Override + protected void clearTagStateForTagPoolingServers() { + if (getPerformClearTagStateForTagPoolingServers() == false) { + return; // If flag is false (default setting), do not perform any state clearing. + } super.clearTagStateForTagPoolingServers(); this.accept = null; this.size = null; diff --git a/core/src/main/java/org/apache/struts2/views/jsp/ui/FormTag.java b/core/src/main/java/org/apache/struts2/views/jsp/ui/FormTag.java index 41b8d275c..e765bb569 100644 --- a/core/src/main/java/org/apache/struts2/views/jsp/ui/FormTag.java +++ b/core/src/main/java/org/apache/struts2/views/jsp/ui/FormTag.java @@ -124,8 +124,19 @@ public class FormTag extends AbstractClosingTag { this.includeContext = includeContext; } - @Override - public void clearTagStateForTagPoolingServers() { + @Override + /** + * Must declare the setter at the descendant Tag class level in order for the tag handler to locate the method. + */ + public void setPerformClearTagStateForTagPoolingServers(boolean performClearTagStateForTagPoolingServers) { + super.setPerformClearTagStateForTagPoolingServers(performClearTagStateForTagPoolingServers); + } + + @Override + protected void clearTagStateForTagPoolingServers() { + if (getPerformClearTagStateForTagPoolingServers() == false) { + return; // If flag is false (default setting), do not perform any state clearing. + } super.clearTagStateForTagPoolingServers(); this.action = null; this.target = null; diff --git a/core/src/main/java/org/apache/struts2/views/jsp/ui/HeadTag.java b/core/src/main/java/org/apache/struts2/views/jsp/ui/HeadTag.java index 49a3b8fa2..b5a457eed 100644 --- a/core/src/main/java/org/apache/struts2/views/jsp/ui/HeadTag.java +++ b/core/src/main/java/org/apache/struts2/views/jsp/ui/HeadTag.java @@ -33,7 +33,16 @@ public class HeadTag extends AbstractUITag { private static final long serialVersionUID = 6876765769175246030L; + @Override public Component getBean(ValueStack stack, HttpServletRequest req, HttpServletResponse res) { return new Head(stack, req, res); } + + @Override + /** + * Must declare the setter at the descendant Tag class level in order for the tag handler to locate the method. + */ + public void setPerformClearTagStateForTagPoolingServers(boolean performClearTagStateForTagPoolingServers) { + super.setPerformClearTagStateForTagPoolingServers(performClearTagStateForTagPoolingServers); + } } diff --git a/core/src/main/java/org/apache/struts2/views/jsp/ui/HiddenTag.java b/core/src/main/java/org/apache/struts2/views/jsp/ui/HiddenTag.java index 7b8b39618..65f7e49d1 100644 --- a/core/src/main/java/org/apache/struts2/views/jsp/ui/HiddenTag.java +++ b/core/src/main/java/org/apache/struts2/views/jsp/ui/HiddenTag.java @@ -33,7 +33,16 @@ public class HiddenTag extends AbstractUITag { private static final long serialVersionUID = -1124367972048371675L; + @Override public Component getBean(ValueStack stack, HttpServletRequest req, HttpServletResponse res) { return new Hidden(stack, req, res); } + + @Override + /** + * Must declare the setter at the descendant Tag class level in order for the tag handler to locate the method. + */ + public void setPerformClearTagStateForTagPoolingServers(boolean performClearTagStateForTagPoolingServers) { + super.setPerformClearTagStateForTagPoolingServers(performClearTagStateForTagPoolingServers); + } } diff --git a/core/src/main/java/org/apache/struts2/views/jsp/ui/InputTransferSelectTag.java b/core/src/main/java/org/apache/struts2/views/jsp/ui/InputTransferSelectTag.java index 99922ff46..4dbf0070d 100644 --- a/core/src/main/java/org/apache/struts2/views/jsp/ui/InputTransferSelectTag.java +++ b/core/src/main/java/org/apache/struts2/views/jsp/ui/InputTransferSelectTag.java @@ -203,8 +203,19 @@ public class InputTransferSelectTag extends AbstractListTag { this.headerValue = headerValue; } - @Override - public void clearTagStateForTagPoolingServers() { + @Override + /** + * Must declare the setter at the descendant Tag class level in order for the tag handler to locate the method. + */ + public void setPerformClearTagStateForTagPoolingServers(boolean performClearTagStateForTagPoolingServers) { + super.setPerformClearTagStateForTagPoolingServers(performClearTagStateForTagPoolingServers); + } + + @Override + protected void clearTagStateForTagPoolingServers() { + if (getPerformClearTagStateForTagPoolingServers() == false) { + return; // If flag is false (default setting), do not perform any state clearing. + } super.clearTagStateForTagPoolingServers(); this.size = null; this.multiple = null; diff --git a/core/src/main/java/org/apache/struts2/views/jsp/ui/LabelTag.java b/core/src/main/java/org/apache/struts2/views/jsp/ui/LabelTag.java index 85a458cd8..b62e50d61 100644 --- a/core/src/main/java/org/apache/struts2/views/jsp/ui/LabelTag.java +++ b/core/src/main/java/org/apache/struts2/views/jsp/ui/LabelTag.java @@ -51,8 +51,19 @@ public class LabelTag extends AbstractUITag { this.forAttr = aFor; } - @Override - public void clearTagStateForTagPoolingServers() { + @Override + /** + * Must declare the setter at the descendant Tag class level in order for the tag handler to locate the method. + */ + public void setPerformClearTagStateForTagPoolingServers(boolean performClearTagStateForTagPoolingServers) { + super.setPerformClearTagStateForTagPoolingServers(performClearTagStateForTagPoolingServers); + } + + @Override + protected void clearTagStateForTagPoolingServers() { + if (getPerformClearTagStateForTagPoolingServers() == false) { + return; // If flag is false (default setting), do not perform any state clearing. + } super.clearTagStateForTagPoolingServers(); this.forAttr = null; } diff --git a/core/src/main/java/org/apache/struts2/views/jsp/ui/OptGroupTag.java b/core/src/main/java/org/apache/struts2/views/jsp/ui/OptGroupTag.java index 8e9ba1ba2..83b6a9de5 100644 --- a/core/src/main/java/org/apache/struts2/views/jsp/ui/OptGroupTag.java +++ b/core/src/main/java/org/apache/struts2/views/jsp/ui/OptGroupTag.java @@ -93,7 +93,18 @@ public class OptGroupTag extends ComponentTagSupport { } @Override - public void clearTagStateForTagPoolingServers() { + /** + * Must declare the setter at the descendant Tag class level in order for the tag handler to locate the method. + */ + public void setPerformClearTagStateForTagPoolingServers(boolean performClearTagStateForTagPoolingServers) { + super.setPerformClearTagStateForTagPoolingServers(performClearTagStateForTagPoolingServers); + } + + @Override + protected void clearTagStateForTagPoolingServers() { + if (getPerformClearTagStateForTagPoolingServers() == false) { + return; // If flag is false (default setting), do not perform any state clearing. + } super.clearTagStateForTagPoolingServers(); this.list = null; this.label = null; diff --git a/core/src/main/java/org/apache/struts2/views/jsp/ui/OptionTransferSelectTag.java b/core/src/main/java/org/apache/struts2/views/jsp/ui/OptionTransferSelectTag.java index da9a097c3..7ad259974 100644 --- a/core/src/main/java/org/apache/struts2/views/jsp/ui/OptionTransferSelectTag.java +++ b/core/src/main/java/org/apache/struts2/views/jsp/ui/OptionTransferSelectTag.java @@ -345,8 +345,19 @@ public class OptionTransferSelectTag extends AbstractDoubleListTag { return this.selectAllOnclick; } - @Override - public void clearTagStateForTagPoolingServers() { + @Override + /** + * Must declare the setter at the descendant Tag class level in order for the tag handler to locate the method. + */ + public void setPerformClearTagStateForTagPoolingServers(boolean performClearTagStateForTagPoolingServers) { + super.setPerformClearTagStateForTagPoolingServers(performClearTagStateForTagPoolingServers); + } + + @Override + protected void clearTagStateForTagPoolingServers() { + if (getPerformClearTagStateForTagPoolingServers() == false) { + return; // If flag is false (default setting), do not perform any state clearing. + } super.clearTagStateForTagPoolingServers(); this.allowAddToLeft = null; this.allowAddToRight = null; diff --git a/core/src/main/java/org/apache/struts2/views/jsp/ui/PasswordTag.java b/core/src/main/java/org/apache/struts2/views/jsp/ui/PasswordTag.java index 3a6b807f3..8732135fb 100644 --- a/core/src/main/java/org/apache/struts2/views/jsp/ui/PasswordTag.java +++ b/core/src/main/java/org/apache/struts2/views/jsp/ui/PasswordTag.java @@ -55,8 +55,19 @@ public class PasswordTag extends TextFieldTag { this.showPassword = showPassword; } - @Override - public void clearTagStateForTagPoolingServers() { + @Override + /** + * Must declare the setter at the descendant Tag class level in order for the tag handler to locate the method. + */ + public void setPerformClearTagStateForTagPoolingServers(boolean performClearTagStateForTagPoolingServers) { + super.setPerformClearTagStateForTagPoolingServers(performClearTagStateForTagPoolingServers); + } + + @Override + protected void clearTagStateForTagPoolingServers() { + if (getPerformClearTagStateForTagPoolingServers() == false) { + return; // If flag is false (default setting), do not perform any state clearing. + } super.clearTagStateForTagPoolingServers(); this.showPassword = null; } diff --git a/core/src/main/java/org/apache/struts2/views/jsp/ui/RadioTag.java b/core/src/main/java/org/apache/struts2/views/jsp/ui/RadioTag.java index 96602979c..a5f4ab1ac 100644 --- a/core/src/main/java/org/apache/struts2/views/jsp/ui/RadioTag.java +++ b/core/src/main/java/org/apache/struts2/views/jsp/ui/RadioTag.java @@ -33,7 +33,16 @@ public class RadioTag extends AbstractRequiredListTag { private static final long serialVersionUID = -6497403399521333624L; + @Override public Component getBean(ValueStack stack, HttpServletRequest req, HttpServletResponse res) { return new Radio(stack, req, res); } + + @Override + /** + * Must declare the setter at the descendant Tag class level in order for the tag handler to locate the method. + */ + public void setPerformClearTagStateForTagPoolingServers(boolean performClearTagStateForTagPoolingServers) { + super.setPerformClearTagStateForTagPoolingServers(performClearTagStateForTagPoolingServers); + } } diff --git a/core/src/main/java/org/apache/struts2/views/jsp/ui/ResetTag.java b/core/src/main/java/org/apache/struts2/views/jsp/ui/ResetTag.java index bda98da93..e623eef7b 100644 --- a/core/src/main/java/org/apache/struts2/views/jsp/ui/ResetTag.java +++ b/core/src/main/java/org/apache/struts2/views/jsp/ui/ResetTag.java @@ -69,8 +69,19 @@ public class ResetTag extends AbstractUITag { this.src = src; } - @Override - public void clearTagStateForTagPoolingServers() { + @Override + /** + * Must declare the setter at the descendant Tag class level in order for the tag handler to locate the method. + */ + public void setPerformClearTagStateForTagPoolingServers(boolean performClearTagStateForTagPoolingServers) { + super.setPerformClearTagStateForTagPoolingServers(performClearTagStateForTagPoolingServers); + } + + @Override + protected void clearTagStateForTagPoolingServers() { + if (getPerformClearTagStateForTagPoolingServers() == false) { + return; // If flag is false (default setting), do not perform any state clearing. + } super.clearTagStateForTagPoolingServers(); this.action = null; this.method = null; diff --git a/core/src/main/java/org/apache/struts2/views/jsp/ui/SelectTag.java b/core/src/main/java/org/apache/struts2/views/jsp/ui/SelectTag.java index dd71eceae..7659f53a2 100644 --- a/core/src/main/java/org/apache/struts2/views/jsp/ui/SelectTag.java +++ b/core/src/main/java/org/apache/struts2/views/jsp/ui/SelectTag.java @@ -76,8 +76,19 @@ public class SelectTag extends AbstractRequiredListTag { this.size = size; } - @Override - public void clearTagStateForTagPoolingServers() { + @Override + /** + * Must declare the setter at the descendant Tag class level in order for the tag handler to locate the method. + */ + public void setPerformClearTagStateForTagPoolingServers(boolean performClearTagStateForTagPoolingServers) { + super.setPerformClearTagStateForTagPoolingServers(performClearTagStateForTagPoolingServers); + } + + @Override + protected void clearTagStateForTagPoolingServers() { + if (getPerformClearTagStateForTagPoolingServers() == false) { + return; // If flag is false (default setting), do not perform any state clearing. + } super.clearTagStateForTagPoolingServers(); this.emptyOption = null; this.headerKey = null; diff --git a/core/src/main/java/org/apache/struts2/views/jsp/ui/SubmitTag.java b/core/src/main/java/org/apache/struts2/views/jsp/ui/SubmitTag.java index 01ca56f34..5250cbe62 100644 --- a/core/src/main/java/org/apache/struts2/views/jsp/ui/SubmitTag.java +++ b/core/src/main/java/org/apache/struts2/views/jsp/ui/SubmitTag.java @@ -87,8 +87,19 @@ public class SubmitTag extends AbstractClosingTag { this.escapeHtmlBody = escapeHtmlBody; } + /** + * Must declare the setter at the descendant Tag class level in order for the tag handler to locate the method. + */ @Override - public void clearTagStateForTagPoolingServers() { + public void setPerformClearTagStateForTagPoolingServers(boolean performClearTagStateForTagPoolingServers) { + super.setPerformClearTagStateForTagPoolingServers(performClearTagStateForTagPoolingServers); + } + + @Override + protected void clearTagStateForTagPoolingServers() { + if (getPerformClearTagStateForTagPoolingServers() == false) { + return; // If flag is false (default setting), do not perform any state clearing. + } super.clearTagStateForTagPoolingServers(); this.action = null; this.method = null; diff --git a/core/src/main/java/org/apache/struts2/views/jsp/ui/TextFieldTag.java b/core/src/main/java/org/apache/struts2/views/jsp/ui/TextFieldTag.java index 71a5d4916..a3325a454 100644 --- a/core/src/main/java/org/apache/struts2/views/jsp/ui/TextFieldTag.java +++ b/core/src/main/java/org/apache/struts2/views/jsp/ui/TextFieldTag.java @@ -69,8 +69,19 @@ public class TextFieldTag extends AbstractUITag { this.type = type; } - @Override - public void clearTagStateForTagPoolingServers() { + @Override + /** + * Must declare the setter at the descendant Tag class level in order for the tag handler to locate the method. + */ + public void setPerformClearTagStateForTagPoolingServers(boolean performClearTagStateForTagPoolingServers) { + super.setPerformClearTagStateForTagPoolingServers(performClearTagStateForTagPoolingServers); + } + + @Override + protected void clearTagStateForTagPoolingServers() { + if (getPerformClearTagStateForTagPoolingServers() == false) { + return; // If flag is false (default setting), do not perform any state clearing. + } super.clearTagStateForTagPoolingServers(); this.maxlength = null; this.readonly = null; diff --git a/core/src/main/java/org/apache/struts2/views/jsp/ui/TextareaTag.java b/core/src/main/java/org/apache/struts2/views/jsp/ui/TextareaTag.java index d1a509f1b..0da6fe8bf 100644 --- a/core/src/main/java/org/apache/struts2/views/jsp/ui/TextareaTag.java +++ b/core/src/main/java/org/apache/struts2/views/jsp/ui/TextareaTag.java @@ -82,8 +82,19 @@ public class TextareaTag extends AbstractUITag { this.minlength = minlength; } - @Override - public void clearTagStateForTagPoolingServers() { + @Override + /** + * Must declare the setter at the descendant Tag class level in order for the tag handler to locate the method. + */ + public void setPerformClearTagStateForTagPoolingServers(boolean performClearTagStateForTagPoolingServers) { + super.setPerformClearTagStateForTagPoolingServers(performClearTagStateForTagPoolingServers); + } + + @Override + protected void clearTagStateForTagPoolingServers() { + if (getPerformClearTagStateForTagPoolingServers() == false) { + return; // If flag is false (default setting), do not perform any state clearing. + } super.clearTagStateForTagPoolingServers(); this.cols = null; this.readonly = null; diff --git a/core/src/main/java/org/apache/struts2/views/jsp/ui/TokenTag.java b/core/src/main/java/org/apache/struts2/views/jsp/ui/TokenTag.java index 1f9468269..806116c79 100644 --- a/core/src/main/java/org/apache/struts2/views/jsp/ui/TokenTag.java +++ b/core/src/main/java/org/apache/struts2/views/jsp/ui/TokenTag.java @@ -33,7 +33,17 @@ public class TokenTag extends AbstractUITag { private static final long serialVersionUID = 722480798151703457L; + @Override public Component getBean(ValueStack stack, HttpServletRequest req, HttpServletResponse res) { return new Token(stack, req, res); } + + @Override + /** + * Must declare the setter at the descendant Tag class level in order for the tag handler to locate the method. + */ + public void setPerformClearTagStateForTagPoolingServers(boolean performClearTagStateForTagPoolingServers) { + super.setPerformClearTagStateForTagPoolingServers(performClearTagStateForTagPoolingServers); + } + } diff --git a/core/src/main/java/org/apache/struts2/views/jsp/ui/UpDownSelectTag.java b/core/src/main/java/org/apache/struts2/views/jsp/ui/UpDownSelectTag.java index f7b36478a..4713c5cf1 100644 --- a/core/src/main/java/org/apache/struts2/views/jsp/ui/UpDownSelectTag.java +++ b/core/src/main/java/org/apache/struts2/views/jsp/ui/UpDownSelectTag.java @@ -122,7 +122,18 @@ public class UpDownSelectTag extends SelectTag { } @Override - public void clearTagStateForTagPoolingServers() { + /** + * Must declare the setter at the descendant Tag class level in order for the tag handler to locate the method. + */ + public void setPerformClearTagStateForTagPoolingServers(boolean performClearTagStateForTagPoolingServers) { + super.setPerformClearTagStateForTagPoolingServers(performClearTagStateForTagPoolingServers); + } + + @Override + protected void clearTagStateForTagPoolingServers() { + if (getPerformClearTagStateForTagPoolingServers() == false) { + return; // If flag is false (default setting), do not perform any state clearing. + } super.clearTagStateForTagPoolingServers(); this.allowMoveUp = null; this.allowMoveDown = null; diff --git a/core/src/test/java/org/apache/struts2/views/jsp/AbstractTagTest.java b/core/src/test/java/org/apache/struts2/views/jsp/AbstractTagTest.java index 4179fde27..c22f90404 100644 --- a/core/src/test/java/org/apache/struts2/views/jsp/AbstractTagTest.java +++ b/core/src/test/java/org/apache/struts2/views/jsp/AbstractTagTest.java @@ -169,4 +169,22 @@ public abstract class AbstractTagTest extends StrutsInternalTestCase { return objectsAreReflectionEqual(tag1, tag2); } + /** + * Helper method to simplify setting the performClearTagStateForTagPoolingServers state for a + * {@link ComponentTagSupport} tag's {@link Component} to match expectations for the test. + * + * The component reference is not available to the tag until after the doStartTag() method is called. + * We need to ensure the component's {@link Component#performClearTagStateForTagPoolingServers} state matches + * what we set for the Tag when a non-default (true) value is used, so this method accesses the component instance, + * sets the value specified and forces the tag's parameters to be repopulated again. + * + * @param tag The ComponentTagSupport tag upon whose component we will set the performClearTagStateForTagPoolingServers state. + * @param performClearTagStateForTagPoolingServers true to clear tag state, false otherwise + */ + protected void setComponentTagClearTagState(ComponentTagSupport tag, boolean performClearTagStateForTagPoolingServers) { + tag.component.setPerformClearTagStateForTagPoolingServers(performClearTagStateForTagPoolingServers); + //tag.populateParams(); // Not safe to call after doStartTag() ... breaks some tests. + tag.populatePerformClearTagStateForTagPoolingServersParam(); // Only populate the performClearTagStateForTagPoolingServers parameter for the Tag. + } + } diff --git a/core/src/test/java/org/apache/struts2/views/jsp/ActionTagTest.java b/core/src/test/java/org/apache/struts2/views/jsp/ActionTagTest.java index ff38a19d6..dc35e3646 100644 --- a/core/src/test/java/org/apache/struts2/views/jsp/ActionTagTest.java +++ b/core/src/test/java/org/apache/struts2/views/jsp/ActionTagTest.java @@ -70,7 +70,41 @@ public class ActionTagTest extends AbstractTagTest { // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). ActionTag freshTag = new ActionTag(); freshTag.setPageContext(pageContext); - assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + 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 testActionTagWithNamespace_clearTagStateSet() { + request.setupGetServletPath(TestConfigurationProvider.TEST_NAMESPACE + "/" + "foo.action"); + + ActionTag tag = new ActionTag(); + tag.setPerformClearTagStateForTagPoolingServers(true); // Explicitly request tag state clearing. + tag.setPageContext(pageContext); + tag.setName(TestConfigurationProvider.TEST_NAMESPACE_ACTION); + tag.setVar(TestConfigurationProvider.TEST_NAMESPACE_ACTION); + + try { + tag.doStartTag(); + setComponentTagClearTagState(tag, true); // Ensure component tag state clearing is set true (to match tag). + ActionComponent ac = ((ActionComponent) tag.component); + tag.doEndTag(); + ActionProxy proxy = ac.getProxy(); + + Object o = pageContext.findAttribute(TestConfigurationProvider.TEST_NAMESPACE_ACTION); + assertTrue(o instanceof TestAction); + + assertEquals(TestConfigurationProvider.TEST_NAMESPACE, proxy.getNamespace()); + } catch (JspException ex) { + ex.printStackTrace(); + fail(); + } + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + ActionTag freshTag = new ActionTag(); + freshTag.setPerformClearTagStateForTagPoolingServers(true); + 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)); } @@ -109,7 +143,50 @@ public class ActionTagTest extends AbstractTagTest { // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). ActionTag freshTag = new ActionTag(); freshTag.setPageContext(pageContext); - assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + 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 testSimple_clearTagStateSet() { + request.setupGetServletPath("/foo.action"); + + ActionConfig config = configuration.getRuntimeConfiguration().getActionConfig("", "testAction"); + container.inject(config.getInterceptors().get(0).getInterceptor()); + + ActionTag tag = new ActionTag(); + tag.setPerformClearTagStateForTagPoolingServers(true); // Explicitly request tag state clearing. + tag.setPageContext(pageContext); + tag.setName("testAction"); + tag.setVar("testAction"); + + int stackSize = stack.size(); + + try { + tag.doStartTag(); + setComponentTagClearTagState(tag, true); // Ensure component tag state clearing is set true (to match tag). + tag.addParameter("foo", "myFoo"); + tag.doEndTag(); + + assertEquals(stack.size(), ActionContext.getContext().getValueStack().size()); + assertEquals("myFoo", stack.findValue("#testAction.foo")); + assertEquals(stackSize, stack.size()); + + Object o = pageContext.findAttribute("testAction"); + assertTrue(o instanceof TestAction); + assertEquals("myFoo", ((TestAction) o).getFoo()); + assertEquals(Action.SUCCESS, ((TestAction) o).getResult()); + } catch (JspException ex) { + ex.printStackTrace(); + fail(); + } + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + ActionTag freshTag = new ActionTag(); + freshTag.setPerformClearTagStateForTagPoolingServers(true); + 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)); @@ -155,7 +232,50 @@ public class ActionTagTest extends AbstractTagTest { // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). ActionTag freshTag = new ActionTag(); freshTag.setPageContext(pageContext); - assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + 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 testSimpleWithctionMethodInOriginalURI_clearTagStateSet() { + request.setupGetServletPath("/foo!foo.action"); + + ActionConfig config = configuration.getRuntimeConfiguration().getActionConfig("", "testAction"); + container.inject(config.getInterceptors().get(0).getInterceptor()); + + ActionTag tag = new ActionTag(); + tag.setPerformClearTagStateForTagPoolingServers(true); // Explicitly request tag state clearing. + tag.setPageContext(pageContext); + tag.setName("testAction"); + tag.setVar("testAction"); + + int stackSize = stack.size(); + + try { + tag.doStartTag(); + setComponentTagClearTagState(tag, true); // Ensure component tag state clearing is set true (to match tag). + tag.addParameter("foo", "myFoo"); + tag.doEndTag(); + + assertEquals(stack.size(), ActionContext.getContext().getValueStack().size()); + assertEquals("myFoo", stack.findValue("#testAction.foo")); + assertEquals(stackSize, stack.size()); + + Object o = pageContext.findAttribute("testAction"); + assertTrue(o instanceof TestAction); + assertEquals("myFoo", ((TestAction) o).getFoo()); + assertEquals(Action.SUCCESS, ((TestAction) o).getResult()); + } catch (JspException ex) { + ex.printStackTrace(); + fail(); + } + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + ActionTag freshTag = new ActionTag(); + freshTag.setPerformClearTagStateForTagPoolingServers(true); + 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)); @@ -184,7 +304,39 @@ public class ActionTagTest extends AbstractTagTest { // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). ActionTag freshTag = new ActionTag(); freshTag.setPageContext(pageContext); - assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + 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 testActionWithExecuteResult_clearTagStateSet() throws Exception { + ActionTag tag = new ActionTag(); + tag.setPerformClearTagStateForTagPoolingServers(true); // Explicitly request tag state clearing. + tag.setPageContext(pageContext); + tag.setNamespace(""); + tag.setName("testActionTagAction"); + tag.setExecuteResult(true); + + tag.doStartTag(); + setComponentTagClearTagState(tag, true); // Ensure component tag state clearing is set true (to match tag). + + // tag clear components on doEndTag + ActionComponent component = (ActionComponent) tag.getComponent(); + + tag.doEndTag(); + + TestActionTagResult result = (TestActionTagResult) component.getProxy().getInvocation().getResult(); + + assertTrue(stack.getContext().containsKey(ServletActionContext.PAGE_CONTEXT)); + assertTrue(stack.getContext().get(ServletActionContext.PAGE_CONTEXT)instanceof PageContext); + assertTrue(result.isExecuted()); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + ActionTag freshTag = new ActionTag(); + freshTag.setPerformClearTagStateForTagPoolingServers(true); + 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)); @@ -213,7 +365,38 @@ public class ActionTagTest extends AbstractTagTest { // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). ActionTag freshTag = new ActionTag(); freshTag.setPageContext(pageContext); - assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + 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 testActionWithoutExecuteResult_clearTagStateSet() throws Exception { + ActionTag tag = new ActionTag(); + tag.setPerformClearTagStateForTagPoolingServers(true); // Explicitly request tag state clearing. + tag.setPageContext(pageContext); + tag.setNamespace(""); + tag.setName("testActionTagAction"); + tag.setExecuteResult(false); + + tag.doStartTag(); + setComponentTagClearTagState(tag, true); // Ensure component tag state clearing is set true (to match tag). + + // tag clear components on doEndTag, so we need to get it here + ActionComponent component = (ActionComponent) tag.getComponent(); + + tag.doEndTag(); + + TestActionTagResult result = (TestActionTagResult) component.getProxy().getInvocation().getResult(); + + assertTrue(stack.getContext().containsKey(ServletActionContext.PAGE_CONTEXT)); + assertTrue(stack.getContext().get(ServletActionContext.PAGE_CONTEXT)instanceof PageContext); + assertNull(result); // result is never executed, hence never set into invocation + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + ActionTag freshTag = new ActionTag(); + freshTag.setPerformClearTagStateForTagPoolingServers(true); + 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)); } @@ -241,7 +424,39 @@ public class ActionTagTest extends AbstractTagTest { // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). ActionTag freshTag = new ActionTag(); freshTag.setPageContext(pageContext); - assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + 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 testExecuteButResetReturnSameInvocation_clearTagStateSet() throws Exception { + Mock mockActionInv = new Mock(ActionInvocation.class); + ActionTag tag = new ActionTag(); + tag.setPerformClearTagStateForTagPoolingServers(true); // Explicitly request tag state clearing. + tag.setPageContext(pageContext); + tag.setNamespace(""); + tag.setName("testActionTagAction"); + tag.setExecuteResult(true); + ActionContext.getContext().setActionInvocation((ActionInvocation) mockActionInv.proxy()); + + ActionInvocation oldInvocation = ActionContext.getContext().getActionInvocation(); + assertNotNull(oldInvocation); + + tag.doStartTag(); + setComponentTagClearTagState(tag, true); // Ensure component tag state clearing is set true (to match tag). + + // tag clear components on doEndTag + ActionComponent component = (ActionComponent) tag.getComponent(); + + tag.doEndTag(); + assertTrue(oldInvocation == ActionContext.getContext().getActionInvocation()); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + ActionTag freshTag = new ActionTag(); + freshTag.setPerformClearTagStateForTagPoolingServers(true); + 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)); } @@ -273,7 +488,43 @@ public class ActionTagTest extends AbstractTagTest { // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). ActionTag freshTag = new ActionTag(); freshTag.setPageContext(pageContext); - assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + 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 testIngoreContextParamsFalse_clearTagStateSet() throws Exception { + ActionTag tag = new ActionTag(); + tag.setPerformClearTagStateForTagPoolingServers(true); // Explicitly request tag state clearing. + tag.setPageContext(pageContext); + tag.setNamespace(""); + tag.setName("testActionTagAction"); + tag.setExecuteResult(false); + tag.setIgnoreContextParams(false); + + Map params = new HashMap<>(); + params.put("user", new String[]{"Santa Claus"}); + ActionContext.getContext().setParameters(HttpParameters.create(params).build()); + + tag.doStartTag(); + setComponentTagClearTagState(tag, true); // Ensure component tag state clearing is set true (to match tag). + + // tag clear components on doEndTag, so we need to get it here + ActionComponent component = (ActionComponent) tag.getComponent(); + + tag.doEndTag(); + + // check parameters, there should be one + ActionInvocation ai = component.getProxy().getInvocation(); + ActionContext ac = ai.getInvocationContext(); + assertEquals(1, ac.getParameters().keySet().size()); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + ActionTag freshTag = new ActionTag(); + freshTag.setPerformClearTagStateForTagPoolingServers(true); + 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)); @@ -306,7 +557,42 @@ public class ActionTagTest extends AbstractTagTest { // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). ActionTag freshTag = new ActionTag(); freshTag.setPageContext(pageContext); - assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + 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 testIngoreContextParamsTrue_clearTagStateSet() throws Exception { + ActionTag tag = new ActionTag(); + tag.setPerformClearTagStateForTagPoolingServers(true); // Explicitly request tag state clearing. + tag.setPageContext(pageContext); + tag.setNamespace(""); + tag.setName("testActionTagAction"); + tag.setExecuteResult(false); + tag.setIgnoreContextParams(true); + + Map params = new HashMap<>(); + params.put("user", new String[] { "Santa Claus" }); + ActionContext.getContext().setParameters(HttpParameters.create(params).build()); + + tag.doStartTag(); + setComponentTagClearTagState(tag, true); // Ensure component tag state clearing is set true (to match tag). + + // tag clear components on doEndTag, so we need to get it here + ActionComponent component = (ActionComponent) tag.getComponent(); + + tag.doEndTag(); + + // check parameters, there should be one + ActionInvocation ai = component.getProxy().getInvocation(); + ActionContext ac = ai.getInvocationContext(); + assertEquals(0, ac.getParameters().keySet().size()); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + ActionTag freshTag = new ActionTag(); + freshTag.setPerformClearTagStateForTagPoolingServers(true); + 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)); } @@ -344,7 +630,30 @@ public class ActionTagTest extends AbstractTagTest { // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). ActionTag freshTag = new ActionTag(); freshTag.setPageContext(pageContext); - assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + 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)); + } + + // FIXME: Logging the error seems to cause the standard Maven build to fail + public void testUnknownNameDefined_clearTagStateSet() throws Exception { + ActionTag tag = new ActionTag(); + tag.setPerformClearTagStateForTagPoolingServers(true); // Explicitly request tag state clearing. + tag.setPageContext(pageContext); + tag.setNamespace(""); + tag.setName("UNKNOWN_NAME"); + tag.setExecuteResult(false); + + tag.doStartTag(); + setComponentTagClearTagState(tag, true); // Ensure component tag state clearing is set true (to match tag). + tag.doEndTag(); + // will just log it to ERROR but we run the code to test that it works somehow + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + ActionTag freshTag = new ActionTag(); + freshTag.setPerformClearTagStateForTagPoolingServers(true); + 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)); } @@ -373,7 +682,39 @@ public class ActionTagTest extends AbstractTagTest { // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). ActionTag freshTag = new ActionTag(); freshTag.setPageContext(pageContext); - assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + 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 testActionMethodWithExecuteResult_clearTagStateSet() throws Exception { + ActionTag tag = new ActionTag(); + tag.setPerformClearTagStateForTagPoolingServers(true); // Explicitly request tag state clearing. + tag.setPageContext(pageContext); + tag.setNamespace(""); + tag.setName("testActionTagAction!input"); + tag.setExecuteResult(true); + ((DefaultActionMapper)container.getInstance(ActionMapper.class)).setAllowDynamicMethodCalls("true"); + + tag.doStartTag(); + setComponentTagClearTagState(tag, true); // Ensure component tag state clearing is set true (to match tag). + + // tag clear components on doEndTag + ActionComponent component = (ActionComponent) tag.getComponent(); + + tag.doEndTag(); + + TestActionTagResult result = (TestActionTagResult) component.getProxy().getInvocation().getResult(); + + assertTrue(stack.getContext().containsKey(ServletActionContext.PAGE_CONTEXT)); + assertTrue(stack.getContext().get(ServletActionContext.PAGE_CONTEXT)instanceof PageContext); + assertTrue(result.isExecuted()); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + ActionTag freshTag = new ActionTag(); + freshTag.setPerformClearTagStateForTagPoolingServers(true); + 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)); } diff --git a/core/src/test/java/org/apache/struts2/views/jsp/AnchorTagTest.java b/core/src/test/java/org/apache/struts2/views/jsp/AnchorTagTest.java index ebff0e1dc..7d0de563c 100644 --- a/core/src/test/java/org/apache/struts2/views/jsp/AnchorTagTest.java +++ b/core/src/test/java/org/apache/struts2/views/jsp/AnchorTagTest.java @@ -53,7 +53,29 @@ public class AnchorTagTest extends AbstractUITagTest { // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). AnchorTag freshTag = new AnchorTag(); freshTag.setPageContext(pageContext); - assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + 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 testActionURL_clearTagStateSet() { + tag.setPerformClearTagStateForTagPoolingServers(true); // Explicitly request tag state clearing. + tag.setHref("TestAction.action"); + try { + tag.doStartTag(); + setComponentTagClearTagState(tag, true); // Ensure component tag state clearing is set true (to match tag). + tag.doEndTag(); + assertTrue(writer.toString().indexOf("href=\"TestAction.action\"") > -1); + } catch (JspException ex) { + ex.printStackTrace(); + fail(); + } + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + AnchorTag freshTag = new AnchorTag(); + freshTag.setPerformClearTagStateForTagPoolingServers(true); + 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)); } @@ -76,7 +98,33 @@ public class AnchorTagTest extends AbstractUITagTest { // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). AnchorTag freshTag = new AnchorTag(); freshTag.setPageContext(pageContext); - assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + 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 testAddParameters_clearTagStateSet() { + tag.setPerformClearTagStateForTagPoolingServers(true); // Explicitly request tag state clearing. + tag.setHref("/TestAction.action"); + String bodyText = ""; + try { + StrutsBodyContent bodyContent = new StrutsBodyContent(null); + bodyContent.print(bodyText); + tag.setBodyContent(bodyContent); + + tag.doStartTag(); + setComponentTagClearTagState(tag, true); // Ensure component tag state clearing is set true (to match tag). + tag.doEndTag(); + } catch (Exception ex) { + ex.printStackTrace(); + fail(); + } + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + AnchorTag freshTag = new AnchorTag(); + freshTag.setPerformClearTagStateForTagPoolingServers(true); + 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)); } @@ -163,7 +211,100 @@ public class AnchorTagTest extends AbstractUITagTest { // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). AnchorTag freshTag = new AnchorTag(); freshTag.setPageContext(pageContext); - assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + 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)); + } + + /** + * To test priority of parameter passed in to url component though + * various way + * - current request url + * - tag's value attribute + * - tag's nested param tag + *
+ * id1 + * === + * - found in current request url + * - found in tag's value attribute + * - found in tag's param tag + * CONCLUSION: tag's param tag takes precedence (paramId1) + *
+ * id2 + * === + * - found in current request url + * - found in tag's value attribute + * CONCLUSION: tag's value attribute take precedence (tagId2) + *
+ * urlParam1 + * ========= + * - found in current request url + * CONCLUSION: param in current request url will be used (urlValue1) + *
+ * urlParam2 + * ========= + * - found in current request url + * CONCLUSION: param in current request url will be used. (urlValue2) + *
+ * tagId + * ===== + * - found in tag's value attribute + * CONCLUSION: param in tag's value attribute wil; be used. (tagValue) + *
+ * param1 + * ====== + * - found in nested param tag + * CONCLUSION: param in nested param tag will be used. (param1value) + *
+ * param2 + * ====== + * - found in nested param tag + * CONCLUSION: param in nested param tag will be used. (param2value) + */ + public void testParametersPriority_clearTagStateSet() throws Exception { + request.setQueryString("id1=urlId1&id2=urlId2&urlParam1=urlValue1&urlParam2=urlValue2"); + + tag.setPerformClearTagStateForTagPoolingServers(true); // Explicitly request tag state clearing. + tag.setValue("testAction.action?id1=tagId1&id2=tagId2&tagId=tagValue"); + + ParamTag param1 = new ParamTag(); + param1.setPageContext(pageContext); + param1.setName("param1"); + param1.setValue("%{'param1value'}"); + + ParamTag param2 = new ParamTag(); + param2.setPageContext(pageContext); + param2.setName("param2"); + param2.setValue("%{'param2value'}"); + + ParamTag param3 = new ParamTag(); + param3.setPageContext(pageContext); + param3.setName("id1"); + param3.setValue("%{'paramId1'}"); + + + tag.doStartTag(); + setComponentTagClearTagState(tag, true); // Ensure component tag state clearing is set true (to match tag). + param1.doStartTag(); + setComponentTagClearTagState(param1, true); // Ensure component tag state clearing is set true (to match tag). + param1.doEndTag(); + param2.doStartTag(); + setComponentTagClearTagState(param2, true); // Ensure component tag state clearing is set true (to match tag). + param2.doEndTag(); + param3.doStartTag(); + setComponentTagClearTagState(param3, true); // Ensure component tag state clearing is set true (to match tag). + param3.doEndTag(); + + tag.doEndTag(); + + assertEquals(wrapWithAnchor("testAction.action?id1=paramId1&id2=tagId2&" + + "amp;tagId=tagValue&urlParam1=urlValue1&urlParam2=urlValue2&param1=param1value&param2=param2value"), writer.toString()); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + AnchorTag freshTag = new AnchorTag(); + freshTag.setPerformClearTagStateForTagPoolingServers(true); + 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)); } @@ -193,7 +334,7 @@ public class AnchorTagTest extends AbstractUITagTest { // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). ParamTag freshParamTag = new ParamTag(); freshParamTag.setPageContext(pageContext); - assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + 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(param1, freshParamTag)); @@ -207,7 +348,7 @@ public class AnchorTagTest extends AbstractUITagTest { param2.doEndTag(); // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). - assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + 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(param2, freshParamTag)); @@ -222,7 +363,7 @@ public class AnchorTagTest extends AbstractUITagTest { param3.doEndTag(); // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). - assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + 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(param3, freshParamTag)); @@ -240,7 +381,94 @@ public class AnchorTagTest extends AbstractUITagTest { // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). AnchorTag freshTag = new AnchorTag(); 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)); + } + + /** + * Use Iterable values as the value of the param tags + * + * @throws Exception + */ + public void testIterableParameters_clearTagStateSet() throws Exception { + tag.setValue("/TestAction.action?p0=z"); + + tag.setPerformClearTagStateForTagPoolingServers(true); // Explicitly request tag state clearing. + tag.doStartTag(); + setComponentTagClearTagState(tag, true); // Ensure component tag state clearing is set true (to match tag). + //Iterable + List list = new ArrayList(); + list.add(new URLTagTest.ValueHolder("a")); + list.add(new URLTagTest.ValueHolder("b")); + stack.getContext().put("param1value", list); + + ParamTag param1 = new ParamTag(); + param1.setPerformClearTagStateForTagPoolingServers(true); // Explicitly request tag state clearing. + param1.setPageContext(pageContext); + param1.setName("p1"); + param1.setValue("%{#param1value}"); + param1.doStartTag(); + setComponentTagClearTagState(param1, true); // Ensure component tag state clearing is set true (to match tag). + param1.doEndTag(); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + ParamTag freshParamTag = new ParamTag(); + freshParamTag.setPerformClearTagStateForTagPoolingServers(true); + freshParamTag.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(param1, freshParamTag)); + + //String[] + stack.getContext().put("param2value", new String[]{"d", "e"}); + ParamTag param2 = new ParamTag(); + param2.setPerformClearTagStateForTagPoolingServers(true); // Explicitly request tag state clearing. + param2.setPageContext(pageContext); + param2.setName("p2"); + param2.setValue("%{#param2value}"); + param2.doStartTag(); + setComponentTagClearTagState(param2, true); // Ensure component tag state clearing is set true (to match tag). + param2.doEndTag(); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + 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(param2, freshParamTag)); + + //ValueHolder[] + stack.getContext().put("param3value", new URLTagTest.ValueHolder[]{ + new URLTagTest.ValueHolder("f"), new URLTagTest.ValueHolder("g")}); + ParamTag param3 = new ParamTag(); + param3.setPerformClearTagStateForTagPoolingServers(true); // Explicitly request tag state clearing. + param3.setPageContext(pageContext); + param3.setName("p3"); + param3.setValue("%{#param3value}"); + param3.doStartTag(); + setComponentTagClearTagState(param3, true); // Ensure component tag state clearing is set true (to match tag). + param3.doEndTag(); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", + strutsBodyTagsAreReflectionEqual(param3, freshParamTag)); + + tag.doEndTag(); + + String result = writer.toString(); + assertTrue(result.contains("p1=a")); + assertTrue(result.contains("p1=b")); + assertTrue(result.contains("p2=d")); + assertTrue(result.contains("p2=e")); + assertTrue(result.contains("p3=f")); + assertTrue(result.contains("p3=g")); + assertTrue(result.contains("p0=z")); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + AnchorTag freshTag = new AnchorTag(); + freshTag.setPerformClearTagStateForTagPoolingServers(true); + 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)); } @@ -298,20 +526,101 @@ public class AnchorTagTest extends AbstractUITagTest { // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). ParamTag freshParamTag = new ParamTag(); freshParamTag.setPageContext(pageContext); - assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + 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(param1, freshParamTag)); - assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + 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(param2, freshParamTag)); - assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + 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(param3, freshParamTag)); // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). AnchorTag freshTag = new AnchorTag(); freshTag.setPageContext(pageContext); - assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + 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)); + } + + /** + *

+ * To test priority of parameter passed in to url component though + * various way, with includeParams="NONE" + *

+ * + * - current request url
+ * - tag's value attribute
+ * - tag's nested param tag
+ * + *

+ * In this case only parameters from the tag itself is taken into account. + * Those from request will not count, only those in tag's value attribute + * and nested param tag. + *

+ * @throws Exception + */ + public void testParametersPriorityWithIncludeParamsAsNONE_clearTagStateSet() throws Exception { + request.setQueryString("id1=urlId1&id2=urlId2&urlParam1=urlValue1&urlParam2=urlValue2"); + + tag.setPerformClearTagStateForTagPoolingServers(true); // Explicitly request tag state clearing. + tag.setValue("testAction.action?id1=tagId1&id2=tagId2&tagId=tagValue"); + tag.setIncludeParams("NONE"); + + ParamTag param1 = new ParamTag(); + param1.setPerformClearTagStateForTagPoolingServers(true); // Explicitly request tag state clearing. + param1.setPageContext(pageContext); + param1.setName("param1"); + param1.setValue("%{'param1value'}"); + + ParamTag param2 = new ParamTag(); + param2.setPerformClearTagStateForTagPoolingServers(true); // Explicitly request tag state clearing. + param2.setPageContext(pageContext); + param2.setName("param2"); + param2.setValue("%{'param2value'}"); + + ParamTag param3 = new ParamTag(); + param3.setPerformClearTagStateForTagPoolingServers(true); // Explicitly request tag state clearing. + param3.setPageContext(pageContext); + param3.setName("id1"); + param3.setValue("%{'paramId1'}"); + + + tag.doStartTag(); + setComponentTagClearTagState(tag, true); // Ensure component tag state clearing is set true (to match tag). + param1.doStartTag(); + setComponentTagClearTagState(param1, true); // Ensure component tag state clearing is set true (to match tag). + param1.doEndTag(); + param2.doStartTag(); + setComponentTagClearTagState(param2, true); // Ensure component tag state clearing is set true (to match tag). + param2.doEndTag(); + param3.doStartTag(); + setComponentTagClearTagState(param3, true); // Ensure component tag state clearing is set true (to match tag). + param3.doEndTag(); + tag.doEndTag(); + + assertEquals(wrapWithAnchor("testAction.action?id1=paramId1&id2=tagId2&tagId=tagValue&param1=param1value&param2=param2value"), writer.toString()); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + ParamTag freshParamTag = new ParamTag(); + freshParamTag.setPerformClearTagStateForTagPoolingServers(true); + freshParamTag.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(param1, freshParamTag)); + 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(param2, freshParamTag)); + 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(param3, freshParamTag)); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + AnchorTag freshTag = new AnchorTag(); + freshTag.setPerformClearTagStateForTagPoolingServers(true); + 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)); } @@ -337,7 +646,36 @@ public class AnchorTagTest extends AbstractUITagTest { // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). AnchorTag freshTag = new AnchorTag(); freshTag.setPageContext(pageContext); - assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + 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 testIncludeParamsDefaultToGET_clearTagStateSet() throws Exception { + request.setQueryString("one=oneVal&two=twoVal&three=threeVal"); + + // request parameter map should not have any effect, as includeParams + // default to GET, which get its param from request.getQueryString() + Map tmp = new HashMap(); + tmp.put("one", "aaa"); + tmp.put("two", "bbb"); + tmp.put("three", "ccc"); + request.setParameterMap(tmp); + + tag.setPerformClearTagStateForTagPoolingServers(true); // Explicitly request tag state clearing. + tag.setValue("TestAction.acton"); + + tag.doStartTag(); + setComponentTagClearTagState(tag, true); // Ensure component tag state clearing is set true (to match tag). + tag.doEndTag(); + + assertEquals(wrapWithAnchor("TestAction.acton?one=oneVal&two=twoVal&three=threeVal"), writer.toString()); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + AnchorTag freshTag = new AnchorTag(); + freshTag.setPerformClearTagStateForTagPoolingServers(true); + 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)); } @@ -379,17 +717,69 @@ public class AnchorTagTest extends AbstractUITagTest { // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). ParamTag freshParamTag = new ParamTag(); freshParamTag.setPageContext(pageContext); - assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + 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(param1, freshParamTag)); - assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + 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(param2, freshParamTag)); // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). AnchorTag freshTag = new AnchorTag(); freshTag.setPageContext(pageContext); - assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + assertTrue("Tag state after doEndTag() under default tag clear state is inequal to new Tag with pageContext/parent set. " + + "For this test, tag only has pageContext set, so it should still be equal.", + strutsBodyTagsAreReflectionEqual(tag, freshTag)); + } + + public void testAddParameters2_clearTagStateSet() throws Exception { + request.setAttribute("struts.request_uri", "/TestAction.action"); + request.setQueryString("param0=value0"); + + tag.setPerformClearTagStateForTagPoolingServers(true); // Explicitly request tag state clearing. + tag.doStartTag(); + setComponentTagClearTagState(tag, true); // Ensure component tag state clearing is set true (to match tag). + ParamTag param1 = new ParamTag(); + param1.setPerformClearTagStateForTagPoolingServers(true); // Explicitly request tag state clearing. + param1.setPageContext(pageContext); + param1.setName("param1"); + param1.setValue("%{'value1'}"); + param1.doStartTag(); + setComponentTagClearTagState(param1, true); // Ensure component tag state clearing is set true (to match tag). + param1.doEndTag(); + + ParamTag param2 = new ParamTag(); + param2.setPerformClearTagStateForTagPoolingServers(true); // Explicitly request tag state clearing. + param2.setPageContext(pageContext); + param2.setName("param2"); + param2.setValue("%{'value2'}"); + param2.doStartTag(); + setComponentTagClearTagState(param2, true); // Ensure component tag state clearing is set true (to match tag). + param2.doEndTag(); + + tag.doEndTag(); + String result = writer.toString(); + assertTrue(result.contains("param0=value0")); + assertTrue(result.contains("param1=value1")); + assertTrue(result.contains("param2=value2")); + assertTrue(result.contains("/TestAction.action")); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + ParamTag freshParamTag = new ParamTag(); + freshParamTag.setPerformClearTagStateForTagPoolingServers(true); + freshParamTag.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(param1, freshParamTag)); + 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(param2, freshParamTag)); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + AnchorTag freshTag = new AnchorTag(); + freshTag.setPerformClearTagStateForTagPoolingServers(true); + 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)); } @@ -407,7 +797,28 @@ public class AnchorTagTest extends AbstractUITagTest { // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). AnchorTag freshTag = new AnchorTag(); freshTag.setPageContext(pageContext); - assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + 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 testEvaluateValue_clearTagStateSet() throws Exception { + URLTagTest.Foo foo = new URLTagTest.Foo(); + foo.setTitle("test"); + stack.push(foo); + tag.setPerformClearTagStateForTagPoolingServers(true); // Explicitly request tag state clearing. + tag.setValue("%{title}"); + + tag.doStartTag(); + setComponentTagClearTagState(tag, true); // Ensure component tag state clearing is set true (to match tag). + tag.doEndTag(); + assertEquals(wrapWithAnchor("test"), writer.toString()); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + AnchorTag freshTag = new AnchorTag(); + freshTag.setPerformClearTagStateForTagPoolingServers(true); + 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)); } @@ -426,7 +837,29 @@ public class AnchorTagTest extends AbstractUITagTest { // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). AnchorTag freshTag = new AnchorTag(); freshTag.setPageContext(pageContext); - assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + 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 testHttps_clearTagStateSet() throws Exception { + request.setScheme("https"); + request.setServerName("localhost"); + request.setServerPort(443); + + tag.setPerformClearTagStateForTagPoolingServers(true); // Explicitly request tag state clearing. + tag.setValue("list-members.action"); + + tag.doStartTag(); + setComponentTagClearTagState(tag, true); // Ensure component tag state clearing is set true (to match tag). + tag.doEndTag(); + assertEquals(wrapWithAnchor("list-members.action"), writer.toString()); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + AnchorTag freshTag = new AnchorTag(); + freshTag.setPerformClearTagStateForTagPoolingServers(true); + 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)); } @@ -446,7 +879,30 @@ public class AnchorTagTest extends AbstractUITagTest { // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). AnchorTag freshTag = new AnchorTag(); freshTag.setPageContext(pageContext); - assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + 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 testAnchor_clearTagStateSet() throws Exception { + request.setScheme("https"); + request.setServerName("localhost"); + request.setServerPort(443); + + tag.setPerformClearTagStateForTagPoolingServers(true); // Explicitly request tag state clearing. + tag.setValue("list-members.action"); + tag.setAnchor("test"); + + tag.doStartTag(); + setComponentTagClearTagState(tag, true); // Ensure component tag state clearing is set true (to match tag). + tag.doEndTag(); + assertEquals(wrapWithAnchor("list-members.action#test"), writer.toString()); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + AnchorTag freshTag = new AnchorTag(); + freshTag.setPerformClearTagStateForTagPoolingServers(true); + 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)); } @@ -475,16 +931,58 @@ public class AnchorTagTest extends AbstractUITagTest { // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). ParamTag freshParamTag = new ParamTag(); freshParamTag.setPageContext(pageContext); - assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + 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(paramTag, freshParamTag)); // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). AnchorTag freshTag = new AnchorTag(); freshTag.setPageContext(pageContext); - assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + 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(anchor, freshTag)); + } + + public void testParamPrecedence_clearTagStateSet() throws Exception { + request.setRequestURI("/context/someAction.action"); + request.setQueryString("id=22&name=John"); + + AnchorTag anchor = new AnchorTag(); + anchor.setPerformClearTagStateForTagPoolingServers(true); // Explicitly request tag state clearing. + anchor.setPageContext(pageContext); + anchor.setIncludeParams("get"); + anchor.setEncode("%{false}"); + + ParamTag paramTag = new ParamTag(); + paramTag.setPerformClearTagStateForTagPoolingServers(true); // Explicitly request tag state clearing. + paramTag.setPageContext(pageContext); + paramTag.setName("id"); + paramTag.setValue("%{'33'}"); + + anchor.doStartTag(); + setComponentTagClearTagState(anchor, true); // Ensure component tag state clearing is set true (to match tag). + paramTag.doStartTag(); + setComponentTagClearTagState(paramTag, true); // Ensure component tag state clearing is set true (to match tag). + paramTag.doEndTag(); + anchor.doEndTag(); + + assertEquals(wrapWithAnchor("/context/someAction.action?id=33&name=John"), writer.getBuffer().toString()); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + ParamTag freshParamTag = new ParamTag(); + freshParamTag.setPerformClearTagStateForTagPoolingServers(true); + freshParamTag.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(paramTag, freshParamTag)); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + AnchorTag freshTag = new AnchorTag(); + freshTag.setPerformClearTagStateForTagPoolingServers(true); + 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(anchor, freshTag)); } public void testParamPrecedenceWithAnchor() throws Exception { @@ -512,18 +1010,60 @@ public class AnchorTagTest extends AbstractUITagTest { // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). ParamTag freshParamTag = new ParamTag(); freshParamTag.setPageContext(pageContext); - assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + 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(paramTag, freshParamTag)); // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). AnchorTag freshTag = new AnchorTag(); freshTag.setPageContext(pageContext); - assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + 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(anchorTag, freshTag)); } + public void testParamPrecedenceWithAnchor_clearTagStateSet() throws Exception { + request.setRequestURI("/context/someAction.action"); + request.setQueryString("id=22&name=John"); + + AnchorTag anchorTag = new AnchorTag(); + anchorTag.setPerformClearTagStateForTagPoolingServers(true); // Explicitly request tag state clearing. + anchorTag.setPageContext(pageContext); + anchorTag.setIncludeParams("get"); + anchorTag.setEncode("%{false}"); + anchorTag.setAnchor("testAnchor"); + + ParamTag paramTag = new ParamTag(); + paramTag.setPerformClearTagStateForTagPoolingServers(true); // Explicitly request tag state clearing. + paramTag.setPageContext(pageContext); + paramTag.setName("id"); + paramTag.setValue("%{'33'}"); + + anchorTag.doStartTag(); + setComponentTagClearTagState(anchorTag, true); // Ensure component tag state clearing is set true (to match tag). + paramTag.doStartTag(); + setComponentTagClearTagState(paramTag, true); // Ensure component tag state clearing is set true (to match tag). + paramTag.doEndTag(); + anchorTag.doEndTag(); + + assertEquals(wrapWithAnchor("/context/someAction.action?id=33&name=John#testAnchor"), writer.getBuffer().toString()); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + ParamTag freshParamTag = new ParamTag(); + freshParamTag.setPerformClearTagStateForTagPoolingServers(true); + freshParamTag.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(paramTag, freshParamTag)); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + AnchorTag freshTag = new AnchorTag(); + freshTag.setPerformClearTagStateForTagPoolingServers(true); + 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(anchorTag, freshTag)); + } public void testUsingValueOnly() throws Exception { tag.setValue("/public/about/team.jsp"); @@ -534,7 +1074,24 @@ public class AnchorTagTest extends AbstractUITagTest { // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). AnchorTag freshTag = new AnchorTag(); freshTag.setPageContext(pageContext); - assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + 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 testUsingValueOnly_clearTagStateSet() throws Exception { + tag.setPerformClearTagStateForTagPoolingServers(true); // Explicitly request tag state clearing. + tag.setValue("/public/about/team.jsp"); + tag.doStartTag(); + setComponentTagClearTagState(tag, true); // Ensure component tag state clearing is set true (to match tag). + tag.doEndTag(); + assertEquals(wrapWithAnchor("/public/about/team.jsp"), writer.toString()); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + AnchorTag freshTag = new AnchorTag(); + freshTag.setPerformClearTagStateForTagPoolingServers(true); + 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)); } @@ -553,7 +1110,29 @@ public class AnchorTagTest extends AbstractUITagTest { // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). AnchorTag freshTag = new AnchorTag(); freshTag.setPageContext(pageContext); - assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + 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 testRequestURIActionIncludeNone_clearTagStateSet() throws Exception { + request.setRequestURI("/public/about"); + request.setQueryString("section=team&company=acme inc"); + + tag.setPerformClearTagStateForTagPoolingServers(true); // Explicitly request tag state clearing. + tag.setAction("team"); + tag.setIncludeParams("none"); + tag.doStartTag(); + setComponentTagClearTagState(tag, true); // Ensure component tag state clearing is set true (to match tag). + tag.doEndTag(); + + assertEquals(wrapWithAnchor("/team.action"), writer.toString()); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + AnchorTag freshTag = new AnchorTag(); + freshTag.setPerformClearTagStateForTagPoolingServers(true); + 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)); } @@ -572,7 +1151,29 @@ public class AnchorTagTest extends AbstractUITagTest { // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). AnchorTag freshTag = new AnchorTag(); freshTag.setPageContext(pageContext); - assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + 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 testRequestURIActionIncludeGet_clearTagStateSet() throws Exception { + request.setRequestURI("/public/about"); + request.setQueryString("section=team&company=acme inc"); + + tag.setPerformClearTagStateForTagPoolingServers(true); // Explicitly request tag state clearing. + tag.setAction("team"); + tag.setIncludeParams("get"); + tag.doStartTag(); + setComponentTagClearTagState(tag, true); // Ensure component tag state clearing is set true (to match tag). + tag.doEndTag(); + + assertEquals(wrapWithAnchor("/team.action?section=team&company=acme+inc"), writer.toString()); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + AnchorTag freshTag = new AnchorTag(); + freshTag.setPerformClearTagStateForTagPoolingServers(true); + 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)); } @@ -592,7 +1193,30 @@ public class AnchorTagTest extends AbstractUITagTest { // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). AnchorTag freshTag = new AnchorTag(); freshTag.setPageContext(pageContext); - assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + 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 testRequestURIActionIncludeGetDoNotEscapeAmp_clearTagStateSet() throws Exception { + request.setRequestURI("/public/about"); + request.setQueryString("section=team&company=acme inc"); + + tag.setPerformClearTagStateForTagPoolingServers(true); // Explicitly request tag state clearing. + tag.setAction("team"); + tag.setIncludeParams("get"); + tag.setEscapeAmp("false"); + tag.doStartTag(); + setComponentTagClearTagState(tag, true); // Ensure component tag state clearing is set true (to match tag). + tag.doEndTag(); + + assertEquals(wrapWithAnchor("/team.action?section=team&company=acme+inc"), writer.toString()); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + AnchorTag freshTag = new AnchorTag(); + freshTag.setPerformClearTagStateForTagPoolingServers(true); + 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)); } @@ -611,7 +1235,29 @@ public class AnchorTagTest extends AbstractUITagTest { // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). AnchorTag freshTag = new AnchorTag(); freshTag.setPageContext(pageContext); - assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + 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 testRequestURINoActionIncludeNone_clearTagStateSet() throws Exception { + request.setRequestURI("/public/about"); + request.setQueryString("section=team&company=acme inc"); + + tag.setPerformClearTagStateForTagPoolingServers(true); // Explicitly request tag state clearing. + tag.setAction(null); + tag.setIncludeParams("none"); + tag.doStartTag(); + setComponentTagClearTagState(tag, true); // Ensure component tag state clearing is set true (to match tag). + tag.doEndTag(); + + assertEquals(wrapWithAnchor("/public/about"), writer.toString()); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + AnchorTag freshTag = new AnchorTag(); + freshTag.setPerformClearTagStateForTagPoolingServers(true); + 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)); } @@ -630,7 +1276,29 @@ public class AnchorTagTest extends AbstractUITagTest { // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). AnchorTag freshTag = new AnchorTag(); freshTag.setPageContext(pageContext); - assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + 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 testNoActionIncludeGet_clearTagStateSet() throws Exception { + request.setRequestURI("/public/about"); + request.setQueryString("section=team&company=acme inc"); + + tag.setPerformClearTagStateForTagPoolingServers(true); // Explicitly request tag state clearing. + tag.setAction(null); + tag.setIncludeParams("get"); + tag.doStartTag(); + setComponentTagClearTagState(tag, true); // Ensure component tag state clearing is set true (to match tag). + tag.doEndTag(); + + assertEquals(wrapWithAnchor("/public/about?section=team&company=acme+inc"), writer.toString()); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + AnchorTag freshTag = new AnchorTag(); + freshTag.setPerformClearTagStateForTagPoolingServers(true); + 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)); } @@ -663,14 +1331,60 @@ public class AnchorTagTest extends AbstractUITagTest { // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). ParamTag freshParamTag = new ParamTag(); freshParamTag.setPageContext(pageContext); - assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + 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(paramTag, freshParamTag)); // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). AnchorTag freshTag = new AnchorTag(); freshTag.setPageContext(pageContext); - assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + 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 testRequestURIActionIncludeAll_clearTagStateSet() throws Exception { + request.setRequestURI("/public/about"); + request.setQueryString("section=team&company=acme inc"); + + tag.setPerformClearTagStateForTagPoolingServers(true); // Explicitly request tag state clearing. + tag.setAction("team"); + tag.setIncludeParams("all"); + + tag.doStartTag(); + setComponentTagClearTagState(tag, true); // Ensure component tag state clearing is set true (to match tag). + + // include nested param tag + ParamTag paramTag = new ParamTag(); + paramTag.setPerformClearTagStateForTagPoolingServers(true); // Explicitly request tag state clearing. + paramTag.setPageContext(pageContext); + paramTag.setName("year"); + paramTag.setValue("2006"); + paramTag.doStartTag(); + setComponentTagClearTagState(paramTag, true); // Ensure component tag state clearing is set true (to match tag). + paramTag.doEndTag(); + + tag.doEndTag(); + + String result = writer.toString(); + assertTrue(result.contains("/team.action?")); + assertTrue(result.contains("section=team")); + assertTrue(result.contains("company=acme+inc")); + assertTrue(result.contains("year=2006")); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + ParamTag freshParamTag = new ParamTag(); + freshParamTag.setPerformClearTagStateForTagPoolingServers(true); + freshParamTag.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(paramTag, freshParamTag)); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + AnchorTag freshTag = new AnchorTag(); + freshTag.setPerformClearTagStateForTagPoolingServers(true); + 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)); } @@ -703,14 +1417,60 @@ public class AnchorTagTest extends AbstractUITagTest { // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). ParamTag freshParamTag = new ParamTag(); freshParamTag.setPageContext(pageContext); - assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + 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(paramTag, freshParamTag)); // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). AnchorTag freshTag = new AnchorTag(); freshTag.setPageContext(pageContext); - assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + 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 testRequestURINoActionIncludeAll_clearTagStateSet() throws Exception { + request.setRequestURI("/public/about"); + request.setQueryString("section=team&company=acme inc"); + + tag.setPerformClearTagStateForTagPoolingServers(true); // Explicitly request tag state clearing. + tag.setAction(null); + tag.setIncludeParams("all"); + + tag.doStartTag(); + setComponentTagClearTagState(tag, true); // Ensure component tag state clearing is set true (to match tag). + + // include nested param tag + ParamTag paramTag = new ParamTag(); + paramTag.setPerformClearTagStateForTagPoolingServers(true); // Explicitly request tag state clearing. + paramTag.setPageContext(pageContext); + paramTag.setName("year"); + paramTag.setValue("2006"); + paramTag.doStartTag(); + setComponentTagClearTagState(paramTag, true); // Ensure component tag state clearing is set true (to match tag). + paramTag.doEndTag(); + + tag.doEndTag(); + + String result = writer.toString(); + assertTrue(result.contains("/public/about?")); + assertTrue(result.contains("section=team")); + assertTrue(result.contains("company=acme+inc")); + assertTrue(result.contains("year=2006")); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + ParamTag freshParamTag = new ParamTag(); + freshParamTag.setPerformClearTagStateForTagPoolingServers(true); + freshParamTag.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(paramTag, freshParamTag)); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + AnchorTag freshTag = new AnchorTag(); + freshTag.setPerformClearTagStateForTagPoolingServers(true); + 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)); } @@ -727,7 +1487,27 @@ public class AnchorTagTest extends AbstractUITagTest { // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). AnchorTag freshTag = new AnchorTag(); freshTag.setPageContext(pageContext); - assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + 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 testUnknownIncludeParam_clearTagStateSet() throws Exception { + request.setRequestURI("/public/about"); + request.setQueryString("section=team"); + + tag.setPerformClearTagStateForTagPoolingServers(true); // Explicitly request tag state clearing. + tag.setIncludeParams("unknown"); // will log at WARN level + tag.doStartTag(); + setComponentTagClearTagState(tag, true); // Ensure component tag state clearing is set true (to match tag). + tag.doEndTag(); + assertEquals(wrapWithAnchor("/public/about"), writer.toString()); // should not add any request parameters + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + AnchorTag freshTag = new AnchorTag(); + freshTag.setPerformClearTagStateForTagPoolingServers(true); + 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)); } @@ -746,7 +1526,29 @@ public class AnchorTagTest extends AbstractUITagTest { // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). AnchorTag freshTag = new AnchorTag(); freshTag.setPageContext(pageContext); - assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + 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 testRequestURIWithAnchor_clearTagStateSet() throws Exception { + request.setRequestURI("/public/about"); + request.setQueryString("company=acme inc#canada"); + + tag.setPerformClearTagStateForTagPoolingServers(true); // Explicitly request tag state clearing. + tag.setAction("company"); + tag.setIncludeParams("get"); + tag.doStartTag(); + setComponentTagClearTagState(tag, true); // Ensure component tag state clearing is set true (to match tag). + tag.doEndTag(); + + assertEquals(wrapWithAnchor("/company.action?company=acme+inc"), writer.toString()); // will always chop anchor if using requestURI + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + AnchorTag freshTag = new AnchorTag(); + freshTag.setPerformClearTagStateForTagPoolingServers(true); + 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)); } @@ -764,7 +1566,28 @@ public class AnchorTagTest extends AbstractUITagTest { // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). AnchorTag freshTag = new AnchorTag(); freshTag.setPageContext(pageContext); - assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + 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 testIncludeContext_clearTagStateSet() throws Exception { + request.setupGetContext("/myapp"); + + tag.setPerformClearTagStateForTagPoolingServers(true); // Explicitly request tag state clearing. + tag.setIncludeContext("true"); + tag.setAction("company"); + tag.doStartTag(); + setComponentTagClearTagState(tag, true); // Ensure component tag state clearing is set true (to match tag). + tag.doEndTag(); + + assertEquals(wrapWithAnchor("/myapp/company.action"), writer.toString()); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + AnchorTag freshTag = new AnchorTag(); + freshTag.setPerformClearTagStateForTagPoolingServers(true); + 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)); } @@ -780,7 +1603,26 @@ public class AnchorTagTest extends AbstractUITagTest { // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). AnchorTag freshTag = new AnchorTag(); freshTag.setPageContext(pageContext); - assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + 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 testForceAddSchemeHostAndPort_clearTagStateSet() throws Exception { + tag.setPerformClearTagStateForTagPoolingServers(true); // Explicitly request tag state clearing. + tag.setForceAddSchemeHostAndPort("true"); + tag.setAction("company"); + tag.doStartTag(); + setComponentTagClearTagState(tag, true); // Ensure component tag state clearing is set true (to match tag). + tag.doEndTag(); + + assertEquals(wrapWithAnchor("http://localhost/company.action"), writer.toString()); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + AnchorTag freshTag = new AnchorTag(); + freshTag.setPerformClearTagStateForTagPoolingServers(true); + 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)); } diff --git a/core/src/test/java/org/apache/struts2/views/jsp/AppendIteratorTagTest.java b/core/src/test/java/org/apache/struts2/views/jsp/AppendIteratorTagTest.java index 6ae0756cc..6adb42a82 100644 --- a/core/src/test/java/org/apache/struts2/views/jsp/AppendIteratorTagTest.java +++ b/core/src/test/java/org/apache/struts2/views/jsp/AppendIteratorTagTest.java @@ -86,20 +86,101 @@ public class AppendIteratorTagTest extends AbstractTagTest { // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). ParamTag freshParamTag = new ParamTag(); freshParamTag.setPageContext(pageContext); - assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + 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(iterator1ParamTag, freshParamTag)); - assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + 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(iterator2ParamTag, freshParamTag)); - assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + 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(iterator3ParamTag, freshParamTag)); // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). AppendIteratorTag freshTag = new AppendIteratorTag(); freshTag.setPageContext(pageContext); - assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + 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 testAppendingIteratorUsingArrayAsSource_clearTagStateSet() throws Exception { + AppendIteratorTag tag = new AppendIteratorTag(); + tag.setPerformClearTagStateForTagPoolingServers(true); // Explicitly request tag state clearing. + tag.setPageContext(pageContext); + tag.setVar("myAppendedIterator"); + + ParamTag iterator1ParamTag = new ParamTag(); + iterator1ParamTag.setPerformClearTagStateForTagPoolingServers(true); // Explicitly request tag state clearing. + iterator1ParamTag.setPageContext(pageContext); + iterator1ParamTag.setValue("%{myArr1}"); + + ParamTag iterator2ParamTag = new ParamTag(); + iterator2ParamTag.setPerformClearTagStateForTagPoolingServers(true); // Explicitly request tag state clearing. + iterator2ParamTag.setPageContext(pageContext); + iterator2ParamTag.setValue("%{myArr2}"); + + ParamTag iterator3ParamTag = new ParamTag(); + iterator3ParamTag.setPerformClearTagStateForTagPoolingServers(true); // Explicitly request tag state clearing. + iterator3ParamTag.setPageContext(pageContext); + iterator3ParamTag.setValue("%{myArr3}"); + + + tag.doStartTag(); + setComponentTagClearTagState(tag, true); // Ensure component tag state clearing is set true (to match tag). + iterator1ParamTag.doStartTag(); + setComponentTagClearTagState(iterator1ParamTag, true); // Ensure component tag state clearing is set true (to match tag). + iterator1ParamTag.doEndTag(); + iterator2ParamTag.doStartTag(); + setComponentTagClearTagState(iterator2ParamTag, true); // Ensure component tag state clearing is set true (to match tag). + iterator2ParamTag.doEndTag(); + iterator3ParamTag.doStartTag(); + setComponentTagClearTagState(iterator3ParamTag, true); // Ensure component tag state clearing is set true (to match tag). + iterator3ParamTag.doEndTag(); + tag.doEndTag(); + + Iterator appendedIterator = (Iterator) stack.findValue("#myAppendedIterator"); + + assertNotNull(appendedIterator); + assertTrue(appendedIterator.hasNext()); + assertEquals(appendedIterator.next(), "1"); + assertTrue(appendedIterator.hasNext()); + assertEquals(appendedIterator.next(), "2"); + assertTrue(appendedIterator.hasNext()); + assertEquals(appendedIterator.next(), "3"); + assertTrue(appendedIterator.hasNext()); + assertEquals(appendedIterator.next(), "a"); + assertTrue(appendedIterator.hasNext()); + assertEquals(appendedIterator.next(), "b"); + assertTrue(appendedIterator.hasNext()); + assertEquals(appendedIterator.next(), "c"); + assertTrue(appendedIterator.hasNext()); + assertEquals(appendedIterator.next(), "A"); + assertTrue(appendedIterator.hasNext()); + assertEquals(appendedIterator.next(), "B"); + assertTrue(appendedIterator.hasNext()); + assertEquals(appendedIterator.next(), "C"); + assertFalse(appendedIterator.hasNext()); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + ParamTag freshParamTag = new ParamTag(); + freshParamTag.setPerformClearTagStateForTagPoolingServers(true); + freshParamTag.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(iterator1ParamTag, freshParamTag)); + 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(iterator2ParamTag, freshParamTag)); + 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(iterator3ParamTag, freshParamTag)); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + AppendIteratorTag freshTag = new AppendIteratorTag(); + freshTag.setPerformClearTagStateForTagPoolingServers(true); + 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)); } @@ -157,25 +238,104 @@ public class AppendIteratorTagTest extends AbstractTagTest { // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). ParamTag freshParamTag = new ParamTag(); freshParamTag.setPageContext(pageContext); - assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + 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(iterator1ParamTag, freshParamTag)); - assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + 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(iterator2ParamTag, freshParamTag)); - assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + 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(iterator3ParamTag, freshParamTag)); // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). AppendIteratorTag freshTag = new AppendIteratorTag(); freshTag.setPageContext(pageContext); - assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + 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 testAppendingIteratorsUsingListAsSource_clearTagStateSet() throws Exception { + AppendIteratorTag tag = new AppendIteratorTag(); + tag.setPerformClearTagStateForTagPoolingServers(true); // Explicitly request tag state clearing. + tag.setPageContext(pageContext); + tag.setVar("myAppendedIterator"); + ParamTag iterator1ParamTag = new ParamTag(); + iterator1ParamTag.setPerformClearTagStateForTagPoolingServers(true); // Explicitly request tag state clearing. + iterator1ParamTag.setPageContext(pageContext); + iterator1ParamTag.setValue("%{myList1}"); + + ParamTag iterator2ParamTag = new ParamTag(); + iterator2ParamTag.setPerformClearTagStateForTagPoolingServers(true); // Explicitly request tag state clearing. + iterator2ParamTag.setPageContext(pageContext); + iterator2ParamTag.setValue("%{myList2}"); + + ParamTag iterator3ParamTag = new ParamTag(); + iterator3ParamTag.setPerformClearTagStateForTagPoolingServers(true); // Explicitly request tag state clearing. + iterator3ParamTag.setPageContext(pageContext); + iterator3ParamTag.setValue("%{myList3}"); + + + tag.doStartTag(); + setComponentTagClearTagState(tag, true); // Ensure component tag state clearing is set true (to match tag). + iterator1ParamTag.doStartTag(); + setComponentTagClearTagState(iterator1ParamTag, true); // Ensure component tag state clearing is set true (to match tag). + iterator1ParamTag.doEndTag(); + iterator2ParamTag.doStartTag(); + setComponentTagClearTagState(iterator2ParamTag, true); // Ensure component tag state clearing is set true (to match tag). + iterator2ParamTag.doEndTag(); + iterator3ParamTag.doStartTag(); + setComponentTagClearTagState(iterator3ParamTag, true); // Ensure component tag state clearing is set true (to match tag). + iterator3ParamTag.doEndTag(); + tag.doEndTag(); + + Iterator appendedIterator = (Iterator) stack.findValue("#myAppendedIterator"); + + assertNotNull(appendedIterator); + assertTrue(appendedIterator.hasNext()); + assertEquals(appendedIterator.next(), "1"); + assertTrue(appendedIterator.hasNext()); + assertEquals(appendedIterator.next(), "2"); + assertTrue(appendedIterator.hasNext()); + assertEquals(appendedIterator.next(), "3"); + assertTrue(appendedIterator.hasNext()); + assertEquals(appendedIterator.next(), "a"); + assertTrue(appendedIterator.hasNext()); + assertEquals(appendedIterator.next(), "b"); + assertTrue(appendedIterator.hasNext()); + assertEquals(appendedIterator.next(), "c"); + assertTrue(appendedIterator.hasNext()); + assertEquals(appendedIterator.next(), "A"); + assertTrue(appendedIterator.hasNext()); + assertEquals(appendedIterator.next(), "B"); + assertTrue(appendedIterator.hasNext()); + assertEquals(appendedIterator.next(), "C"); + assertFalse(appendedIterator.hasNext()); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + ParamTag freshParamTag = new ParamTag(); + freshParamTag.setPerformClearTagStateForTagPoolingServers(true); + freshParamTag.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(iterator1ParamTag, freshParamTag)); + 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(iterator2ParamTag, freshParamTag)); + 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(iterator3ParamTag, freshParamTag)); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + AppendIteratorTag freshTag = new AppendIteratorTag(); + freshTag.setPerformClearTagStateForTagPoolingServers(true); + freshTag.setPageContext(pageContext); + assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", + strutsBodyTagsAreReflectionEqual(tag, freshTag)); + } @Override public Action getAction() { diff --git a/core/src/test/java/org/apache/struts2/views/jsp/BeanTagTest.java b/core/src/test/java/org/apache/struts2/views/jsp/BeanTagTest.java index 5d8d43a9c..b6a801e14 100644 --- a/core/src/test/java/org/apache/struts2/views/jsp/BeanTagTest.java +++ b/core/src/test/java/org/apache/struts2/views/jsp/BeanTagTest.java @@ -50,8 +50,42 @@ public class BeanTagTest extends AbstractUITagTest { // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). BeanTag freshTag = new BeanTag(); freshTag.setPageContext(pageContext); - assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + 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 testSimple_clearTagStateSet() { + BeanTag tag = new BeanTag(); + tag.setPerformClearTagStateForTagPoolingServers(true); // Explicitly request tag state clearing. + tag.setPageContext(pageContext); + tag.setName("org.apache.struts2.TestAction"); + + try { + tag.doStartTag(); + setComponentTagClearTagState(tag, true); // Ensure component tag state clearing is set true (to match tag). + tag.component.addParameter("result", "success"); + + assertEquals("success", stack.findValue("result")); + // TestAction from bean tag, Action from execution and DefaultTextProvider + assertEquals(3, stack.size()); + tag.doEndTag(); + assertEquals(2, stack.size()); + } catch (JspException ex) { + ex.printStackTrace(); + fail(); + } + + request.verify(); + pageContext.verify(); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + BeanTag freshTag = new BeanTag(); + freshTag.setPerformClearTagStateForTagPoolingServers(true); + 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)); + } + } diff --git a/core/src/test/java/org/apache/struts2/views/jsp/ElseIfTagTest.java b/core/src/test/java/org/apache/struts2/views/jsp/ElseIfTagTest.java index c5b8648ee..487377f7d 100644 --- a/core/src/test/java/org/apache/struts2/views/jsp/ElseIfTagTest.java +++ b/core/src/test/java/org/apache/struts2/views/jsp/ElseIfTagTest.java @@ -54,7 +54,30 @@ public class ElseIfTagTest extends StrutsInternalTestCase { // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). ElseIfTag freshTag = new ElseIfTag(); freshTag.setPageContext(pageContext); - assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + 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.", + objectsAreReflectionEqual(tag, freshTag)); + } + + public void testIfIsFalseElseIfIsTrue_clearTagStateSet() throws Exception { + stack.getContext().put(If.ANSWER, Boolean.FALSE); + + ElseIfTag tag = new ElseIfTag(); + tag.setPerformClearTagStateForTagPoolingServers(true); // Explicitly request tag state clearing. + tag.setPageContext(pageContext); + tag.setTest("true"); + + int result = tag.doStartTag(); + setComponentTagClearTagState(tag, true); // Ensure component tag state clearing is set true (to match tag). + tag.doEndTag(); + + assertEquals(result, TagSupport.EVAL_BODY_INCLUDE); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + ElseIfTag freshTag = new ElseIfTag(); + freshTag.setPerformClearTagStateForTagPoolingServers(true); + 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.", objectsAreReflectionEqual(tag, freshTag)); } @@ -74,7 +97,30 @@ public class ElseIfTagTest extends StrutsInternalTestCase { // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). ElseIfTag freshTag = new ElseIfTag(); freshTag.setPageContext(pageContext); - assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + 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.", + objectsAreReflectionEqual(tag, freshTag)); + } + + public void testIfIsFalseElseIfIsFalse_clearTagStateSet() throws Exception { + stack.getContext().put(If.ANSWER, Boolean.FALSE); + + ElseIfTag tag = new ElseIfTag(); + tag.setPerformClearTagStateForTagPoolingServers(true); // Explicitly request tag state clearing. + tag.setPageContext(pageContext); + tag.setTest("false"); + + int result = tag.doStartTag(); + setComponentTagClearTagState(tag, true); // Ensure component tag state clearing is set true (to match tag). + tag.doEndTag(); + + assertEquals(result, TagSupport.SKIP_BODY); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + ElseIfTag freshTag = new ElseIfTag(); + freshTag.setPerformClearTagStateForTagPoolingServers(true); + 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.", objectsAreReflectionEqual(tag, freshTag)); } @@ -94,7 +140,30 @@ public class ElseIfTagTest extends StrutsInternalTestCase { // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). ElseIfTag freshTag = new ElseIfTag(); freshTag.setPageContext(pageContext); - assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + 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.", + objectsAreReflectionEqual(tag, freshTag)); + } + + public void testIfIsTrueElseIfIsTrue_clearTagStateSet() throws Exception { + stack.getContext().put(If.ANSWER, Boolean.TRUE); + + ElseIfTag tag = new ElseIfTag(); + tag.setPerformClearTagStateForTagPoolingServers(true); // Explicitly request tag state clearing. + tag.setPageContext(pageContext); + tag.setTest("true"); + + int result = tag.doStartTag(); + setComponentTagClearTagState(tag, true); // Ensure component tag state clearing is set true (to match tag). + tag.doEndTag(); + + assertEquals(result, TagSupport.SKIP_BODY); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + ElseIfTag freshTag = new ElseIfTag(); + freshTag.setPerformClearTagStateForTagPoolingServers(true); + 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.", objectsAreReflectionEqual(tag, freshTag)); } @@ -114,11 +183,33 @@ public class ElseIfTagTest extends StrutsInternalTestCase { // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). ElseIfTag freshTag = new ElseIfTag(); freshTag.setPageContext(pageContext); - assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + 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.", objectsAreReflectionEqual(tag, freshTag)); } + public void testIfIsTrueElseIfIsFalse_clearTagStateSet() throws Exception { + stack.getContext().put(If.ANSWER, Boolean.TRUE); + + ElseIfTag tag = new ElseIfTag(); + tag.setPerformClearTagStateForTagPoolingServers(true); // Explicitly request tag state clearing. + tag.setPageContext(pageContext); + tag.setTest("false"); + + int result = tag.doStartTag(); + setComponentTagClearTagState(tag, true); // Ensure component tag state clearing is set true (to match tag). + tag.doEndTag(); + + assertEquals(result, TagSupport.SKIP_BODY); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + ElseIfTag freshTag = new ElseIfTag(); + freshTag.setPerformClearTagStateForTagPoolingServers(true); + 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.", + objectsAreReflectionEqual(tag, freshTag)); + } @Override protected void setUp() throws Exception { @@ -140,5 +231,22 @@ public class ElseIfTagTest extends StrutsInternalTestCase { request.setAttribute(ServletActionContext.STRUTS_VALUESTACK_KEY, stack); } + /** + * Helper method to simplify setting the performClearTagStateForTagPoolingServers state for a + * {@link ComponentTagSupport} tag's {@link Component} to match expectations for the test. + * + * The component reference is not available to the tag until after the doStartTag() method is called. + * We need to ensure the component's {@link Component#performClearTagStateForTagPoolingServers} state matches + * what we set for the Tag when a non-default (true) value is used, so this method accesses the component instance, + * sets the value specified and forces the tag's parameters to be repopulated again. + * + * @param tag The ComponentTagSupport tag upon whose component we will set the performClearTagStateForTagPoolingServers state. + * @param performClearTagStateForTagPoolingServers true to clear tag state, false otherwise + */ + protected void setComponentTagClearTagState(ComponentTagSupport tag, boolean performClearTagStateForTagPoolingServers) { + tag.component.setPerformClearTagStateForTagPoolingServers(performClearTagStateForTagPoolingServers); + //tag.populateParams(); // Not safe to call after doStartTag() ... breaks some tests. + tag.populatePerformClearTagStateForTagPoolingServersParam(); // Only populate the performClearTagStateForTagPoolingServers parameter for the Tag. + } } diff --git a/core/src/test/java/org/apache/struts2/views/jsp/ElseTagTest.java b/core/src/test/java/org/apache/struts2/views/jsp/ElseTagTest.java index 270ac77cd..4d7d7cfcb 100644 --- a/core/src/test/java/org/apache/struts2/views/jsp/ElseTagTest.java +++ b/core/src/test/java/org/apache/struts2/views/jsp/ElseTagTest.java @@ -58,7 +58,34 @@ public class ElseTagTest extends StrutsInternalTestCase { // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). ElseTag freshTag = new ElseTag(); freshTag.setPageContext(pageContext); - assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + // ElseTag has no additional state, so it compares as equal with the default tag clear state as well. + assertTrue("Tag state after doEndTag() under default tag clear state is inequal to new Tag with pageContext/parent set. " + + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", + objectsAreReflectionEqual(elseTag, freshTag)); + } + + public void testTestFalse_clearTagStateSet() { + stack.getContext().put(If.ANSWER, new Boolean(false)); + + int result = 0; + + try { + elseTag.setPerformClearTagStateForTagPoolingServers(true); // Explicitly request tag state clearing. + elseTag.setPageContext(pageContext); + result = elseTag.doStartTag(); + setComponentTagClearTagState(elseTag, true); // Ensure component tag state clearing is set true (to match tag). + elseTag.doEndTag(); + } catch (JspException e) { + e.printStackTrace(); + fail(); + } + assertEquals(TagSupport.EVAL_BODY_INCLUDE, result); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + ElseTag freshTag = new ElseTag(); + freshTag.setPerformClearTagStateForTagPoolingServers(true); + 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.", objectsAreReflectionEqual(elseTag, freshTag)); } @@ -81,7 +108,34 @@ public class ElseTagTest extends StrutsInternalTestCase { // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). ElseTag freshTag = new ElseTag(); freshTag.setPageContext(pageContext); - assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + // ElseTag has no additional state, so it compares as equal with the default tag clear state as well. + assertTrue("Tag state after doEndTag() under default tag clear state is inequal to new Tag with pageContext/parent set. " + + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", + objectsAreReflectionEqual(elseTag, freshTag)); + } + + public void testTestNull_clearTagStateSet() { + elseTag.setPerformClearTagStateForTagPoolingServers(true); // Explicitly request tag state clearing. + elseTag.setPageContext(pageContext); + + int result = 0; + + try { + result = elseTag.doStartTag(); + setComponentTagClearTagState(elseTag, true); // Ensure component tag state clearing is set true (to match tag). + elseTag.doEndTag(); + } catch (JspException e) { + e.printStackTrace(); + fail(); + } + + assertEquals(TagSupport.SKIP_BODY, result); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + ElseTag freshTag = new ElseTag(); + freshTag.setPerformClearTagStateForTagPoolingServers(true); + 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.", objectsAreReflectionEqual(elseTag, freshTag)); } @@ -105,11 +159,57 @@ public class ElseTagTest extends StrutsInternalTestCase { // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). ElseTag freshTag = new ElseTag(); freshTag.setPageContext(pageContext); - assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + // ElseTag has no additional state, so it compares as equal with the default tag clear state as well. + assertTrue("Tag state after doEndTag() under default tag clear state is inequal to new Tag with pageContext/parent set. " + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", objectsAreReflectionEqual(elseTag, freshTag)); } + public void testTestTrue_clearTagStateSet() { + stack.getContext().put(If.ANSWER, new Boolean(true)); + elseTag.setPerformClearTagStateForTagPoolingServers(true); // Explicitly request tag state clearing. + elseTag.setPageContext(pageContext); + + int result = 0; + + try { + result = elseTag.doStartTag(); + setComponentTagClearTagState(elseTag, true); // Ensure component tag state clearing is set true (to match tag). + elseTag.doEndTag(); + } catch (JspException e) { + e.printStackTrace(); + fail(); + } + + assertEquals(TagSupport.SKIP_BODY, result); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + ElseTag freshTag = new ElseTag(); + freshTag.setPerformClearTagStateForTagPoolingServers(true); + 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.", + objectsAreReflectionEqual(elseTag, freshTag)); + } + + /** + * Helper method to simplify setting the performClearTagStateForTagPoolingServers state for a + * {@link ComponentTagSupport} tag's {@link Component} to match expecations for a test. + * + * Since the component is not available to the tag until after the doStartTag() method is called, + * but we need to ensure the component's {@link Component#performClearTagStateForTagPoolingServers} state matches + * what we set for the Tag when a non-default (true) value is used, this method retrieves the component instance, + * sets the value specified and forces the parameters to be repopulated again. + * + * @param tag The ComponentTagSupport tag upon whose component we will set the performClearTagStateForTagPoolingServers state. + * @param performClearTagStateForTagPoolingServers true to clear tag state, false otherwise + */ + protected void setComponentTagClearTagState(ComponentTagSupport tag, boolean performClearTagStateForTagPoolingServers) { + tag.component.setPerformClearTagStateForTagPoolingServers(performClearTagStateForTagPoolingServers); + //tag.populateParams(); // Not safe to call after doStartTag() ... breaks some tests. + tag.populatePerformClearTagStateForTagPoolingServersParam(); // Only populate the performClearTagStateForTagPoolingServers parameter for the Tag. + } + @Override protected void setUp() throws Exception { super.setUp(); diff --git a/core/src/test/java/org/apache/struts2/views/jsp/I18nTagTest.java b/core/src/test/java/org/apache/struts2/views/jsp/I18nTagTest.java index 39659e8b6..46a5d4176 100644 --- a/core/src/test/java/org/apache/struts2/views/jsp/I18nTagTest.java +++ b/core/src/test/java/org/apache/struts2/views/jsp/I18nTagTest.java @@ -81,11 +81,63 @@ public class I18nTagTest extends StrutsInternalTestCase { // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). I18nTag freshTag = new I18nTag(); freshTag.setPageContext(pageContext); - assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + 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.", objectsAreReflectionEqual(tag, freshTag)); } + public void testSimple_clearTagStateSet() throws Exception { + + tag.setPerformClearTagStateForTagPoolingServers(true); // Explicitly request tag state clearing. + // set the resource bundle + tag.setName("testmessages"); + + int result = 0; + + try { + result = tag.doStartTag(); + setComponentTagClearTagState(tag, true); // Ensure component tag state clearing is set true (to match tag). + } catch (JspException e) { + e.printStackTrace(); + fail(); + } + + assertEquals(TagSupport.EVAL_BODY_INCLUDE, result); + + try { + result = tag.doEndTag(); + } catch (JspException e) { + e.printStackTrace(); + fail(); + } + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + I18nTag freshTag = new I18nTag(); + freshTag.setPerformClearTagStateForTagPoolingServers(true); + 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.", + objectsAreReflectionEqual(tag, freshTag)); + } + + /** + * Helper method to simplify setting the performClearTagStateForTagPoolingServers state for a + * {@link ComponentTagSupport} tag's {@link Component} to match expecations for a test. + * + * Since the component is not available to the tag until after the doStartTag() method is called, + * but we need to ensure the component's {@link Component#performClearTagStateForTagPoolingServers} state matches + * what we set for the Tag when a non-default (true) value is used, this method retrieves the component instance, + * sets the value specified and forces the parameters to be repopulated again. + * + * @param tag The ComponentTagSupport tag upon whose component we will set the performClearTagStateForTagPoolingServers state. + * @param performClearTagStateForTagPoolingServers true to clear tag state, false otherwise + */ + protected void setComponentTagClearTagState(ComponentTagSupport tag, boolean performClearTagStateForTagPoolingServers) { + tag.component.setPerformClearTagStateForTagPoolingServers(performClearTagStateForTagPoolingServers); + //tag.populateParams(); // Not safe to call after doStartTag() ... breaks some tests. + tag.populatePerformClearTagStateForTagPoolingServersParam(); // Only populate the performClearTagStateForTagPoolingServers parameter for the Tag. + } + /** * Asserts that an exception is thrown when something unexpected is popped off the stack by the closing tag * diff --git a/core/src/test/java/org/apache/struts2/views/jsp/IfTagTest.java b/core/src/test/java/org/apache/struts2/views/jsp/IfTagTest.java index 31b9e4dc6..29813f8d1 100644 --- a/core/src/test/java/org/apache/struts2/views/jsp/IfTagTest.java +++ b/core/src/test/java/org/apache/struts2/views/jsp/IfTagTest.java @@ -69,7 +69,45 @@ public class IfTagTest extends StrutsInternalTestCase { // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). IfTag freshTag = new IfTag(); freshTag.setPageContext(pageContext); - assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + 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.", + objectsAreReflectionEqual(tag, freshTag)); + } + + public void testNonBooleanTest_clearTagStateSet() { + // set up the stack + Foo foo = new Foo(); + foo.setNum(1); + stack.push(foo); + + tag.setPerformClearTagStateForTagPoolingServers(true); // Explicitly request tag state clearing. + // set up the test + tag.setTest("num"); + + int result = 0; + + try { + result = tag.doStartTag(); + setComponentTagClearTagState(tag, true); // Ensure component tag state clearing is set true (to match tag). + } catch (JspException e) { + e.printStackTrace(); + fail(); + } + + assertEquals(TagSupport.EVAL_BODY_INCLUDE, result); + + try { + result = tag.doEndTag(); + } catch (JspException e) { + e.printStackTrace(); + fail(); + } + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + IfTag freshTag = new IfTag(); + freshTag.setPerformClearTagStateForTagPoolingServers(true); + 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.", objectsAreReflectionEqual(tag, freshTag)); } @@ -104,7 +142,45 @@ public class IfTagTest extends StrutsInternalTestCase { // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). IfTag freshTag = new IfTag(); freshTag.setPageContext(pageContext); - assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + 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.", + objectsAreReflectionEqual(tag, freshTag)); + } + + public void testTestError_clearTagStateSet() { + // set up the stack + Foo foo = new Foo(); + foo.setNum(2); + stack.push(foo); + + tag.setPerformClearTagStateForTagPoolingServers(true); // Explicitly request tag state clearing. + // set up the test + tag.setTest("nuuuuum == 2"); + + int result = 0; + + try { + result = tag.doStartTag(); + setComponentTagClearTagState(tag, true); // Ensure component tag state clearing is set true (to match tag). + } catch (JspException e) { + e.printStackTrace(); + fail(); + } + + assertEquals(TagSupport.SKIP_BODY, result); + + try { + result = tag.doEndTag(); + } catch (JspException e) { + e.printStackTrace(); + fail(); + } + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + IfTag freshTag = new IfTag(); + freshTag.setPerformClearTagStateForTagPoolingServers(true); + 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.", objectsAreReflectionEqual(tag, freshTag)); } @@ -139,7 +215,45 @@ public class IfTagTest extends StrutsInternalTestCase { // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). IfTag freshTag = new IfTag(); freshTag.setPageContext(pageContext); - assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + 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.", + objectsAreReflectionEqual(tag, freshTag)); + } + + public void testTestFalse_clearTagStateSet() { + // set up the stack + Foo foo = new Foo(); + foo.setNum(2); + stack.push(foo); + + tag.setPerformClearTagStateForTagPoolingServers(true); // Explicitly request tag state clearing. + // set up the test + tag.setTest("num != 2"); + + int result = 0; + + try { + result = tag.doStartTag(); + setComponentTagClearTagState(tag, true); // Ensure component tag state clearing is set true (to match tag). + } catch (JspException e) { + e.printStackTrace(); + fail(); + } + + assertEquals(TagSupport.SKIP_BODY, result); + + try { + result = tag.doEndTag(); + } catch (JspException e) { + e.printStackTrace(); + fail(); + } + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + IfTag freshTag = new IfTag(); + freshTag.setPerformClearTagStateForTagPoolingServers(true); + 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.", objectsAreReflectionEqual(tag, freshTag)); } @@ -175,11 +289,49 @@ public class IfTagTest extends StrutsInternalTestCase { // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). IfTag freshTag = new IfTag(); freshTag.setPageContext(pageContext); - assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + 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.", objectsAreReflectionEqual(tag, freshTag)); } + public void testTestTrue_clearTagStateSet() { + // set up the stack + Foo foo = new Foo(); + foo.setNum(2); + stack.push(foo); + + tag.setPerformClearTagStateForTagPoolingServers(true); // Explicitly request tag state clearing. + // set up the test + tag.setTest("num == 2"); + + int result = 0; + //tag.setPageContext(pageContext); + + try { + result = tag.doStartTag(); + setComponentTagClearTagState(tag, true); // Ensure component tag state clearing is set true (to match tag). + } catch (JspException e) { + e.printStackTrace(); + fail(); + } + + assertEquals(TagSupport.EVAL_BODY_INCLUDE, result); + + try { + result = tag.doEndTag(); + } catch (JspException e) { + e.printStackTrace(); + fail(); + } + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + IfTag freshTag = new IfTag(); + freshTag.setPerformClearTagStateForTagPoolingServers(true); + 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.", + objectsAreReflectionEqual(tag, freshTag)); + } public void testIfElse1() throws Exception { IfTag ifTag = new IfTag(); @@ -200,14 +352,52 @@ public class IfTagTest extends StrutsInternalTestCase { // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). IfTag freshTag = new IfTag(); freshTag.setPageContext(pageContext); - assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + 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.", objectsAreReflectionEqual(ifTag, freshTag)); // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). ElseTag freshTag2 = new ElseTag(); freshTag2.setPageContext(pageContext); - assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + // ElseTag has no additional state, so it compares as equal with the default tag clear state as well. + assertTrue("Tag state after doEndTag() under default tag clear state is inequal to new Tag with pageContext/parent set. " + + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", + objectsAreReflectionEqual(elseTag, freshTag2)); + } + + public void testIfElse1_clearTagStateSet() throws Exception { + IfTag ifTag = new IfTag(); + ifTag.setPerformClearTagStateForTagPoolingServers(true); // Explicitly request tag state clearing. + ifTag.setPageContext(pageContext); + ifTag.setTest("true"); + + ElseTag elseTag = new ElseTag(); + elseTag.setPerformClearTagStateForTagPoolingServers(true); // Explicitly request tag state clearing. + elseTag.setPageContext(pageContext); + + int r1 = ifTag.doStartTag(); + setComponentTagClearTagState(ifTag, true); // Ensure component tag state clearing is set true (to match tag). + ifTag.doEndTag(); + int r2 = elseTag.doStartTag(); + setComponentTagClearTagState(elseTag, true); // Ensure component tag state clearing is set true (to match tag). + elseTag.doEndTag(); + + assertEquals(TagSupport.EVAL_BODY_INCLUDE, r1); + assertEquals(TagSupport.SKIP_BODY, r2); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + IfTag freshTag = new IfTag(); + freshTag.setPerformClearTagStateForTagPoolingServers(true); + 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.", + objectsAreReflectionEqual(ifTag, freshTag)); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + ElseTag freshTag2 = new ElseTag(); + freshTag2.setPerformClearTagStateForTagPoolingServers(true); + freshTag2.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.", objectsAreReflectionEqual(elseTag, freshTag2)); } @@ -231,14 +421,52 @@ public class IfTagTest extends StrutsInternalTestCase { // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). IfTag freshTag = new IfTag(); freshTag.setPageContext(pageContext); - assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + 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.", objectsAreReflectionEqual(ifTag, freshTag)); // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). ElseTag freshTag2 = new ElseTag(); freshTag2.setPageContext(pageContext); - assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + // ElseTag has no additional state, so it compares as equal with the default tag clear state as well. + assertTrue("Tag state after doEndTag() under default tag clear state is inequal to new Tag with pageContext/parent set. " + + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", + objectsAreReflectionEqual(elseTag, freshTag2)); + } + + public void testIfElse2_clearTagStateSet() throws Exception { + IfTag ifTag = new IfTag(); + ifTag.setPerformClearTagStateForTagPoolingServers(true); // Explicitly request tag state clearing. + ifTag.setPageContext(pageContext); + ifTag.setTest("false"); + + ElseTag elseTag = new ElseTag(); + elseTag.setPerformClearTagStateForTagPoolingServers(true); // Explicitly request tag state clearing. + elseTag.setPageContext(pageContext); + + int r1 = ifTag.doStartTag(); + setComponentTagClearTagState(ifTag, true); // Ensure component tag state clearing is set true (to match tag). + ifTag.doEndTag(); + int r2 = elseTag.doStartTag(); + setComponentTagClearTagState(elseTag, true); // Ensure component tag state clearing is set true (to match tag). + elseTag.doEndTag(); + + assertEquals(TagSupport.SKIP_BODY, r1); + assertEquals(TagSupport.EVAL_BODY_INCLUDE, r2); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + IfTag freshTag = new IfTag(); + freshTag.setPerformClearTagStateForTagPoolingServers(true); + 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.", + objectsAreReflectionEqual(ifTag, freshTag)); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + ElseTag freshTag2 = new ElseTag(); + freshTag2.setPerformClearTagStateForTagPoolingServers(true); + freshTag2.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.", objectsAreReflectionEqual(elseTag, freshTag2)); } @@ -277,20 +505,82 @@ public class IfTagTest extends StrutsInternalTestCase { // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). IfTag freshTag = new IfTag(); freshTag.setPageContext(pageContext); - assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + 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.", objectsAreReflectionEqual(ifTag, freshTag)); // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). ElseIfTag freshTag2 = new ElseIfTag(); freshTag2.setPageContext(pageContext); - assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + 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.", objectsAreReflectionEqual(elseIfTag1, freshTag2)); - assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + 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.", objectsAreReflectionEqual(elseIfTag2, freshTag2)); - assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + 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.", + objectsAreReflectionEqual(elseIfTag3, freshTag2)); + } + + public void testIfElseIf_clearTagStateSet() throws Exception { + IfTag ifTag = new IfTag(); + ifTag.setPerformClearTagStateForTagPoolingServers(true); // Explicitly request tag state clearing. + ifTag.setPageContext(pageContext); + ifTag.setTest("false"); + + ElseIfTag elseIfTag1 = new ElseIfTag(); + elseIfTag1.setPerformClearTagStateForTagPoolingServers(true); // Explicitly request tag state clearing. + elseIfTag1.setPageContext(pageContext); + elseIfTag1.setTest("false"); + + ElseIfTag elseIfTag2 = new ElseIfTag(); + elseIfTag2.setPerformClearTagStateForTagPoolingServers(true); // Explicitly request tag state clearing. + elseIfTag2.setPageContext(pageContext); + elseIfTag2.setTest("true"); + + ElseIfTag elseIfTag3 = new ElseIfTag(); + elseIfTag3.setPerformClearTagStateForTagPoolingServers(true); // Explicitly request tag state clearing. + elseIfTag3.setPageContext(pageContext); + elseIfTag3.setTest("true"); + + int r1 = ifTag.doStartTag(); + setComponentTagClearTagState(ifTag, true); // Ensure component tag state clearing is set true (to match tag). + ifTag.doEndTag(); + int r2 = elseIfTag1.doStartTag(); + setComponentTagClearTagState(elseIfTag1, true); // Ensure component tag state clearing is set true (to match tag). + elseIfTag1.doEndTag(); + int r3 = elseIfTag2.doStartTag(); + setComponentTagClearTagState(elseIfTag2, true); // Ensure component tag state clearing is set true (to match tag). + elseIfTag2.doEndTag(); + int r4 = elseIfTag3.doStartTag(); + setComponentTagClearTagState(elseIfTag3, true); // Ensure component tag state clearing is set true (to match tag). + elseIfTag3.doEndTag(); + + assertEquals(TagSupport.SKIP_BODY, r1); + assertEquals(TagSupport.SKIP_BODY, r2); + assertEquals(TagSupport.EVAL_BODY_INCLUDE, r3); + assertEquals(TagSupport.SKIP_BODY, r4); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + IfTag freshTag = new IfTag(); + freshTag.setPerformClearTagStateForTagPoolingServers(true); + 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.", + objectsAreReflectionEqual(ifTag, freshTag)); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + ElseIfTag freshTag2 = new ElseIfTag(); + freshTag2.setPerformClearTagStateForTagPoolingServers(true); + freshTag2.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.", + objectsAreReflectionEqual(elseIfTag1, freshTag2)); + 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.", + objectsAreReflectionEqual(elseIfTag2, freshTag2)); + 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.", objectsAreReflectionEqual(elseIfTag3, freshTag2)); } @@ -335,31 +625,109 @@ public class IfTagTest extends StrutsInternalTestCase { // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). IfTag freshTag = new IfTag(); freshTag.setPageContext(pageContext); - assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + 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.", objectsAreReflectionEqual(ifTag, freshTag)); // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). ElseIfTag freshTag2 = new ElseIfTag(); freshTag2.setPageContext(pageContext); - assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + 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.", objectsAreReflectionEqual(elseIfTag1, freshTag2)); - assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + 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.", objectsAreReflectionEqual(elseIfTag2, freshTag2)); - assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + 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.", objectsAreReflectionEqual(elseIfTag3, freshTag2)); // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). ElseTag freshTag3 = new ElseTag(); freshTag3.setPageContext(pageContext); - assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + // ElseTag has no additional state, so it compares as equal with the default tag clear state as well. + assertTrue("Tag state after doEndTag() under default tag clear state is inequal to new Tag with pageContext/parent set. " + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", objectsAreReflectionEqual(elseTag, freshTag3)); } + public void testIfElseIfElse_clearTagStateSet() throws Exception { + IfTag ifTag = new IfTag(); + ifTag.setPerformClearTagStateForTagPoolingServers(true); // Explicitly request tag state clearing. + ifTag.setPageContext(pageContext); + ifTag.setTest("false"); + + ElseIfTag elseIfTag1 = new ElseIfTag(); + elseIfTag1.setPerformClearTagStateForTagPoolingServers(true); // Explicitly request tag state clearing. + elseIfTag1.setPageContext(pageContext); + elseIfTag1.setTest("false"); + + ElseIfTag elseIfTag2 = new ElseIfTag(); + elseIfTag2.setPerformClearTagStateForTagPoolingServers(true); // Explicitly request tag state clearing. + elseIfTag2.setPageContext(pageContext); + elseIfTag2.setTest("false"); + + ElseIfTag elseIfTag3 = new ElseIfTag(); + elseIfTag3.setPerformClearTagStateForTagPoolingServers(true); // Explicitly request tag state clearing. + elseIfTag3.setPageContext(pageContext); + elseIfTag3.setTest("false"); + + ElseTag elseTag = new ElseTag(); + elseTag.setPerformClearTagStateForTagPoolingServers(true); // Explicitly request tag state clearing. + elseTag.setPageContext(pageContext); + + int r1 = ifTag.doStartTag(); + setComponentTagClearTagState(ifTag, true); // Ensure component tag state clearing is set true (to match tag). + ifTag.doEndTag(); + int r2 = elseIfTag1.doStartTag(); + setComponentTagClearTagState(elseIfTag1, true); // Ensure component tag state clearing is set true (to match tag). + elseIfTag1.doEndTag(); + int r3 = elseIfTag2.doStartTag(); + setComponentTagClearTagState(elseIfTag2, true); // Ensure component tag state clearing is set true (to match tag). + elseIfTag2.doEndTag(); + int r4 = elseIfTag3.doStartTag(); + setComponentTagClearTagState(elseIfTag3, true); // Ensure component tag state clearing is set true (to match tag). + elseIfTag3.doEndTag(); + int r5 = elseTag.doStartTag(); + setComponentTagClearTagState(elseTag, true); // Ensure component tag state clearing is set true (to match tag). + elseTag.doEndTag(); + + assertEquals(TagSupport.SKIP_BODY, r1); + assertEquals(TagSupport.SKIP_BODY, r2); + assertEquals(TagSupport.SKIP_BODY, r3); + assertEquals(TagSupport.SKIP_BODY, r4); + assertEquals(TagSupport.EVAL_BODY_INCLUDE, r5); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + IfTag freshTag = new IfTag(); + freshTag.setPerformClearTagStateForTagPoolingServers(true); + 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.", + objectsAreReflectionEqual(ifTag, freshTag)); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + ElseIfTag freshTag2 = new ElseIfTag(); + freshTag2.setPerformClearTagStateForTagPoolingServers(true); + freshTag2.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.", + objectsAreReflectionEqual(elseIfTag1, freshTag2)); + 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.", + objectsAreReflectionEqual(elseIfTag2, freshTag2)); + 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.", + objectsAreReflectionEqual(elseIfTag3, freshTag2)); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + ElseTag freshTag3 = new ElseTag(); + freshTag3.setPerformClearTagStateForTagPoolingServers(true); + freshTag3.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.", + objectsAreReflectionEqual(elseTag, freshTag3)); + } public void testNestedIfElse1() throws Exception { IfTag ifTag = new IfTag(); @@ -390,17 +758,70 @@ public class IfTagTest extends StrutsInternalTestCase { // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). IfTag freshTag = new IfTag(); freshTag.setPageContext(pageContext); - assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + 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.", objectsAreReflectionEqual(ifTag, freshTag)); - assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + 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.", objectsAreReflectionEqual(nestedIfTag, freshTag)); // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). ElseTag freshTag2 = new ElseTag(); freshTag2.setPageContext(pageContext); - assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + // ElseTag has no additional state, so it compares as equal with the default tag clear state as well. + assertTrue("Tag state after doEndTag() under default tag clear state is inequal to new Tag with pageContext/parent set. " + + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", + objectsAreReflectionEqual(elseTag, freshTag2)); + } + + public void testNestedIfElse1_clearTagStateSet() throws Exception { + IfTag ifTag = new IfTag(); + ifTag.setPerformClearTagStateForTagPoolingServers(true); // Explicitly request tag state clearing. + ifTag.setPageContext(pageContext); + ifTag.setTest("true"); + + IfTag nestedIfTag = new IfTag(); + nestedIfTag.setPerformClearTagStateForTagPoolingServers(true); // Explicitly request tag state clearing. + nestedIfTag.setPageContext(pageContext); + nestedIfTag.setTest("true"); + + ElseTag elseTag = new ElseTag(); + elseTag.setPerformClearTagStateForTagPoolingServers(true); // Explicitly request tag state clearing. + elseTag.setPageContext(pageContext); + + int r1 = ifTag.doStartTag(); + setComponentTagClearTagState(ifTag, true); // Ensure component tag state clearing is set true (to match tag). + int r2 = nestedIfTag.doStartTag(); + setComponentTagClearTagState(nestedIfTag, true); // Ensure component tag state clearing is set true (to match tag). + int r3 = nestedIfTag.doEndTag(); + int r4 = ifTag.doEndTag(); + int r5 = elseTag.doStartTag(); + setComponentTagClearTagState(elseTag, true); // Ensure component tag state clearing is set true (to match tag). + int r6 = elseTag.doEndTag(); + + assertEquals(TagSupport.EVAL_BODY_INCLUDE, r1); + assertEquals(TagSupport.EVAL_BODY_INCLUDE, r2); + assertEquals(TagSupport.EVAL_PAGE, r3); + assertEquals(TagSupport.EVAL_PAGE, r4); + assertEquals(TagSupport.SKIP_BODY, r5); + assertEquals(TagSupport.EVAL_PAGE, r6); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + IfTag freshTag = new IfTag(); + freshTag.setPerformClearTagStateForTagPoolingServers(true); + 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.", + objectsAreReflectionEqual(ifTag, freshTag)); + 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.", + objectsAreReflectionEqual(nestedIfTag, freshTag)); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + ElseTag freshTag2 = new ElseTag(); + freshTag2.setPerformClearTagStateForTagPoolingServers(true); + freshTag2.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.", objectsAreReflectionEqual(elseTag, freshTag2)); } @@ -434,23 +855,91 @@ public class IfTagTest extends StrutsInternalTestCase { // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). IfTag freshTag = new IfTag(); freshTag.setPageContext(pageContext); - assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + 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.", objectsAreReflectionEqual(ifTag, freshTag)); - assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + 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.", objectsAreReflectionEqual(nestedIfTag, freshTag)); // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). ElseTag freshTag2 = new ElseTag(); freshTag2.setPageContext(pageContext); - assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + // ElseTag has no additional state, so it compares as equal with the default tag clear state as well. + assertTrue("Tag state after doEndTag() under default tag clear state is inequal to new Tag with pageContext/parent set. " + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", objectsAreReflectionEqual(elseTag, freshTag2)); } + public void testNestedIfElse2_clearTagStateSet() throws Exception { + IfTag ifTag = new IfTag(); + ifTag.setPerformClearTagStateForTagPoolingServers(true); // Explicitly request tag state clearing. + ifTag.setPageContext(pageContext); + ifTag.setTest("true"); + IfTag nestedIfTag = new IfTag(); + nestedIfTag.setPerformClearTagStateForTagPoolingServers(true); // Explicitly request tag state clearing. + nestedIfTag.setPageContext(pageContext); + nestedIfTag.setTest("false"); + ElseTag elseTag = new ElseTag(); + elseTag.setPerformClearTagStateForTagPoolingServers(true); // Explicitly request tag state clearing. + elseTag.setPageContext(pageContext); + + int r1 = ifTag.doStartTag(); + setComponentTagClearTagState(ifTag, true); // Ensure component tag state clearing is set true (to match tag). + int r2 = nestedIfTag.doStartTag(); + setComponentTagClearTagState(nestedIfTag, true); // Ensure component tag state clearing is set true (to match tag). + int r3 = nestedIfTag.doEndTag(); + int r4 = ifTag.doEndTag(); + int r5 = elseTag.doStartTag(); + setComponentTagClearTagState(elseTag, true); // Ensure component tag state clearing is set true (to match tag). + int r6 = elseTag.doEndTag(); + + assertEquals(TagSupport.EVAL_BODY_INCLUDE, r1); + assertEquals(TagSupport.SKIP_BODY, r2); + assertEquals(TagSupport.EVAL_PAGE, r3); + assertEquals(TagSupport.EVAL_PAGE, r4); + assertEquals(TagSupport.SKIP_BODY, r5); + assertEquals(TagSupport.EVAL_PAGE, r6); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + IfTag freshTag = new IfTag(); + freshTag.setPerformClearTagStateForTagPoolingServers(true); + 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.", + objectsAreReflectionEqual(ifTag, freshTag)); + 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.", + objectsAreReflectionEqual(nestedIfTag, freshTag)); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + ElseTag freshTag2 = new ElseTag(); + freshTag2.setPerformClearTagStateForTagPoolingServers(true); + freshTag2.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.", + objectsAreReflectionEqual(elseTag, freshTag2)); + } + + /** + * Helper method to simplify setting the performClearTagStateForTagPoolingServers state for a + * {@link ComponentTagSupport} tag's {@link Component} to match expecations for a test. + * + * Since the component is not available to the tag until after the doStartTag() method is called, + * but we need to ensure the component's {@link Component#performClearTagStateForTagPoolingServers} state matches + * what we set for the Tag when a non-default (true) value is used, this method retrieves the component instance, + * sets the value specified and forces the parameters to be repopulated again. + * + * @param tag The ComponentTagSupport tag upon whose component we will set the performClearTagStateForTagPoolingServers state. + * @param performClearTagStateForTagPoolingServers true to clear tag state, false otherwise + */ + protected void setComponentTagClearTagState(ComponentTagSupport tag, boolean performClearTagStateForTagPoolingServers) { + tag.component.setPerformClearTagStateForTagPoolingServers(performClearTagStateForTagPoolingServers); + //tag.populateParams(); // Not safe to call after doStartTag() ... breaks some tests. + tag.populatePerformClearTagStateForTagPoolingServersParam(); // Only populate the performClearTagStateForTagPoolingServers parameter for the Tag. + } @Override protected void setUp() throws Exception { diff --git a/core/src/test/java/org/apache/struts2/views/jsp/IncludeTagTest.java b/core/src/test/java/org/apache/struts2/views/jsp/IncludeTagTest.java index 69d134292..85fe212b1 100644 --- a/core/src/test/java/org/apache/struts2/views/jsp/IncludeTagTest.java +++ b/core/src/test/java/org/apache/struts2/views/jsp/IncludeTagTest.java @@ -69,7 +69,35 @@ public class IncludeTagTest extends AbstractTagTest { // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). IncludeTag freshTag = new IncludeTag(); freshTag.setPageContext(pageContext); - assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + 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 testIncludeNoParam_clearTagStateSet() throws Exception { + + // Use always matcher as we can not determine the exact objects used in mock.include(request, response) call + mockRequestDispatcher.include(anyObject(ServletRequest.class), anyObject(ServletResponse.class)); + expectLastCall().times(1); + + replay(mockRequestDispatcher); + + tag.setPerformClearTagStateForTagPoolingServers(true); // Explicitly request tag state clearing. + tag.setValue("person/list.jsp"); + tag.doStartTag(); + setComponentTagClearTagState(tag, true); // Ensure component tag state clearing is set true (to match tag). + tag.doEndTag(); + + assertEquals("/person/list.jsp", request.getRequestDispatherString()); + assertEquals("", writer.toString()); + + verify(mockRequestDispatcher); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + IncludeTag freshTag = new IncludeTag(); + freshTag.setPerformClearTagStateForTagPoolingServers(true); + 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)); } @@ -97,7 +125,38 @@ public class IncludeTagTest extends AbstractTagTest { // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). IncludeTag freshTag = new IncludeTag(); freshTag.setPageContext(pageContext); - assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + 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 testIncludeWithParameters_clearTagStateSet() throws Exception { + + // Use always matcher as we can not determine the exact objects used in mock.include(request, response) call + mockRequestDispatcher.include(anyObject(ServletRequest.class), anyObject(ServletResponse.class)); + expectLastCall().times(1); + + replay(mockRequestDispatcher); + + tag.setPerformClearTagStateForTagPoolingServers(true); // Explicitly request tag state clearing. + tag.setValue("person/create.jsp"); + tag.doStartTag(); + setComponentTagClearTagState(tag, true); // Ensure component tag state clearing is set true (to match tag). + // adding param must be done after doStartTag() + Include include = (Include) tag.getComponent(); + include.addParameter("user", "Santa Claus"); + tag.doEndTag(); + + assertEquals("/person/create.jsp?user=Santa+Claus", request.getRequestDispatherString()); + assertEquals("", writer.toString()); + + verify(mockRequestDispatcher); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + IncludeTag freshTag = new IncludeTag(); + freshTag.setPerformClearTagStateForTagPoolingServers(true); + 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)); } @@ -124,7 +183,37 @@ public class IncludeTagTest extends AbstractTagTest { // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). IncludeTag freshTag = new IncludeTag(); freshTag.setPageContext(pageContext); - assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + 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 testIncludeRelative2Dots_clearTagStateSet() throws Exception { + // TODO: we should test for .. in unit test - is this test correct? + // Use always matcher as we can not determine the exact objects used in mock.include(request, response) call + mockRequestDispatcher.include(anyObject(ServletRequest.class), anyObject(ServletResponse.class)); + expectLastCall().times(1); + + replay(mockRequestDispatcher); + + request.setupGetServletPath("app/manager"); + tag.setPerformClearTagStateForTagPoolingServers(true); // Explicitly request tag state clearing. + tag.setValue("../car/view.jsp"); + tag.doStartTag(); + setComponentTagClearTagState(tag, true); // Ensure component tag state clearing is set true (to match tag). + tag.doEndTag(); + + + assertEquals("/car/view.jsp", request.getRequestDispatherString()); + assertEquals("", writer.toString()); + + verify(mockRequestDispatcher); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + IncludeTag freshTag = new IncludeTag(); + freshTag.setPerformClearTagStateForTagPoolingServers(true); + 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)); } @@ -158,7 +247,44 @@ public class IncludeTagTest extends AbstractTagTest { // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). IncludeTag freshTag = new IncludeTag(); freshTag.setPageContext(pageContext); - assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + 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 testIncludeSetUseResponseEncodingTrue_clearTagStateSet() throws Exception { + // TODO: If possible in future mock-test an actual content-includes with various encodings + // while setting the response encoding to match. Doesn't appear to be possible + // right now in unit-test form. + // Seems that the best we can do is verify the setUseResponseEncoding() doesn't fail... + + // Use always matcher as we can not determine the exact objects used in mock.include(request, response) call + mockRequestDispatcher.include(anyObject(ServletRequest.class), anyObject(ServletResponse.class)); + expectLastCall().times(1); + + replay(mockRequestDispatcher); + + tag.setPerformClearTagStateForTagPoolingServers(true); // Explicitly request tag state clearing. + tag.setValue("person/create.jsp"); + response.setCharacterEncoding("UTF-8"); + tag.doStartTag(); + setComponentTagClearTagState(tag, true); // Ensure component tag state clearing is set true (to match tag). + // Manipulate after doStartTag to ensure the tag component has undergone injection + Include include = (Include) tag.getComponent(); + include.setUseResponseEncoding("true"); + tag.doEndTag(); + + assertEquals("UTF-8", response.getCharacterEncoding()); + assertEquals("/person/create.jsp", request.getRequestDispatherString()); + assertEquals("", writer.toString()); // Nothing gets written for mock-include + + verify(mockRequestDispatcher); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + IncludeTag freshTag = new IncludeTag(); + freshTag.setPerformClearTagStateForTagPoolingServers(true); + 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)); } @@ -192,7 +318,44 @@ public class IncludeTagTest extends AbstractTagTest { // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). IncludeTag freshTag = new IncludeTag(); freshTag.setPageContext(pageContext); - assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + 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 testIncludeSetUseResponseEncodingFalse_clearTagStateSet() throws Exception { + // TODO: If possible in future mock-test an actual content-includes with various encodings + // while setting the response encoding to match. Doesn't appear to be possible + // right now in unit-test form. + // Seems that the best we can do is verify the setUseResponseEncoding() doesn't fail... + + // Use always matcher as we can not determine the exact objects used in mock.include(request, response) call + mockRequestDispatcher.include(anyObject(ServletRequest.class), anyObject(ServletResponse.class)); + expectLastCall().times(1); + + replay(mockRequestDispatcher); + + tag.setPerformClearTagStateForTagPoolingServers(true); // Explicitly request tag state clearing. + tag.setValue("person/create.jsp"); + response.setCharacterEncoding("UTF-8"); + tag.doStartTag(); + setComponentTagClearTagState(tag, true); // Ensure component tag state clearing is set true (to match tag). + // Manipulate after doStartTag to ensure the tag component has undergone injection + Include include = (Include) tag.getComponent(); + include.setUseResponseEncoding("false"); + tag.doEndTag(); + + assertEquals("UTF-8", response.getCharacterEncoding()); + assertEquals("/person/create.jsp", request.getRequestDispatherString()); + assertEquals("", writer.toString()); // Nothing gets written for mock-include + + verify(mockRequestDispatcher); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + IncludeTag freshTag = new IncludeTag(); + freshTag.setPerformClearTagStateForTagPoolingServers(true); + 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)); } diff --git a/core/src/test/java/org/apache/struts2/views/jsp/IteratorGeneratorTagTest.java b/core/src/test/java/org/apache/struts2/views/jsp/IteratorGeneratorTagTest.java index cf53dd14c..d1748e16f 100644 --- a/core/src/test/java/org/apache/struts2/views/jsp/IteratorGeneratorTagTest.java +++ b/core/src/test/java/org/apache/struts2/views/jsp/IteratorGeneratorTagTest.java @@ -69,7 +69,51 @@ public class IteratorGeneratorTagTest extends AbstractTagTest { // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). IteratorGeneratorTag freshTag = new IteratorGeneratorTag(); freshTag.setPageContext(pageContext); - assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + 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 testGeneratorBasic_clearTagStateSet() throws Exception { + IteratorGeneratorTag tag = new IteratorGeneratorTag(); + + tag.setPerformClearTagStateForTagPoolingServers(true); // Explicitly request tag state clearing. + tag.setPageContext(pageContext); + tag.setVal("%{'aaa,bbb,ccc,ddd,eee'}"); + tag.doStartTag(); + Object topOfStack = stack.findValue("top"); + + + assertTrue(topOfStack instanceof Iterator); + // 1 + assertTrue(((Iterator)topOfStack).hasNext()); + assertEquals(((Iterator)topOfStack).next(), "aaa"); + // 2 + assertTrue(((Iterator)topOfStack).hasNext()); + assertEquals(((Iterator)topOfStack).next(), "bbb"); + // 3 + assertTrue(((Iterator)topOfStack).hasNext()); + assertEquals(((Iterator)topOfStack).next(), "ccc"); + // 4 + assertTrue(((Iterator)topOfStack).hasNext()); + assertEquals(((Iterator)topOfStack).next(), "ddd"); + // 5 + assertTrue(((Iterator)topOfStack).hasNext()); + assertEquals(((Iterator)topOfStack).next(),"eee"); + + assertFalse(((Iterator)topOfStack).hasNext()); + + tag.doEndTag(); + Object afterTopOfStack = stack.findValue("top"); + + + assertNotSame(afterTopOfStack, topOfStack); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + IteratorGeneratorTag freshTag = new IteratorGeneratorTag(); + freshTag.setPerformClearTagStateForTagPoolingServers(true); + 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)); } @@ -108,7 +152,48 @@ public class IteratorGeneratorTagTest extends AbstractTagTest { // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). IteratorGeneratorTag freshTag = new IteratorGeneratorTag(); freshTag.setPageContext(pageContext); - assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + 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 testGeneratorWithSeparator_clearTagStateSet() throws Exception { + IteratorGeneratorTag tag = new IteratorGeneratorTag(); + + tag.setPerformClearTagStateForTagPoolingServers(true); // Explicitly request tag state clearing. + tag.setPageContext(pageContext); + tag.setVal("%{'aaa|bbb|ccc|ddd|eee'}"); + tag.setSeparator("|"); + tag.doStartTag(); + Object topOfStack = stack.findValue("top"); + tag.doEndTag(); + Object afterTopOfStack = stack.findValue("top"); + + assertTrue(topOfStack instanceof Iterator); + // 1 + assertTrue(((Iterator)topOfStack).hasNext()); + assertEquals(((Iterator)topOfStack).next(), "aaa"); + // 2 + assertTrue(((Iterator)topOfStack).hasNext()); + assertEquals(((Iterator)topOfStack).next(), "bbb"); + // 3 + assertTrue(((Iterator)topOfStack).hasNext()); + assertEquals(((Iterator)topOfStack).next(), "ccc"); + // 4 + assertTrue(((Iterator)topOfStack).hasNext()); + assertEquals(((Iterator)topOfStack).next(), "ddd"); + // 5 + assertTrue(((Iterator)topOfStack).hasNext()); + assertEquals(((Iterator)topOfStack).next(), "eee"); + + assertFalse(((Iterator)topOfStack).hasNext()); + assertNotSame(afterTopOfStack, topOfStack); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + IteratorGeneratorTag freshTag = new IteratorGeneratorTag(); + freshTag.setPerformClearTagStateForTagPoolingServers(true); + 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)); } @@ -147,7 +232,48 @@ public class IteratorGeneratorTagTest extends AbstractTagTest { // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). IteratorGeneratorTag freshTag = new IteratorGeneratorTag(); freshTag.setPageContext(pageContext); - assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + 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 testGeneratorWithConverter_clearTagStateSet() throws Exception { + IteratorGeneratorTag tag = new IteratorGeneratorTag(); + + tag.setPerformClearTagStateForTagPoolingServers(true); // Explicitly request tag state clearing. + tag.setPageContext(pageContext); + tag.setVal("%{'aaa, bbb, ccc, ddd, eee'}"); + tag.setConverter("myConverter"); + tag.doStartTag(); + Object topOfStack = stack.findValue("top"); + tag.doEndTag(); + Object afterTopOfStack = stack.findValue("top"); + + assertTrue(topOfStack instanceof Iterator); + // 1. + assertTrue(((Iterator)topOfStack).hasNext()); + assertEquals(((Iterator)topOfStack).next(), "myConverter-aaa"); + // 2 + assertTrue(((Iterator)topOfStack).hasNext()); + assertEquals(((Iterator)topOfStack).next(), "myConverter-bbb"); + // 3 + assertTrue(((Iterator)topOfStack).hasNext()); + assertEquals(((Iterator)topOfStack).next(), "myConverter-ccc"); + // 4. + assertTrue(((Iterator)topOfStack).hasNext()); + assertEquals(((Iterator)topOfStack).next(), "myConverter-ddd"); + // 5. + assertTrue(((Iterator)topOfStack).hasNext()); + assertEquals(((Iterator)topOfStack).next(), "myConverter-eee"); + + assertFalse(((Iterator)topOfStack).hasNext()); + assertNotSame(afterTopOfStack, topOfStack); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + IteratorGeneratorTag freshTag = new IteratorGeneratorTag(); + freshTag.setPerformClearTagStateForTagPoolingServers(true); + 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)); } @@ -184,7 +310,46 @@ public class IteratorGeneratorTagTest extends AbstractTagTest { // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). IteratorGeneratorTag freshTag = new IteratorGeneratorTag(); freshTag.setPageContext(pageContext); - assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + 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 testGeneratorWithId_clearTagStateSet() throws Exception { + IteratorGeneratorTag tag = new IteratorGeneratorTag(); + tag.setPerformClearTagStateForTagPoolingServers(true); // Explicitly request tag state clearing. + tag.setPageContext(pageContext); + tag.setVal("%{'aaa,bbb,ccc,ddd,eee'}"); + tag.setVar("myPageContextAttId"); + tag.doStartTag(); + tag.doEndTag(); + + Object pageContextIterator = stack.findValue("myPageContextAttId"); + + assertTrue(pageContextIterator instanceof Iterator); + // 1 + assertTrue(((Iterator)pageContextIterator).hasNext()); + assertEquals(((Iterator)pageContextIterator).next(), "aaa"); + // 2. + assertTrue(((Iterator)pageContextIterator).hasNext()); + assertEquals(((Iterator)pageContextIterator).next(), "bbb"); + // 3. + assertTrue(((Iterator)pageContextIterator).hasNext()); + assertEquals(((Iterator)pageContextIterator).next(), "ccc"); + // 4 + assertTrue(((Iterator)pageContextIterator).hasNext()); + assertEquals(((Iterator)pageContextIterator).next(), "ddd"); + // 5 + assertTrue(((Iterator)pageContextIterator).hasNext()); + assertEquals(((Iterator)pageContextIterator).next(), "eee"); + + assertFalse(((Iterator)pageContextIterator).hasNext()); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + IteratorGeneratorTag freshTag = new IteratorGeneratorTag(); + freshTag.setPerformClearTagStateForTagPoolingServers(true); + 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)); } @@ -218,11 +383,46 @@ public class IteratorGeneratorTagTest extends AbstractTagTest { // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). IteratorGeneratorTag freshTag = new IteratorGeneratorTag(); freshTag.setPageContext(pageContext); - assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + 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 testGeneratorWithCount_clearTagStateSet() throws Exception { + IteratorGeneratorTag tag = new IteratorGeneratorTag(); + + tag.setPerformClearTagStateForTagPoolingServers(true); // Explicitly request tag state clearing. + tag.setPageContext(pageContext); + tag.setVal("%{'aaa,bbb,ccc,ddd,eee'}"); + tag.setCount("myCount"); + tag.doStartTag(); + Object topOfStack = stack.findValue("top"); + tag.doEndTag(); + Object afterTopOfStack = stack.findValue("top"); + + + assertTrue(topOfStack instanceof Iterator); + // 1 + assertTrue(((Iterator)topOfStack).hasNext()); + assertEquals(((Iterator)topOfStack).next(), "aaa"); + // 2 + assertTrue(((Iterator)topOfStack).hasNext()); + assertEquals(((Iterator)topOfStack).next(), "bbb"); + // 3. + assertTrue(((Iterator)topOfStack).hasNext()); + assertEquals(((Iterator)topOfStack).next(), "ccc"); + + assertFalse(((Iterator)topOfStack).hasNext()); + assertNotSame(topOfStack, afterTopOfStack); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + IteratorGeneratorTag freshTag = new IteratorGeneratorTag(); + freshTag.setPerformClearTagStateForTagPoolingServers(true); + 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)); + } @Override public Action getAction() { diff --git a/core/src/test/java/org/apache/struts2/views/jsp/IteratorTagTest.java b/core/src/test/java/org/apache/struts2/views/jsp/IteratorTagTest.java index a473931cf..df5022c0a 100644 --- a/core/src/test/java/org/apache/struts2/views/jsp/IteratorTagTest.java +++ b/core/src/test/java/org/apache/struts2/views/jsp/IteratorTagTest.java @@ -103,11 +103,81 @@ public class IteratorTagTest extends AbstractUITagTest { // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). IteratorTag freshTag = new IteratorTag(); freshTag.setPageContext(pageContext); - assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + 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 testIteratingWithIdSpecified_clearTagStateSet() throws Exception { + List list = new ArrayList(); + list.add("one"); + list.add("two"); + list.add("three"); + list.add("four"); + list.add("five"); + + Foo foo = new Foo(); + foo.setList(list); + + stack.push(foo); + + tag.setPerformClearTagStateForTagPoolingServers(true); // Explicitly request tag state clearing. + tag.setValue("list"); + tag.setVar("myId"); + + // one + int result = tag.doStartTag(); + setComponentTagClearTagState(tag, true); // Ensure component tag state clearing is set true (to match tag). + assertEquals(TagSupport.EVAL_BODY_INCLUDE, result); + assertEquals(stack.peek(), "one"); + assertEquals(stack.getContext().get("myId"), "one"); + + + tag.doInitBody(); + + // two + result = tag.doAfterBody(); + assertEquals(TagSupport.EVAL_BODY_AGAIN, result); + assertEquals(stack.peek(), "two"); + assertEquals(stack.getContext().get("myId"), "two"); + + + // three + result = tag.doAfterBody(); + assertEquals(TagSupport.EVAL_BODY_AGAIN, result); + assertEquals(stack.peek(), "three"); + assertEquals(stack.getContext().get("myId"), "three"); + + + // four + result = tag.doAfterBody(); + assertEquals(TagSupport.EVAL_BODY_AGAIN, result); + assertEquals(stack.peek(), "four"); + assertEquals(stack.getContext().get("myId"), "four"); + + + // five + result = tag.doAfterBody(); + assertEquals(TagSupport.EVAL_BODY_AGAIN, result); + assertEquals(stack.peek(), "five"); + assertEquals(stack.getContext().get("myId"), "five"); + + + result = tag.doAfterBody(); + assertEquals(TagSupport.SKIP_BODY, result); + + result = tag.doEndTag(); + assertEquals(TagSupport.EVAL_PAGE, result); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + IteratorTag freshTag = new IteratorTag(); + freshTag.setPerformClearTagStateForTagPoolingServers(true); + 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)); + } + public void testIteratingWithIdSpecifiedAndNullElementOnCollection() throws Exception { List list = new ArrayList(); list.add("one"); @@ -153,11 +223,63 @@ public class IteratorTagTest extends AbstractUITagTest { // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). IteratorTag freshTag = new IteratorTag(); freshTag.setPageContext(pageContext); - assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + 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 testIteratingWithIdSpecifiedAndNullElementOnCollection_clearTagStateSet() throws Exception { + List list = new ArrayList(); + list.add("one"); + list.add(null); + list.add("three"); + + Foo foo = new Foo(); + foo.setList(list); + + stack.push(foo); + + tag.setPerformClearTagStateForTagPoolingServers(true); // Explicitly request tag state clearing. + tag.setValue("list"); + tag.setVar("myId"); + + // one + int result = tag.doStartTag(); + setComponentTagClearTagState(tag, true); // Ensure component tag state clearing is set true (to match tag). + assertEquals(TagSupport.EVAL_BODY_INCLUDE, result); + assertEquals(stack.peek(), "one"); + assertEquals(stack.getContext().get("myId"), "one"); + + + tag.doInitBody(); + + // two + result = tag.doAfterBody(); + assertEquals(TagSupport.EVAL_BODY_AGAIN, result); + assertNull(stack.peek()); + assertNull(stack.getContext().get("myId")); + + + // three + result = tag.doAfterBody(); + assertEquals(TagSupport.EVAL_BODY_AGAIN, result); + assertEquals(stack.peek(), "three"); + assertEquals(stack.getContext().get("myId"), "three"); + + result = tag.doAfterBody(); + assertEquals(TagSupport.SKIP_BODY, result); + + result = tag.doEndTag(); + assertEquals(TagSupport.EVAL_PAGE, result); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + IteratorTag freshTag = new IteratorTag(); + freshTag.setPerformClearTagStateForTagPoolingServers(true); + 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)); + } public void testArrayIterator() { Foo foo = new Foo(); @@ -259,7 +381,84 @@ public class IteratorTagTest extends AbstractUITagTest { // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). IteratorTag freshTag = new IteratorTag(); freshTag.setPageContext(pageContext); - assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + 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 testMapIterator_clearTagStateSet() { + Foo foo = new Foo(); + HashMap map = new HashMap(); + map.put("test1", "123"); + map.put("test2", "456"); + map.put("test3", "789"); + foo.setMap(map); + + stack.push(foo); + + tag.setPerformClearTagStateForTagPoolingServers(true); // Explicitly request tag state clearing. + tag.setValue("map"); + + int result = 0; + + try { + result = tag.doStartTag(); + setComponentTagClearTagState(tag, true); // Ensure component tag state clearing is set true (to match tag). + } catch (JspException e) { + e.printStackTrace(); + fail(); + } + + assertEquals(TagSupport.EVAL_BODY_INCLUDE, result); + assertEquals(4, stack.size()); + assertTrue(stack.getRoot().peek() instanceof Map.Entry); + + try { + result = tag.doAfterBody(); + } catch (JspException e) { + e.printStackTrace(); + fail(); + } + + assertEquals(TagSupport.EVAL_BODY_AGAIN, result); + assertEquals(4, stack.size()); + assertTrue(stack.getRoot().peek() instanceof Map.Entry); + + try { + result = tag.doAfterBody(); + } catch (JspException e) { + e.printStackTrace(); + fail(); + } + + assertEquals(TagSupport.EVAL_BODY_AGAIN, result); + assertEquals(4, stack.size()); + assertTrue(stack.getRoot().peek() instanceof Map.Entry); + + try { + result = tag.doAfterBody(); + } catch (JspException e) { + e.printStackTrace(); + fail(); + } + + assertEquals(TagSupport.SKIP_BODY, result); + assertEquals(3, stack.size()); + + try { + result = tag.doEndTag(); + } catch (JspException e) { + e.printStackTrace(); + fail(); + } + + assertEquals(TagSupport.EVAL_PAGE, result); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + IteratorTag freshTag = new IteratorTag(); + freshTag.setPerformClearTagStateForTagPoolingServers(true); + 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)); } @@ -347,7 +546,98 @@ public class IteratorTagTest extends AbstractUITagTest { // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). IteratorTag freshTag = new IteratorTag(); freshTag.setPageContext(pageContext); - assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + 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 testStatus_clearTagStateSet() { + Foo foo = new Foo(); + foo.setArray(new String[]{"test1", "test2", "test3"}); + + stack.push(foo); + + tag.setPerformClearTagStateForTagPoolingServers(true); // Explicitly request tag state clearing. + tag.setValue("array"); + tag.setStatus("fooStatus"); + + int result = 0; + + try { + result = tag.doStartTag(); + setComponentTagClearTagState(tag, true); // Ensure component tag state clearing is set true (to match tag). + } catch (JspException e) { + e.printStackTrace(); + fail(); + } + + assertEquals(TagSupport.EVAL_BODY_INCLUDE, result); + assertEquals("test1", stack.getRoot().peek()); + assertEquals(4, stack.size()); + + IteratorStatus status = (IteratorStatus) context.get("fooStatus"); + assertNotNull(status); + assertFalse(status.isLast()); + assertTrue(status.isFirst()); + assertEquals(0, status.getIndex()); + assertEquals(1, status.getCount()); + assertTrue(status.isOdd()); + assertFalse(status.isEven()); + + try { + result = tag.doAfterBody(); + } catch (JspException e) { + e.printStackTrace(); + fail(); + } + + assertEquals(TagSupport.EVAL_BODY_AGAIN, result); + assertEquals("test2", stack.getRoot().peek()); + assertEquals(4, stack.size()); + + status = (IteratorStatus) context.get("fooStatus"); + assertNotNull(status); + assertFalse(status.isLast()); + assertFalse(status.isFirst()); + assertEquals(1, status.getIndex()); + assertEquals(2, status.getCount()); + assertFalse(status.isOdd()); + assertTrue(status.isEven()); + + try { + result = tag.doAfterBody(); + } catch (JspException e) { + e.printStackTrace(); + fail(); + } + + assertEquals(TagSupport.EVAL_BODY_AGAIN, result); + assertEquals("test3", stack.getRoot().peek()); + assertEquals(4, stack.size()); + + status = (IteratorStatus) context.get("fooStatus"); + assertNotNull(status); + assertTrue(status.isLast()); + assertFalse(status.isFirst()); + assertEquals(2, status.getIndex()); + assertEquals(3, status.getCount()); + assertTrue(status.isOdd()); + assertFalse(status.isEven()); + + try { + result = tag.doEndTag(); + } catch (JspException e) { + e.printStackTrace(); + fail(); + } + + assertEquals(TagSupport.EVAL_PAGE, result); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + IteratorTag freshTag = new IteratorTag(); + freshTag.setPerformClearTagStateForTagPoolingServers(true); + 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)); } @@ -807,7 +1097,7 @@ public class IteratorTagTest extends AbstractUITagTest { // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). IteratorTag freshTag = new IteratorTag(); freshTag.setPageContext(pageContext); - assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + 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)); } diff --git a/core/src/test/java/org/apache/struts2/views/jsp/MergeIteratorTagTest.java b/core/src/test/java/org/apache/struts2/views/jsp/MergeIteratorTagTest.java index 811f4de44..f4a97842c 100644 --- a/core/src/test/java/org/apache/struts2/views/jsp/MergeIteratorTagTest.java +++ b/core/src/test/java/org/apache/struts2/views/jsp/MergeIteratorTagTest.java @@ -86,24 +86,104 @@ public class MergeIteratorTagTest extends AbstractTagTest { // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). ParamTag freshParamTag = new ParamTag(); freshParamTag.setPageContext(pageContext); - assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + 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(iterator1ParamTag, freshParamTag)); - assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + 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(iterator2ParamTag, freshParamTag)); - assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + 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(iterator3ParamTag, freshParamTag)); // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). MergeIteratorTag freshTag = new MergeIteratorTag(); freshTag.setPageContext(pageContext); - assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + 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 testMergingIteratorWithArrayAsSource_clearTagStateSet() throws Exception { + MergeIteratorTag tag = new MergeIteratorTag(); + tag.setPerformClearTagStateForTagPoolingServers(true); // Explicitly request tag state clearing. + tag.setPageContext(pageContext); + tag.setVar("myMergedIterator"); + + ParamTag iterator1ParamTag = new ParamTag(); + iterator1ParamTag.setPerformClearTagStateForTagPoolingServers(true); // Explicitly request tag state clearing. + iterator1ParamTag.setPageContext(pageContext); + iterator1ParamTag.setValue("myArr1"); + + ParamTag iterator2ParamTag = new ParamTag(); + iterator2ParamTag.setPerformClearTagStateForTagPoolingServers(true); // Explicitly request tag state clearing. + iterator2ParamTag.setPageContext(pageContext); + iterator2ParamTag.setValue("myArr2"); + + ParamTag iterator3ParamTag = new ParamTag(); + iterator3ParamTag.setPerformClearTagStateForTagPoolingServers(true); // Explicitly request tag state clearing. + iterator3ParamTag.setPageContext(pageContext); + iterator3ParamTag.setValue("myArr3"); + + + tag.doStartTag(); + setComponentTagClearTagState(tag, true); // Ensure component tag state clearing is set true (to match tag). + iterator1ParamTag.doStartTag(); + setComponentTagClearTagState(iterator1ParamTag, true); // Ensure component tag state clearing is set true (to match tag). + iterator1ParamTag.doEndTag(); + iterator2ParamTag.doStartTag(); + setComponentTagClearTagState(iterator2ParamTag, true); // Ensure component tag state clearing is set true (to match tag). + iterator2ParamTag.doEndTag(); + iterator3ParamTag.doStartTag(); + setComponentTagClearTagState(iterator3ParamTag, true); // Ensure component tag state clearing is set true (to match tag). + iterator3ParamTag.doEndTag(); + tag.doEndTag(); + + Iterator mergedIterator = (Iterator) stack.findValue("#myMergedIterator"); // if not iterator, let CCE surface + + assertNotNull(mergedIterator); + assertTrue(mergedIterator.hasNext()); + assertEquals(mergedIterator.next(), "1"); + assertTrue(mergedIterator.hasNext()); + assertEquals(mergedIterator.next(), "a"); + assertTrue(mergedIterator.hasNext()); + assertEquals(mergedIterator.next(), "A"); + assertTrue(mergedIterator.hasNext()); + assertEquals(mergedIterator.next(), "2"); + assertTrue(mergedIterator.hasNext()); + assertEquals(mergedIterator.next(), "b"); + assertTrue(mergedIterator.hasNext()); + assertEquals(mergedIterator.next(), "B"); + assertTrue(mergedIterator.hasNext()); + assertEquals(mergedIterator.next(), "3"); + assertTrue(mergedIterator.hasNext()); + assertEquals(mergedIterator.next(), "c"); + assertTrue(mergedIterator.hasNext()); + assertEquals(mergedIterator.next(), "C"); + assertFalse(mergedIterator.hasNext()); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + ParamTag freshParamTag = new ParamTag(); + freshParamTag.setPerformClearTagStateForTagPoolingServers(true); + freshParamTag.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(iterator1ParamTag, freshParamTag)); + 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(iterator2ParamTag, freshParamTag)); + 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(iterator3ParamTag, freshParamTag)); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + MergeIteratorTag freshTag = new MergeIteratorTag(); + freshTag.setPerformClearTagStateForTagPoolingServers(true); + 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)); + } public void testMergingIteratorsWithListAsSource() throws Exception { MergeIteratorTag tag = new MergeIteratorTag(); @@ -158,25 +238,104 @@ public class MergeIteratorTagTest extends AbstractTagTest { // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). ParamTag freshParamTag = new ParamTag(); freshParamTag.setPageContext(pageContext); - assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + 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(iterator1ParamTag, freshParamTag)); - assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + 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(iterator2ParamTag, freshParamTag)); - assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + 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(iterator3ParamTag, freshParamTag)); // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). MergeIteratorTag freshTag = new MergeIteratorTag(); freshTag.setPageContext(pageContext); - assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + 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 testMergingIteratorsWithListAsSource_clearTagStateSet() throws Exception { + MergeIteratorTag tag = new MergeIteratorTag(); + tag.setPerformClearTagStateForTagPoolingServers(true); // Explicitly request tag state clearing. + tag.setPageContext(pageContext); + tag.setVar("myMergedIterator"); + ParamTag iterator1ParamTag = new ParamTag(); + iterator1ParamTag.setPerformClearTagStateForTagPoolingServers(true); // Explicitly request tag state clearing. + iterator1ParamTag.setPageContext(pageContext); + iterator1ParamTag.setValue("myList1"); + + ParamTag iterator2ParamTag = new ParamTag(); + iterator2ParamTag.setPerformClearTagStateForTagPoolingServers(true); // Explicitly request tag state clearing. + iterator2ParamTag.setPageContext(pageContext); + iterator2ParamTag.setValue("myList2"); + + ParamTag iterator3ParamTag = new ParamTag(); + iterator3ParamTag.setPerformClearTagStateForTagPoolingServers(true); // Explicitly request tag state clearing. + iterator3ParamTag.setPageContext(pageContext); + iterator3ParamTag.setValue("myList3"); + + + tag.doStartTag(); + setComponentTagClearTagState(tag, true); // Ensure component tag state clearing is set true (to match tag). + iterator1ParamTag.doStartTag(); + setComponentTagClearTagState(iterator1ParamTag, true); // Ensure component tag state clearing is set true (to match tag). + iterator1ParamTag.doEndTag(); + iterator2ParamTag.doStartTag(); + setComponentTagClearTagState(iterator2ParamTag, true); // Ensure component tag state clearing is set true (to match tag). + iterator2ParamTag.doEndTag(); + iterator3ParamTag.doStartTag(); + setComponentTagClearTagState(iterator3ParamTag, true); // Ensure component tag state clearing is set true (to match tag). + iterator3ParamTag.doEndTag(); + tag.doEndTag(); + + Iterator mergedIterator = (Iterator) stack.findValue("#myMergedIterator"); // if not iterator, let CCE surface + + assertNotNull(mergedIterator); + assertTrue(mergedIterator.hasNext()); + assertEquals(mergedIterator.next(), "1"); + assertTrue(mergedIterator.hasNext()); + assertEquals(mergedIterator.next(), "a"); + assertTrue(mergedIterator.hasNext()); + assertEquals(mergedIterator.next(), "A"); + assertTrue(mergedIterator.hasNext()); + assertEquals(mergedIterator.next(), "2"); + assertTrue(mergedIterator.hasNext()); + assertEquals(mergedIterator.next(), "b"); + assertTrue(mergedIterator.hasNext()); + assertEquals(mergedIterator.next(), "B"); + assertTrue(mergedIterator.hasNext()); + assertEquals(mergedIterator.next(), "3"); + assertTrue(mergedIterator.hasNext()); + assertEquals(mergedIterator.next(), "c"); + assertTrue(mergedIterator.hasNext()); + assertEquals(mergedIterator.next(), "C"); + assertFalse(mergedIterator.hasNext()); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + ParamTag freshParamTag = new ParamTag(); + freshParamTag.setPerformClearTagStateForTagPoolingServers(true); + freshParamTag.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(iterator1ParamTag, freshParamTag)); + 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(iterator2ParamTag, freshParamTag)); + 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(iterator3ParamTag, freshParamTag)); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + MergeIteratorTag freshTag = new MergeIteratorTag(); + freshTag.setPerformClearTagStateForTagPoolingServers(true); + 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)); + } public Action getAction() { diff --git a/core/src/test/java/org/apache/struts2/views/jsp/NumberTagTest.java b/core/src/test/java/org/apache/struts2/views/jsp/NumberTagTest.java index 9a414545e..0390866f6 100644 --- a/core/src/test/java/org/apache/struts2/views/jsp/NumberTagTest.java +++ b/core/src/test/java/org/apache/struts2/views/jsp/NumberTagTest.java @@ -48,11 +48,40 @@ public class NumberTagTest extends AbstractTagTest { // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). NumberTag freshTag = new NumberTag(); freshTag.setPageContext(pageContext); - assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + 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 testSimpleFloatFormat_clearTagStateSet() throws Exception { + // given + context.put(ActionContext.LOCALE, Locale.US); + + TestAction testAction = (TestAction) action; + testAction.setFloatNumber(120.0f); + + NumberTag tag = new NumberTag(); + tag.setPerformClearTagStateForTagPoolingServers(true); // Explicitly request tag state clearing. + tag.setPageContext(pageContext); + tag.setName("floatNumber"); + + // when + tag.doStartTag(); + setComponentTagClearTagState(tag, true); // Ensure component tag state clearing is set true (to match tag). + tag.doEndTag(); + + // then + assertEquals("120", writer.toString()); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + NumberTag freshTag = new NumberTag(); + freshTag.setPerformClearTagStateForTagPoolingServers(true); + 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)); + } + public void testSimpleCurrencyUSFormat() throws Exception { // given context = ActionContext.of(context).withLocale(Locale.US).getContextMap(); @@ -74,11 +103,40 @@ public class NumberTagTest extends AbstractTagTest { NumberTag freshTag = new NumberTag(); freshTag.setPageContext(pageContext); - assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + 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 testSimpleCurrencyUSFormat_clearTagStateSet() throws Exception { + // given + context.put(ActionContext.LOCALE, Locale.US); + + TestAction testAction = (TestAction) action; + testAction.setFloatNumber(120.0f); + + NumberTag tag = new NumberTag(); + tag.setPerformClearTagStateForTagPoolingServers(true); // Explicitly request tag state clearing. + tag.setPageContext(pageContext); + tag.setName("floatNumber"); + tag.setType("currency"); + + // when + tag.doStartTag(); + setComponentTagClearTagState(tag, true); // Ensure component tag state clearing is set true (to match tag). + tag.doEndTag(); + + // then + assertEquals("$120.00", writer.toString()); + + NumberTag freshTag = new NumberTag(); + freshTag.setPerformClearTagStateForTagPoolingServers(true); + 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)); + } + public void testSimpleCurrencyPLFormat() throws Exception { // given context = ActionContext.of(context).withLocale(new Locale("pl", "PL")).getContextMap(); @@ -105,7 +163,40 @@ public class NumberTagTest extends AbstractTagTest { NumberTag freshTag = new NumberTag(); freshTag.setPageContext(pageContext); - assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + 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 testSimpleCurrencyPLFormat_clearTagStateSet() throws Exception { + // given + context.put(ActionContext.LOCALE, new Locale("pl", "PL")); + + TestAction testAction = (TestAction) action; + testAction.setFloatNumber(120.0f); + + NumberTag tag = new NumberTag(); + tag.setPerformClearTagStateForTagPoolingServers(true); // Explicitly request tag state clearing. + tag.setPageContext(pageContext); + tag.setName("floatNumber"); + tag.setType("currency"); + + // when + tag.doStartTag(); + setComponentTagClearTagState(tag, true); // Ensure component tag state clearing is set true (to match tag). + tag.doEndTag(); + + // then + NumberFormat format = NumberFormat.getCurrencyInstance((Locale) context.get(ActionContext.LOCALE)); + format.setRoundingMode(RoundingMode.CEILING); + String expected = format.format(120.0f); + + assertEquals(expected, writer.toString()); + + NumberTag freshTag = new NumberTag(); + freshTag.setPerformClearTagStateForTagPoolingServers(true); + 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)); } @@ -136,7 +227,40 @@ public class NumberTagTest extends AbstractTagTest { NumberTag freshTag = new NumberTag(); freshTag.setPageContext(pageContext); - assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + 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 testSimpleRoundingCeiling_clearTagStateSet() throws Exception { + // given + context.put(ActionContext.LOCALE, Locale.US); + + TestAction testAction = (TestAction) action; + testAction.setFloatNumber(120.45f); + + NumberTag tag = new NumberTag(); + tag.setPerformClearTagStateForTagPoolingServers(true); // Explicitly request tag state clearing. + tag.setPageContext(pageContext); + tag.setName("floatNumber"); + tag.setRoundingMode("down"); + + // when + tag.doStartTag(); + setComponentTagClearTagState(tag, true); // Ensure component tag state clearing is set true (to match tag). + tag.doEndTag(); + + // then + NumberFormat format = NumberFormat.getInstance((Locale) context.get(ActionContext.LOCALE)); + format.setRoundingMode(RoundingMode.DOWN); + String expected = format.format(120.45f); + + assertEquals(expected, writer.toString()); + + NumberTag freshTag = new NumberTag(); + freshTag.setPerformClearTagStateForTagPoolingServers(true); + 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)); } diff --git a/core/src/test/java/org/apache/struts2/views/jsp/PropertyTagTest.java b/core/src/test/java/org/apache/struts2/views/jsp/PropertyTagTest.java index 8b074222e..b843e5685 100644 --- a/core/src/test/java/org/apache/struts2/views/jsp/PropertyTagTest.java +++ b/core/src/test/java/org/apache/struts2/views/jsp/PropertyTagTest.java @@ -76,7 +76,54 @@ public class PropertyTagTest extends StrutsInternalTestCase { // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). PropertyTag freshTag = new PropertyTag(); freshTag.setPageContext(pageContext); - assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + 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.", + objectsAreReflectionEqual(tag, freshTag)); + } + + public void testDefaultValue_clearTagStateSet() { + PropertyTag tag = new PropertyTag(); + + Foo foo = new Foo(); + + stack.push(foo); + + MockJspWriter jspWriter = new MockJspWriter(); + jspWriter.setExpectedData("TEST"); + + MockPageContext pageContext = new MockPageContext(); + pageContext.setJspWriter(jspWriter); + pageContext.setRequest(request); + + tag.setPerformClearTagStateForTagPoolingServers(true); // Explicitly request tag state clearing. + tag.setPageContext(pageContext); + tag.setValue("title"); + tag.setDefault("TEST"); + + try { + tag.doStartTag(); + setComponentTagClearTagState(tag, true); // Ensure component tag state clearing is set true (to match tag). + } catch (JspException e) { + e.printStackTrace(); + fail(); + } + + request.verify(); + jspWriter.verify(); + pageContext.verify(); + + try { + tag.doEndTag(); + } catch (JspException e) { + e.printStackTrace(); + fail(); + } + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + PropertyTag freshTag = new PropertyTag(); + freshTag.setPerformClearTagStateForTagPoolingServers(true); + 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.", objectsAreReflectionEqual(tag, freshTag)); } @@ -119,7 +166,53 @@ public class PropertyTagTest extends StrutsInternalTestCase { // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). PropertyTag freshTag = new PropertyTag(); freshTag.setPageContext(pageContext); - assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + 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.", + objectsAreReflectionEqual(tag, freshTag)); + } + + public void testNull_clearTagStateSet() { + PropertyTag tag = new PropertyTag(); + + Foo foo = new Foo(); + + stack.push(foo); + + MockJspWriter jspWriter = new MockJspWriter(); + jspWriter.setExpectedData(""); + + MockPageContext pageContext = new MockPageContext(); + pageContext.setJspWriter(jspWriter); + pageContext.setRequest(request); + + tag.setPerformClearTagStateForTagPoolingServers(true); // Explicitly request tag state clearing. + tag.setPageContext(pageContext); + tag.setValue("title"); + + try { + tag.doStartTag(); + setComponentTagClearTagState(tag, true); // Ensure component tag state clearing is set true (to match tag). + } catch (JspException e) { + e.printStackTrace(); + fail(); + } + + request.verify(); + jspWriter.verify(); + pageContext.verify(); + + try { + tag.doEndTag(); + } catch (JspException e) { + e.printStackTrace(); + fail(); + } + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + PropertyTag freshTag = new PropertyTag(); + freshTag.setPerformClearTagStateForTagPoolingServers(true); + 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.", objectsAreReflectionEqual(tag, freshTag)); } @@ -163,7 +256,54 @@ public class PropertyTagTest extends StrutsInternalTestCase { // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). PropertyTag freshTag = new PropertyTag(); freshTag.setPageContext(pageContext); - assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + 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.", + objectsAreReflectionEqual(tag, freshTag)); + } + + public void testSimple_clearTagStateSet() { + PropertyTag tag = new PropertyTag(); + + Foo foo = new Foo(); + foo.setTitle("test"); + + stack.push(foo); + + MockJspWriter jspWriter = new MockJspWriter(); + jspWriter.setExpectedData("test"); + + MockPageContext pageContext = new MockPageContext(); + pageContext.setJspWriter(jspWriter); + pageContext.setRequest(request); + + tag.setPerformClearTagStateForTagPoolingServers(true); // Explicitly request tag state clearing. + tag.setPageContext(pageContext); + tag.setValue("title"); + + try { + tag.doStartTag(); + setComponentTagClearTagState(tag, true); // Ensure component tag state clearing is set true (to match tag). + } catch (JspException e) { + e.printStackTrace(); + fail(); + } + + request.verify(); + jspWriter.verify(); + pageContext.verify(); + + try { + tag.doEndTag(); + } catch (JspException e) { + e.printStackTrace(); + fail(); + } + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + PropertyTag freshTag = new PropertyTag(); + freshTag.setPerformClearTagStateForTagPoolingServers(true); + 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.", objectsAreReflectionEqual(tag, freshTag)); } @@ -206,11 +346,57 @@ public class PropertyTagTest extends StrutsInternalTestCase { // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). PropertyTag freshTag = new PropertyTag(); freshTag.setPageContext(pageContext); - assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + // PropertyTag had no explicit values set in this test, so it compares as equal with the default tag clear state as well. + assertTrue("Tag state after doEndTag() under default tag clear state is inequal to new Tag with pageContext/parent set. " + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", objectsAreReflectionEqual(tag, freshTag)); } + public void testTopOfStack_clearTagStateSet() { + PropertyTag tag = new PropertyTag(); + + Foo foo = new Foo(); + foo.setTitle("test"); + + stack.push(foo); + + MockJspWriter jspWriter = new MockJspWriter(); + jspWriter.setExpectedData("Foo is: test"); + + MockPageContext pageContext = new MockPageContext(); + pageContext.setJspWriter(jspWriter); + pageContext.setRequest(request); + + tag.setPerformClearTagStateForTagPoolingServers(true); // Explicitly request tag state clearing. + tag.setPageContext(pageContext); + + try { + tag.doStartTag(); + setComponentTagClearTagState(tag, true); // Ensure component tag state clearing is set true (to match tag). + } catch (JspException e) { + e.printStackTrace(); + fail(); + } + + request.verify(); + jspWriter.verify(); + pageContext.verify(); + + try { + tag.doEndTag(); + } catch (JspException e) { + e.printStackTrace(); + fail(); + } + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + PropertyTag freshTag = new PropertyTag(); + freshTag.setPerformClearTagStateForTagPoolingServers(true); + 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.", + objectsAreReflectionEqual(tag, freshTag)); + } public void testWithAltSyntax1() throws Exception { // setups @@ -236,7 +422,47 @@ public class PropertyTagTest extends StrutsInternalTestCase { // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). PropertyTag freshTag = new PropertyTag(); freshTag.setPageContext(pageContext); - assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + 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.", + objectsAreReflectionEqual(tag, freshTag)); + } + + // verify test + request.verify(); + jspWriter.verify(); + pageContext.verify(); + } + + public void testWithAltSyntax1_clearTagStateSet() throws Exception { + // setups + initDispatcher(new HashMap() {{ put(StrutsConstants.STRUTS_TAG_ALTSYNTAX, "true");}}); + + Foo foo = new Foo(); + foo.setTitle("tm_jee"); + stack.push(foo); + + MockJspWriter jspWriter = new MockJspWriter(); + jspWriter.setExpectedData("Foo is: tm_jee"); + + MockPageContext pageContext = new MockPageContext(); + pageContext.setJspWriter(jspWriter); + pageContext.setRequest(request); + + // test + { + PropertyTag tag = new PropertyTag(); + tag.setPerformClearTagStateForTagPoolingServers(true); // Explicitly request tag state clearing. + tag.setPageContext(pageContext); + tag.setValue("%{formatTitle()}"); + tag.doStartTag(); + setComponentTagClearTagState(tag, true); // Ensure component tag state clearing is set true (to match tag). + tag.doEndTag(); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + PropertyTag freshTag = new PropertyTag(); + freshTag.setPerformClearTagStateForTagPoolingServers(true); + 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.", objectsAreReflectionEqual(tag, freshTag)); } @@ -272,7 +498,47 @@ public class PropertyTagTest extends StrutsInternalTestCase { // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). PropertyTag freshTag = new PropertyTag(); freshTag.setPageContext(pageContext); - assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + 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.", + objectsAreReflectionEqual(tag, freshTag));} + + // verify test + request.verify(); + jspWriter.verify(); + pageContext.verify(); + } + + public void testEscapeJavaScript_clearTagStateSet() throws Exception { + // setups + initDispatcher(new HashMap() {{ put(StrutsConstants.STRUTS_TAG_ALTSYNTAX, "true");}}); + + Foo foo = new Foo(); + foo.setTitle("\t\b\n\f\r\"\'/\\"); + stack.push(foo); + + MockJspWriter jspWriter = new MockJspWriter(); + jspWriter.setExpectedData("Foo is: \\t\\b\\n\\f\\r\\\"\\\'\\/\\\\"); + + MockPageContext pageContext = new MockPageContext(); + pageContext.setJspWriter(jspWriter); + pageContext.setRequest(request); + + // test + {PropertyTag tag = new PropertyTag(); + tag.setPerformClearTagStateForTagPoolingServers(true); // Explicitly request tag state clearing. + tag.setEscapeHtml(false); + tag.setEscapeJavaScript(true); + tag.setPageContext(pageContext); + tag.setValue("%{formatTitle()}"); + tag.doStartTag(); + setComponentTagClearTagState(tag, true); // Ensure component tag state clearing is set true (to match tag). + tag.doEndTag(); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + PropertyTag freshTag = new PropertyTag(); + freshTag.setPerformClearTagStateForTagPoolingServers(true); + 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.", objectsAreReflectionEqual(tag, freshTag));} @@ -307,7 +573,47 @@ public class PropertyTagTest extends StrutsInternalTestCase { // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). PropertyTag freshTag = new PropertyTag(); freshTag.setPageContext(pageContext); - assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + 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.", + objectsAreReflectionEqual(tag, freshTag));} + + // verify test + request.verify(); + jspWriter.verify(); + pageContext.verify(); + } + + public void testEscapeXml_clearTagStateSet() throws Exception { + // setups + initDispatcher(new HashMap() {{ put(StrutsConstants.STRUTS_TAG_ALTSYNTAX, "true");}}); + + Foo foo = new Foo(); + foo.setTitle("<>'\"&"); + stack.push(foo); + + MockJspWriter jspWriter = new MockJspWriter(); + jspWriter.setExpectedData("Foo is: <>'"&"); + + MockPageContext pageContext = new MockPageContext(); + pageContext.setJspWriter(jspWriter); + pageContext.setRequest(request); + + // test + {PropertyTag tag = new PropertyTag(); + tag.setPerformClearTagStateForTagPoolingServers(true); // Explicitly request tag state clearing. + tag.setEscapeHtml(false); + tag.setEscapeXml(true); + tag.setPageContext(pageContext); + tag.setValue("%{formatTitle()}"); + tag.doStartTag(); + setComponentTagClearTagState(tag, true); // Ensure component tag state clearing is set true (to match tag). + tag.doEndTag(); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + PropertyTag freshTag = new PropertyTag(); + freshTag.setPerformClearTagStateForTagPoolingServers(true); + 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.", objectsAreReflectionEqual(tag, freshTag));} @@ -342,7 +648,47 @@ public class PropertyTagTest extends StrutsInternalTestCase { // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). PropertyTag freshTag = new PropertyTag(); freshTag.setPageContext(pageContext); - assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + 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.", + objectsAreReflectionEqual(tag, freshTag));} + + // verify test + request.verify(); + jspWriter.verify(); + pageContext.verify(); + } + + public void testEscapeCsv_clearTagStateSet() throws Exception { + // setups + initDispatcher(new HashMap() {{ put(StrutsConstants.STRUTS_TAG_ALTSYNTAX, "true");}}); + + Foo foo = new Foo(); + foo.setTitle("\"something,\",\""); + stack.push(foo); + + MockJspWriter jspWriter = new MockJspWriter(); + jspWriter.setExpectedData("\"Foo is: \"\"something,\"\",\"\"\""); + + MockPageContext pageContext = new MockPageContext(); + pageContext.setJspWriter(jspWriter); + pageContext.setRequest(request); + + // test + {PropertyTag tag = new PropertyTag(); + tag.setPerformClearTagStateForTagPoolingServers(true); // Explicitly request tag state clearing. + tag.setEscapeHtml(false); + tag.setEscapeCsv(true); + tag.setPageContext(pageContext); + tag.setValue("%{formatTitle()}"); + tag.doStartTag(); + setComponentTagClearTagState(tag, true); // Ensure component tag state clearing is set true (to match tag). + tag.doEndTag(); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + PropertyTag freshTag = new PropertyTag(); + freshTag.setPerformClearTagStateForTagPoolingServers(true); + 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.", objectsAreReflectionEqual(tag, freshTag));} @@ -375,7 +721,45 @@ public class PropertyTagTest extends StrutsInternalTestCase { // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). PropertyTag freshTag = new PropertyTag(); freshTag.setPageContext(pageContext); - assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + 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.", + objectsAreReflectionEqual(tag, freshTag));} + + // verify test + request.verify(); + jspWriter.verify(); + pageContext.verify(); + } + + public void testWithAltSyntax2_clearTagStateSet() throws Exception { + // setups + initDispatcher(new HashMap() {{ put(StrutsConstants.STRUTS_TAG_ALTSYNTAX, "true");}}); + + Foo foo = new Foo(); + foo.setTitle("tm_jee"); + stack.push(foo); + + MockJspWriter jspWriter = new MockJspWriter(); + jspWriter.setExpectedData("Foo is: tm_jee"); + + MockPageContext pageContext = new MockPageContext(); + pageContext.setJspWriter(jspWriter); + pageContext.setRequest(request); + + // test + {PropertyTag tag = new PropertyTag(); + tag.setPerformClearTagStateForTagPoolingServers(true); // Explicitly request tag state clearing. + tag.setPageContext(pageContext); + tag.setValue("formatTitle()"); + tag.doStartTag(); + setComponentTagClearTagState(tag, true); // Ensure component tag state clearing is set true (to match tag). + tag.doEndTag(); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + PropertyTag freshTag = new PropertyTag(); + freshTag.setPerformClearTagStateForTagPoolingServers(true); + 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.", objectsAreReflectionEqual(tag, freshTag));} @@ -408,7 +792,7 @@ public class PropertyTagTest extends StrutsInternalTestCase { // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). PropertyTag freshTag = new PropertyTag(); freshTag.setPageContext(pageContext); - assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + 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.", objectsAreReflectionEqual(tag, freshTag));} @@ -418,6 +802,43 @@ public class PropertyTagTest extends StrutsInternalTestCase { pageContext.verify(); } + public void testWithoutAltSyntax1_clearTagStateSet() throws Exception { + // setups + initDispatcher(new HashMap() {{ put(StrutsConstants.STRUTS_TAG_ALTSYNTAX, "false");}}); + + Foo foo = new Foo(); + foo.setTitle("tm_jee"); + stack.push(foo); + + MockJspWriter jspWriter = new MockJspWriter(); + jspWriter.setExpectedData("Foo is: tm_jee"); + + MockPageContext pageContext = new MockPageContext(); + pageContext.setJspWriter(jspWriter); + pageContext.setRequest(request); + + // test + {PropertyTag tag = new PropertyTag(); + tag.setPerformClearTagStateForTagPoolingServers(true); // Explicitly request tag state clearing. + tag.setPageContext(pageContext); + tag.setValue("formatTitle()"); + tag.doStartTag(); + setComponentTagClearTagState(tag, true); // Ensure component tag state clearing is set true (to match tag). + tag.doEndTag(); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + PropertyTag freshTag = new PropertyTag(); + freshTag.setPerformClearTagStateForTagPoolingServers(true); + 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.", + objectsAreReflectionEqual(tag, freshTag));} + + // verify test + request.verify(); + jspWriter.verify(); + pageContext.verify(); + } public void testWithoutAltSyntax2() throws Exception { // setups @@ -441,7 +862,7 @@ public class PropertyTagTest extends StrutsInternalTestCase { // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). PropertyTag freshTag = new PropertyTag(); freshTag.setPageContext(pageContext); - assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + 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.", objectsAreReflectionEqual(tag, freshTag));} @@ -451,6 +872,42 @@ public class PropertyTagTest extends StrutsInternalTestCase { pageContext.verify(); } + public void testWithoutAltSyntax2_clearTagStateSet() throws Exception { + // setups + initDispatcher(new HashMap() {{ put(StrutsConstants.STRUTS_TAG_ALTSYNTAX, "false");}}); + + Foo foo = new Foo(); + foo.setTitle("tm_jee"); + stack.push(foo); + + MockJspWriter jspWriter = new MockJspWriter(); + + MockPageContext pageContext = new MockPageContext(); + pageContext.setJspWriter(jspWriter); + pageContext.setRequest(request); + + // test + {PropertyTag tag = new PropertyTag(); + tag.setPerformClearTagStateForTagPoolingServers(true); // Explicitly request tag state clearing. + tag.setPageContext(pageContext); + tag.setValue("%{formatTitle()}"); + tag.doStartTag(); + setComponentTagClearTagState(tag, true); // Ensure component tag state clearing is set true (to match tag). + tag.doEndTag(); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + PropertyTag freshTag = new PropertyTag(); + freshTag.setPerformClearTagStateForTagPoolingServers(true); + 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.", + objectsAreReflectionEqual(tag, freshTag));} + + // verify test + request.verify(); + jspWriter.verify(); + pageContext.verify(); + } @Override protected void setUp() throws Exception { @@ -459,6 +916,23 @@ public class PropertyTagTest extends StrutsInternalTestCase { request.setAttribute(ServletActionContext.STRUTS_VALUESTACK_KEY, stack); } + /** + * Helper method to simplify setting the performClearTagStateForTagPoolingServers state for a + * {@link ComponentTagSupport} tag's {@link Component} to match expectations for the test. + * + * The component reference is not available to the tag until after the doStartTag() method is called. + * We need to ensure the component's {@link Component#performClearTagStateForTagPoolingServers} state matches + * what we set for the Tag when a non-default (true) value is used, so this method accesses the component instance, + * sets the value specified and forces the tag's parameters to be repopulated again. + * + * @param tag The ComponentTagSupport tag upon whose component we will set the performClearTagStateForTagPoolingServers state. + * @param performClearTagStateForTagPoolingServers true to clear tag state, false otherwise + */ + protected void setComponentTagClearTagState(ComponentTagSupport tag, boolean performClearTagStateForTagPoolingServers) { + tag.component.setPerformClearTagStateForTagPoolingServers(performClearTagStateForTagPoolingServers); + //tag.populateParams(); // Not safe to call after doStartTag() ... breaks some tests. + tag.populatePerformClearTagStateForTagPoolingServersParam(); // Only populate the performClearTagStateForTagPoolingServers parameter for the Tag. + } public static class Foo { private String title; diff --git a/core/src/test/java/org/apache/struts2/views/jsp/PushTagTest.java b/core/src/test/java/org/apache/struts2/views/jsp/PushTagTest.java index 80fb7324b..4da1b5ef1 100644 --- a/core/src/test/java/org/apache/struts2/views/jsp/PushTagTest.java +++ b/core/src/test/java/org/apache/struts2/views/jsp/PushTagTest.java @@ -47,7 +47,37 @@ public class PushTagTest extends AbstractUITagTest { // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). PushTag freshTag = new PushTag(); freshTag.setPageContext(pageContext); - assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + 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 testSimple_clearTagStateSet() { + PushTag tag = new PushTag(); + + stack.setValue("foo", "bar"); + + tag.setPerformClearTagStateForTagPoolingServers(true); // Explicitly request tag state clearing. + tag.setPageContext(pageContext); + tag.setValue("foo"); + + try { + assertEquals(2, stack.size()); + tag.doStartTag(); + setComponentTagClearTagState(tag, true); // Ensure component tag state clearing is set true (to match tag). + assertEquals(3, stack.size()); + tag.doEndTag(); + assertEquals(2, stack.size()); + } catch (JspException e) { + e.printStackTrace(); + fail(); + } + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + PushTag freshTag = new PushTag(); + freshTag.setPerformClearTagStateForTagPoolingServers(true); + 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)); } diff --git a/core/src/test/java/org/apache/struts2/views/jsp/SetTagTest.java b/core/src/test/java/org/apache/struts2/views/jsp/SetTagTest.java index 7e8aba387..9e5c30eb5 100644 --- a/core/src/test/java/org/apache/struts2/views/jsp/SetTagTest.java +++ b/core/src/test/java/org/apache/struts2/views/jsp/SetTagTest.java @@ -43,7 +43,27 @@ public class SetTagTest extends AbstractUITagTest { // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). SetTag freshTag = new SetTag(); freshTag.setPageContext(pageContext); - assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + 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 testApplicationScope_clearTagStateSet() throws JspException { + tag.setPerformClearTagStateForTagPoolingServers(true); // Explicitly request tag state clearing. + tag.setName("foo"); + tag.setValue("name"); + tag.setScope("application"); + tag.doStartTag(); + setComponentTagClearTagState(tag, true); // Ensure component tag state clearing is set true (to match tag). + tag.doEndTag(); + + assertEquals("chewie", servletContext.getAttribute("foo")); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + SetTag freshTag = new SetTag(); + freshTag.setPerformClearTagStateForTagPoolingServers(true); + 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)); } @@ -60,7 +80,27 @@ public class SetTagTest extends AbstractUITagTest { // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). SetTag freshTag = new SetTag(); freshTag.setPageContext(pageContext); - assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + 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 testPageScope_clearTagStateSet() throws JspException { + tag.setPerformClearTagStateForTagPoolingServers(true); // Explicitly request tag state clearing. + tag.setName("foo"); + tag.setValue("name"); + tag.setScope("page"); + tag.doStartTag(); + setComponentTagClearTagState(tag, true); // Ensure component tag state clearing is set true (to match tag). + tag.doEndTag(); + + assertEquals("chewie", pageContext.getAttribute("foo")); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + SetTag freshTag = new SetTag(); + freshTag.setPerformClearTagStateForTagPoolingServers(true); + 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)); } @@ -76,7 +116,26 @@ public class SetTagTest extends AbstractUITagTest { // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). SetTag freshTag = new SetTag(); freshTag.setPageContext(pageContext); - assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + 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 testRequestScope_clearTagStateSet() throws JspException { + tag.setPerformClearTagStateForTagPoolingServers(true); // Explicitly request tag state clearing. + tag.setName("foo"); + tag.setValue("name"); + tag.setScope("request"); + tag.doStartTag(); + setComponentTagClearTagState(tag, true); // Ensure component tag state clearing is set true (to match tag). + tag.doEndTag(); + assertEquals("chewie", request.getAttribute("foo")); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + SetTag freshTag = new SetTag(); + freshTag.setPerformClearTagStateForTagPoolingServers(true); + 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)); } @@ -93,7 +152,27 @@ public class SetTagTest extends AbstractUITagTest { // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). SetTag freshTag = new SetTag(); freshTag.setPageContext(pageContext); - assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + 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 testSessionScope_clearTagStateSet() throws JspException { + tag.setPerformClearTagStateForTagPoolingServers(true); // Explicitly request tag state clearing. + tag.setName("foo"); + tag.setValue("name"); + tag.setScope("session"); + tag.doStartTag(); + setComponentTagClearTagState(tag, true); // Ensure component tag state clearing is set true (to match tag). + tag.doEndTag(); + + assertEquals("chewie", session.get("foo")); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + SetTag freshTag = new SetTag(); + freshTag.setPerformClearTagStateForTagPoolingServers(true); + 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)); } @@ -108,7 +187,25 @@ public class SetTagTest extends AbstractUITagTest { // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). SetTag freshTag = new SetTag(); freshTag.setPageContext(pageContext); - assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + 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 testStrutsScope_clearTagStateSet() throws JspException { + tag.setPerformClearTagStateForTagPoolingServers(true); // Explicitly request tag state clearing. + tag.setName("foo"); + tag.setValue("name"); + tag.doStartTag(); + setComponentTagClearTagState(tag, true); // Ensure component tag state clearing is set true (to match tag). + tag.doEndTag(); + assertEquals("chewie", context.get("foo")); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + SetTag freshTag = new SetTag(); + freshTag.setPerformClearTagStateForTagPoolingServers(true); + 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)); } @@ -122,7 +219,24 @@ public class SetTagTest extends AbstractUITagTest { // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). SetTag freshTag = new SetTag(); freshTag.setPageContext(pageContext); - assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + 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 testStrutsScope2_clearTagStateSet() throws JspException { + tag.setPerformClearTagStateForTagPoolingServers(true); // Explicitly request tag state clearing. + tag.setName("chewie"); + tag.doStartTag(); + setComponentTagClearTagState(tag, true); // Ensure component tag state clearing is set true (to match tag). + tag.doEndTag(); + assertEquals(chewie, context.get("chewie")); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + SetTag freshTag = new SetTag(); + freshTag.setPerformClearTagStateForTagPoolingServers(true); + 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)); } @@ -145,7 +259,7 @@ public class SetTagTest extends AbstractUITagTest { // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). SetTag freshTag = new SetTag(); freshTag.setPageContext(pageContext); - assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + 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)); @@ -160,8 +274,7 @@ public class SetTagTest extends AbstractUITagTest { assertEquals(trimmedBeginEndSpaceString, context.get("foo")); // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). - freshTag.setPageContext(pageContext); - assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + 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)); @@ -176,8 +289,65 @@ public class SetTagTest extends AbstractUITagTest { assertEquals(beginEndSpaceString, context.get("foo")); // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + 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 testSetTrimBody_clearTagStateSet() throws JspException, IOException { + final String beginEndSpaceString = " Preceding and trailing spaces. "; + final String trimmedBeginEndSpaceString = beginEndSpaceString.trim(); + StrutsMockBodyContent mockBodyContent; + + tag.setPerformClearTagStateForTagPoolingServers(true); // Explicitly request tag state clearing. + tag.setName("foo"); + tag.setValue(null); + // Do not set any value - default for tag should be true + mockBodyContent = new StrutsMockBodyContent(new MockJspWriter()); + mockBodyContent.setString(beginEndSpaceString); + tag.setBodyContent(mockBodyContent); + tag.doStartTag(); + setComponentTagClearTagState(tag, true); // Ensure component tag state clearing is set true (to match tag). + tag.doEndTag(); + assertEquals(trimmedBeginEndSpaceString, context.get("foo")); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + SetTag freshTag = new SetTag(); + freshTag.setPerformClearTagStateForTagPoolingServers(true); freshTag.setPageContext(pageContext); - assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + 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)); + + tag.setName("foo"); + tag.setValue(null); + tag.setTrimBody(true); + mockBodyContent = new StrutsMockBodyContent(new MockJspWriter()); + mockBodyContent.setString(beginEndSpaceString); + tag.setBodyContent(mockBodyContent); + tag.doStartTag(); + setComponentTagClearTagState(tag, true); // Ensure component tag state clearing is set true (to match tag). + tag.doEndTag(); + assertEquals(trimmedBeginEndSpaceString, context.get("foo")); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + 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)); + + tag.setName("foo"); + tag.setValue(null); + tag.setTrimBody(false); + mockBodyContent = new StrutsMockBodyContent(new MockJspWriter()); + mockBodyContent.setString(beginEndSpaceString); + tag.setBodyContent(mockBodyContent); + tag.doStartTag(); + setComponentTagClearTagState(tag, true); // Ensure component tag state clearing is set true (to match tag). + tag.doEndTag(); + assertEquals(beginEndSpaceString, context.get("foo")); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + 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)); } @@ -198,11 +368,36 @@ public class SetTagTest extends AbstractUITagTest { // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). SetTag freshTag = new SetTag(); freshTag.setPageContext(pageContext); - assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + 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 testEmptyBody_clearTagStateSet() throws JspException { + StrutsMockBodyContent mockBodyContent; + String variableName = "foo"; + tag.setPerformClearTagStateForTagPoolingServers(true); // Explicitly request tag state clearing. + tag.setName(variableName); + tag.setValue(null); + mockBodyContent = new StrutsMockBodyContent(new MockJspWriter()); + String emptyBody = ""; + mockBodyContent.setString(emptyBody); + tag.setBodyContent(mockBodyContent); + tag.doStartTag(); + setComponentTagClearTagState(tag, true); // Ensure component tag state clearing is set true (to match tag). + tag.doEndTag(); + assertEquals(emptyBody, context.get(variableName)); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + SetTag freshTag = new SetTag(); + freshTag.setPerformClearTagStateForTagPoolingServers(true); + 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)); + } + + @Override protected void setUp() throws Exception { super.setUp(); diff --git a/core/src/test/java/org/apache/struts2/views/jsp/SortIteratorTagTest.java b/core/src/test/java/org/apache/struts2/views/jsp/SortIteratorTagTest.java index 3efb4eaa1..f88c2ae81 100644 --- a/core/src/test/java/org/apache/struts2/views/jsp/SortIteratorTagTest.java +++ b/core/src/test/java/org/apache/struts2/views/jsp/SortIteratorTagTest.java @@ -71,7 +71,49 @@ public class SortIteratorTagTest extends AbstractTagTest { // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). SortIteratorTag freshTag = new SortIteratorTag(); freshTag.setPageContext(pageContext); - assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + 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 testSortWithoutId_clearTagStateSet() throws Exception { + SortIteratorTag tag = new SortIteratorTag(); + + tag.setPerformClearTagStateForTagPoolingServers(true); // Explicitly request tag state clearing. + tag.setComparator("comparator"); + tag.setSource("source"); + + tag.setPageContext(pageContext); + tag.doStartTag(); + + // if not an Iterator, just let the ClassCastException be thrown as error instead of failure + Iterator sortedIterator = (Iterator) stack.findValue("top"); + + assertNotNull(sortedIterator); + // 1 + assertTrue(sortedIterator.hasNext()); + assertEquals(sortedIterator.next(), new Integer(1)); + // 2 + assertTrue(sortedIterator.hasNext()); + assertEquals(sortedIterator.next(), new Integer(2)); + // 3. + assertTrue(sortedIterator.hasNext()); + assertEquals(sortedIterator.next(), new Integer(3)); + // 4. + assertTrue(sortedIterator.hasNext()); + assertEquals(sortedIterator.next(), new Integer(4)); + // 5 + assertTrue(sortedIterator.hasNext()); + assertEquals(sortedIterator.next(), new Integer(5)); + + assertFalse(sortedIterator.hasNext()); + tag.doEndTag(); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + SortIteratorTag freshTag = new SortIteratorTag(); + freshTag.setPerformClearTagStateForTagPoolingServers(true); + 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)); } @@ -115,11 +157,55 @@ public class SortIteratorTagTest extends AbstractTagTest { // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). SortIteratorTag freshTag = new SortIteratorTag(); freshTag.setPageContext(pageContext); - assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + 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 testSortWithIdIteratorAvailableInStackTop_clearTagStateSet() throws Exception { + SortIteratorTag tag = new SortIteratorTag(); + + tag.setPerformClearTagStateForTagPoolingServers(true); // Explicitly request tag state clearing. + tag.setVar("myId"); + tag.setComparator("comparator"); + tag.setSource("source"); + + tag.setPageContext(pageContext); + tag.doStartTag(); + + { + Iterator sortedIterator = (Iterator) stack.findValue("top"); + + assertNotNull(sortedIterator); + // 1 + assertTrue(sortedIterator.hasNext()); + assertEquals(sortedIterator.next(), new Integer(1)); + // 2 + assertTrue(sortedIterator.hasNext()); + assertEquals(sortedIterator.next(), new Integer(2)); + // 3 + assertTrue(sortedIterator.hasNext()); + assertEquals(sortedIterator.next(), new Integer(3)); + // 4 + assertTrue(sortedIterator.hasNext()); + assertEquals(sortedIterator.next(), new Integer(4)); + // 5 + assertTrue(sortedIterator.hasNext()); + assertEquals(sortedIterator.next(), new Integer(5)); + + assertFalse(sortedIterator.hasNext()); + } + + tag.doEndTag(); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + SortIteratorTag freshTag = new SortIteratorTag(); + freshTag.setPerformClearTagStateForTagPoolingServers(true); + 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)); + } public void testSortWithIdIteratorAvailableInPageContext() throws Exception { SortIteratorTag tag = new SortIteratorTag(); @@ -159,7 +245,52 @@ public class SortIteratorTagTest extends AbstractTagTest { // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). SortIteratorTag freshTag = new SortIteratorTag(); freshTag.setPageContext(pageContext); - assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + 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 testSortWithIdIteratorAvailableInPageContext_clearTagStateSet() throws Exception { + SortIteratorTag tag = new SortIteratorTag(); + + tag.setPerformClearTagStateForTagPoolingServers(true); // Explicitly request tag state clearing. + tag.setVar("myId"); + tag.setComparator("comparator"); + tag.setSource("source"); + + tag.setPageContext(pageContext); + tag.doStartTag(); + + { + Iterator sortedIterator = (Iterator) pageContext.getAttribute("myId"); + + assertNotNull(sortedIterator); + // 1 + assertTrue(sortedIterator.hasNext()); + assertEquals(sortedIterator.next(), new Integer(1)); + // 2 + assertTrue(sortedIterator.hasNext()); + assertEquals(sortedIterator.next(), new Integer(2)); + // 3 + assertTrue(sortedIterator.hasNext()); + assertEquals(sortedIterator.next(), new Integer(3)); + // 4 + assertTrue(sortedIterator.hasNext()); + assertEquals(sortedIterator.next(), new Integer(4)); + // 5 + assertTrue(sortedIterator.hasNext()); + assertEquals(sortedIterator.next(), new Integer(5)); + + assertFalse(sortedIterator.hasNext()); + } + + tag.doEndTag(); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + SortIteratorTag freshTag = new SortIteratorTag(); + freshTag.setPerformClearTagStateForTagPoolingServers(true); + 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)); } diff --git a/core/src/test/java/org/apache/struts2/views/jsp/SubsetIteratorTagTest.java b/core/src/test/java/org/apache/struts2/views/jsp/SubsetIteratorTagTest.java index 1d7a439f2..4498124bb 100644 --- a/core/src/test/java/org/apache/struts2/views/jsp/SubsetIteratorTagTest.java +++ b/core/src/test/java/org/apache/struts2/views/jsp/SubsetIteratorTagTest.java @@ -55,7 +55,7 @@ public class SubsetIteratorTagTest extends AbstractTagTest { // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). SubsetIteratorTag freshTag = new SubsetIteratorTag(); freshTag.setPageContext(pageContext); - assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + 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)); } @@ -78,7 +78,59 @@ public class SubsetIteratorTagTest extends AbstractTagTest { // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). SubsetIteratorTag freshTag = new SubsetIteratorTag(); freshTag.setPageContext(pageContext); - assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + 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 testBasic_clearTagStateSet() throws Exception { + { // List as Source + SubsetIteratorTag tag = new SubsetIteratorTag(); + tag.setPerformClearTagStateForTagPoolingServers(true); // Explicitly request tag state clearing. + tag.setPageContext(pageContext); + tag.setSource("myList"); + + tag.doStartTag(); + Iterator subsetIterator = (Iterator) stack.findValue("top"); + tag.doEndTag(); + + assertEquals(subsetIterator.next(), new Integer(1)); + assertEquals(subsetIterator.next(), new Integer(2)); + assertEquals(subsetIterator.next(), new Integer(3)); + assertEquals(subsetIterator.next(), new Integer(4)); + assertEquals(subsetIterator.next(), new Integer(5)); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + SubsetIteratorTag freshTag = new SubsetIteratorTag(); + freshTag.setPerformClearTagStateForTagPoolingServers(true); + 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)); + } + + { // Array as Source + SubsetIteratorTag tag = new SubsetIteratorTag(); + tag.setPerformClearTagStateForTagPoolingServers(true); // Explicitly request tag state clearing. + tag.setPageContext(pageContext); + tag.setSource("myArray"); + + tag.doStartTag(); + Iterator subsetIterator = (Iterator) stack.findValue("top"); + tag.doEndTag(); + + assertEquals(subsetIterator.next(), new Integer(1)); + assertEquals(subsetIterator.next(), new Integer(2)); + assertEquals(subsetIterator.next(), new Integer(3)); + assertEquals(subsetIterator.next(), new Integer(4)); + assertEquals(subsetIterator.next(), new Integer(5)); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + SubsetIteratorTag freshTag = new SubsetIteratorTag(); + freshTag.setPerformClearTagStateForTagPoolingServers(true); + 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)); } @@ -101,7 +153,7 @@ public class SubsetIteratorTagTest extends AbstractTagTest { // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). SubsetIteratorTag freshTag = new SubsetIteratorTag(); freshTag.setPageContext(pageContext); - assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + 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)); } @@ -122,7 +174,55 @@ public class SubsetIteratorTagTest extends AbstractTagTest { // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). SubsetIteratorTag freshTag = new SubsetIteratorTag(); freshTag.setPageContext(pageContext); - assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + 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 testWithStartAttribute_clearTagStateSet() throws Exception { + { // List as source + SubsetIteratorTag tag = new SubsetIteratorTag(); + tag.setPerformClearTagStateForTagPoolingServers(true); // Explicitly request tag state clearing. + tag.setPageContext(pageContext); + tag.setSource("myList"); + tag.setStart("3"); + + tag.doStartTag(); + Iterator subsetIterator = (Iterator) stack.findValue("top"); + tag.doEndTag(); + + assertEquals(subsetIterator.next(), new Integer(4)); + assertEquals(subsetIterator.next(), new Integer(5)); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + SubsetIteratorTag freshTag = new SubsetIteratorTag(); + freshTag.setPerformClearTagStateForTagPoolingServers(true); + 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)); + } + + { // Array as source + SubsetIteratorTag tag = new SubsetIteratorTag(); + tag.setPerformClearTagStateForTagPoolingServers(true); // Explicitly request tag state clearing. + tag.setPageContext(pageContext); + tag.setSource("myArray"); + tag.setStart("3"); + + tag.doStartTag(); + Iterator subsetIterator = (Iterator) stack.findValue("top"); + tag.doEndTag(); + + assertEquals(subsetIterator.next(), new Integer(4)); + assertEquals(subsetIterator.next(), new Integer(5)); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + SubsetIteratorTag freshTag = new SubsetIteratorTag(); + freshTag.setPerformClearTagStateForTagPoolingServers(true); + 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)); } @@ -146,7 +246,7 @@ public class SubsetIteratorTagTest extends AbstractTagTest { // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). SubsetIteratorTag freshTag = new SubsetIteratorTag(); freshTag.setPageContext(pageContext); - assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + 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)); } @@ -168,7 +268,57 @@ public class SubsetIteratorTagTest extends AbstractTagTest { // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). SubsetIteratorTag freshTag = new SubsetIteratorTag(); freshTag.setPageContext(pageContext); - assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + 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 testWithCountAttribute_clearTagStateSet() throws Exception { + { // List as source + SubsetIteratorTag tag = new SubsetIteratorTag(); + tag.setPerformClearTagStateForTagPoolingServers(true); // Explicitly request tag state clearing. + tag.setPageContext(pageContext); + tag.setSource("myList"); + tag.setCount("3"); + + tag.doStartTag(); + Iterator subsetIterator = (Iterator) stack.findValue("top"); + tag.doEndTag(); + + assertEquals(subsetIterator.next(), new Integer(1)); + assertEquals(subsetIterator.next(), new Integer(2)); + assertEquals(subsetIterator.next(), new Integer(3)); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + SubsetIteratorTag freshTag = new SubsetIteratorTag(); + freshTag.setPerformClearTagStateForTagPoolingServers(true); + 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)); + } + + { // array as source + SubsetIteratorTag tag = new SubsetIteratorTag(); + tag.setPerformClearTagStateForTagPoolingServers(true); // Explicitly request tag state clearing. + tag.setPageContext(pageContext); + tag.setSource("myArray"); + tag.setCount("3"); + + tag.doStartTag(); + Iterator subsetIterator = (Iterator) stack.findValue("top"); + tag.doEndTag(); + + assertEquals(subsetIterator.next(), new Integer(1)); + assertEquals(subsetIterator.next(), new Integer(2)); + assertEquals(subsetIterator.next(), new Integer(3)); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + SubsetIteratorTag freshTag = new SubsetIteratorTag(); + freshTag.setPerformClearTagStateForTagPoolingServers(true); + 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)); } @@ -192,7 +342,7 @@ public class SubsetIteratorTagTest extends AbstractTagTest { // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). SubsetIteratorTag freshTag = new SubsetIteratorTag(); freshTag.setPageContext(pageContext); - assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + 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)); } @@ -214,7 +364,57 @@ public class SubsetIteratorTagTest extends AbstractTagTest { // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). SubsetIteratorTag freshTag = new SubsetIteratorTag(); freshTag.setPageContext(pageContext); - assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + 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 testWIthStartAndCountAttribute_clearTagStateSet() throws Exception { + { // List as source + SubsetIteratorTag tag = new SubsetIteratorTag(); + tag.setPerformClearTagStateForTagPoolingServers(true); // Explicitly request tag state clearing. + tag.setPageContext(pageContext); + tag.setSource("myList"); + tag.setStart("3"); + tag.setCount("3"); + + tag.doStartTag(); + Iterator subsetIterator = (Iterator) stack.findValue("top"); + tag.doEndTag(); + + assertEquals(subsetIterator.next(), new Integer("4")); + assertEquals(subsetIterator.next(), new Integer("5")); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + SubsetIteratorTag freshTag = new SubsetIteratorTag(); + freshTag.setPerformClearTagStateForTagPoolingServers(true); + 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)); + } + + { // Array as source + SubsetIteratorTag tag = new SubsetIteratorTag(); + tag.setPerformClearTagStateForTagPoolingServers(true); // Explicitly request tag state clearing. + tag.setPageContext(pageContext); + tag.setSource("myArray"); + tag.setStart("3"); + tag.setCount("3"); + + tag.doStartTag(); + Iterator subsetIterator = (Iterator) stack.findValue("top"); + tag.doEndTag(); + + assertEquals(subsetIterator.next(), new Integer("4")); + assertEquals(subsetIterator.next(), new Integer("5")); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + SubsetIteratorTag freshTag = new SubsetIteratorTag(); + freshTag.setPerformClearTagStateForTagPoolingServers(true); + 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)); } @@ -245,7 +445,7 @@ public class SubsetIteratorTagTest extends AbstractTagTest { // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). SubsetIteratorTag freshTag = new SubsetIteratorTag(); freshTag.setPageContext(pageContext); - assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + 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)); } @@ -274,7 +474,71 @@ public class SubsetIteratorTagTest extends AbstractTagTest { // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). SubsetIteratorTag freshTag = new SubsetIteratorTag(); freshTag.setPageContext(pageContext); - assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + 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 testWithId_clearTagStateSet() throws Exception { + { // List as Source + SubsetIteratorTag tag = new SubsetIteratorTag(); + tag.setPerformClearTagStateForTagPoolingServers(true); // Explicitly request tag state clearing. + tag.setPageContext(pageContext); + tag.setSource("myList"); + tag.setVar("myPageContextId1"); + + tag.doStartTag(); + Iterator subsetIterator1 = (Iterator) stack.findValue("top"); + tag.doEndTag(); + + Iterator subsetIterator2 = (Iterator) pageContext.getAttribute("myPageContextId1"); + + assertNotNull(subsetIterator1); + assertNotNull(subsetIterator2); + assertEquals(subsetIterator1, subsetIterator2); + assertEquals(subsetIterator2.next(), new Integer(1)); + assertEquals(subsetIterator2.next(), new Integer(2)); + assertEquals(subsetIterator2.next(), new Integer(3)); + assertEquals(subsetIterator2.next(), new Integer(4)); + assertEquals(subsetIterator2.next(), new Integer(5)); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + SubsetIteratorTag freshTag = new SubsetIteratorTag(); + freshTag.setPerformClearTagStateForTagPoolingServers(true); + 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)); + } + + { // Array as source + SubsetIteratorTag tag = new SubsetIteratorTag(); + tag.setPerformClearTagStateForTagPoolingServers(true); // Explicitly request tag state clearing. + tag.setPageContext(pageContext); + tag.setSource("myArray"); + tag.setVar("myPageContextId2"); + + tag.doStartTag(); + Iterator subsetIterator1 = (Iterator) stack.findValue("top"); + tag.doEndTag(); + + Iterator subsetIterator2 = (Iterator) pageContext.getAttribute("myPageContextId2"); + + assertNotNull(subsetIterator1); + assertNotNull(subsetIterator2); + assertEquals(subsetIterator1, subsetIterator2); + assertEquals(subsetIterator2.next(), new Integer(1)); + assertEquals(subsetIterator2.next(), new Integer(2)); + assertEquals(subsetIterator2.next(), new Integer(3)); + assertEquals(subsetIterator2.next(), new Integer(4)); + assertEquals(subsetIterator2.next(), new Integer(5)); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + SubsetIteratorTag freshTag = new SubsetIteratorTag(); + freshTag.setPerformClearTagStateForTagPoolingServers(true); + 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)); } @@ -297,7 +561,7 @@ public class SubsetIteratorTagTest extends AbstractTagTest { // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). SubsetIteratorTag freshTag = new SubsetIteratorTag(); freshTag.setPageContext(pageContext); - assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + 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)); } @@ -318,13 +582,59 @@ public class SubsetIteratorTagTest extends AbstractTagTest { // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). SubsetIteratorTag freshTag = new SubsetIteratorTag(); freshTag.setPageContext(pageContext); - assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + 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 testWithDecider_clearTagStateSet() throws Exception { + { // List as source + SubsetIteratorTag tag = new SubsetIteratorTag(); + tag.setPerformClearTagStateForTagPoolingServers(true); // Explicitly request tag state clearing. + tag.setPageContext(pageContext); + tag.setSource("myList"); + tag.setDecider("myDecider"); + tag.doStartTag(); + Iterator subsetIterator = (Iterator) stack.findValue("top"); + tag.doEndTag(); + + assertEquals(subsetIterator.next(), new Integer(2)); + assertEquals(subsetIterator.next(), new Integer(4)); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + SubsetIteratorTag freshTag = new SubsetIteratorTag(); + freshTag.setPerformClearTagStateForTagPoolingServers(true); + 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)); + } + + { // Array As source + SubsetIteratorTag tag = new SubsetIteratorTag(); + tag.setPerformClearTagStateForTagPoolingServers(true); // Explicitly request tag state clearing. + tag.setPageContext(pageContext); + tag.setSource("myList"); + tag.setDecider("myDecider"); + + tag.doStartTag(); + Iterator subsetIterator = (Iterator) stack.findValue("top"); + tag.doEndTag(); + + assertEquals(subsetIterator.next(), new Integer(2)); + assertEquals(subsetIterator.next(), new Integer(4)); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + SubsetIteratorTag freshTag = new SubsetIteratorTag(); + freshTag.setPerformClearTagStateForTagPoolingServers(true); + 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)); + } + } @Override public Action getAction() { diff --git a/core/src/test/java/org/apache/struts2/views/jsp/TextTagTest.java b/core/src/test/java/org/apache/struts2/views/jsp/TextTagTest.java index 99e0bf565..1dfc98d4e 100644 --- a/core/src/test/java/org/apache/struts2/views/jsp/TextTagTest.java +++ b/core/src/test/java/org/apache/struts2/views/jsp/TextTagTest.java @@ -76,7 +76,33 @@ public class TextTagTest extends AbstractTagTest { // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). TextTag freshTag = new TextTag(); freshTag.setPageContext(pageContext); - assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + 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 testDefaultMessageOk_clearTagStateSet() throws Exception { + // NOTE: + // simulate the condition + // My Default Message + + StrutsMockBodyContent mockBodyContent = new StrutsMockBodyContent(new MockJspWriter()); + mockBodyContent.setString("Sample Of Default Message"); + tag.setPerformClearTagStateForTagPoolingServers(true); // Explicitly request tag state clearing. + tag.setBodyContent(mockBodyContent); + tag.setName("some.invalid.key.so.we.should.get.the.default.message"); + int startStatus = tag.doStartTag(); + setComponentTagClearTagState(tag, true); // Ensure component tag state clearing is set true (to match tag). + tag.doEndTag(); + + assertEquals(startStatus, BodyTag.EVAL_BODY_BUFFERED); + assertEquals("Sample Of Default Message", writer.toString()); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + TextTag freshTag = new TextTag(); + freshTag.setPerformClearTagStateForTagPoolingServers(true); + 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)); } @@ -92,7 +118,26 @@ public class TextTagTest extends AbstractTagTest { // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). TextTag freshTag = new TextTag(); freshTag.setPageContext(pageContext); - assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + 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 testExpressionsEvaluated_clearTagStateSet() throws Exception { + String key = "expressionKey"; + String value = "Foo is " + fooValue; + tag.setPerformClearTagStateForTagPoolingServers(true); // Explicitly request tag state clearing. + tag.setName(key); + tag.doStartTag(); + setComponentTagClearTagState(tag, true); // Ensure component tag state clearing is set true (to match tag). + tag.doEndTag(); + assertEquals(value, writer.toString()); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + TextTag freshTag = new TextTag(); + freshTag.setPerformClearTagStateForTagPoolingServers(true); + 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)); } @@ -108,7 +153,26 @@ public class TextTagTest extends AbstractTagTest { // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). TextTag freshTag = new TextTag(); freshTag.setPageContext(pageContext); - assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + 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 testCorrectI18NKey_clearTagStateSet() throws Exception { + String key = "foo.bar.baz"; + String value = "This should start with foo"; + tag.setPerformClearTagStateForTagPoolingServers(true); // Explicitly request tag state clearing. + tag.setName(key); + tag.doStartTag(); + setComponentTagClearTagState(tag, true); // Ensure component tag state clearing is set true (to match tag). + tag.doEndTag(); + assertEquals(value, writer.toString()); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + TextTag freshTag = new TextTag(); + freshTag.setPerformClearTagStateForTagPoolingServers(true); + 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)); } @@ -124,7 +188,26 @@ public class TextTagTest extends AbstractTagTest { // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). TextTag freshTag = new TextTag(); freshTag.setPageContext(pageContext); - assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + 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 testCorrectI18NKey2_clearTagStateSet() throws Exception { + String key = "bar.baz"; + String value = "No foo here"; + tag.setPerformClearTagStateForTagPoolingServers(true); // Explicitly request tag state clearing. + tag.setName(key); + tag.doStartTag(); + setComponentTagClearTagState(tag, true); // Ensure component tag state clearing is set true (to match tag). + tag.doEndTag(); + assertEquals(value, writer.toString()); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + TextTag freshTag = new TextTag(); + freshTag.setPerformClearTagStateForTagPoolingServers(true); + 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)); } @@ -154,7 +237,40 @@ public class TextTagTest extends AbstractTagTest { // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). TextTag freshTag = new TextTag(); freshTag.setPageContext(pageContext); - assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + 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 testMessageFormatWorks_clearTagStateSet() throws Exception { + String key = "messageFormatKey"; + String pattern = "Params are {0} {1} {2}"; + Object param1 = new Integer(12); + Object param2 = new Date(); + Object param3 = "StringVal"; + List params = new ArrayList(); + params.add(param1); + params.add(param2); + params.add(param3); + + MessageFormat format = new MessageFormat(pattern, ActionContext.getContext().getLocale()); + String expected = format.format(params.toArray()); + + tag.setPerformClearTagStateForTagPoolingServers(true); // Explicitly request tag state clearing. + tag.setName(key); + tag.doStartTag(); + setComponentTagClearTagState(tag, true); // Ensure component tag state clearing is set true (to match tag). + ((Text) tag.component).addParameter(param1); + ((Text) tag.component).addParameter(param2); + ((Text) tag.component).addParameter(param3); + tag.doEndTag(); + assertEquals(expected, writer.toString()); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + TextTag freshTag = new TextTag(); + freshTag.setPerformClearTagStateForTagPoolingServers(true); + 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)); } @@ -170,7 +286,26 @@ public class TextTagTest extends AbstractTagTest { // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). TextTag freshTag = new TextTag(); freshTag.setPageContext(pageContext); - assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + 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 testSimpleKeyValueWorks_clearTagStateSet() throws JspException { + String key = "simpleKey"; + String value = "Simple Message"; + tag.setPerformClearTagStateForTagPoolingServers(true); // Explicitly request tag state clearing. + tag.setName(key); + tag.doStartTag(); + setComponentTagClearTagState(tag, true); // Ensure component tag state clearing is set true (to match tag). + tag.doEndTag(); + assertEquals(value, writer.toString()); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + TextTag freshTag = new TextTag(); + freshTag.setPerformClearTagStateForTagPoolingServers(true); + 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)); } @@ -216,7 +351,7 @@ public class TextTagTest extends AbstractTagTest { // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). TextTag freshTag = new TextTag(); freshTag.setPageContext(pageContext); - assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + 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)); @@ -234,7 +369,47 @@ public class TextTagTest extends AbstractTagTest { // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). freshTag.setPageContext(pageContext); - assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + 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 testTextTagUsesValueStackInRequestNotActionContext_clearTagStateSet() throws JspException { + String key = "simpleKey"; + String value1 = "Simple Message"; + Locale foreignLocale = getForeignLocale(); + String value2 = getLocalizedMessage(foreignLocale); + tag.setPerformClearTagStateForTagPoolingServers(true); // Explicitly request tag state clearing. + tag.setName(key); + tag.doStartTag(); + setComponentTagClearTagState(tag, true); // Ensure component tag state clearing is set true (to match tag). + tag.doEndTag(); + assertEquals(value1, writer.toString()); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + TextTag freshTag = new TextTag(); + freshTag.setPerformClearTagStateForTagPoolingServers(true); + 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)); + + final StringBuffer buffer = writer.getBuffer(); + buffer.delete(0, buffer.length()); + ValueStack newStack = container.getInstance(ValueStackFactory.class).createValueStack(); + newStack.getContext().put(ActionContext.LOCALE, foreignLocale); + newStack.getContext().put(ActionContext.CONTAINER, container); + newStack.push(container.inject(TestAction1.class)); + request.setAttribute(ServletActionContext.STRUTS_VALUESTACK_KEY, newStack); + assertNotSame(ActionContext.getContext().getValueStack().peek(), newStack.peek()); + tag.setName(key); // Required as WW-5124 fix clears tag state. + tag.doStartTag(); + setComponentTagClearTagState(tag, true); // Ensure component tag state clearing is set true (to match tag). + tag.doEndTag(); + assertEquals(value2, writer.toString()); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + 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)); } @@ -258,7 +433,7 @@ public class TextTagTest extends AbstractTagTest { // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). TextTag freshTag = new TextTag(); freshTag.setPageContext(pageContext); - assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + 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)); @@ -278,11 +453,174 @@ public class TextTagTest extends AbstractTagTest { // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). freshTag.setPageContext(pageContext); - assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + 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 testTextTagUsesLocaleFromValueStack_clearTagStateSet() throws JspException { + stack.pop(); + stack.push(container.inject(TestAction1.class)); + + Locale defaultLocale = getDefaultLocale(); + Locale foreignLocale = getForeignLocale(); + assertNotSame(defaultLocale, foreignLocale); + + ActionContext.getContext().setLocale(defaultLocale); + String key = "simpleKey"; + String value_default = getLocalizedMessage(defaultLocale); + tag.setPerformClearTagStateForTagPoolingServers(true); // Explicitly request tag state clearing. + tag.setName(key); + tag.doStartTag(); + setComponentTagClearTagState(tag, true); // Ensure component tag state clearing is set true (to match tag). + tag.doEndTag(); + assertEquals(value_default, writer.toString()); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + TextTag freshTag = new TextTag(); + freshTag.setPerformClearTagStateForTagPoolingServers(true); + 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)); + + final StringBuffer buffer = writer.getBuffer(); + buffer.delete(0, buffer.length()); + String value_int = getLocalizedMessage(foreignLocale); + assertFalse(value_default.equals(value_int)); + ValueStack newStack = container.getInstance(ValueStackFactory.class).createValueStack(stack); + newStack.getContext().put(ActionContext.LOCALE, foreignLocale); + newStack.getContext().put(ActionContext.CONTAINER, container); + assertNotSame(newStack.getContext().get(ActionContext.LOCALE), ActionContext.getContext().getLocale()); + request.setAttribute(ServletActionContext.STRUTS_VALUESTACK_KEY, newStack); + assertEquals(ActionContext.getContext().getValueStack().peek(), newStack.peek()); + tag.setName(key); // Required as WW-5124 fix clears tag state. + tag.doStartTag(); + setComponentTagClearTagState(tag, true); // Ensure component tag state clearing is set true (to match tag). + tag.doEndTag(); + assertEquals(value_int, writer.toString()); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + 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)); + } + +<<<<<<< HEAD +======= + public void testTextTagCanSearchStackToFindValue() throws JspException { + String key = "result"; + + tag.setName(key); + tag.setSearchValueStack("true"); + final StringBuffer buffer = writer.getBuffer(); + buffer.delete(0, buffer.length()); + ValueStack newStack = container.getInstance(ValueStackFactory.class).createValueStack(); + newStack.getContext().put(ActionContext.CONTAINER, container); + TestAction testAction = new TestAction(); + container.inject(testAction); + testAction.setResult("bar"); + newStack.push(testAction); + request.setAttribute(ServletActionContext.STRUTS_VALUESTACK_KEY, newStack); + + tag.doStartTag(); + tag.doEndTag(); + assertEquals("bar", writer.toString()); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + TextTag freshTag = new TextTag(); + 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 testTextTagCanSearchStackToFindValue_clearTagStateSet() throws JspException { + String key = "result"; + + tag.setPerformClearTagStateForTagPoolingServers(true); // Explicitly request tag state clearing. + tag.setName(key); + tag.setSearchValueStack("true"); + final StringBuffer buffer = writer.getBuffer(); + buffer.delete(0, buffer.length()); + ValueStack newStack = container.getInstance(ValueStackFactory.class).createValueStack(); + newStack.getContext().put(ActionContext.CONTAINER, container); + TestAction testAction = new TestAction(); + container.inject(testAction); + testAction.setResult("bar"); + newStack.push(testAction); + request.setAttribute(ServletActionContext.STRUTS_VALUESTACK_KEY, newStack); + + tag.doStartTag(); + setComponentTagClearTagState(tag, true); // Ensure component tag state clearing is set true (to match tag). + tag.doEndTag(); + assertEquals("bar", writer.toString()); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + TextTag freshTag = new TextTag(); + freshTag.setPerformClearTagStateForTagPoolingServers(true); + 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)); + } + + public void testTextTagDoNotSearchStackByDefault() throws JspException { + String key = "result"; + + tag.setName(key); + final StringBuffer buffer = writer.getBuffer(); + buffer.delete(0, buffer.length()); + ValueStack newStack = container.getInstance(ValueStackFactory.class).createValueStack(); + newStack.getContext().put(ActionContext.CONTAINER, container); + TestAction testAction = new TestAction(); + container.inject(testAction); + testAction.setResult("bar"); + newStack.push(testAction); + request.setAttribute(ServletActionContext.STRUTS_VALUESTACK_KEY, newStack); + + tag.doStartTag(); + tag.doEndTag(); + assertEquals("result", writer.toString()); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + TextTag freshTag = new TextTag(); + 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 testTextTagDoNotSearchStackByDefault_clearTagStateSet() throws JspException { + String key = "result"; + + tag.setPerformClearTagStateForTagPoolingServers(true); // Explicitly request tag state clearing. + tag.setName(key); + final StringBuffer buffer = writer.getBuffer(); + buffer.delete(0, buffer.length()); + ValueStack newStack = container.getInstance(ValueStackFactory.class).createValueStack(); + newStack.getContext().put(ActionContext.CONTAINER, container); + TestAction testAction = new TestAction(); + container.inject(testAction); + testAction.setResult("bar"); + newStack.push(testAction); + request.setAttribute(ServletActionContext.STRUTS_VALUESTACK_KEY, newStack); + + tag.doStartTag(); + setComponentTagClearTagState(tag, true); // Ensure component tag state clearing is set true (to match tag). + tag.doEndTag(); + assertEquals("result", writer.toString()); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + TextTag freshTag = new TextTag(); + freshTag.setPerformClearTagStateForTagPoolingServers(true); + 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)); + } + +>>>>>>> da46cefa2 (Update:) public void testWithNoMessageAndBodyIsNotEmptyBodyIsReturned() throws Exception { final String key = "key.does.not.exist"; final String bodyText = "body text"; @@ -298,7 +636,30 @@ public class TextTagTest extends AbstractTagTest { // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). TextTag freshTag = new TextTag(); freshTag.setPageContext(pageContext); - assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + 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 testWithNoMessageAndBodyIsNotEmptyBodyIsReturned_clearTagStateSet() throws Exception { + final String key = "key.does.not.exist"; + final String bodyText = "body text"; + tag.setName(key); + + StrutsBodyContent bodyContent = new StrutsBodyContent(null); + bodyContent.print(bodyText); + tag.setPerformClearTagStateForTagPoolingServers(true); // Explicitly request tag state clearing. + tag.setBodyContent(bodyContent); + tag.doStartTag(); + setComponentTagClearTagState(tag, true); // Ensure component tag state clearing is set true (to match tag). + tag.doEndTag(); + assertEquals(bodyText, writer.toString()); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + TextTag freshTag = new TextTag(); + freshTag.setPerformClearTagStateForTagPoolingServers(true); + 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)); } @@ -313,7 +674,25 @@ public class TextTagTest extends AbstractTagTest { // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). TextTag freshTag = new TextTag(); freshTag.setPageContext(pageContext); - assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + 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 testWithNoMessageAndNoDefaultKeyReturned_clearTagStateSet() throws JspException { + final String key = "key.does.not.exist"; + tag.setPerformClearTagStateForTagPoolingServers(true); // Explicitly request tag state clearing. + tag.setName(key); + tag.doStartTag(); + setComponentTagClearTagState(tag, true); // Ensure component tag state clearing is set true (to match tag). + tag.doEndTag(); + assertEquals(key, writer.toString()); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + TextTag freshTag = new TextTag(); + freshTag.setPerformClearTagStateForTagPoolingServers(true); + 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)); } @@ -340,7 +719,24 @@ public class TextTagTest extends AbstractTagTest { // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). TextTag freshTag = new TextTag(); freshTag.setPageContext(pageContext); - assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + 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 testBlankNameDefined_clearTagStateSet() throws Exception { + tag.setPerformClearTagStateForTagPoolingServers(true); // Explicitly request tag state clearing. + tag.setName(""); + tag.doStartTag(); + setComponentTagClearTagState(tag, true); // Ensure component tag state clearing is set true (to match tag). + tag.doEndTag(); + assertEquals("", writer.toString()); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + TextTag freshTag = new TextTag(); + freshTag.setPerformClearTagStateForTagPoolingServers(true); + 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)); } @@ -357,7 +753,27 @@ public class TextTagTest extends AbstractTagTest { // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). TextTag freshTag = new TextTag(); freshTag.setPageContext(pageContext); - assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + 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 testPutId_clearTagStateSet() throws Exception { + assertEquals(null, stack.findString("myId")); // nothing in stack + tag.setPerformClearTagStateForTagPoolingServers(true); // Explicitly request tag state clearing. + tag.setVar("myId"); + tag.setName("bar.baz"); + tag.doStartTag(); + setComponentTagClearTagState(tag, true); // Ensure component tag state clearing is set true (to match tag). + tag.doEndTag(); + assertEquals("", writer.toString()); + assertEquals("No foo here", stack.findString("myId")); // is in stack now + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + TextTag freshTag = new TextTag(); + freshTag.setPerformClearTagStateForTagPoolingServers(true); + 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)); } @@ -374,7 +790,27 @@ public class TextTagTest extends AbstractTagTest { // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). TextTag freshTag = new TextTag(); freshTag.setPageContext(pageContext); - assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + 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 testEscapeHtml_clearTagStateSet() throws Exception { + final String key = "foo.escape.html"; + final String value = "1 < 2"; + tag.setPerformClearTagStateForTagPoolingServers(true); // Explicitly request tag state clearing. + tag.setName(key); + tag.setEscapeHtml(true); + tag.doStartTag(); + setComponentTagClearTagState(tag, true); // Ensure component tag state clearing is set true (to match tag). + tag.doEndTag(); + assertEquals(value, writer.toString()); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + TextTag freshTag = new TextTag(); + freshTag.setPerformClearTagStateForTagPoolingServers(true); + 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)); } @@ -391,7 +827,27 @@ public class TextTagTest extends AbstractTagTest { // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). TextTag freshTag = new TextTag(); freshTag.setPageContext(pageContext); - assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + 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 testEscapeXml_clearTagStateSet() throws Exception { + final String key = "foo.escape.xml"; + final String value = "<>'"&"; + tag.setPerformClearTagStateForTagPoolingServers(true); // Explicitly request tag state clearing. + tag.setName(key); + tag.setEscapeXml(true); + tag.doStartTag(); + setComponentTagClearTagState(tag, true); // Ensure component tag state clearing is set true (to match tag). + tag.doEndTag(); + assertEquals(value, writer.toString()); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + TextTag freshTag = new TextTag(); + freshTag.setPerformClearTagStateForTagPoolingServers(true); + 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)); } @@ -408,7 +864,27 @@ public class TextTagTest extends AbstractTagTest { // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). TextTag freshTag = new TextTag(); freshTag.setPageContext(pageContext); - assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + 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 testEscapeJavaScript_clearTagStateSet() throws Exception { + final String key = "foo.escape.javascript"; + final String value = "\\t\\b\\n\\f\\r\\\"\\\'\\/\\\\"; + tag.setPerformClearTagStateForTagPoolingServers(true); // Explicitly request tag state clearing. + tag.setName(key); + tag.setEscapeJavaScript(true); + tag.doStartTag(); + setComponentTagClearTagState(tag, true); // Ensure component tag state clearing is set true (to match tag). + tag.doEndTag(); + assertEquals(value, writer.toString()); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + TextTag freshTag = new TextTag(); + freshTag.setPerformClearTagStateForTagPoolingServers(true); + 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)); } @@ -425,7 +901,27 @@ public class TextTagTest extends AbstractTagTest { // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). TextTag freshTag = new TextTag(); freshTag.setPageContext(pageContext); - assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + 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 testEscapeCsv_clearTagStateSet() throws Exception { + final String key = "foo.escape.csv"; + final String value = "\"something,\"\",\"\"\""; + tag.setPerformClearTagStateForTagPoolingServers(true); // Explicitly request tag state clearing. + tag.setName(key); + tag.setEscapeCsv(true); + tag.doStartTag(); + setComponentTagClearTagState(tag, true); // Ensure component tag state clearing is set true (to match tag). + tag.doEndTag(); + assertEquals(value, writer.toString()); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + TextTag freshTag = new TextTag(); + freshTag.setPerformClearTagStateForTagPoolingServers(true); + 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)); } diff --git a/core/src/test/java/org/apache/struts2/views/jsp/URLTagTest.java b/core/src/test/java/org/apache/struts2/views/jsp/URLTagTest.java index b34788c84..e496f4d23 100644 --- a/core/src/test/java/org/apache/struts2/views/jsp/URLTagTest.java +++ b/core/src/test/java/org/apache/struts2/views/jsp/URLTagTest.java @@ -150,20 +150,141 @@ public class URLTagTest extends AbstractUITagTest { // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). ParamTag freshParamTag = new ParamTag(); freshParamTag.setPageContext(pageContext); - assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + 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(param1, freshParamTag)); - assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + 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(param2, freshParamTag)); - assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + 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(param3, freshParamTag)); // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). URLTag freshTag = new URLTag(); freshTag.setPageContext(pageContext); - assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + 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)); + } + + /** + * To test priority of parameter passed in to url component though + * various way + * - current request url + * - tag's value attribute + * - tag's nested param tag + * + * id1 + * === + * - found in current request url + * - found in tag's value attribute + * - found in tag's param tag + * CONCLUSION: tag's param tag takes precedence (paramId1) + * + * id2 + * === + * - found in current request url + * - found in tag's value attribute + * CONCLUSION: tag's value attribute take precedence (tagId2) + * + * urlParam1 + * ========= + * - found in current request url + * CONCLUSION: param in current request url will be used (urlValue1) + * + * urlParam2 + * ========= + * - found in current request url + * CONCLUSION: param in current request url will be used. (urlValue2) + * + * tagId + * ===== + * - found in tag's value attribute + * CONCLUSION: param in tag's value attribute wil; be used. (tagValue) + * + * param1 + * ====== + * - found in nested param tag + * CONCLUSION: param in nested param tag will be used. (param1value) + * + * param2 + * ====== + * - found in nested param tag + * CONCLUSION: param in nested param tag will be used. (param2value) + */ + public void testParametersPriority_clearTagStateSet() throws Exception { + request.setQueryString("id1=urlId1&id2=urlId2&urlParam1=urlValue1&urlParam2=urlValue2"); + + tag.setPerformClearTagStateForTagPoolingServers(true); // Explicitly request tag state clearing. + tag.setValue("testAction.action?id1=tagId1&id2=tagId2&tagId=tagValue"); + + ParamTag param1 = new ParamTag(); + param1.setPerformClearTagStateForTagPoolingServers(true); // Explicitly request tag state clearing. + param1.setPageContext(pageContext); + param1.setName("param1"); + param1.setValue("%{'param1value'}"); + + ParamTag param2 = new ParamTag(); + param2.setPerformClearTagStateForTagPoolingServers(true); // Explicitly request tag state clearing. + param2.setPageContext(pageContext); + param2.setName("param2"); + param2.setValue("%{'param2value'}"); + + ParamTag param3 = new ParamTag(); + param3.setPerformClearTagStateForTagPoolingServers(true); // Explicitly request tag state clearing. + param3.setPageContext(pageContext); + param3.setName("id1"); + param3.setValue("%{'paramId1'}"); + + + tag.doStartTag(); + setComponentTagClearTagState(tag, true); // Ensure component tag state clearing is set true (to match tag). + param1.doStartTag(); + setComponentTagClearTagState(param1, true); // Ensure component tag state clearing is set true (to match tag). + param1.doEndTag(); + param2.doStartTag(); + setComponentTagClearTagState(param2, true); // Ensure component tag state clearing is set true (to match tag). + param2.doEndTag(); + param3.doStartTag(); + setComponentTagClearTagState(param3, true); // Ensure component tag state clearing is set true (to match tag). + param3.doEndTag(); + + URL url = (URL) tag.getComponent(); + Map parameters = url.getParameters(); + + + assertNotNull(parameters); + assertEquals(parameters.size(), 7); + assertEquals(parameters.get("id1"), "paramId1"); + assertEquals(parameters.get("id2"), "tagId2"); + assertEquals(parameters.get("urlParam1"), "urlValue1"); + assertEquals(parameters.get("urlParam2"), "urlValue2"); + assertEquals(parameters.get("tagId"), "tagValue"); + assertEquals(parameters.get("param1"), "param1value"); + assertEquals(parameters.get("param2"), "param2value"); + + tag.doEndTag(); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + ParamTag freshParamTag = new ParamTag(); + freshParamTag.setPerformClearTagStateForTagPoolingServers(true); + freshParamTag.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(param1, freshParamTag)); + 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(param2, freshParamTag)); + 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(param3, freshParamTag)); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + URLTag freshTag = new URLTag(); + freshTag.setPerformClearTagStateForTagPoolingServers(true); + 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)); } @@ -194,11 +315,46 @@ public class URLTagTest extends AbstractUITagTest { // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). URLTag freshTag = new URLTag(); freshTag.setPageContext(pageContext); - assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + 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)); } - + + /** + * Use Iterable values as the value of the param tags + * @throws Exception + */ + public void testIterableParameters_clearTagStateSet() throws Exception { + tag.setPerformClearTagStateForTagPoolingServers(true); // Explicitly request tag state clearing. + tag.setValue("/TestAction.action?p0=z"); + + tag.doStartTag(); + setComponentTagClearTagState(tag, true); // Ensure component tag state clearing is set true (to match tag). + //Iterable + List list = new ArrayList(); + list.add(new ValueHolder("a")); + list.add(new ValueHolder("b")); + tag.component.addParameter("p1", list); + + //String[] + tag.component.addParameter("p2", new String[] { "d", "e" }); + //ValueHolder[] + tag.component.addParameter("p3", new ValueHolder[] { + new ValueHolder("f"), new ValueHolder("g") }); + + tag.doEndTag(); + + assertEquals("/TestAction.action?p0=z&p1=a&p1=b&p2=d&p2=e&p3=f&p3=g", writer.toString()); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + URLTag freshTag = new URLTag(); + freshTag.setPerformClearTagStateForTagPoolingServers(true); + 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)); + } + /** * To test priority of parameter passed in to url component though * various way, with includeParams="NONE" @@ -254,20 +410,105 @@ public class URLTagTest extends AbstractUITagTest { // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). ParamTag freshParamTag = new ParamTag(); freshParamTag.setPageContext(pageContext); - assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + 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(param1, freshParamTag)); - assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + 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(param2, freshParamTag)); - assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + 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(param3, freshParamTag)); // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). URLTag freshTag = new URLTag(); freshTag.setPageContext(pageContext); - assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + 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)); + } + + /** + * To test priority of parameter passed in to url component though + * various way, with includeParams="NONE" + * - current request url + * - tag's value attribute + * - tag's nested param tag + * + * In this case only parameters from the tag itself is taken into account. + * Those from request will not count, only those in tag's value attribute + * and nested param tag. + * + * @throws Exception + */ + public void testParametersPriorityWithIncludeParamsAsNONE_clearTagStateSet() throws Exception { + request.setQueryString("id1=urlId1&id2=urlId2&urlParam1=urlValue1&urlParam2=urlValue2"); + + tag.setPerformClearTagStateForTagPoolingServers(true); // Explicitly request tag state clearing. + tag.setValue("testAction.action?id1=tagId1&id2=tagId2&tagId=tagValue"); + tag.setIncludeParams("NONE"); + + ParamTag param1 = new ParamTag(); + param1.setPerformClearTagStateForTagPoolingServers(true); // Explicitly request tag state clearing. + param1.setPageContext(pageContext); + param1.setName("param1"); + param1.setValue("%{'param1value'}"); + + ParamTag param2 = new ParamTag(); + param2.setPerformClearTagStateForTagPoolingServers(true); // Explicitly request tag state clearing. + param2.setPageContext(pageContext); + param2.setName("param2"); + param2.setValue("%{'param2value'}"); + + ParamTag param3 = new ParamTag(); + param3.setPerformClearTagStateForTagPoolingServers(true); // Explicitly request tag state clearing. + param3.setPageContext(pageContext); + param3.setName("id1"); + param3.setValue("%{'paramId1'}"); + + tag.doStartTag(); + setComponentTagClearTagState(tag, true); // Ensure component tag state clearing is set true (to match tag). + param1.doStartTag(); + setComponentTagClearTagState(param1, true); // Ensure component tag state clearing is set true (to match tag). + param1.doEndTag(); + param2.doStartTag(); + setComponentTagClearTagState(param2, true); // Ensure component tag state clearing is set true (to match tag). + param2.doEndTag(); + param3.doStartTag(); + setComponentTagClearTagState(param3, true); // Ensure component tag state clearing is set true (to match tag). + param3.doEndTag(); + + URL url = (URL) tag.getComponent(); + Map parameters = url.getParameters(); + + assertEquals(parameters.size(), 5); + assertEquals(parameters.get("id1"), "paramId1"); + assertEquals(parameters.get("id2"), "tagId2"); + assertEquals(parameters.get("tagId"), "tagValue"); + assertEquals(parameters.get("param1"), "param1value"); + assertEquals(parameters.get("param2"), "param2value"); + + tag.doEndTag(); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + ParamTag freshParamTag = new ParamTag(); + freshParamTag.setPerformClearTagStateForTagPoolingServers(true); + freshParamTag.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(param1, freshParamTag)); + 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(param2, freshParamTag)); + 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(param3, freshParamTag)); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + URLTag freshTag = new URLTag(); + freshTag.setPerformClearTagStateForTagPoolingServers(true); + 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)); } @@ -299,7 +540,42 @@ public class URLTagTest extends AbstractUITagTest { // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). URLTag freshTag = new URLTag(); freshTag.setPageContext(pageContext); - assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + 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 testIncludeParamsDefaultToGET_clearTagStateSet() throws Exception { + request.setQueryString("one=oneVal&two=twoVal&three=threeVal"); + + // request parameter map should not have any effect, as includeParams + // default to GET, which get its param from request.getQueryString() + Map tmp = new HashMap(); + tmp.put("one", "aaa"); + tmp.put("two", "bbb"); + tmp.put("three", "ccc"); + request.setParameterMap(tmp); + + tag.setPerformClearTagStateForTagPoolingServers(true); // Explicitly request tag state clearing. + tag.setValue("TestAction.acton"); + + tag.doStartTag(); + setComponentTagClearTagState(tag, true); // Ensure component tag state clearing is set true (to match tag). + + URL url = (URL) tag.getComponent(); + Map parameters = url.getParameters(); + + tag.doEndTag(); + + assertEquals(parameters.get("one"), "oneVal"); + assertEquals(parameters.get("two"), "twoVal"); + assertEquals(parameters.get("three"), "threeVal"); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + URLTag freshTag = new URLTag(); + freshTag.setPerformClearTagStateForTagPoolingServers(true); + 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)); } @@ -314,7 +590,25 @@ public class URLTagTest extends AbstractUITagTest { // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). URLTag freshTag = new URLTag(); freshTag.setPageContext(pageContext); - assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + 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 testActionURL_clearTagStateSet() throws Exception { + tag.setPerformClearTagStateForTagPoolingServers(true); // Explicitly request tag state clearing. + tag.setValue("TestAction.action"); + + tag.doStartTag(); + setComponentTagClearTagState(tag, true); // Ensure component tag state clearing is set true (to match tag). + tag.doEndTag(); + assertEquals("TestAction.action", writer.toString()); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + URLTag freshTag = new URLTag(); + freshTag.setPerformClearTagStateForTagPoolingServers(true); + 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)); } @@ -334,7 +628,31 @@ public class URLTagTest extends AbstractUITagTest { // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). URLTag freshTag = new URLTag(); freshTag.setPageContext(pageContext); - assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + // URLTag clears component in doEndTag and has no additional state set here, so it compares as equal with the default tag clear state as well. + assertTrue("Tag state after doEndTag() under default tag clear state is inequal to new Tag with pageContext/parent set. " + + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", + strutsBodyTagsAreReflectionEqual(tag, freshTag)); + } + + public void testAddParameters_clearTagStateSet() throws Exception { + request.setAttribute("struts.request_uri", "/Test.action"); + + request.setAttribute("struts.request_uri", "/TestAction.action"); + request.setQueryString("param0=value0"); + + tag.setPerformClearTagStateForTagPoolingServers(true); // Explicitly request tag state clearing. + tag.doStartTag(); + setComponentTagClearTagState(tag, true); // Ensure component tag state clearing is set true (to match tag). + tag.component.addParameter("param1", "value1"); + tag.component.addParameter("param2", "value2"); + tag.doEndTag(); + assertEquals("/TestAction.action?param0=value0&param1=value1&param2=value2", writer.toString()); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + URLTag freshTag = new URLTag(); + freshTag.setPerformClearTagStateForTagPoolingServers(true); + 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)); } @@ -352,7 +670,28 @@ public class URLTagTest extends AbstractUITagTest { // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). URLTag freshTag = new URLTag(); freshTag.setPageContext(pageContext); - assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + 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 testEvaluateValue_clearTagStateSet() throws Exception { + Foo foo = new Foo(); + foo.setTitle("test"); + stack.push(foo); + tag.setPerformClearTagStateForTagPoolingServers(true); // Explicitly request tag state clearing. + tag.setValue("%{title}"); + + tag.doStartTag(); + setComponentTagClearTagState(tag, true); // Ensure component tag state clearing is set true (to match tag). + tag.doEndTag(); + assertEquals("test", writer.toString()); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + URLTag freshTag = new URLTag(); + freshTag.setPerformClearTagStateForTagPoolingServers(true); + 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)); } @@ -371,7 +710,29 @@ public class URLTagTest extends AbstractUITagTest { // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). URLTag freshTag = new URLTag(); freshTag.setPageContext(pageContext); - assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + 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 testHttps_clearTagStateSet() throws Exception { + request.setScheme("https"); + request.setServerName("localhost"); + request.setServerPort(443); + + tag.setPerformClearTagStateForTagPoolingServers(true); // Explicitly request tag state clearing. + tag.setValue("list-members.action"); + + tag.doStartTag(); + setComponentTagClearTagState(tag, true); // Ensure component tag state clearing is set true (to match tag). + tag.doEndTag(); + assertEquals("list-members.action", writer.toString()); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + URLTag freshTag = new URLTag(); + freshTag.setPerformClearTagStateForTagPoolingServers(true); + 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)); } @@ -391,7 +752,30 @@ public class URLTagTest extends AbstractUITagTest { // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). URLTag freshTag = new URLTag(); freshTag.setPageContext(pageContext); - assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + 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 testAnchor_clearTagStateSet() throws Exception { + request.setScheme("https"); + request.setServerName("localhost"); + request.setServerPort(443); + + tag.setPerformClearTagStateForTagPoolingServers(true); // Explicitly request tag state clearing. + tag.setValue("list-members.action"); + tag.setAnchor("test"); + + tag.doStartTag(); + setComponentTagClearTagState(tag, true); // Ensure component tag state clearing is set true (to match tag). + tag.doEndTag(); + assertEquals("list-members.action#test", writer.toString()); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + URLTag freshTag = new URLTag(); + freshTag.setPerformClearTagStateForTagPoolingServers(true); + 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)); } @@ -420,16 +804,58 @@ public class URLTagTest extends AbstractUITagTest { // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). ParamTag freshParamTag = new ParamTag(); freshParamTag.setPageContext(pageContext); - assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + 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(paramTag, freshParamTag)); // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). URLTag freshTag = new URLTag(); freshTag.setPageContext(pageContext); - assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + 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(urlTag, freshTag)); + } + + public void testParamPrecedence_clearTagStateSet() throws Exception { + request.setRequestURI("/context/someAction.action"); + request.setQueryString("id=22&name=John"); + + URLTag urlTag = new URLTag(); + urlTag.setPerformClearTagStateForTagPoolingServers(true); // Explicitly request tag state clearing. + urlTag.setPageContext(pageContext); + urlTag.setIncludeParams("get"); + urlTag.setEncode("%{false}"); + + ParamTag paramTag = new ParamTag(); + paramTag.setPerformClearTagStateForTagPoolingServers(true); // Explicitly request tag state clearing. + paramTag.setPageContext(pageContext); + paramTag.setName("id"); + paramTag.setValue("%{'33'}"); + + urlTag.doStartTag(); + setComponentTagClearTagState(urlTag, true); // Ensure component tag state clearing is set true (to match tag). + paramTag.doStartTag(); + setComponentTagClearTagState(paramTag, true); // Ensure component tag state clearing is set true (to match tag). + paramTag.doEndTag(); + urlTag.doEndTag(); + + assertEquals("/context/someAction.action?id=33&name=John", writer.getBuffer().toString()); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + ParamTag freshParamTag = new ParamTag(); + freshParamTag.setPerformClearTagStateForTagPoolingServers(true); + freshParamTag.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(paramTag, freshParamTag)); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + URLTag freshTag = new URLTag(); + freshTag.setPerformClearTagStateForTagPoolingServers(true); + 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(urlTag, freshTag)); } public void testParamPrecedenceWithAnchor() throws Exception { @@ -457,21 +883,64 @@ public class URLTagTest extends AbstractUITagTest { // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). ParamTag freshParamTag = new ParamTag(); freshParamTag.setPageContext(pageContext); - assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + 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(paramTag, freshParamTag)); // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). URLTag freshTag = new URLTag(); freshTag.setPageContext(pageContext); - assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + 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(urlTag, freshTag)); + } + + public void testParamPrecedenceWithAnchor_clearTagStateSet() throws Exception { + request.setRequestURI("/context/someAction.action"); + request.setQueryString("id=22&name=John"); + + URLTag urlTag = new URLTag(); + urlTag.setPerformClearTagStateForTagPoolingServers(true); // Explicitly request tag state clearing. + urlTag.setPageContext(pageContext); + urlTag.setIncludeParams("get"); + urlTag.setEncode("%{false}"); + urlTag.setAnchor("testAnchor"); + + ParamTag paramTag = new ParamTag(); + paramTag.setPerformClearTagStateForTagPoolingServers(true); // Explicitly request tag state clearing. + paramTag.setPageContext(pageContext); + paramTag.setName("id"); + paramTag.setValue("%{'33'}"); + + urlTag.doStartTag(); + setComponentTagClearTagState(urlTag, true); // Ensure component tag state clearing is set true (to match tag). + paramTag.doStartTag(); + setComponentTagClearTagState(paramTag, true); // Ensure component tag state clearing is set true (to match tag). + paramTag.doEndTag(); + urlTag.doEndTag(); + + assertEquals("/context/someAction.action?id=33&name=John#testAnchor", writer.getBuffer().toString()); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + ParamTag freshParamTag = new ParamTag(); + freshParamTag.setPerformClearTagStateForTagPoolingServers(true); + freshParamTag.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(paramTag, freshParamTag)); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + URLTag freshTag = new URLTag(); + freshTag.setPerformClearTagStateForTagPoolingServers(true); + 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(urlTag, freshTag)); } public void testPutId() throws Exception { tag.setValue("/public/about"); - assertNull(stack.findString("myId")); // nothing in stack + assertEquals(null, stack.findString("myId")); // nothing in stack tag.setVar("myId"); tag.doStartTag(); tag.doEndTag(); @@ -481,7 +950,27 @@ public class URLTagTest extends AbstractUITagTest { // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). URLTag freshTag = new URLTag(); freshTag.setPageContext(pageContext); - assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + 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 testPutId_clearTagStateSet() throws Exception { + tag.setPerformClearTagStateForTagPoolingServers(true); // Explicitly request tag state clearing. + tag.setValue("/public/about"); + assertEquals(null, stack.findString("myId")); // nothing in stack + tag.setVar("myId"); + tag.doStartTag(); + setComponentTagClearTagState(tag, true); // Ensure component tag state clearing is set true (to match tag). + tag.doEndTag(); + assertEquals("", writer.toString()); + assertEquals("/public/about", stack.findString("myId")); // is in stack now + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + URLTag freshTag = new URLTag(); + freshTag.setPerformClearTagStateForTagPoolingServers(true); + 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)); } @@ -495,7 +984,24 @@ public class URLTagTest extends AbstractUITagTest { // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). URLTag freshTag = new URLTag(); freshTag.setPageContext(pageContext); - assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + 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 testUsingValueOnly_clearTagStateSet() throws Exception { + tag.setPerformClearTagStateForTagPoolingServers(true); // Explicitly request tag state clearing. + tag.setValue("/public/about/team.jsp"); + tag.doStartTag(); + setComponentTagClearTagState(tag, true); // Ensure component tag state clearing is set true (to match tag). + tag.doEndTag(); + assertEquals("/public/about/team.jsp", writer.toString()); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + URLTag freshTag = new URLTag(); + freshTag.setPerformClearTagStateForTagPoolingServers(true); + 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)); } @@ -514,7 +1020,29 @@ public class URLTagTest extends AbstractUITagTest { // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). URLTag freshTag = new URLTag(); freshTag.setPageContext(pageContext); - assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + 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 testRequestURIActionIncludeNone_clearTagStateSet() throws Exception { + request.setRequestURI("/public/about"); + request.setQueryString("section=team&company=acme inc"); + + tag.setPerformClearTagStateForTagPoolingServers(true); // Explicitly request tag state clearing. + tag.setAction("team"); + tag.setIncludeParams("none"); + tag.doStartTag(); + setComponentTagClearTagState(tag, true); // Ensure component tag state clearing is set true (to match tag). + tag.doEndTag(); + + assertEquals("/team.action", writer.toString()); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + URLTag freshTag = new URLTag(); + freshTag.setPerformClearTagStateForTagPoolingServers(true); + 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)); } @@ -533,7 +1061,29 @@ public class URLTagTest extends AbstractUITagTest { // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). URLTag freshTag = new URLTag(); freshTag.setPageContext(pageContext); - assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + 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 testRequestURIActionIncludeGet_clearTagStateSet() throws Exception { + request.setRequestURI("/public/about"); + request.setQueryString("section=team&company=acme inc"); + + tag.setPerformClearTagStateForTagPoolingServers(true); // Explicitly request tag state clearing. + tag.setAction("team"); + tag.setIncludeParams("get"); + tag.doStartTag(); + setComponentTagClearTagState(tag, true); // Ensure component tag state clearing is set true (to match tag). + tag.doEndTag(); + + assertEquals("/team.action?section=team&company=acme+inc", writer.toString()); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + URLTag freshTag = new URLTag(); + freshTag.setPerformClearTagStateForTagPoolingServers(true); + 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)); } @@ -553,11 +1103,34 @@ public class URLTagTest extends AbstractUITagTest { // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). URLTag freshTag = new URLTag(); freshTag.setPageContext(pageContext); - assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + 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 testRequestURIActionIncludeGetDoNotEscapeAmp_clearTagStateSet() throws Exception { + request.setRequestURI("/public/about"); + request.setQueryString("section=team&company=acme inc"); + + tag.setPerformClearTagStateForTagPoolingServers(true); // Explicitly request tag state clearing. + tag.setAction("team"); + tag.setIncludeParams("get"); + tag.setEscapeAmp("false"); + tag.doStartTag(); + setComponentTagClearTagState(tag, true); // Ensure component tag state clearing is set true (to match tag). + tag.doEndTag(); + + assertEquals("/team.action?section=team&company=acme+inc", writer.toString()); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + URLTag freshTag = new URLTag(); + freshTag.setPerformClearTagStateForTagPoolingServers(true); + 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)); + } + public void testRequestURINoActionIncludeNone() throws Exception { request.setRequestURI("/public/about"); request.setQueryString("section=team&company=acme inc"); @@ -572,7 +1145,29 @@ public class URLTagTest extends AbstractUITagTest { // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). URLTag freshTag = new URLTag(); freshTag.setPageContext(pageContext); - assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + 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 testRequestURINoActionIncludeNone_clearTagStateSet() throws Exception { + request.setRequestURI("/public/about"); + request.setQueryString("section=team&company=acme inc"); + + tag.setPerformClearTagStateForTagPoolingServers(true); // Explicitly request tag state clearing. + tag.setAction(null); + tag.setIncludeParams("none"); + tag.doStartTag(); + setComponentTagClearTagState(tag, true); // Ensure component tag state clearing is set true (to match tag). + tag.doEndTag(); + + assertEquals("/public/about", writer.toString()); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + URLTag freshTag = new URLTag(); + freshTag.setPerformClearTagStateForTagPoolingServers(true); + 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)); } @@ -591,7 +1186,29 @@ public class URLTagTest extends AbstractUITagTest { // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). URLTag freshTag = new URLTag(); freshTag.setPageContext(pageContext); - assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + 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 testNoActionIncludeGet_clearTagStateSet() throws Exception { + request.setRequestURI("/public/about"); + request.setQueryString("section=team&company=acme inc"); + + tag.setPerformClearTagStateForTagPoolingServers(true); // Explicitly request tag state clearing. + tag.setAction(null); + tag.setIncludeParams("get"); + tag.doStartTag(); + setComponentTagClearTagState(tag, true); // Ensure component tag state clearing is set true (to match tag). + tag.doEndTag(); + + assertEquals("/public/about?section=team&company=acme+inc", writer.toString()); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + URLTag freshTag = new URLTag(); + freshTag.setPerformClearTagStateForTagPoolingServers(true); + 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)); } @@ -620,14 +1237,56 @@ public class URLTagTest extends AbstractUITagTest { // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). ParamTag freshParamTag = new ParamTag(); freshParamTag.setPageContext(pageContext); - assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + 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(paramTag, freshParamTag)); // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). URLTag freshTag = new URLTag(); freshTag.setPageContext(pageContext); - assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + 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 testRequestURIActionIncludeAll_clearTagStateSet() throws Exception { + request.setRequestURI("/public/about"); + request.setQueryString("section=team&company=acme inc"); + + tag.setPerformClearTagStateForTagPoolingServers(true); // Explicitly request tag state clearing. + tag.setAction("team"); + tag.setIncludeParams("all"); + + tag.doStartTag(); + setComponentTagClearTagState(tag, true); // Ensure component tag state clearing is set true (to match tag). + + // include nested param tag + ParamTag paramTag = new ParamTag(); + paramTag.setPerformClearTagStateForTagPoolingServers(true); // Explicitly request tag state clearing. + paramTag.setPageContext(pageContext); + paramTag.setName("year"); + paramTag.setValue("2006"); + paramTag.doStartTag(); + setComponentTagClearTagState(paramTag, true); // Ensure component tag state clearing is set true (to match tag). + paramTag.doEndTag(); + + tag.doEndTag(); + + assertEquals("/team.action?section=team&company=acme+inc&year=2006", writer.toString()); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + ParamTag freshParamTag = new ParamTag(); + freshParamTag.setPerformClearTagStateForTagPoolingServers(true); + freshParamTag.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(paramTag, freshParamTag)); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + URLTag freshTag = new URLTag(); + freshTag.setPerformClearTagStateForTagPoolingServers(true); + 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)); } @@ -656,14 +1315,56 @@ public class URLTagTest extends AbstractUITagTest { // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). ParamTag freshParamTag = new ParamTag(); freshParamTag.setPageContext(pageContext); - assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + 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(paramTag, freshParamTag)); // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). URLTag freshTag = new URLTag(); freshTag.setPageContext(pageContext); - assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + 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 testRequestURINoActionIncludeAll_clearTagStateSet() throws Exception { + request.setRequestURI("/public/about"); + request.setQueryString("section=team&company=acme inc"); + + tag.setPerformClearTagStateForTagPoolingServers(true); // Explicitly request tag state clearing. + tag.setAction(null); + tag.setIncludeParams("all"); + + tag.doStartTag(); + setComponentTagClearTagState(tag, true); // Ensure component tag state clearing is set true (to match tag). + + // include nested param tag + ParamTag paramTag = new ParamTag(); + paramTag.setPerformClearTagStateForTagPoolingServers(true); // Explicitly request tag state clearing. + paramTag.setPageContext(pageContext); + paramTag.setName("year"); + paramTag.setValue("2006"); + paramTag.doStartTag(); + setComponentTagClearTagState(paramTag, true); // Ensure component tag state clearing is set true (to match tag). + paramTag.doEndTag(); + + tag.doEndTag(); + + assertEquals("/public/about?section=team&company=acme+inc&year=2006", writer.toString()); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + ParamTag freshParamTag = new ParamTag(); + freshParamTag.setPerformClearTagStateForTagPoolingServers(true); + freshParamTag.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(paramTag, freshParamTag)); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + URLTag freshTag = new URLTag(); + freshTag.setPerformClearTagStateForTagPoolingServers(true); + 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)); } @@ -680,7 +1381,27 @@ public class URLTagTest extends AbstractUITagTest { // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). URLTag freshTag = new URLTag(); freshTag.setPageContext(pageContext); - assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + 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 testUnknownIncludeParam_clearTagStateSet() throws Exception { + request.setRequestURI("/public/about"); + request.setQueryString("section=team"); + + tag.setPerformClearTagStateForTagPoolingServers(true); // Explicitly request tag state clearing. + tag.setIncludeParams("unknown"); // will log at WARN level + tag.doStartTag(); + setComponentTagClearTagState(tag, true); // Ensure component tag state clearing is set true (to match tag). + tag.doEndTag(); + assertEquals("/public/about", writer.toString()); // should not add any request parameters + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + URLTag freshTag = new URLTag(); + freshTag.setPerformClearTagStateForTagPoolingServers(true); + 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)); } @@ -699,7 +1420,29 @@ public class URLTagTest extends AbstractUITagTest { // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). URLTag freshTag = new URLTag(); freshTag.setPageContext(pageContext); - assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + 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 testRequestURIWithAnchor_clearTagStateSet() throws Exception { + request.setRequestURI("/public/about"); + request.setQueryString("company=acme inc#canada"); + + tag.setPerformClearTagStateForTagPoolingServers(true); // Explicitly request tag state clearing. + tag.setAction("company"); + tag.setIncludeParams("get"); + tag.doStartTag(); + setComponentTagClearTagState(tag, true); // Ensure component tag state clearing is set true (to match tag). + tag.doEndTag(); + + assertEquals("/company.action?company=acme+inc", writer.toString()); // will always chop anchor if using requestURI + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + URLTag freshTag = new URLTag(); + freshTag.setPerformClearTagStateForTagPoolingServers(true); + 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)); } @@ -717,7 +1460,28 @@ public class URLTagTest extends AbstractUITagTest { // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). URLTag freshTag = new URLTag(); freshTag.setPageContext(pageContext); - assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + 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 testIncludeContext_clearTagStateSet() throws Exception { + request.setupGetContext("/myapp"); + + tag.setPerformClearTagStateForTagPoolingServers(true); // Explicitly request tag state clearing. + tag.setIncludeContext("true"); + tag.setAction("company"); + tag.doStartTag(); + setComponentTagClearTagState(tag, true); // Ensure component tag state clearing is set true (to match tag). + tag.doEndTag(); + + assertEquals("/myapp/company.action", writer.toString()); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + URLTag freshTag = new URLTag(); + freshTag.setPerformClearTagStateForTagPoolingServers(true); + 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)); } @@ -733,11 +1497,30 @@ public class URLTagTest extends AbstractUITagTest { // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). URLTag freshTag = new URLTag(); freshTag.setPageContext(pageContext); - assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + 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 testForceAddSchemeHostAndPort_clearTagStateSet() throws Exception { + tag.setPerformClearTagStateForTagPoolingServers(true); // Explicitly request tag state clearing. + tag.setForceAddSchemeHostAndPort("true"); + tag.setAction("company"); + tag.doStartTag(); + setComponentTagClearTagState(tag, true); // Ensure component tag state clearing is set true (to match tag). + tag.doEndTag(); + + assertEquals("http://localhost/company.action", writer.toString()); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + URLTag freshTag = new URLTag(); + freshTag.setPerformClearTagStateForTagPoolingServers(true); + 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)); + } + public void testEmptyActionCustomMapper() throws Exception { Map props = new HashMap<>(); props.put("config", "struts-default.xml,struts-plugin.xml,struts.xml,org/apache/struts2/views/jsp/WW3090-struts.xml"); @@ -746,6 +1529,123 @@ public class URLTagTest extends AbstractUITagTest { Dispatcher du = this.initDispatcher(props); + /** + * create our standard mock objects + */ + action = this.getAction(); + stack = ActionContext.getContext().getValueStack(); + context = stack.getContext(); + stack.push(action); + + request = new StrutsMockHttpServletRequest(); + request.setAttribute(ServletActionContext.STRUTS_VALUESTACK_KEY, stack); + response = new StrutsMockHttpServletResponse(); + request.setSession(new StrutsMockHttpSession()); + request.setupGetServletPath("/"); + + writer = new StringWriter(); + + servletContext = new StrutsMockServletContext(); + servletContext.setRealPath(new File("nosuchfile.properties").getAbsolutePath()); + servletContext.setServletInfo("Resin"); + + pageContext = new StrutsMockPageContext(); + pageContext.setRequest(request); + pageContext.setResponse(response); + pageContext.setServletContext(servletContext); + + mockContainer = new Mock(Container.class); + + session = new SessionMap(request); + Map extraContext = du.createContextMap(new RequestMap(request), + HttpParameters.create(request.getParameterMap()).build(), + session, + new ApplicationMap(pageContext.getServletContext()), + request, + response); + // let's not set the locale -- there is a test that checks if Dispatcher actually picks this up... + // ... but generally we want to just use no locale (let it stay system default) + extraContext.remove(ActionContext.LOCALE); + stack.getContext().putAll(extraContext); + + context.put(ServletActionContext.HTTP_REQUEST, request); + context.put(ServletActionContext.HTTP_RESPONSE, response); + context.put(ServletActionContext.SERVLET_CONTEXT, servletContext); + + ActionContext.setContext(new ActionContext(context)); + + // Make sure we have an action invocation available + ActionContext.getContext().setActionInvocation(new DefaultActionInvocation(null, true)); + DefaultActionProxyFactory apFactory = new DefaultActionProxyFactory(); + apFactory.setContainer(container); + ActionProxy ap = apFactory.createActionProxy("/", "hello", null, null); + ActionContext.getContext().getActionInvocation().init(ap); + + request.setScheme("http"); + request.setServerName("localhost"); + request.setServerPort(80); + + tag = new URLTag(); + tag.setPageContext(pageContext); + JspWriter jspWriter = new StrutsMockJspWriter(writer); + pageContext.setJspWriter(jspWriter); + + request.setRequestURI("/context/someAction.action"); + + tag.setAction(null); + tag.setValue(null); + tag.doStartTag(); + tag.doEndTag(); + + assertEquals("/hello.action-red", writer.toString()); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + URLTag freshTag = new URLTag(); + freshTag.setPageContext(pageContext); + // URLTag clears component in doEndTag and has no additional state set here, so it compares as equal with the default tag clear state as well. + assertTrue("Tag state after doEndTag() under default tag clear state is inequal to new Tag with pageContext/parent set. " + + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", + strutsBodyTagsAreReflectionEqual(tag, freshTag)); + + writer = new StringWriter(); + jspWriter = new StrutsMockJspWriter(writer); + pageContext.setJspWriter(jspWriter); + + tag.doStartTag(); + tag.doEndTag(); + + assertEquals("/hello.action-blue", writer.toString()); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + // URLTag clears component in doEndTag and has no additional state set here, so it compares as equal with the default tag clear state as well. + assertTrue("Tag state after doEndTag() under default tag clear state is inequal to new Tag with pageContext/parent set. " + + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", + strutsBodyTagsAreReflectionEqual(tag, freshTag)); + + writer = new StringWriter(); + jspWriter = new StrutsMockJspWriter(writer); + pageContext.setJspWriter(jspWriter); + + tag.doStartTag(); + tag.doEndTag(); + + assertEquals("/hello.action-red", writer.toString()); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + // URLTag clears component in doEndTag and has no additional state set here, so it compares as equal with the default tag clear state as well. + assertTrue("Tag state after doEndTag() under default tag clear state is inequal to new Tag with pageContext/parent set. " + + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", + strutsBodyTagsAreReflectionEqual(tag, freshTag)); + } + + public void testEmptyActionCustomMapper_clearTagStateSet() throws Exception { + Map props = new HashMap(); + props.put("config", "struts-default.xml,struts-plugin.xml,struts.xml,org/apache/struts2/views/jsp/WW3090-struts.xml"); + + this.tearDown(); + + Dispatcher du = this.initDispatcher(props); + action = this.getAction(); stack = ActionContext.getContext().getValueStack(); context = stack.getContext(); @@ -800,6 +1700,7 @@ public class URLTagTest extends AbstractUITagTest { request.setServerPort(80); tag = new URLTag(); + tag.setPerformClearTagStateForTagPoolingServers(true); // Explicitly request tag state clearing. tag.setPageContext(pageContext); JspWriter jspWriter = new StrutsMockJspWriter(writer); pageContext.setJspWriter(jspWriter); @@ -809,14 +1710,16 @@ public class URLTagTest extends AbstractUITagTest { tag.setAction(null); tag.setValue(null); tag.doStartTag(); + setComponentTagClearTagState(tag, true); // Ensure component tag state clearing is set true (to match tag). tag.doEndTag(); assertEquals("/hello.action-red", writer.toString()); // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). URLTag freshTag = new URLTag(); + freshTag.setPerformClearTagStateForTagPoolingServers(true); freshTag.setPageContext(pageContext); - assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + 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)); @@ -825,13 +1728,13 @@ public class URLTagTest extends AbstractUITagTest { pageContext.setJspWriter(jspWriter); tag.doStartTag(); + setComponentTagClearTagState(tag, true); // Ensure component tag state clearing is set true (to match tag). tag.doEndTag(); assertEquals("/hello.action-blue", writer.toString()); // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). - freshTag.setPageContext(pageContext); - assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + 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)); @@ -840,13 +1743,13 @@ public class URLTagTest extends AbstractUITagTest { pageContext.setJspWriter(jspWriter); tag.doStartTag(); + setComponentTagClearTagState(tag, true); // Ensure component tag state clearing is set true (to match tag). tag.doEndTag(); assertEquals("/hello.action-red", writer.toString()); // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). - freshTag.setPageContext(pageContext); - assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + 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)); } @@ -878,14 +1781,59 @@ public class URLTagTest extends AbstractUITagTest { // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). ParamTag freshParamTag = new ParamTag(); freshParamTag.setPageContext(pageContext); - assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + 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(paramTag, freshParamTag)); // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). URLTag freshTag = new URLTag(); freshTag.setPageContext(pageContext); - assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + 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 testEmbeddedParamTagExpressionGetsEvaluatedCorrectly_clearTagStateSet() throws Exception { + request.setRequestURI("/public/about"); + request.setQueryString("section=team&company=acme inc"); + + tag.setPerformClearTagStateForTagPoolingServers(true); // Explicitly request tag state clearing. + tag.setAction("team"); + tag.setIncludeParams("all"); + + tag.doStartTag(); + setComponentTagClearTagState(tag, true); // Ensure component tag state clearing is set true (to match tag). + + Foo foo = new Foo("test"); + stack.push(foo); + + // include nested param tag + ParamTag paramTag = new ParamTag(); + paramTag.setPerformClearTagStateForTagPoolingServers(true); // Explicitly request tag state clearing. + paramTag.setPageContext(pageContext); + paramTag.setName("title"); + paramTag.setValue("%{title}"); + paramTag.doStartTag(); + setComponentTagClearTagState(paramTag, true); // Ensure component tag state clearing is set true (to match tag). + paramTag.doEndTag(); + + tag.doEndTag(); + + assertEquals("/team.action?section=team&company=acme+inc&title=test", writer.toString()); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + ParamTag freshParamTag = new ParamTag(); + freshParamTag.setPerformClearTagStateForTagPoolingServers(true); + freshParamTag.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(paramTag, freshParamTag)); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + URLTag freshTag = new URLTag(); + freshTag.setPerformClearTagStateForTagPoolingServers(true); + 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)); } @@ -928,7 +1876,53 @@ public class URLTagTest extends AbstractUITagTest { // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). URLTag freshTag = new URLTag(); freshTag.setPageContext(pageContext); - assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + 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 testAccessToStackInternalsGetsHandledCorrectly_clearTagStateSet() throws Exception { + Map params = new LinkedHashMap<>(); + params.put("aaa", new String[] {"1${#session[\"foo\"]='true'}"}); + params.put("aab", new String[]{"1${#session[\"bar\"]}"}); + params.put("aac", new String[]{"1${#_memberAccess[\"allowStaticMethodAccess\"]='true'}"}); + params.put("aad", new String[]{"1${#_memberAccess[\"allowStaticMethodAccess\"]}"}); + + request.setParameterMap(params); + request.setRequestURI("/public/about"); + request.setQueryString("aae${%23session[\"bar\"]}=1%24%7B%23session%5B%22bar%22%5D%7D"); + session.put("bar", "rab"); + + tag.setPerformClearTagStateForTagPoolingServers(true); // Explicitly request tag state clearing. + tag.setAction("team"); + tag.setIncludeParams("all"); + + tag.doStartTag(); + setComponentTagClearTagState(tag, true); // Ensure component tag state clearing is set true (to match tag). + tag.doEndTag(); + + Object allowMethodAccess = stack.findValue("\u0023_memberAccess['allowStaticMethodAccess']"); + assertNull(allowMethodAccess); + + assertNull(session.get("foo")); + + assertEquals("/team.action?aaa=1%24%7B%23session%5B%22foo%22%5D%3D%27true%27%7D" + + "&" + + "aab=1%24%7B%23session%5B%22bar%22%5D%7D" + + "&" + + "aac=1%24%7B%23_memberAccess%5B%22allowStaticMethodAccess%22%5D%3D%27true%27%7D" + + "&" + + "aad=1%24%7B%23_memberAccess%5B%22allowStaticMethodAccess%22%5D%7D" + + "&" + + "aae%24%7B%23session%5B%22bar%22%5D%7D=1%24%7B%23session%5B%22bar%22%5D%7D" + , writer.toString() + ); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + URLTag freshTag = new URLTag(); + freshTag.setPerformClearTagStateForTagPoolingServers(true); + 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)); } @@ -990,27 +1984,118 @@ public class URLTagTest extends AbstractUITagTest { // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). ParamTag freshParamTag = new ParamTag(); freshParamTag.setPageContext(pageContext); - assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + 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(param1, freshParamTag)); - assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + 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(param2, freshParamTag)); - assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + 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(param3, freshParamTag)); - assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + 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(param4, freshParamTag)); // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). URLTag freshTag = new URLTag(); freshTag.setPageContext(pageContext); - assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + 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 testIncludeEmptyParameters_clearTagStateSet() throws Exception { + request.setRequestURI("/public/about"); + + tag.setPerformClearTagStateForTagPoolingServers(true); // Explicitly request tag state clearing. + tag.setAction("company"); + tag.setEscapeAmp("false"); + + tag.doStartTag(); + setComponentTagClearTagState(tag, true); // Ensure component tag state clearing is set true (to match tag). + + ParamTag param1 = new ParamTag(); + param1.setPerformClearTagStateForTagPoolingServers(true); // Explicitly request tag state clearing. + param1.setPageContext(pageContext); + param1.setName("paramWithSetValue"); + param1.setValue(""); + param1.setSuppressEmptyParameters(false); + param1.doStartTag(); + setComponentTagClearTagState(param1, true); // Ensure component tag state clearing is set true (to match tag). + param1.doEndTag(); + + ParamTag param2 = new ParamTag(); + param2.setPerformClearTagStateForTagPoolingServers(true); // Explicitly request tag state clearing. + param2.setPageContext(pageContext); + param2.setName("paramWithSetBody"); + param2.setBodyContent(new MockBodyContent() { + @Override + public String getString() { + return ""; + } + }); + param2.setSuppressEmptyParameters(false); + param2.doStartTag(); + setComponentTagClearTagState(param2, true); // Ensure component tag state clearing is set true (to match tag). + param2.doEndTag(); + + ParamTag param3 = new ParamTag(); + param3.setPerformClearTagStateForTagPoolingServers(true); // Explicitly request tag state clearing. + param3.setPageContext(pageContext); + param3.setName("paramWithSetValueSuppressed"); + param3.setValue(""); + param3.setSuppressEmptyParameters(true); + param3.doStartTag(); + setComponentTagClearTagState(param3, true); // Ensure component tag state clearing is set true (to match tag). + param3.doEndTag(); + + ParamTag param4 = new ParamTag(); + param4.setPerformClearTagStateForTagPoolingServers(true); // Explicitly request tag state clearing. + param4.setPageContext(pageContext); + param4.setName("paramWithSetBodySuppressed"); + param4.setBodyContent(new MockBodyContent() { + @Override + public String getString() { + return ""; + } + }); + param4.setSuppressEmptyParameters(true); + param4.doStartTag(); + setComponentTagClearTagState(param4, true); // Ensure component tag state clearing is set true (to match tag). + param4.doEndTag(); + + tag.doEndTag(); + + assertEquals("/company.action?paramWithSetValue=¶mWithSetBody=", writer.toString()); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + ParamTag freshParamTag = new ParamTag(); + freshParamTag.setPerformClearTagStateForTagPoolingServers(true); + freshParamTag.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(param1, freshParamTag)); + 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(param2, freshParamTag)); + 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(param3, freshParamTag)); + 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(param4, freshParamTag)); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + URLTag freshTag = new URLTag(); + freshTag.setPerformClearTagStateForTagPoolingServers(true); + 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)); + } + + @Override protected void setUp() throws Exception { super.setUp(); diff --git a/core/src/test/java/org/apache/struts2/views/jsp/ui/ActionErrorTagTest.java b/core/src/test/java/org/apache/struts2/views/jsp/ui/ActionErrorTagTest.java index f0bdcbc7f..418533986 100644 --- a/core/src/test/java/org/apache/struts2/views/jsp/ui/ActionErrorTagTest.java +++ b/core/src/test/java/org/apache/struts2/views/jsp/ui/ActionErrorTagTest.java @@ -49,7 +49,29 @@ public class ActionErrorTagTest extends AbstractUITagTest { // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). ActionErrorTag freshTag = new ActionErrorTag(); freshTag.setPageContext(pageContext); - assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + // AcionErrorTag has no additional state set here, so it compares as equal with the default tag clear state as well. + assertTrue("Tag state after doEndTag() under default tag clear state is inequal to new Tag with pageContext/parent set. " + + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", + strutsBodyTagsAreReflectionEqual(tag, freshTag)); + } + + public void testNoActionErrors_clearTagStateSet() throws Exception { + ActionErrorTag tag = new ActionErrorTag(); + ((InternalActionSupport)action).setHasActionErrors(false); + tag.setPerformClearTagStateForTagPoolingServers(true); // Explicitly request tag state clearing. + tag.setPageContext(pageContext); + tag.doStartTag(); + setComponentTagClearTagState(tag, true); // Ensure component tag state clearing is set true (to match tag). + tag.doEndTag(); + + //assertEquals("", writer.toString()); + verify(ActionErrorTagTest.class.getResource("actionerror-1.txt")); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + ActionErrorTag freshTag = new ActionErrorTag(); + freshTag.setPerformClearTagStateForTagPoolingServers(true); + 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)); } @@ -72,7 +94,34 @@ public class ActionErrorTagTest extends AbstractUITagTest { // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). ActionErrorTag freshTag = new ActionErrorTag(); freshTag.setPageContext(pageContext); - assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + // AcionErrorTag sets escape true by default and has no additional state set here, so it compares as equal with the default tag clear state as well. + assertTrue("Tag state after doEndTag() under default tag clear state is inequal to new Tag with pageContext/parent set. " + + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", + strutsBodyTagsAreReflectionEqual(tag, freshTag)); + } + + public void testActionErrorsEscape_clearTagStateSet() throws Exception { + + ActionErrorTag tag = new ActionErrorTag(); + TestAction testAction = new TestAction(); + testAction.addActionError("

hey

"); + stack.pop(); + stack.push(testAction); + tag.setPerformClearTagStateForTagPoolingServers(true); // Explicitly request tag state clearing. + tag.setEscape(true); + tag.setPageContext(pageContext); + tag.doStartTag(); + setComponentTagClearTagState(tag, true); // Ensure component tag state clearing is set true (to match tag). + tag.doEndTag(); + + assertEquals(normalize("
  • <p>hey</p>
", true), + normalize(writer.toString(), true)); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + ActionErrorTag freshTag = new ActionErrorTag(); + freshTag.setPerformClearTagStateForTagPoolingServers(true); + 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)); } @@ -95,7 +144,33 @@ public class ActionErrorTagTest extends AbstractUITagTest { // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). ActionErrorTag freshTag = new ActionErrorTag(); freshTag.setPageContext(pageContext); - assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + 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 testActionErrorsDontEscape_clearTagStateSet() throws Exception { + + ActionErrorTag tag = new ActionErrorTag(); + TestAction testAction = new TestAction(); + testAction.addActionError("

hey

"); + stack.pop(); + stack.push(testAction); + tag.setPerformClearTagStateForTagPoolingServers(true); // Explicitly request tag state clearing. + tag.setEscape(false); + tag.setPageContext(pageContext); + tag.doStartTag(); + setComponentTagClearTagState(tag, true); // Ensure component tag state clearing is set true (to match tag). + tag.doEndTag(); + + assertEquals(normalize("
  • hey

", true), + normalize(writer.toString(), true)); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + ActionErrorTag freshTag = new ActionErrorTag(); + freshTag.setPerformClearTagStateForTagPoolingServers(true); + 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)); } @@ -114,7 +189,29 @@ public class ActionErrorTagTest extends AbstractUITagTest { // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). ActionErrorTag freshTag = new ActionErrorTag(); freshTag.setPageContext(pageContext); - assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + 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 testHaveActionErrors_clearTagStateSet() throws Exception { + + ActionErrorTag tag = new ActionErrorTag(); + tag.setPerformClearTagStateForTagPoolingServers(true); // Explicitly request tag state clearing. + tag.setId("someid"); + ((InternalActionSupport)action).setHasActionErrors(true); + tag.setPageContext(pageContext); + tag.doStartTag(); + setComponentTagClearTagState(tag, true); // Ensure component tag state clearing is set true (to match tag). + tag.doEndTag(); + + verify(ActionErrorTagTest.class.getResource("actionerror-2.txt")); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + ActionErrorTag freshTag = new ActionErrorTag(); + freshTag.setPerformClearTagStateForTagPoolingServers(true); + 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)); } @@ -134,7 +231,30 @@ public class ActionErrorTagTest extends AbstractUITagTest { // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). ActionErrorTag freshTag = new ActionErrorTag(); freshTag.setPageContext(pageContext); - assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + 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 testNullError_clearTagStateSet() throws Exception { + + ActionErrorTag tag = new ActionErrorTag(); + tag.setPerformClearTagStateForTagPoolingServers(true); // Explicitly request tag state clearing. + tag.setId("someid"); + ((InternalActionSupport)action).setHasActionErrors(true); + ((InternalActionSupport)action).addActionError(null); + tag.setPageContext(pageContext); + tag.doStartTag(); + setComponentTagClearTagState(tag, true); // Ensure component tag state clearing is set true (to match tag). + tag.doEndTag(); + + verify(ActionErrorTagTest.class.getResource("actionerror-2.txt")); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + ActionErrorTag freshTag = new ActionErrorTag(); + freshTag.setPerformClearTagStateForTagPoolingServers(true); + 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)); } @@ -154,11 +274,33 @@ public class ActionErrorTagTest extends AbstractUITagTest { // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). ActionErrorTag freshTag = new ActionErrorTag(); freshTag.setPageContext(pageContext); - assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + 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 testEmptyErrorList_clearTagStateSet() throws Exception { + + ActionErrorTag tag = new ActionErrorTag(); + tag.setPerformClearTagStateForTagPoolingServers(true); // Explicitly request tag state clearing. + tag.setId("someid"); + ((InternalActionSupport)action).setHasActionErrors(true); + ((InternalActionSupport)action).setJustNullElement(true); + tag.setPageContext(pageContext); + tag.doStartTag(); + setComponentTagClearTagState(tag, true); // Ensure component tag state clearing is set true (to match tag). + tag.doEndTag(); + + assertTrue(StringUtils.isBlank(writer.toString())); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + ActionErrorTag freshTag = new ActionErrorTag(); + freshTag.setPerformClearTagStateForTagPoolingServers(true); + 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)); + } @Override public Action getAction() { diff --git a/core/src/test/java/org/apache/struts2/views/jsp/ui/ActionMessageTagTest.java b/core/src/test/java/org/apache/struts2/views/jsp/ui/ActionMessageTagTest.java index 8819db8bf..776880c82 100644 --- a/core/src/test/java/org/apache/struts2/views/jsp/ui/ActionMessageTagTest.java +++ b/core/src/test/java/org/apache/struts2/views/jsp/ui/ActionMessageTagTest.java @@ -49,7 +49,29 @@ public class ActionMessageTagTest extends AbstractUITagTest { // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). ActionMessageTag freshTag = new ActionMessageTag(); freshTag.setPageContext(pageContext); - assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + // AcionMessageTag has no additional state set here, so it compares as equal with the default tag clear state as well. + assertTrue("Tag state after doEndTag() under default tag clear state is inequal to new Tag with pageContext/parent set. " + + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", + strutsBodyTagsAreReflectionEqual(tag, freshTag)); + } + + public void testNoActionMessages_clearTagStateSet() throws Exception { + + ActionMessageTag tag = new ActionMessageTag(); + ((InternalActionSupport)action).setHasActionMessage(false); + tag.setPerformClearTagStateForTagPoolingServers(true); // Explicitly request tag state clearing. + tag.setPageContext(pageContext); + tag.doStartTag(); + setComponentTagClearTagState(tag, true); // Ensure component tag state clearing is set true (to match tag). + tag.doEndTag(); + + verify(ActionMessageTagTest.class.getResource("actionmessage-1.txt")); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + ActionMessageTag freshTag = new ActionMessageTag(); + freshTag.setPerformClearTagStateForTagPoolingServers(true); + 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)); } @@ -72,7 +94,34 @@ public class ActionMessageTagTest extends AbstractUITagTest { // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). ActionMessageTag freshTag = new ActionMessageTag(); freshTag.setPageContext(pageContext); - assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + // AcionMessageTag sets escape true by default and has no additional state set here, so it compares as equal with the default tag clear state as well. + assertTrue("Tag state after doEndTag() under default tag clear state is inequal to new Tag with pageContext/parent set. " + + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", + strutsBodyTagsAreReflectionEqual(tag, freshTag)); + } + + public void testActionMessageEscape_clearTagStateSet() throws Exception { + + ActionMessageTag tag = new ActionMessageTag(); + TestAction testAction = new TestAction(); + testAction.addActionMessage("

hey

"); + stack.pop(); + stack.push(testAction); + tag.setPerformClearTagStateForTagPoolingServers(true); // Explicitly request tag state clearing. + tag.setEscape(true); + tag.setPageContext(pageContext); + tag.doStartTag(); + setComponentTagClearTagState(tag, true); // Ensure component tag state clearing is set true (to match tag). + tag.doEndTag(); + + assertEquals(normalize("
  • <p>hey</p>
", true), + normalize(writer.toString(), true)); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + ActionMessageTag freshTag = new ActionMessageTag(); + freshTag.setPerformClearTagStateForTagPoolingServers(true); + 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)); } @@ -95,11 +144,36 @@ public class ActionMessageTagTest extends AbstractUITagTest { // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). ActionMessageTag freshTag = new ActionMessageTag(); freshTag.setPageContext(pageContext); - assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + 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 testActionErrorsDontEscape_clearTagStateSet() throws Exception { + + ActionMessageTag tag = new ActionMessageTag(); + TestAction testAction = new TestAction(); + testAction.addActionMessage("

hey

"); + stack.pop(); + stack.push(testAction); + tag.setPerformClearTagStateForTagPoolingServers(true); // Explicitly request tag state clearing. + tag.setEscape(false); + tag.setPageContext(pageContext); + tag.doStartTag(); + setComponentTagClearTagState(tag, true); // Ensure component tag state clearing is set true (to match tag). + tag.doEndTag(); + + assertEquals(normalize("
  • hey

", true), + normalize(writer.toString(), true)); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + ActionMessageTag freshTag = new ActionMessageTag(); + freshTag.setPerformClearTagStateForTagPoolingServers(true); + 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)); + } public void testYesActionMessages() throws Exception { @@ -115,7 +189,29 @@ public class ActionMessageTagTest extends AbstractUITagTest { // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). ActionMessageTag freshTag = new ActionMessageTag(); freshTag.setPageContext(pageContext); - assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + 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 testYesActionMessages_clearTagStateSet() throws Exception { + + ActionMessageTag tag = new ActionMessageTag(); + tag.setPerformClearTagStateForTagPoolingServers(true); // Explicitly request tag state clearing. + tag.setId("someid"); + ((InternalActionSupport)action).setHasActionMessage(true); + tag.setPageContext(pageContext); + tag.doStartTag(); + setComponentTagClearTagState(tag, true); // Ensure component tag state clearing is set true (to match tag). + tag.doEndTag(); + + verify(ActionMessageTagTest.class.getResource("actionmessage-2.txt")); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + ActionMessageTag freshTag = new ActionMessageTag(); + freshTag.setPerformClearTagStateForTagPoolingServers(true); + 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)); } @@ -135,7 +231,30 @@ public class ActionMessageTagTest extends AbstractUITagTest { // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). ActionMessageTag freshTag = new ActionMessageTag(); freshTag.setPageContext(pageContext); - assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + 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 testYesActionMessagesWithEmptyMessages_clearTagStateSet() throws Exception { + + ActionMessageTag tag = new ActionMessageTag(); + tag.setId("someid"); + InternalActionSupport internalActionSupport = (InternalActionSupport) action; + internalActionSupport.setJustNullElement(true); + tag.setPerformClearTagStateForTagPoolingServers(true); // Explicitly request tag state clearing. + tag.setPageContext(pageContext); + tag.doStartTag(); + setComponentTagClearTagState(tag, true); // Ensure component tag state clearing is set true (to match tag). + tag.doEndTag(); + + assertTrue(StringUtils.isBlank(writer.toString())); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + ActionMessageTag freshTag = new ActionMessageTag(); + freshTag.setPerformClearTagStateForTagPoolingServers(true); + 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)); } @@ -155,7 +274,30 @@ public class ActionMessageTagTest extends AbstractUITagTest { // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). ActionMessageTag freshTag = new ActionMessageTag(); freshTag.setPageContext(pageContext); - assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + 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 testNullMessage_clearTagStateSet() throws Exception { + + ActionMessageTag tag = new ActionMessageTag(); + tag.setPerformClearTagStateForTagPoolingServers(true); // Explicitly request tag state clearing. + tag.setId("someid"); + ((InternalActionSupport)action).setHasActionMessage(true); + ((InternalActionSupport)action).addActionMessage(null); + tag.setPageContext(pageContext); + tag.doStartTag(); + setComponentTagClearTagState(tag, true); // Ensure component tag state clearing is set true (to match tag). + tag.doEndTag(); + + verify(ActionMessageTagTest.class.getResource("actionmessage-2.txt")); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + ActionMessageTag freshTag = new ActionMessageTag(); + freshTag.setPerformClearTagStateForTagPoolingServers(true); + 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)); } diff --git a/core/src/test/java/org/apache/struts2/views/jsp/ui/AnchorTest.java b/core/src/test/java/org/apache/struts2/views/jsp/ui/AnchorTest.java index 25bc1e549..8101cc8a1 100644 --- a/core/src/test/java/org/apache/struts2/views/jsp/ui/AnchorTest.java +++ b/core/src/test/java/org/apache/struts2/views/jsp/ui/AnchorTest.java @@ -51,7 +51,28 @@ public class AnchorTest extends AbstractUITagTest { // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). AnchorTag freshTag = new AnchorTag(); freshTag.setPageContext(pageContext); - assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + 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 testSimple_clearTagStateSet() throws Exception { + createAction(); + + AnchorTag tag = createTag(); + tag.setPerformClearTagStateForTagPoolingServers(true); // Explicitly request tag state clearing. + tag.setHref("a"); + tag.doStartTag(); + setComponentTagClearTagState(tag, true); // Ensure component tag state clearing is set true (to match tag). + tag.doEndTag(); + + verifyResource("href-1.txt"); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + AnchorTag freshTag = new AnchorTag(); + freshTag.setPerformClearTagStateForTagPoolingServers(true); + 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)); } @@ -69,7 +90,28 @@ public class AnchorTest extends AbstractUITagTest { // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). AnchorTag freshTag = new AnchorTag(); freshTag.setPageContext(pageContext); - assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + 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 testSimpleBadQuote_clearTagStateSet() throws Exception { + createAction(); + + AnchorTag tag = createTag(); + tag.setPerformClearTagStateForTagPoolingServers(true); // Explicitly request tag state clearing. + tag.setHref("a\""); + tag.doStartTag(); + setComponentTagClearTagState(tag, true); // Ensure component tag state clearing is set true (to match tag). + tag.doEndTag(); + + verifyResource("href-2.txt"); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + AnchorTag freshTag = new AnchorTag(); + freshTag.setPerformClearTagStateForTagPoolingServers(true); + 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)); } @@ -90,7 +132,31 @@ public class AnchorTest extends AbstractUITagTest { // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). AnchorTag freshTag = new AnchorTag(); freshTag.setPageContext(pageContext); - assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + 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 testDynamicAttribute_clearTagStateSet() throws Exception { + createAction(); + + AnchorTag tag = createTag(); + tag.setPerformClearTagStateForTagPoolingServers(true); // Explicitly request tag state clearing. + tag.setHref("a"); + + tag.setDynamicAttribute("uri", "dynAttrName", "dynAttrValue"); + + tag.doStartTag(); + setComponentTagClearTagState(tag, true); // Ensure component tag state clearing is set true (to match tag). + tag.doEndTag(); + + verifyResource("Anchor-2.txt"); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + AnchorTag freshTag = new AnchorTag(); + freshTag.setPerformClearTagStateForTagPoolingServers(true); + 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)); } @@ -111,7 +177,31 @@ public class AnchorTest extends AbstractUITagTest { // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). AnchorTag freshTag = new AnchorTag(); freshTag.setPageContext(pageContext); - assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + 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 testDynamicAttributeAsExpression_clearTagStateSet() throws Exception { + createAction(); + + AnchorTag tag = createTag(); + tag.setPerformClearTagStateForTagPoolingServers(true); // Explicitly request tag state clearing. + tag.setHref("a"); + + tag.setDynamicAttribute("uri", "placeholder", "%{foo}"); + + tag.doStartTag(); + setComponentTagClearTagState(tag, true); // Ensure component tag state clearing is set true (to match tag). + tag.doEndTag(); + + verifyResource("Anchor-3.txt"); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + AnchorTag freshTag = new AnchorTag(); + freshTag.setPerformClearTagStateForTagPoolingServers(true); + 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)); } diff --git a/core/src/test/java/org/apache/struts2/views/jsp/ui/CheckboxListTest.java b/core/src/test/java/org/apache/struts2/views/jsp/ui/CheckboxListTest.java index dcc964c20..0ea404aa1 100644 --- a/core/src/test/java/org/apache/struts2/views/jsp/ui/CheckboxListTest.java +++ b/core/src/test/java/org/apache/struts2/views/jsp/ui/CheckboxListTest.java @@ -103,7 +103,43 @@ public class CheckboxListTest extends AbstractUITagTest { // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). CheckboxListTag freshTag = new CheckboxListTag(); freshTag.setPageContext(pageContext); - assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + 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 testMultiple_clearTagStateSet() throws Exception { + TestAction testAction = (TestAction) action; + Collection collection = new ArrayList(2); + collection.add("hello"); + collection.add("foo"); + testAction.setCollection(collection); + testAction.setList(new String[][]{ + {"hello", "world"}, + {"foo", "bar"}, + {"cat", "dog"} + }); + + CheckboxListTag tag = new CheckboxListTag(); + tag.setPerformClearTagStateForTagPoolingServers(true); // Explicitly request tag state clearing. + tag.setPageContext(pageContext); + tag.setLabel("mylabel"); + tag.setName("collection"); + tag.setList("list"); + tag.setListKey("top[0]"); + tag.setListValue("top[1]"); + + tag.doStartTag(); + setComponentTagClearTagState(tag, true); // Ensure component tag state clearing is set true (to match tag). + tag.doEndTag(); + + verify(CheckboxListTag.class.getResource("CheckboxList-2.txt")); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + CheckboxListTag freshTag = new CheckboxListTag(); + freshTag.setPerformClearTagStateForTagPoolingServers(true); + 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)); } @@ -137,7 +173,44 @@ public class CheckboxListTest extends AbstractUITagTest { // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). CheckboxListTag freshTag = new CheckboxListTag(); freshTag.setPageContext(pageContext); - assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + 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 testMultipleWithDisabledOn_clearTagStateSet() throws Exception { + TestAction testAction = (TestAction) action; + Collection collection = new ArrayList(2); + collection.add("hello"); + collection.add("foo"); + testAction.setCollection(collection); + testAction.setList(new String[][]{ + {"hello", "world"}, + {"foo", "bar"}, + {"cat", "dog"} + }); + + CheckboxListTag tag = new CheckboxListTag(); + tag.setPerformClearTagStateForTagPoolingServers(true); // Explicitly request tag state clearing. + tag.setPageContext(pageContext); + tag.setLabel("mylabel"); + tag.setName("collection"); + tag.setList("list"); + tag.setListKey("top[0]"); + tag.setListValue("top[1]"); + tag.setDisabled("true"); + + tag.doStartTag(); + setComponentTagClearTagState(tag, true); // Ensure component tag state clearing is set true (to match tag). + tag.doEndTag(); + + verify(CheckboxListTag.class.getResource("CheckboxList-3.txt")); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + CheckboxListTag freshTag = new CheckboxListTag(); + freshTag.setPerformClearTagStateForTagPoolingServers(true); + 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)); } @@ -169,7 +242,42 @@ public class CheckboxListTest extends AbstractUITagTest { // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). CheckboxListTag freshTag = new CheckboxListTag(); freshTag.setPageContext(pageContext); - assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + 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 testSimple_clearTagStateSet() throws Exception { + TestAction testAction = (TestAction) action; + testAction.setFoo("hello"); + testAction.setList(new String[][]{ + {"hello", "world"}, + {"foo", "bar"}, + {"baz", null} + }); + + CheckboxListTag tag = new CheckboxListTag(); + tag.setPerformClearTagStateForTagPoolingServers(true); // Explicitly request tag state clearing. + tag.setPageContext(pageContext); + tag.setLabel("mylabel"); + tag.setName("foo"); + tag.setList("list"); + tag.setListKey("top[0]"); + tag.setListValue("top[1]"); + tag.setOnchange("alert('foo');"); + tag.setTitle("mytitle"); + + tag.doStartTag(); + setComponentTagClearTagState(tag, true); // Ensure component tag state clearing is set true (to match tag). + tag.doEndTag(); + + verify(CheckboxListTag.class.getResource("CheckboxList-1.txt")); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + CheckboxListTag freshTag = new CheckboxListTag(); + freshTag.setPerformClearTagStateForTagPoolingServers(true); + 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)); } @@ -200,7 +308,41 @@ public class CheckboxListTest extends AbstractUITagTest { // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). CheckboxListTag freshTag = new CheckboxListTag(); freshTag.setPageContext(pageContext); - assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + 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 testSimpleWithDisableOn_clearTagStateSet() throws Exception { + TestAction testAction = (TestAction) action; + testAction.setFoo("hello"); + testAction.setList(new String[][]{ + {"hello", "world"}, + {"foo", "bar"} + }); + + CheckboxListTag tag = new CheckboxListTag(); + tag.setPerformClearTagStateForTagPoolingServers(true); // Explicitly request tag state clearing. + tag.setPageContext(pageContext); + tag.setLabel("mylabel"); + tag.setName("foo"); + tag.setList("list"); + tag.setListKey("top[0]"); + tag.setListValue("top[1]"); + tag.setOnchange("alert('foo');"); + tag.setDisabled("true"); + + tag.doStartTag(); + setComponentTagClearTagState(tag, true); // Ensure component tag state clearing is set true (to match tag). + tag.doEndTag(); + + verify(CheckboxListTag.class.getResource("CheckboxList-4.txt")); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + CheckboxListTag freshTag = new CheckboxListTag(); + freshTag.setPerformClearTagStateForTagPoolingServers(true); + 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)); } diff --git a/core/src/test/java/org/apache/struts2/views/jsp/ui/CheckboxTest.java b/core/src/test/java/org/apache/struts2/views/jsp/ui/CheckboxTest.java index ac507ac52..778fb19f4 100644 --- a/core/src/test/java/org/apache/struts2/views/jsp/ui/CheckboxTest.java +++ b/core/src/test/java/org/apache/struts2/views/jsp/ui/CheckboxTest.java @@ -77,7 +77,36 @@ public class CheckboxTest extends AbstractUITagTest { // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). CheckboxTag freshTag = new CheckboxTag(); freshTag.setPageContext(pageContext); - assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + 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 testChecked_clearTagStateSet() throws Exception { + TestAction testAction = (TestAction) action; + testAction.setFoo("true"); + + CheckboxTag tag = new CheckboxTag(); + tag.setPerformClearTagStateForTagPoolingServers(true); // Explicitly request tag state clearing. + tag.setPageContext(pageContext); + tag.setId("someId"); + tag.setLabel("mylabel"); + tag.setName("foo"); + tag.setFieldValue("baz"); + tag.setOnfocus("test();"); + tag.setTitle("mytitle"); + + tag.doStartTag(); + setComponentTagClearTagState(tag, true); // Ensure component tag state clearing is set true (to match tag). + tag.doEndTag(); + + verify(CheckboxTag.class.getResource("Checkbox-1.txt")); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + CheckboxTag freshTag = new CheckboxTag(); + freshTag.setPerformClearTagStateForTagPoolingServers(true); + 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)); } @@ -104,7 +133,37 @@ public class CheckboxTest extends AbstractUITagTest { // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). CheckboxTag freshTag = new CheckboxTag(); freshTag.setPageContext(pageContext); - assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + 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 testCheckedWithTopLabelPosition_clearTagStateSet() throws Exception { + TestAction testAction = (TestAction) action; + testAction.setFoo("true"); + + CheckboxTag tag = new CheckboxTag(); + tag.setPerformClearTagStateForTagPoolingServers(true); // Explicitly request tag state clearing. + tag.setPageContext(pageContext); + tag.setId("someId"); + tag.setLabel("mylabel"); + tag.setName("foo"); + tag.setFieldValue("baz"); + tag.setOnfocus("test();"); + tag.setTitle("mytitle"); + tag.setLabelposition("top"); + + tag.doStartTag(); + setComponentTagClearTagState(tag, true); // Ensure component tag state clearing is set true (to match tag). + tag.doEndTag(); + + verify(CheckboxTag.class.getResource("Checkbox-4.txt")); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + CheckboxTag freshTag = new CheckboxTag(); + freshTag.setPerformClearTagStateForTagPoolingServers(true); + 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)); } @@ -131,7 +190,37 @@ public class CheckboxTest extends AbstractUITagTest { // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). CheckboxTag freshTag = new CheckboxTag(); freshTag.setPageContext(pageContext); - assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + 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 testCheckedWithLeftLabelPosition_clearTagStateSet() throws Exception { + TestAction testAction = (TestAction) action; + testAction.setFoo("true"); + + CheckboxTag tag = new CheckboxTag(); + tag.setPerformClearTagStateForTagPoolingServers(true); // Explicitly request tag state clearing. + tag.setPageContext(pageContext); + tag.setId("someId"); + tag.setLabel("mylabel"); + tag.setName("foo"); + tag.setFieldValue("baz"); + tag.setOnfocus("test();"); + tag.setTitle("mytitle"); + tag.setLabelposition("left"); + + tag.doStartTag(); + setComponentTagClearTagState(tag, true); // Ensure component tag state clearing is set true (to match tag). + tag.doEndTag(); + + verify(CheckboxTag.class.getResource("Checkbox-5.txt")); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + CheckboxTag freshTag = new CheckboxTag(); + freshTag.setPerformClearTagStateForTagPoolingServers(true); + 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)); } @@ -160,7 +249,39 @@ public class CheckboxTest extends AbstractUITagTest { // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). CheckboxTag freshTag = new CheckboxTag(); freshTag.setPageContext(pageContext); - assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + 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 testCheckedWithError_clearTagStateSet() throws Exception { + TestAction testAction = (TestAction) action; + testAction.setFoo("true"); + testAction.addFieldError("foo", "Some Foo Error"); + testAction.addFieldError("foo", "Another Foo Error"); + + CheckboxTag tag = new CheckboxTag(); + tag.setPerformClearTagStateForTagPoolingServers(true); // Explicitly request tag state clearing. + tag.setPageContext(pageContext); + tag.setLabel("mylabel"); + tag.setName("foo"); + tag.setFieldValue("baz"); + tag.setOndblclick("test();"); + tag.setOnclick("test();"); + tag.setTitle("mytitle"); + tag.setCssErrorClass("myErrorClass"); + + tag.doStartTag(); + setComponentTagClearTagState(tag, true); // Ensure component tag state clearing is set true (to match tag). + tag.doEndTag(); + + verify(CheckboxTag.class.getResource("Checkbox-3.txt")); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + CheckboxTag freshTag = new CheckboxTag(); + freshTag.setPerformClearTagStateForTagPoolingServers(true); + 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)); } @@ -189,7 +310,39 @@ public class CheckboxTest extends AbstractUITagTest { // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). CheckboxTag freshTag = new CheckboxTag(); freshTag.setPageContext(pageContext); - assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + 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 testCheckedWithErrorStyle_clearTagStateSet() throws Exception { + TestAction testAction = (TestAction) action; + testAction.setFoo("true"); + testAction.addFieldError("foo", "Some Foo Error"); + testAction.addFieldError("foo", "Another Foo Error"); + + CheckboxTag tag = new CheckboxTag(); + tag.setPerformClearTagStateForTagPoolingServers(true); // Explicitly request tag state clearing. + tag.setPageContext(pageContext); + tag.setLabel("mylabel"); + tag.setName("foo"); + tag.setFieldValue("baz"); + tag.setOndblclick("test();"); + tag.setOnclick("test();"); + tag.setTitle("mytitle"); + tag.setCssErrorStyle("color:red"); + + tag.doStartTag(); + setComponentTagClearTagState(tag, true); // Ensure component tag state clearing is set true (to match tag). + tag.doEndTag(); + + verify(CheckboxTag.class.getResource("Checkbox-33.txt")); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + CheckboxTag freshTag = new CheckboxTag(); + freshTag.setPerformClearTagStateForTagPoolingServers(true); + 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)); } @@ -213,11 +366,38 @@ public class CheckboxTest extends AbstractUITagTest { // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). CheckboxTag freshTag = new CheckboxTag(); freshTag.setPageContext(pageContext); - assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + 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 testUnchecked_clearTagStateSet() throws Exception { + TestAction testAction = (TestAction) action; + testAction.setFoo("false"); + + CheckboxTag tag = new CheckboxTag(); + tag.setPerformClearTagStateForTagPoolingServers(true); // Explicitly request tag state clearing. + tag.setPageContext(pageContext); + tag.setLabel("mylabel"); + tag.setName("foo"); + tag.setFieldValue("baz"); + tag.setTitle("mytitle"); + + tag.doStartTag(); + setComponentTagClearTagState(tag, true); // Ensure component tag state clearing is set true (to match tag). + tag.doEndTag(); + + verify(CheckboxTag.class.getResource("Checkbox-2.txt")); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + CheckboxTag freshTag = new CheckboxTag(); + freshTag.setPerformClearTagStateForTagPoolingServers(true); + 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)); + } + public void testDisabled() throws Exception { TestAction testAction = (TestAction) action; testAction.setFoo("true"); @@ -238,7 +418,35 @@ public class CheckboxTest extends AbstractUITagTest { // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). CheckboxTag freshTag = new CheckboxTag(); freshTag.setPageContext(pageContext); - assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + 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 testDisabled_clearTagStateSet() throws Exception { + TestAction testAction = (TestAction) action; + testAction.setFoo("true"); + + CheckboxTag tag = new CheckboxTag(); + tag.setPerformClearTagStateForTagPoolingServers(true); // Explicitly request tag state clearing. + tag.setPageContext(pageContext); + tag.setLabel("mylabel"); + tag.setName("foo"); + tag.setFieldValue("baz"); + tag.setTitle("mytitle"); + tag.setDisabled("true"); + + tag.doStartTag(); + setComponentTagClearTagState(tag, true); // Ensure component tag state clearing is set true (to match tag). + tag.doEndTag(); + + verify(CheckboxTag.class.getResource("Checkbox-6.txt")); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + CheckboxTag freshTag = new CheckboxTag(); + freshTag.setPerformClearTagStateForTagPoolingServers(true); + 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)); } diff --git a/core/src/test/java/org/apache/struts2/views/jsp/ui/ComboBoxTest.java b/core/src/test/java/org/apache/struts2/views/jsp/ui/ComboBoxTest.java index 20302c4f1..afd786e08 100644 --- a/core/src/test/java/org/apache/struts2/views/jsp/ui/ComboBoxTest.java +++ b/core/src/test/java/org/apache/struts2/views/jsp/ui/ComboBoxTest.java @@ -83,7 +83,40 @@ public class ComboBoxTest extends AbstractUITagTest { // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). ComboBoxTag freshTag = new ComboBoxTag(); freshTag.setPageContext(pageContext); - assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + 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 testSimple_clearTagStateSet() throws Exception { + TestAction testAction = (TestAction) action; + testAction.setFoo("hello"); + + ArrayList collection = new ArrayList(); + collection.add("foo"); + collection.add("bar"); + collection.add("baz"); + testAction.setCollection(collection); + + ComboBoxTag tag = new ComboBoxTag(); + tag.setPerformClearTagStateForTagPoolingServers(true); // Explicitly request tag state clearing. + tag.setPageContext(pageContext); + tag.setLabel("mylabel"); + tag.setName("foo"); + tag.setId("cb"); + tag.setList("collection"); + + tag.doStartTag(); + setComponentTagClearTagState(tag, true); // Ensure component tag state clearing is set true (to match tag). + tag.doEndTag(); + + verify(ComboBoxTag.class.getResource("ComboBox-1.txt")); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + ComboBoxTag freshTag = new ComboBoxTag(); + freshTag.setPerformClearTagStateForTagPoolingServers(true); + 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)); } @@ -117,7 +150,44 @@ public class ComboBoxTest extends AbstractUITagTest { // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). ComboBoxTag freshTag = new ComboBoxTag(); freshTag.setPageContext(pageContext); - assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + 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 testWithEmptyOptionAndHeader_clearTagStateSet() throws Exception { + TestAction testAction = (TestAction) action; + testAction.setFoo("banana"); + + List l = new ArrayList(); + l.add("apple"); + l.add("banana"); + l.add("pineaple"); + l.add("grapes"); + testAction.setCollection(l); + + ComboBoxTag tag = new ComboBoxTag(); + tag.setPerformClearTagStateForTagPoolingServers(true); // Explicitly request tag state clearing. + tag.setPageContext(pageContext); + tag.setLabel("My Favourite Fruit"); + tag.setName("myFavouriteFruit"); + tag.setEmptyOption("true"); + tag.setHeaderKey("-1"); + tag.setHeaderValue("--- Please Select ---"); + tag.setList("collection"); + tag.setValue("%{foo}"); + + tag.doStartTag(); + setComponentTagClearTagState(tag, true); // Ensure component tag state clearing is set true (to match tag). + tag.doEndTag(); + + verify(ComboBoxTag.class.getResource("ComboBox-2.txt")); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + ComboBoxTag freshTag = new ComboBoxTag(); + freshTag.setPerformClearTagStateForTagPoolingServers(true); + 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)); } @@ -151,7 +221,44 @@ public class ComboBoxTest extends AbstractUITagTest { // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). ComboBoxTag freshTag = new ComboBoxTag(); freshTag.setPageContext(pageContext); - assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + 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 testWithMap_clearTagStateSet() throws Exception { + TestAction testAction = (TestAction) action; + testAction.setFoo("banana"); + + Map m = new LinkedHashMap(); + m.put("apple", "apple"); + m.put("banana", "banana"); + m.put("pineaple", "pineaple"); + m.put("grapes", "grapes"); + testAction.setMap(m); + + ComboBoxTag tag = new ComboBoxTag(); + tag.setPerformClearTagStateForTagPoolingServers(true); // Explicitly request tag state clearing. + tag.setPageContext(pageContext); + tag.setLabel("My Favourite Fruit"); + tag.setName("myFavouriteFruit"); + tag.setHeaderKey("-1"); + tag.setHeaderValue("--- Please Select ---"); + tag.setEmptyOption("true"); + tag.setList("map"); + tag.setValue("%{foo}"); + + tag.doStartTag(); + setComponentTagClearTagState(tag, true); // Ensure component tag state clearing is set true (to match tag). + tag.doEndTag(); + + verify(ComboBoxTag.class.getResource("ComboBox-3.txt")); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + ComboBoxTag freshTag = new ComboBoxTag(); + freshTag.setPerformClearTagStateForTagPoolingServers(true); + 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)); } @@ -179,7 +286,38 @@ public class ComboBoxTest extends AbstractUITagTest { // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). ComboBoxTag freshTag = new ComboBoxTag(); freshTag.setPageContext(pageContext); - assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + 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 testJsCallNamingUsesEscapedId_clearTagStateSet() throws Exception { + TestAction testAction = (TestAction) action; + testAction.setFoo("hello"); + + ArrayList collection = new ArrayList(); + collection.add("foo"); + testAction.setCollection(collection); + + ComboBoxTag tag = new ComboBoxTag(); + tag.setPerformClearTagStateForTagPoolingServers(true); // Explicitly request tag state clearing. + tag.setPageContext(pageContext); + tag.setLabel("mylabel"); + tag.setName("foo"); + tag.setId("cb.bc"); + tag.setList("collection"); + + tag.doStartTag(); + setComponentTagClearTagState(tag, true); // Ensure component tag state clearing is set true (to match tag). + tag.doEndTag(); + + verify(ComboBoxTag.class.getResource("ComboBox-4.txt")); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + ComboBoxTag freshTag = new ComboBoxTag(); + freshTag.setPerformClearTagStateForTagPoolingServers(true); + 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)); } diff --git a/core/src/test/java/org/apache/struts2/views/jsp/ui/ComponentTest.java b/core/src/test/java/org/apache/struts2/views/jsp/ui/ComponentTest.java index f0d816986..7e227ac61 100644 --- a/core/src/test/java/org/apache/struts2/views/jsp/ui/ComponentTest.java +++ b/core/src/test/java/org/apache/struts2/views/jsp/ui/ComponentTest.java @@ -49,7 +49,38 @@ public class ComponentTest extends AbstractUITagTest { // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). TextFieldTag freshTag = new TextFieldTag(); freshTag.setPageContext(pageContext); - assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + 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)); + } + + /** + * Test that id attribute is evaludated against the Ognl Stack. + * @throws Exception + */ + public void testIdIsEvaluatedAgainstStack1_clearTagStateSet() throws Exception { + TestAction testAction = (TestAction) action; + testAction.setFoo("myFooValue"); + + TextFieldTag tag = new TextFieldTag(); + tag.setPerformClearTagStateForTagPoolingServers(true); // Explicitly request tag state clearing. + tag.setPageContext(pageContext); + tag.setLabel("mylabel"); + tag.setName("myname"); + tag.setValue("foo"); + tag.setId("%{foo}"); + + tag.doStartTag(); + setComponentTagClearTagState(tag, true); // Ensure component tag state clearing is set true (to match tag). + tag.doEndTag(); + + verify(ComponentTag.class.getResource("Component-2.txt")); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + TextFieldTag freshTag = new TextFieldTag(); + freshTag.setPerformClearTagStateForTagPoolingServers(true); + 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)); } @@ -73,11 +104,37 @@ public class ComponentTest extends AbstractUITagTest { // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). TextFieldTag freshTag = new TextFieldTag(); freshTag.setPageContext(pageContext); - assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + 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 testIdIsEvaludatedAgainstStack2_clearTagStateSet() throws Exception { + TestAction testAction = (TestAction) action; + testAction.setFoo("myFooValue"); + + TextFieldTag tag = new TextFieldTag(); + tag.setPerformClearTagStateForTagPoolingServers(true); // Explicitly request tag state clearing + tag.setPageContext(pageContext); + tag.setLabel("mylabel"); + tag.setName("myname"); + tag.setValue("foo"); + tag.setId("foo"); + + tag.doStartTag(); + setComponentTagClearTagState(tag, true); // Ensure component tag state clearing is set true (to match tag). + tag.doEndTag(); + + verify(ComponentTag.class.getResource("Component-3.txt")); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + TextFieldTag freshTag = new TextFieldTag(); + freshTag.setPerformClearTagStateForTagPoolingServers(true); + 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)); + } /** * Note -- this test uses empty.vm, so it's basically clear @@ -100,7 +157,36 @@ public class ComponentTest extends AbstractUITagTest { // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). ComponentTag freshTag = new ComponentTag(); freshTag.setPageContext(pageContext); - assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + 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)); + } + + /** + * Note -- this test uses empty.vm, so it's basically clear + */ + public void testSimple_clearTagStateSet() throws Exception { + TestAction testAction = (TestAction) action; + testAction.setFoo("bar"); + + ComponentTag tag = new ComponentTag(); + tag.setPerformClearTagStateForTagPoolingServers(true); // Explicitly request tag state clearing. + tag.setPageContext(pageContext); + tag.setLabel("mylabel"); + tag.setName("myname"); + tag.setValue("foo"); + + tag.doStartTag(); + setComponentTagClearTagState(tag, true); // Ensure component tag state clearing is set true (to match tag). + tag.doEndTag(); + + verify(ComponentTag.class.getResource("Component-1.txt")); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + ComponentTag freshTag = new ComponentTag(); + freshTag.setPerformClearTagStateForTagPoolingServers(true); + 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)); } @@ -135,7 +221,45 @@ public class ComponentTest extends AbstractUITagTest { // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). ComponentTag freshTag = new ComponentTag(); freshTag.setPageContext(pageContext); - assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + 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)); + } + + /** + * executes a component test passing in a custom parameter. it also executes calling a custom template using an + * absolute reference. + */ + public void testWithParam_clearTagStateSet() throws Exception { + TestAction testAction = (TestAction) action; + testAction.setFoo("bar"); + + ComponentTag tag = new ComponentTag(); + tag.setPerformClearTagStateForTagPoolingServers(true); // Explicitly request tag state clearing. + tag.setPageContext(pageContext); + tag.setLabel("mylabel"); + tag.setName("myname"); + tag.setValue("foo"); + tag.setTheme("test"); + tag.setTemplate("Component"); + + tag.doStartTag(); + setComponentTagClearTagState(tag, true); // Ensure component tag state clearing is set true (to match tag). + tag.getComponent().addParameter("hello", "world"); + tag.getComponent().addParameter("argle", "bargle"); + tag.getComponent().addParameter("glip", "glop"); + tag.getComponent().addParameter("array", new String[]{"a", "b", "c"}); + tag.getComponent().addParameter("objClass", tag.getClass().getName()); + tag.doEndTag(); + + // System.out.println(writer); + verify(ComponentTag.class.getResource("Component-param.txt")); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + ComponentTag freshTag = new ComponentTag(); + freshTag.setPerformClearTagStateForTagPoolingServers(true); + 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)); } 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 4a5be78bd..1f29d8239 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 @@ -58,7 +58,31 @@ public class DateTagTest extends AbstractTagTest { // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). DateTag freshTag = new DateTag(); freshTag.setPageContext(pageContext); - assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + 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); + context.put("myDate", now); + + tag.setPerformClearTagStateForTagPoolingServers(true); // Explicitly request tag state clearing. + tag.setName("myDate"); + tag.setNice(false); + tag.setFormat(format); + tag.doStartTag(); + setComponentTagClearTagState(tag, true); // Ensure component tag state clearing is set true (to match tag). + tag.doEndTag(); + assertEquals(formatted, writer.toString()); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + DateTag freshTag = new DateTag(); + freshTag.setPerformClearTagStateForTagPoolingServers(true); + 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)); } @@ -91,13 +115,41 @@ public class DateTagTest extends AbstractTagTest { tag.setFormat(format); tag.setTimezone("GMT+1"); tag.doStartTag(); + setComponentTagClearTagState(tag, true); // Ensure component tag state clearing is set true (to match tag). tag.doEndTag(); assertEquals(formatted, writer.toString()); // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). DateTag freshTag = new DateTag(); freshTag.setPageContext(pageContext); - assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + 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 testCustomFormatWithTimezone_clearTagStateSet() throws Exception { + String format = "yyyy/MM/dd hh:mm:ss"; + Date now = Calendar.getInstance(TimeZone.getTimeZone("UTC+1")).getTime(); + SimpleDateFormat sdf = new SimpleDateFormat(format); + sdf.setTimeZone(TimeZone.getTimeZone("UTC+1")); + String formatted = sdf.format(now); + context.put("myDate", now); + + tag.setPerformClearTagStateForTagPoolingServers(true); // Explicitly request tag state clearing. + tag.setName("myDate"); + tag.setNice(false); + tag.setFormat(format); + tag.setTimezone("UTC+1"); + tag.doStartTag(); + setComponentTagClearTagState(tag, true); // Ensure component tag state clearing is set true (to match tag). + tag.doEndTag(); + assertEquals(formatted, writer.toString()); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + DateTag freshTag = new DateTag(); + freshTag.setPerformClearTagStateForTagPoolingServers(true); + 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)); } @@ -122,7 +174,35 @@ public class DateTagTest extends AbstractTagTest { // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). DateTag freshTag = new DateTag(); freshTag.setPageContext(pageContext); - assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + 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 testCustomFormatWithTimezoneAsExpression_clearTagStateSet() throws Exception { + String format = "yyyy/MM/dd hh:mm:ss"; + Date now = Calendar.getInstance(TimeZone.getTimeZone("UTC+2")).getTime(); + SimpleDateFormat sdf = new SimpleDateFormat(format); + sdf.setTimeZone(TimeZone.getTimeZone("UTC+2")); + String formatted = sdf.format(now); + context.put("myDate", now); + context.put("myTimezone", "UTC+2"); + + tag.setPerformClearTagStateForTagPoolingServers(true); // Explicitly request tag state clearing. + tag.setName("myDate"); + tag.setNice(false); + tag.setFormat(format); + tag.setTimezone("myTimezone"); + tag.doStartTag(); + setComponentTagClearTagState(tag, true); // Ensure component tag state clearing is set true (to match tag). + tag.doEndTag(); + assertEquals(formatted, writer.toString()); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + DateTag freshTag = new DateTag(); + freshTag.setPerformClearTagStateForTagPoolingServers(true); + 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)); } @@ -143,7 +223,31 @@ public class DateTagTest extends AbstractTagTest { // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). DateTag freshTag = new DateTag(); freshTag.setPageContext(pageContext); - assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + 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 testCustomFormatCalendar_clearTagStateSet() throws Exception { + String format = "yyyy/MM/dd hh:mm:ss"; + Calendar calendar = Calendar.getInstance(); + String formatted = new SimpleDateFormat(format).format(calendar.getTime()); + context.put("myDate", calendar); + + tag.setPerformClearTagStateForTagPoolingServers(true); // Explicitly request tag state clearing. + tag.setName("myDate"); + tag.setNice(false); + tag.setFormat(format); + tag.doStartTag(); + setComponentTagClearTagState(tag, true); // Ensure component tag state clearing is set true (to match tag). + tag.doEndTag(); + assertEquals(formatted, writer.toString()); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + DateTag freshTag = new DateTag(); + freshTag.setPerformClearTagStateForTagPoolingServers(true); + 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)); } @@ -165,7 +269,32 @@ public class DateTagTest extends AbstractTagTest { // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). DateTag freshTag = new DateTag(); freshTag.setPageContext(pageContext); - assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + 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 testCustomFormatLong_clearTagStateSet() throws Exception { + String format = "yyyy/MM/dd hh:mm:ss"; + Date date = new Date(); + String formatted = new SimpleDateFormat(format).format(date); + // long + context.put("myDate", date.getTime()); + + tag.setPerformClearTagStateForTagPoolingServers(true); // Explicitly request tag state clearing. + tag.setName("myDate"); + tag.setNice(false); + tag.setFormat(format); + tag.doStartTag(); + setComponentTagClearTagState(tag, true); // Ensure component tag state clearing is set true (to match tag). + tag.doEndTag(); + assertEquals(formatted, writer.toString()); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + DateTag freshTag = new DateTag(); + freshTag.setPerformClearTagStateForTagPoolingServers(true); + 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)); } @@ -213,7 +342,30 @@ public class DateTagTest extends AbstractTagTest { // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). DateTag freshTag = new DateTag(); freshTag.setPageContext(pageContext); - assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + 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 testDefaultFormat_clearTagStateSet() throws Exception { + Date now = new Date(); + String formatted = DateFormat.getDateTimeInstance(DateFormat.MEDIUM, DateFormat.MEDIUM, + ActionContext.getContext().getLocale()).format(now); + + context.put("myDate", now); + tag.setPerformClearTagStateForTagPoolingServers(true); // Explicitly request tag state clearing. + tag.setName("myDate"); + tag.setNice(false); + tag.doStartTag(); + setComponentTagClearTagState(tag, true); // Ensure component tag state clearing is set true (to match tag). + tag.doEndTag(); + assertEquals(formatted, writer.toString()); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + DateTag freshTag = new DateTag(); + freshTag.setPerformClearTagStateForTagPoolingServers(true); + 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)); } @@ -243,7 +395,40 @@ public class DateTagTest extends AbstractTagTest { // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). DateTag freshTag = new DateTag(); freshTag.setPageContext(pageContext); - assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + 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 testCustomFormatAndComponent_clearTagStateSet() throws Exception { + String format = "yyyy/MM/dd hh:mm:ss"; + Date now = new Date(); + String formatted = new SimpleDateFormat(format).format(now); + context.put("myDate", now); + + tag.setPerformClearTagStateForTagPoolingServers(true); // Explicitly request tag state clearing. + tag.setName("myDate"); + tag.setFormat(format); + tag.setNice(false); + + tag.doStartTag(); + setComponentTagClearTagState(tag, true); // Ensure component tag state clearing is set true (to match tag). + + // component test must be done between start and end tag + 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()); + + tag.doEndTag(); + + assertEquals(formatted, writer.toString()); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + DateTag freshTag = new DateTag(); + freshTag.setPerformClearTagStateForTagPoolingServers(true); + 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)); } @@ -265,7 +450,32 @@ public class DateTagTest extends AbstractTagTest { // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). DateTag freshTag = new DateTag(); freshTag.setPageContext(pageContext); - assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + 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 testSetId_clearTagStateSet() throws Exception { + String format = "yyyy/MM/dd hh:mm:ss"; + Date now = new Date(); + String formatted = new SimpleDateFormat(format).format(now); + context.put("myDate", now); + + tag.setPerformClearTagStateForTagPoolingServers(true); // Explicitly request tag state clearing. + tag.setName("myDate"); + tag.setNice(false); + tag.setFormat(format); + tag.setVar("myId"); + tag.doStartTag(); + setComponentTagClearTagState(tag, true); // Ensure component tag state clearing is set true (to match tag). + tag.doEndTag(); + assertEquals(formatted, context.get("myId")); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + DateTag freshTag = new DateTag(); + freshTag.setPerformClearTagStateForTagPoolingServers(true); + 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)); } @@ -287,7 +497,32 @@ public class DateTagTest extends AbstractTagTest { // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). DateTag freshTag = new DateTag(); freshTag.setPageContext(pageContext); - assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + 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 testFutureNiceHour_clearTagStateSet() throws Exception { + Date now = new Date(); + Calendar future = Calendar.getInstance(); + future.setTime(now); + future.add(Calendar.HOUR, 1); + future.add(Calendar.SECOND, 5); // always add a little slack otherwise we could calculate wrong + + context.put("myDate", future.getTime()); + tag.setPerformClearTagStateForTagPoolingServers(true); // Explicitly request tag state clearing. + tag.setName("myDate"); + tag.setNice(true); + tag.doStartTag(); + setComponentTagClearTagState(tag, true); // Ensure component tag state clearing is set true (to match tag). + tag.doEndTag(); + assertEquals("in one hour", writer.toString()); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + DateTag freshTag = new DateTag(); + freshTag.setPerformClearTagStateForTagPoolingServers(true); + 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)); } @@ -309,7 +544,32 @@ public class DateTagTest extends AbstractTagTest { // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). DateTag freshTag = new DateTag(); freshTag.setPageContext(pageContext); - assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + 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 testPastNiceHour_clearTagStateSet() throws Exception { + Date now = new Date(); + Calendar future = Calendar.getInstance(); + future.setTime(now); + future.add(Calendar.HOUR, -1); + future.add(Calendar.SECOND, -5); // always add a little slack otherwise we could calculate wrong + + context.put("myDate", future.getTime()); + tag.setPerformClearTagStateForTagPoolingServers(true); // Explicitly request tag state clearing. + tag.setName("myDate"); + tag.setNice(true); + tag.doStartTag(); + setComponentTagClearTagState(tag, true); // Ensure component tag state clearing is set true (to match tag). + tag.doEndTag(); + assertEquals("one hour ago", writer.toString()); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + DateTag freshTag = new DateTag(); + freshTag.setPerformClearTagStateForTagPoolingServers(true); + 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)); } @@ -332,7 +592,33 @@ public class DateTagTest extends AbstractTagTest { // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). DateTag freshTag = new DateTag(); freshTag.setPageContext(pageContext); - assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + 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 testFutureNiceHourMinSec_clearTagStateSet() throws Exception { + Date now = new Date(); + Calendar future = Calendar.getInstance(); + future.setTime(now); + future.add(Calendar.HOUR, 2); + future.add(Calendar.MINUTE, 33); + future.add(Calendar.SECOND, 5); // always add a little slack otherwise we could calculate wrong + + context.put("myDate", future.getTime()); + tag.setPerformClearTagStateForTagPoolingServers(true); // Explicitly request tag state clearing. + tag.setName("myDate"); + tag.setNice(true); + tag.doStartTag(); + setComponentTagClearTagState(tag, true); // Ensure component tag state clearing is set true (to match tag). + tag.doEndTag(); + assertEquals("in 2 hours, 33 minutes", writer.toString()); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + DateTag freshTag = new DateTag(); + freshTag.setPerformClearTagStateForTagPoolingServers(true); + 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)); } @@ -355,7 +641,33 @@ public class DateTagTest extends AbstractTagTest { // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). DateTag freshTag = new DateTag(); freshTag.setPageContext(pageContext); - assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + 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 testPastNiceHourMin_clearTagStateSet() throws Exception { + Date now = new Date(); + Calendar past = Calendar.getInstance(); + past.setTime(now); + past.add(Calendar.HOUR, -4); + past.add(Calendar.MINUTE, -55); + past.add(Calendar.SECOND, -5); // always add a little slack otherwise we could calculate wrong + + context.put("myDate", past.getTime()); + tag.setPerformClearTagStateForTagPoolingServers(true); // Explicitly request tag state clearing. + tag.setName("myDate"); + tag.setNice(true); + tag.doStartTag(); + setComponentTagClearTagState(tag, true); // Ensure component tag state clearing is set true (to match tag). + tag.doEndTag(); + assertEquals("4 hours, 55 minutes ago", writer.toString()); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + DateTag freshTag = new DateTag(); + freshTag.setPerformClearTagStateForTagPoolingServers(true); + 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)); } @@ -377,7 +689,32 @@ public class DateTagTest extends AbstractTagTest { // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). DateTag freshTag = new DateTag(); freshTag.setPageContext(pageContext); - assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + 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 testFutureLessOneMin_clearTagStateSet() throws Exception { + Date now = new Date(); + Calendar future = Calendar.getInstance(); + future.setTime(now); + future.add(Calendar.SECOND, 47); + future.add(Calendar.SECOND, 5); // always add a little slack otherwise we could calculate wrong + + context.put("myDate", future.getTime()); + tag.setPerformClearTagStateForTagPoolingServers(true); // Explicitly request tag state clearing. + tag.setName("myDate"); + tag.setNice(true); + tag.doStartTag(); + setComponentTagClearTagState(tag, true); // Ensure component tag state clearing is set true (to match tag). + tag.doEndTag(); + assertEquals("in an instant", writer.toString()); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + DateTag freshTag = new DateTag(); + freshTag.setPerformClearTagStateForTagPoolingServers(true); + 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)); } @@ -399,7 +736,32 @@ public class DateTagTest extends AbstractTagTest { // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). DateTag freshTag = new DateTag(); freshTag.setPageContext(pageContext); - assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + 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 testFutureLessOneHour_clearTagStateSet() throws Exception { + Date now = new Date(); + Calendar future = Calendar.getInstance(); + future.setTime(now); + future.add(Calendar.MINUTE, 36); + future.add(Calendar.SECOND, 5); // always add a little slack otherwise we could calculate wrong + + context.put("myDate", future.getTime()); + tag.setPerformClearTagStateForTagPoolingServers(true); // Explicitly request tag state clearing. + tag.setName("myDate"); + tag.setNice(true); + tag.doStartTag(); + setComponentTagClearTagState(tag, true); // Ensure component tag state clearing is set true (to match tag). + tag.doEndTag(); + assertEquals("in 36 minutes", writer.toString()); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + DateTag freshTag = new DateTag(); + freshTag.setPerformClearTagStateForTagPoolingServers(true); + 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)); } @@ -421,7 +783,32 @@ public class DateTagTest extends AbstractTagTest { // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). DateTag freshTag = new DateTag(); freshTag.setPageContext(pageContext); - assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + 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 testFutureLessOneYear_clearTagStateSet() throws Exception { + Date now = new Date(); + Calendar future = Calendar.getInstance(); + future.setTime(now); + future.add(Calendar.HOUR, 40 * 24); + future.add(Calendar.SECOND, 5); // always add a little slack otherwise we could calculate wrong + + context.put("myDate", future.getTime()); + tag.setPerformClearTagStateForTagPoolingServers(true); // Explicitly request tag state clearing. + tag.setName("myDate"); + tag.setNice(true); + tag.doStartTag(); + setComponentTagClearTagState(tag, true); // Ensure component tag state clearing is set true (to match tag). + tag.doEndTag(); + assertEquals("in 40 days", writer.toString()); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + DateTag freshTag = new DateTag(); + freshTag.setPerformClearTagStateForTagPoolingServers(true); + 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)); } @@ -447,7 +834,36 @@ public class DateTagTest extends AbstractTagTest { // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). DateTag freshTag = new DateTag(); freshTag.setPageContext(pageContext); - assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + 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 testFutureTwoYears_clearTagStateSet() throws Exception { + Date now = new Date(); + Calendar future = Calendar.getInstance(); + future.setTime(now); + future.add(Calendar.YEAR, 2); + future.add(Calendar.DATE, 1); + future.add(Calendar.SECOND, 5); // always add a little slack otherwise we could calculate wrong + + context.put("myDate", future.getTime()); + tag.setPerformClearTagStateForTagPoolingServers(true); // Explicitly request tag state clearing. + tag.setName("myDate"); + tag.setNice(true); + tag.doStartTag(); + setComponentTagClearTagState(tag, true); // Ensure component tag state clearing is set true (to match tag). + tag.doEndTag(); + + // hmmm the Date component isn't the best to calculate the excat difference so we'll just check + // that it starts with in 2 years + assertTrue(writer.toString().startsWith("in 2 years")); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + DateTag freshTag = new DateTag(); + freshTag.setPerformClearTagStateForTagPoolingServers(true); + 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)); } @@ -464,7 +880,27 @@ public class DateTagTest extends AbstractTagTest { // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). DateTag freshTag = new DateTag(); freshTag.setPageContext(pageContext); - assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + 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 testNoDateObjectInContext_clearTagStateSet() throws Exception { + context.put("myDate", "this is not a java.util.Date object"); + tag.setPerformClearTagStateForTagPoolingServers(true); // Explicitly request tag state clearing. + tag.setName("myDate"); + tag.setNice(true); + tag.doStartTag(); + setComponentTagClearTagState(tag, true); // Ensure component tag state clearing is set true (to match tag). + tag.doEndTag(); + //should return a blank + assertEquals("", writer.toString()); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + DateTag freshTag = new DateTag(); + freshTag.setPerformClearTagStateForTagPoolingServers(true); + 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)); } diff --git a/core/src/test/java/org/apache/struts2/views/jsp/ui/DebugTagTest.java b/core/src/test/java/org/apache/struts2/views/jsp/ui/DebugTagTest.java index 50ef1f6bd..5553a4e28 100644 --- a/core/src/test/java/org/apache/struts2/views/jsp/ui/DebugTagTest.java +++ b/core/src/test/java/org/apache/struts2/views/jsp/ui/DebugTagTest.java @@ -61,7 +61,28 @@ public class DebugTagTest extends AbstractUITagTest { // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). DebugTag freshTag = new DebugTag(); freshTag.setPageContext(pageContext); - assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + // DebugTag has no additional state, so it compares as equal with the default tag clear state as well. + assertTrue("Tag state after doEndTag() under default tag clear state is inequal to new Tag with pageContext/parent set. " + + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", + strutsBodyTagsAreReflectionEqual(tag, freshTag)); + } + + public void testDevModeEnabled_clearTagStateSet() throws Exception { + setDevMode(true); + + tag.setPerformClearTagStateForTagPoolingServers(true); // Explicitly request tag state clearing. + tag.doStartTag(); + setComponentTagClearTagState(tag, true); // Ensure component tag state clearing is set true (to match tag). + tag.doEndTag(); + String result = writer.toString(); + assertTrue(StringUtils.isNotEmpty(result)); + assertTrue("Property 'checkStackProperty' should be in Debug Tag output", StringUtils.contains(result, "checkStackProperty")); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + DebugTag freshTag = new DebugTag(); + freshTag.setPerformClearTagStateForTagPoolingServers(true); + 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)); } @@ -76,7 +97,26 @@ public class DebugTagTest extends AbstractUITagTest { // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). DebugTag freshTag = new DebugTag(); freshTag.setPageContext(pageContext); - assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + // DebugTag has no additional state, so it compares as equal with the default tag clear state as well. + assertTrue("Tag state after doEndTag() under default tag clear state is inequal to new Tag with pageContext/parent set. " + + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", + strutsBodyTagsAreReflectionEqual(tag, freshTag)); + } + + public void testDevModeDisabled_clearTagStateSet() throws Exception { + setDevMode(false); + + tag.setPerformClearTagStateForTagPoolingServers(true); // Explicitly request tag state clearing. + tag.doStartTag(); + setComponentTagClearTagState(tag, true); // Ensure component tag state clearing is set true (to match tag). + tag.doEndTag(); + assertTrue("nothing to see here, devMode=false", StringUtils.isEmpty(writer.toString())); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + DebugTag freshTag = new DebugTag(); + freshTag.setPerformClearTagStateForTagPoolingServers(true); + 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)); } @@ -94,7 +134,29 @@ public class DebugTagTest extends AbstractUITagTest { // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). DebugTag freshTag = new DebugTag(); freshTag.setPageContext(pageContext); - assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + // DebugTag has no additional state, so it compares as equal with the default tag clear state as well. + assertTrue("Tag state after doEndTag() under default tag clear state is inequal to new Tag with pageContext/parent set. " + + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", + strutsBodyTagsAreReflectionEqual(tag, freshTag)); + } + + public void testTagAttributeOverrideDevModeTrue_clearTagStateSet() throws Exception { + setDevMode(false); + + PrepareOperations.overrideDevMode(true); + tag.setPerformClearTagStateForTagPoolingServers(true); // Explicitly request tag state clearing. + tag.doStartTag(); + setComponentTagClearTagState(tag, true); // Ensure component tag state clearing is set true (to match tag). + tag.doEndTag(); + String result = writer.toString(); + assertTrue(StringUtils.isNotEmpty(result)); + assertTrue("Property 'checkStackProperty' should be in Debug Tag output", StringUtils.contains(result, "checkStackProperty")); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + DebugTag freshTag = new DebugTag(); + freshTag.setPerformClearTagStateForTagPoolingServers(true); + 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)); } @@ -110,7 +172,27 @@ public class DebugTagTest extends AbstractUITagTest { // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). DebugTag freshTag = new DebugTag(); freshTag.setPageContext(pageContext); - assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + // DebugTag has no additional state, so it compares as equal with the default tag clear state as well. + assertTrue("Tag state after doEndTag() under default tag clear state is inequal to new Tag with pageContext/parent set. " + + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", + strutsBodyTagsAreReflectionEqual(tag, freshTag)); + } + + public void testTagAttributeOverrideDevModeFalse_clearTagStateSet() throws Exception { + setDevMode(false); + + PrepareOperations.overrideDevMode(false); + tag.setPerformClearTagStateForTagPoolingServers(true); // Explicitly request tag state clearing. + tag.doStartTag(); + setComponentTagClearTagState(tag, true); // Ensure component tag state clearing is set true (to match tag). + tag.doEndTag(); + assertTrue("nothing to see here, devMode=false and overrideDevMode=false", StringUtils.isEmpty(writer.toString())); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + DebugTag freshTag = new DebugTag(); + freshTag.setPerformClearTagStateForTagPoolingServers(true); + 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)); } diff --git a/core/src/test/java/org/apache/struts2/views/jsp/ui/DoubleSelectTest.java b/core/src/test/java/org/apache/struts2/views/jsp/ui/DoubleSelectTest.java index a91dc7ce1..a9c80f3bd 100644 --- a/core/src/test/java/org/apache/struts2/views/jsp/ui/DoubleSelectTest.java +++ b/core/src/test/java/org/apache/struts2/views/jsp/ui/DoubleSelectTest.java @@ -98,7 +98,80 @@ public class DoubleSelectTest extends AbstractUITagTest { // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). DoubleSelectTag freshTag = new DoubleSelectTag(); freshTag.setPageContext(pageContext); - assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + 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 testDouble_clearTagStateSet() throws Exception { + TestAction testAction = (TestAction) action; + + Region antwerp = new Region("Antwerp", "AN"); + Region gent = new Region("Gent", "GN"); + Region brugge = new Region("Brugge", "BRG"); + ArrayList belgiumRegions = new ArrayList(); + belgiumRegions.add(antwerp); + belgiumRegions.add(gent); + belgiumRegions.add(brugge); + Country belgium = new Country("Belgium", "BE", belgiumRegions); + + Region paris = new Region("Paris", "PA"); + Region bordeaux = new Region("Bordeaux", "BOR"); + ArrayList franceRegions = new ArrayList(); + franceRegions.add(paris); + franceRegions.add(bordeaux); + Country france = new Country("France", "FR", franceRegions); + + Collection collection = new ArrayList(2); + collection.add("AN"); + testAction.setCollection(collection); + + List countries = new ArrayList(); + countries.add(belgium); + countries.add(france); + + testAction.setList2(countries); + + DoubleSelectTag tag = new DoubleSelectTag(); + tag.setPerformClearTagStateForTagPoolingServers(true); // Explicitly request tag state clearing. + tag.setPageContext(pageContext); + tag.setLabel("mylabel"); + tag.setName("foo"); + tag.setDoubleName("region"); + + tag.setList("list2"); + tag.setDoubleList("regions"); + + tag.setListKey("iso"); + tag.setDoubleListKey("key"); + tag.setListValue("name"); + tag.setDoubleListValue("name"); + + tag.setFormName("inputForm"); + + tag.setOnmousedown("window.status='onmousedown';"); + tag.setOnmousemove("window.status='onmousemove';"); + tag.setOnmouseout("window.status='onmouseout';"); + tag.setOnmouseover("window.status='onmouseover';"); + tag.setOnmouseup("window.status='onmouseup';"); + + //css style and class + tag.setCssClass("c1"); + tag.setCssStyle("s1"); + tag.setDoubleCssClass("c2"); + tag.setDoubleCssStyle("s2"); + + tag.doStartTag(); + setComponentTagClearTagState(tag, true); // Ensure component tag state clearing is set true (to match tag). + tag.doEndTag(); + + verify(SelectTag.class.getResource("DoubleSelect-1.txt")); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + DoubleSelectTag freshTag = new DoubleSelectTag(); + freshTag.setPerformClearTagStateForTagPoolingServers(true); + 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)); } @@ -169,11 +242,84 @@ public class DoubleSelectTest extends AbstractUITagTest { // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). DoubleSelectTag freshTag = new DoubleSelectTag(); freshTag.setPageContext(pageContext); - assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + 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 testOnchange_clearTagStateSet() throws Exception { + TestAction testAction = (TestAction) action; + + Region antwerp = new Region("Antwerp", "AN"); + Region gent = new Region("Gent", "GN"); + Region brugge = new Region("Brugge", "BRG"); + ArrayList belgiumRegions = new ArrayList(); + belgiumRegions.add(antwerp); + belgiumRegions.add(gent); + belgiumRegions.add(brugge); + Country belgium = new Country("Belgium", "BE", belgiumRegions); + + Region paris = new Region("Paris", "PA"); + Region bordeaux = new Region("Bordeaux", "BOR"); + ArrayList franceRegions = new ArrayList(); + franceRegions.add(paris); + franceRegions.add(bordeaux); + Country france = new Country("France", "FR", franceRegions); + + Collection collection = new ArrayList(2); + collection.add("AN"); + testAction.setCollection(collection); + + List countries = new ArrayList(); + countries.add(belgium); + countries.add(france); + + testAction.setList2(countries); + + DoubleSelectTag tag = new DoubleSelectTag(); + tag.setPerformClearTagStateForTagPoolingServers(true); // Explicitly request tag state clearing. + tag.setPageContext(pageContext); + tag.setLabel("mylabel"); + tag.setName("foo"); + tag.setDoubleName("region"); + + tag.setList("list2"); + tag.setDoubleList("regions"); + + tag.setListKey("iso"); + tag.setDoubleListKey("key"); + tag.setListValue("name"); + tag.setDoubleListValue("name"); + + tag.setFormName("inputForm"); + + tag.setOnmousedown("window.status='onmousedown';"); + tag.setOnmousemove("window.status='onmousemove';"); + tag.setOnmouseout("window.status='onmouseout';"); + tag.setOnmouseover("window.status='onmouseover';"); + tag.setOnmouseup("window.status='onmouseup';"); + tag.setOnchange("window.status='onchange';"); + + //css style and class + tag.setCssClass("c1"); + tag.setCssStyle("s1"); + tag.setDoubleCssClass("c2"); + tag.setDoubleCssStyle("s2"); + + tag.doStartTag(); + setComponentTagClearTagState(tag, true); // Ensure component tag state clearing is set true (to match tag). + tag.doEndTag(); + + verify(SelectTag.class.getResource("DoubleSelect-4.txt")); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + DoubleSelectTag freshTag = new DoubleSelectTag(); + freshTag.setPerformClearTagStateForTagPoolingServers(true); + 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)); + } public void testDoubleWithDefaultSelectedValues() throws Exception { @@ -238,7 +384,78 @@ public class DoubleSelectTest extends AbstractUITagTest { // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). DoubleSelectTag freshTag = new DoubleSelectTag(); freshTag.setPageContext(pageContext); - assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + 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 testDoubleWithDefaultSelectedValues_clearTagStateSet() throws Exception { + + TestAction testAction = (TestAction) action; + + Region antwerp = new Region("Antwerp", "AN"); + Region gent = new Region("Gent", "GN"); + Region brugge = new Region("Brugge", "BRG"); + ArrayList belgiumRegions = new ArrayList(); + belgiumRegions.add(antwerp); + belgiumRegions.add(gent); + belgiumRegions.add(brugge); + Country belgium = new Country("Belgium", "BE", belgiumRegions); + + Region paris = new Region("Paris", "PA"); + Region bordeaux = new Region("Bordeaux", "BOR"); + ArrayList franceRegions = new ArrayList(); + franceRegions.add(paris); + franceRegions.add(bordeaux); + Country france = new Country("France", "FR", franceRegions); + + Collection collection = new ArrayList(2); + collection.add("AN"); + testAction.setCollection(collection); + + List countries = new ArrayList(); + countries.add(belgium); + countries.add(france); + + testAction.setList2(countries); + + DoubleSelectTag tag = new DoubleSelectTag(); + tag.setPerformClearTagStateForTagPoolingServers(true); // Explicitly request tag state clearing. + tag.setPageContext(pageContext); + tag.setLabel("mylabel"); + tag.setName("foo"); + tag.setDoubleName("region"); + + tag.setValue("'FR'"); + tag.setDoubleValue("'BOR'"); + + tag.setList("list2"); + tag.setDoubleList("regions"); + + tag.setListKey("iso"); + tag.setDoubleListKey("key"); + tag.setListValue("name"); + tag.setDoubleListValue("name"); + + tag.setFormName("inputForm"); + + tag.setOnmousedown("window.status='onmousedown';"); + tag.setOnmousemove("window.status='onmousemove';"); + tag.setOnmouseout("window.status='onmouseout';"); + tag.setOnmouseover("window.status='onmouseover';"); + tag.setOnmouseup("window.status='onmouseup';"); + + tag.doStartTag(); + setComponentTagClearTagState(tag, true); // Ensure component tag state clearing is set true (to match tag). + tag.doEndTag(); + + verify(SelectTag.class.getResource("DoubleSelect-2.txt")); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + DoubleSelectTag freshTag = new DoubleSelectTag(); + freshTag.setPerformClearTagStateForTagPoolingServers(true); + 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)); } @@ -302,7 +519,74 @@ public class DoubleSelectTest extends AbstractUITagTest { // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). DoubleSelectTag freshTag = new DoubleSelectTag(); freshTag.setPageContext(pageContext); - assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + 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 testDoubleWithDotName_clearTagStateSet() throws Exception { + TestAction testAction = (TestAction) action; + + Region antwerp = new Region("Antwerp", "AN"); + Region gent = new Region("Gent", "GN"); + Region brugge = new Region("Brugge", "BRG"); + ArrayList belgiumRegions = new ArrayList(); + belgiumRegions.add(antwerp); + belgiumRegions.add(gent); + belgiumRegions.add(brugge); + Country belgium = new Country("Belgium", "BE", belgiumRegions); + + Region paris = new Region("Paris", "PA"); + Region bordeaux = new Region("Bordeaux", "BOR"); + ArrayList franceRegions = new ArrayList(); + franceRegions.add(paris); + franceRegions.add(bordeaux); + Country france = new Country("France", "FR", franceRegions); + + Collection collection = new ArrayList(2); + collection.add("AN"); + testAction.setCollection(collection); + + List countries = new ArrayList(); + countries.add(belgium); + countries.add(france); + + testAction.setList2(countries); + + DoubleSelectTag tag = new DoubleSelectTag(); + tag.setPerformClearTagStateForTagPoolingServers(true); // Explicitly request tag state clearing. + tag.setPageContext(pageContext); + tag.setLabel("mylabel"); + tag.setName("foo.bar"); + tag.setDoubleName("region"); + + tag.setList("list2"); + tag.setDoubleList("regions"); + + tag.setListKey("iso"); + tag.setDoubleListKey("key"); + tag.setListValue("name"); + tag.setDoubleListValue("name"); + + tag.setFormName("inputForm"); + + tag.setOnmousedown("window.status='onmousedown';"); + tag.setOnmousemove("window.status='onmousemove';"); + tag.setOnmouseout("window.status='onmouseout';"); + tag.setOnmouseover("window.status='onmouseover';"); + tag.setOnmouseup("window.status='onmouseup';"); + + tag.doStartTag(); + setComponentTagClearTagState(tag, true); // Ensure component tag state clearing is set true (to match tag). + tag.doEndTag(); + + verify(SelectTag.class.getResource("DoubleSelect-3.txt")); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + DoubleSelectTag freshTag = new DoubleSelectTag(); + freshTag.setPerformClearTagStateForTagPoolingServers(true); + 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)); } diff --git a/core/src/test/java/org/apache/struts2/views/jsp/ui/FieldErrorTagTest.java b/core/src/test/java/org/apache/struts2/views/jsp/ui/FieldErrorTagTest.java index 6c984299b..f8e611337 100644 --- a/core/src/test/java/org/apache/struts2/views/jsp/ui/FieldErrorTagTest.java +++ b/core/src/test/java/org/apache/struts2/views/jsp/ui/FieldErrorTagTest.java @@ -50,7 +50,28 @@ public class FieldErrorTagTest extends AbstractUITagTest { // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). FieldErrorTag freshTag = new FieldErrorTag(); freshTag.setPageContext(pageContext); - assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + // FieldErrorTag has no non=default state set here, so it compares as equal with the default tag clear state as well. + assertTrue("Tag state after doEndTag() under default tag clear state is inequal to new Tag with pageContext/parent set. " + + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", + strutsBodyTagsAreReflectionEqual(tag, freshTag)); + } + + public void testWithoutParamsWithFieldErrors_clearTagStateSet() throws Exception { + FieldErrorTag tag = new FieldErrorTag(); + ((InternalAction)action).setHaveFieldErrors(true); + tag.setPerformClearTagStateForTagPoolingServers(true); // Explicitly request tag state clearing. + tag.setPageContext(pageContext); + tag.doStartTag(); + setComponentTagClearTagState(tag, true); // Ensure component tag state clearing is set true (to match tag). + tag.doEndTag(); + + verify(FieldErrorTagTest.class.getResource("fielderror-1.txt")); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + FieldErrorTag freshTag = new FieldErrorTag(); + freshTag.setPerformClearTagStateForTagPoolingServers(true); + 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)); } @@ -67,7 +88,28 @@ public class FieldErrorTagTest extends AbstractUITagTest { // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). FieldErrorTag freshTag = new FieldErrorTag(); freshTag.setPageContext(pageContext); - assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + // FieldErrorTag has no non=default state set here, so it compares as equal with the default tag clear state as well. + assertTrue("Tag state after doEndTag() under default tag clear state is inequal to new Tag with pageContext/parent set. " + + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", + strutsBodyTagsAreReflectionEqual(tag, freshTag)); + } + + public void testWithoutParamsWithoutFieldErrors_clearTagStateSet() throws Exception { + FieldErrorTag tag = new FieldErrorTag(); + ((InternalAction)action).setHaveFieldErrors(false); + tag.setPerformClearTagStateForTagPoolingServers(true); // Explicitly request tag state clearing. + tag.setPageContext(pageContext); + tag.doStartTag(); + setComponentTagClearTagState(tag, true); // Ensure component tag state clearing is set true (to match tag). + tag.doEndTag(); + + verify(FieldErrorTagTest.class.getResource("fielderror-2.txt")); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + FieldErrorTag freshTag = new FieldErrorTag(); + freshTag.setPerformClearTagStateForTagPoolingServers(true); + 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)); } @@ -90,7 +132,34 @@ public class FieldErrorTagTest extends AbstractUITagTest { // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). FieldErrorTag freshTag = new FieldErrorTag(); freshTag.setPageContext(pageContext); - assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + // FieldErrorTag has no non=default state set here and escape is true by default, so it compares as equal with the default tag clear state as well. + assertTrue("Tag state after doEndTag() under default tag clear state is inequal to new Tag with pageContext/parent set. " + + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", + strutsBodyTagsAreReflectionEqual(tag, freshTag)); + } + + public void testFieldErrorsEscape_clearTagStateSet() throws Exception { + + FieldErrorTag tag = new FieldErrorTag(); + TestAction testAction = new TestAction(); + testAction.addFieldError("f", "

hey

"); + stack.pop(); + stack.push(testAction); + tag.setPerformClearTagStateForTagPoolingServers(true); // Explicitly request tag state clearing. + tag.setEscape(true); + tag.setPageContext(pageContext); + tag.doStartTag(); + setComponentTagClearTagState(tag, true); // Ensure component tag state clearing is set true (to match tag). + tag.doEndTag(); + + assertEquals(normalize("
  • <p>hey</p>
", true), + normalize(writer.toString(), true)); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + FieldErrorTag freshTag = new FieldErrorTag(); + freshTag.setPerformClearTagStateForTagPoolingServers(true); + 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)); } @@ -113,7 +182,33 @@ public class FieldErrorTagTest extends AbstractUITagTest { // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). FieldErrorTag freshTag = new FieldErrorTag(); freshTag.setPageContext(pageContext); - assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + 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 testFieldErrorsDontEscape_clearTagStateSet() throws Exception { + + FieldErrorTag tag = new FieldErrorTag(); + TestAction testAction = new TestAction(); + testAction.addFieldError("f", "

hey

"); + stack.pop(); + stack.push(testAction); + tag.setPerformClearTagStateForTagPoolingServers(true); // Explicitly request tag state clearing. + tag.setEscape(false); + tag.setPageContext(pageContext); + tag.doStartTag(); + setComponentTagClearTagState(tag, true); // Ensure component tag state clearing is set true (to match tag). + tag.doEndTag(); + + assertEquals(normalize("
  • hey

", true), + normalize(writer.toString(), true)); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + FieldErrorTag freshTag = new FieldErrorTag(); + freshTag.setPerformClearTagStateForTagPoolingServers(true); + 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)); } @@ -143,17 +238,65 @@ public class FieldErrorTagTest extends AbstractUITagTest { // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). ParamTag freshParamTag = new ParamTag(); freshParamTag.setPageContext(pageContext); - assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + 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(pTag1, freshParamTag)); - assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + 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(pTag2, freshParamTag)); // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). FieldErrorTag freshTag = new FieldErrorTag(); freshTag.setPageContext(pageContext); - assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + 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 testWithParamsWithFieldErrors1_clearTagStateSet() throws Exception { + FieldErrorTag tag = new FieldErrorTag(); + tag.setPerformClearTagStateForTagPoolingServers(true); // Explicitly request tag state clearing. + tag.setId("someid"); + ((InternalAction)action).setHaveFieldErrors(true); + tag.setPageContext(pageContext); + tag.doStartTag(); + setComponentTagClearTagState(tag, true); // Ensure component tag state clearing is set true (to match tag). + ParamTag pTag1 = new ParamTag(); + pTag1.setPerformClearTagStateForTagPoolingServers(true); // Explicitly request tag state clearing. + pTag1.setPageContext(pageContext); + pTag1.setValue("%{'field1'}"); + pTag1.doStartTag(); + setComponentTagClearTagState(pTag1, true); // Ensure component tag state clearing is set true (to match tag). + pTag1.doEndTag(); + + ParamTag pTag2 = new ParamTag(); + pTag2.setPerformClearTagStateForTagPoolingServers(true); // Explicitly request tag state clearing. + pTag2.setPageContext(pageContext); + pTag2.setValue("%{'field3'}"); + pTag2.doStartTag(); + setComponentTagClearTagState(pTag2, true); // Ensure component tag state clearing is set true (to match tag). + pTag2.doEndTag(); + + tag.doEndTag(); + + verify(FieldErrorTagTest.class.getResource("fielderror-3.txt")); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + ParamTag freshParamTag = new ParamTag(); + freshParamTag.setPerformClearTagStateForTagPoolingServers(true); + freshParamTag.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(pTag1, freshParamTag)); + 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(pTag2, freshParamTag)); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + FieldErrorTag freshTag = new FieldErrorTag(); + freshTag.setPerformClearTagStateForTagPoolingServers(true); + 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)); } @@ -171,7 +314,28 @@ public class FieldErrorTagTest extends AbstractUITagTest { // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). FieldErrorTag freshTag = new FieldErrorTag(); freshTag.setPageContext(pageContext); - assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + 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 testWithFieldName_clearTagStateSet() throws Exception { + FieldErrorTag tag = new FieldErrorTag(); + tag.setPerformClearTagStateForTagPoolingServers(true); // Explicitly request tag state clearing. + tag.setFieldName("field1"); + ((InternalAction)action).setHaveFieldErrors(true); + tag.setPageContext(pageContext); + tag.doStartTag(); + setComponentTagClearTagState(tag, true); // Ensure component tag state clearing is set true (to match tag). + tag.doEndTag(); + + verify(FieldErrorTagTest.class.getResource("fielderror-6.txt")); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + FieldErrorTag freshTag = new FieldErrorTag(); + freshTag.setPerformClearTagStateForTagPoolingServers(true); + 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)); } @@ -200,21 +364,68 @@ public class FieldErrorTagTest extends AbstractUITagTest { // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). ParamTag freshParamTag = new ParamTag(); freshParamTag.setPageContext(pageContext); - assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + 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(pTag1, freshParamTag)); - assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + 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(pTag2, freshParamTag)); // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). FieldErrorTag freshTag = new FieldErrorTag(); freshTag.setPageContext(pageContext); - assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + // FieldErrorTag has no non=default state set here, so it compares as equal with the default tag clear state as well. + assertTrue("Tag state after doEndTag() under default tag clear state is inequal to new Tag with pageContext/parent set. " + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", strutsBodyTagsAreReflectionEqual(tag, freshTag)); } + public void testWithParamsWithFieldErrors2_clearTagStateSet() throws Exception { + FieldErrorTag tag = new FieldErrorTag(); + ((InternalAction)action).setHaveFieldErrors(true); + tag.setPerformClearTagStateForTagPoolingServers(true); // Explicitly request tag state clearing. + tag.setPageContext(pageContext); + tag.doStartTag(); + setComponentTagClearTagState(tag, true); // Ensure component tag state clearing is set true (to match tag). + ParamTag pTag1 = new ParamTag(); + pTag1.setPerformClearTagStateForTagPoolingServers(true); // Explicitly request tag state clearing. + pTag1.setPageContext(pageContext); + pTag1.setValue("%{'field1'}"); + pTag1.doStartTag(); + setComponentTagClearTagState(pTag1, true); // Ensure component tag state clearing is set true (to match tag). + pTag1.doEndTag(); + + ParamTag pTag2 = new ParamTag(); + pTag2.setPerformClearTagStateForTagPoolingServers(true); // Explicitly request tag state clearing. + pTag2.setPageContext(pageContext); + pTag2.setValue("%{'field2'}"); + pTag2.doStartTag(); + setComponentTagClearTagState(pTag2, true); // Ensure component tag state clearing is set true (to match tag). + pTag2.doEndTag(); + + tag.doEndTag(); + + verify(FieldErrorTagTest.class.getResource("fielderror-4.txt")); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + ParamTag freshParamTag = new ParamTag(); + freshParamTag.setPerformClearTagStateForTagPoolingServers(true); + freshParamTag.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(pTag1, freshParamTag)); + 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(pTag2, freshParamTag)); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + FieldErrorTag freshTag = new FieldErrorTag(); + freshTag.setPerformClearTagStateForTagPoolingServers(true); + 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)); + } public void testWithParamsWithFieldErrors3() throws Exception { FieldErrorTag tag = new FieldErrorTag(); @@ -234,14 +445,51 @@ public class FieldErrorTagTest extends AbstractUITagTest { // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). ParamTag freshParamTag = new ParamTag(); freshParamTag.setPageContext(pageContext); - assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + 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(pTag1, freshParamTag)); // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). FieldErrorTag freshTag = new FieldErrorTag(); freshTag.setPageContext(pageContext); - assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + // FieldErrorTag has no non=default state set here, so it compares as equal with the default tag clear state as well. + assertTrue("Tag state after doEndTag() under default tag clear state is inequal to new Tag with pageContext/parent set. " + + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", + strutsBodyTagsAreReflectionEqual(tag, freshTag)); + } + + public void testWithParamsWithFieldErrors3_clearTagStateSet() throws Exception { + FieldErrorTag tag = new FieldErrorTag(); + ((InternalAction)action).setHaveFieldErrors(true); + tag.setPerformClearTagStateForTagPoolingServers(true); // Explicitly request tag state clearing. + tag.setPageContext(pageContext); + tag.doStartTag(); + setComponentTagClearTagState(tag, true); // Ensure component tag state clearing is set true (to match tag). + ParamTag pTag1 = new ParamTag(); + pTag1.setPerformClearTagStateForTagPoolingServers(true); // Explicitly request tag state clearing. + pTag1.setPageContext(pageContext); + pTag1.setValue("%{'field2'}"); + pTag1.doStartTag(); + setComponentTagClearTagState(pTag1, true); // Ensure component tag state clearing is set true (to match tag). + pTag1.doEndTag(); + + tag.doEndTag(); + + verify(FieldErrorTagTest.class.getResource("fielderror-5.txt")); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + ParamTag freshParamTag = new ParamTag(); + freshParamTag.setPerformClearTagStateForTagPoolingServers(true); + freshParamTag.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(pTag1, freshParamTag)); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + FieldErrorTag freshTag = new FieldErrorTag(); + freshTag.setPerformClearTagStateForTagPoolingServers(true); + 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)); } @@ -269,17 +517,64 @@ public class FieldErrorTagTest extends AbstractUITagTest { // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). ParamTag freshParamTag = new ParamTag(); freshParamTag.setPageContext(pageContext); - assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + 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(pTag1, freshParamTag)); - assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + 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(pTag2, freshParamTag)); // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). FieldErrorTag freshTag = new FieldErrorTag(); freshTag.setPageContext(pageContext); - assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + // FieldErrorTag has no non=default state set here, so it compares as equal with the default tag clear state as well. + assertTrue("Tag state after doEndTag() under default tag clear state is inequal to new Tag with pageContext/parent set. " + + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", + strutsBodyTagsAreReflectionEqual(tag, freshTag)); + } + + public void testWithParamsWithoutFieldErrors1_clearTagStateSet() throws Exception { + FieldErrorTag tag = new FieldErrorTag(); + ((InternalAction)action).setHaveFieldErrors(false); + tag.setPerformClearTagStateForTagPoolingServers(true); // Explicitly request tag state clearing. + tag.setPageContext(pageContext); + tag.doStartTag(); + setComponentTagClearTagState(tag, true); // Ensure component tag state clearing is set true (to match tag). + ParamTag pTag1 = new ParamTag(); + pTag1.setPerformClearTagStateForTagPoolingServers(true); // Explicitly request tag state clearing. + pTag1.setPageContext(pageContext); + pTag1.setValue("%{'field1'}"); + pTag1.doStartTag(); + setComponentTagClearTagState(pTag1, true); // Ensure component tag state clearing is set true (to match tag). + pTag1.doEndTag(); + + ParamTag pTag2 = new ParamTag(); + pTag2.setPerformClearTagStateForTagPoolingServers(true); // Explicitly request tag state clearing. + pTag2.setPageContext(pageContext); + pTag2.setValue("%{'field3'}"); + pTag2.doStartTag(); + setComponentTagClearTagState(pTag2, true); // Ensure component tag state clearing is set true (to match tag). + pTag2.doEndTag(); + tag.doEndTag(); + + verify(FieldErrorTagTest.class.getResource("fielderror-2.txt")); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + ParamTag freshParamTag = new ParamTag(); + freshParamTag.setPerformClearTagStateForTagPoolingServers(true); + freshParamTag.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(pTag1, freshParamTag)); + 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(pTag2, freshParamTag)); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + FieldErrorTag freshTag = new FieldErrorTag(); + freshTag.setPerformClearTagStateForTagPoolingServers(true); + 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)); } @@ -307,21 +602,67 @@ public class FieldErrorTagTest extends AbstractUITagTest { // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). ParamTag freshParamTag = new ParamTag(); freshParamTag.setPageContext(pageContext); - assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + 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(pTag1, freshParamTag)); - assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + 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(pTag2, freshParamTag)); // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). FieldErrorTag freshTag = new FieldErrorTag(); freshTag.setPageContext(pageContext); - assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + // FieldErrorTag has no non=default state set here, so it compares as equal with the default tag clear state as well. + assertTrue("Tag state after doEndTag() under default tag clear state is inequal to new Tag with pageContext/parent set. " + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", strutsBodyTagsAreReflectionEqual(tag, freshTag)); } + public void testWithParamsWithoutFieldErrors2_clearTagStateSet() throws Exception { + FieldErrorTag tag = new FieldErrorTag(); + ((InternalAction)action).setHaveFieldErrors(false); + tag.setPerformClearTagStateForTagPoolingServers(true); // Explicitly request tag state clearing. + tag.setPageContext(pageContext); + tag.doStartTag(); + setComponentTagClearTagState(tag, true); // Ensure component tag state clearing is set true (to match tag). + ParamTag pTag1 = new ParamTag(); + pTag1.setPerformClearTagStateForTagPoolingServers(true); // Explicitly request tag state clearing. + pTag1.setPageContext(pageContext); + pTag1.setValue("%{'field1'}"); + pTag1.doStartTag(); + setComponentTagClearTagState(pTag1, true); // Ensure component tag state clearing is set true (to match tag). + pTag1.doEndTag(); + + ParamTag pTag2 = new ParamTag(); + pTag2.setPerformClearTagStateForTagPoolingServers(true); // Explicitly request tag state clearing. + pTag2.setPageContext(pageContext); + pTag2.setValue("%{'field3'}"); + pTag2.doStartTag(); + setComponentTagClearTagState(pTag2, true); // Ensure component tag state clearing is set true (to match tag). + pTag2.doEndTag(); + tag.doEndTag(); + + verify(FieldErrorTagTest.class.getResource("fielderror-2.txt")); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + ParamTag freshParamTag = new ParamTag(); + freshParamTag.setPerformClearTagStateForTagPoolingServers(true); + freshParamTag.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(pTag1, freshParamTag)); + 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(pTag2, freshParamTag)); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + FieldErrorTag freshTag = new FieldErrorTag(); + freshTag.setPerformClearTagStateForTagPoolingServers(true); + 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)); + } public void testWithParamsWithoutFieldErrors3() throws Exception { FieldErrorTag tag = new FieldErrorTag(); @@ -341,14 +682,51 @@ public class FieldErrorTagTest extends AbstractUITagTest { // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). ParamTag freshParamTag = new ParamTag(); freshParamTag.setPageContext(pageContext); - assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + 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(pTag1, freshParamTag)); // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). FieldErrorTag freshTag = new FieldErrorTag(); freshTag.setPageContext(pageContext); - assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + // FieldErrorTag has no non=default state set here, so it compares as equal with the default tag clear state as well. + assertTrue("Tag state after doEndTag() under default tag clear state is inequal to new Tag with pageContext/parent set. " + + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", + strutsBodyTagsAreReflectionEqual(tag, freshTag)); + } + + public void testWithParamsWithoutFieldErrors3_clearTagStateSet() throws Exception { + FieldErrorTag tag = new FieldErrorTag(); + ((InternalAction)action).setHaveFieldErrors(false); + tag.setPerformClearTagStateForTagPoolingServers(true); // Explicitly request tag state clearing. + tag.setPageContext(pageContext); + tag.doStartTag(); + setComponentTagClearTagState(tag, true); // Ensure component tag state clearing is set true (to match tag). + ParamTag pTag1 = new ParamTag(); + pTag1.setPerformClearTagStateForTagPoolingServers(true); // Explicitly request tag state clearing. + pTag1.setPageContext(pageContext); + pTag1.setValue("%{'field2'}"); + pTag1.doStartTag(); + setComponentTagClearTagState(pTag1, true); // Ensure component tag state clearing is set true (to match tag). + pTag1.doEndTag(); + + tag.doEndTag(); + + verify(FieldErrorTagTest.class.getResource("fielderror-2.txt")); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + ParamTag freshParamTag = new ParamTag(); + freshParamTag.setPerformClearTagStateForTagPoolingServers(true); + freshParamTag.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(pTag1, freshParamTag)); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + FieldErrorTag freshTag = new FieldErrorTag(); + freshTag.setPerformClearTagStateForTagPoolingServers(true); + 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)); } @@ -372,18 +750,55 @@ public class FieldErrorTagTest extends AbstractUITagTest { // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). ParamTag freshParamTag = new ParamTag(); freshParamTag.setPageContext(pageContext); - assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + 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(pTag1, freshParamTag)); // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). FieldErrorTag freshTag = new FieldErrorTag(); freshTag.setPageContext(pageContext); - assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + // FieldErrorTag has no non=default state set here, so it compares as equal with the default tag clear state as well. + assertTrue("Tag state after doEndTag() under default tag clear state is inequal to new Tag with pageContext/parent set. " + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", strutsBodyTagsAreReflectionEqual(tag, freshTag)); } + public void testWithNullFieldErrors_clearTagStateSet() throws Exception { + FieldErrorTag tag = new FieldErrorTag(); + ((InternalAction)action).setHaveFieldErrors(false); + ((InternalAction)action).setReturnNullForFieldErrors(true); + tag.setPerformClearTagStateForTagPoolingServers(true); // Explicitly request tag state clearing. + tag.setPageContext(pageContext); + tag.doStartTag(); + setComponentTagClearTagState(tag, true); // Ensure component tag state clearing is set true (to match tag). + ParamTag pTag1 = new ParamTag(); + pTag1.setPerformClearTagStateForTagPoolingServers(true); // Explicitly request tag state clearing. + pTag1.setPageContext(pageContext); + pTag1.setValue("%{'field2'}"); + pTag1.doStartTag(); + setComponentTagClearTagState(pTag1, true); // Ensure component tag state clearing is set true (to match tag). + pTag1.doEndTag(); + + tag.doEndTag(); + + verify(FieldErrorTagTest.class.getResource("fielderror-2.txt")); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + ParamTag freshParamTag = new ParamTag(); + freshParamTag.setPerformClearTagStateForTagPoolingServers(true); + freshParamTag.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(pTag1, freshParamTag)); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + FieldErrorTag freshTag = new FieldErrorTag(); + freshTag.setPerformClearTagStateForTagPoolingServers(true); + 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)); + } @Override public Action getAction() { diff --git a/core/src/test/java/org/apache/struts2/views/jsp/ui/FileTest.java b/core/src/test/java/org/apache/struts2/views/jsp/ui/FileTest.java index 483d7f406..32b932229 100644 --- a/core/src/test/java/org/apache/struts2/views/jsp/ui/FileTest.java +++ b/core/src/test/java/org/apache/struts2/views/jsp/ui/FileTest.java @@ -53,7 +53,36 @@ public class FileTest extends AbstractUITagTest { // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). FileTag freshTag = new FileTag(); freshTag.setPageContext(pageContext); - assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + 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 testSimple_clearTagStateSet() throws Exception { + TestAction testAction = (TestAction) action; + testAction.setFoo("bar"); + + FileTag tag = new FileTag(); + tag.setPerformClearTagStateForTagPoolingServers(true); // Explicitly request tag state clearing. + tag.setPageContext(pageContext); + tag.setLabel("mylabel"); + tag.setName("myname"); + tag.setAccept("*.txt"); + tag.setValue("%{foo}"); + tag.setSize("10"); + tag.setTitle("mytitle"); + + tag.doStartTag(); + setComponentTagClearTagState(tag, true); // Ensure component tag state clearing is set true (to match tag). + tag.doEndTag(); + + verify(TextFieldTag.class.getResource("File-1.txt")); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + FileTag freshTag = new FileTag(); + freshTag.setPerformClearTagStateForTagPoolingServers(true); + 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)); } diff --git a/core/src/test/java/org/apache/struts2/views/jsp/ui/FormTagTest.java b/core/src/test/java/org/apache/struts2/views/jsp/ui/FormTagTest.java index d5a56448e..cd3caa577 100644 --- a/core/src/test/java/org/apache/struts2/views/jsp/ui/FormTagTest.java +++ b/core/src/test/java/org/apache/struts2/views/jsp/ui/FormTagTest.java @@ -62,7 +62,33 @@ public class FormTagTest extends AbstractUITagTest { // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). FormTag freshTag = new FormTag(); freshTag.setPageContext(pageContext); - assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + 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 testFormWithActionAttributeContainingQueryString_clearTagStateSet() throws Exception { + FormTag tag = new FormTag(); + tag.setPerformClearTagStateForTagPoolingServers(true); // Explicitly request tag state clearing. + tag.setPageContext(pageContext); + tag.setName("myForm"); + tag.setMethod("post"); + tag.setAcceptcharset("UTF-8"); + tag.setAction("testAction?paramone=one¶mtwo=two"); + tag.setEnctype("myEncType"); + tag.setTitle("mytitle"); + tag.setOnsubmit("submitMe()"); + tag.doStartTag(); + setComponentTagClearTagState(tag, true); // Ensure component tag state clearing is set true (to match tag). + tag.doEndTag(); + + verify(FormTag.class.getResource("Formtag-26.txt")); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + FormTag freshTag = new FormTag(); + freshTag.setPerformClearTagStateForTagPoolingServers(true); + 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)); } @@ -85,7 +111,33 @@ public class FormTagTest extends AbstractUITagTest { // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). FormTag freshTag = new FormTag(); freshTag.setPageContext(pageContext); - assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + 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 testFormWithActionAttributeContainingBothActionAndMethod_clearTagStateSet() throws Exception { + FormTag tag = new FormTag(); + tag.setPerformClearTagStateForTagPoolingServers(true); // Explicitly request tag state clearing. + tag.setPageContext(pageContext); + tag.setName("myForm"); + tag.setMethod("post"); + tag.setAcceptcharset("UTF-8"); + tag.setAction("testAction"); + tag.setEnctype("myEncType"); + tag.setTitle("mytitle"); + tag.setOnsubmit("submitMe()"); + tag.doStartTag(); + setComponentTagClearTagState(tag, true); // Ensure component tag state clearing is set true (to match tag). + tag.doEndTag(); + + verify(FormTag.class.getResource("Formtag-9.txt")); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + FormTag freshTag = new FormTag(); + freshTag.setPerformClearTagStateForTagPoolingServers(true); + 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)); } @@ -107,7 +159,32 @@ public class FormTagTest extends AbstractUITagTest { // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). FormTag freshTag = new FormTag(); freshTag.setPageContext(pageContext); - assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + 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 testFormWithoutContext_clearTagStateSet() throws Exception { + request.setupGetContext("somecontext"); + + FormTag tag = new FormTag(); + tag.setPerformClearTagStateForTagPoolingServers(true); // Explicitly request tag state clearing. + tag.setTheme("xhtml"); + tag.setPageContext(pageContext); + tag.setAction("testAction"); + tag.setIncludeContext(false); + tag.doStartTag(); + setComponentTagClearTagState(tag, true); // Ensure component tag state clearing is set true (to match tag). + tag.doEndTag(); + + + verify(FormTag.class.getResource("Formtag-14.txt")); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + FormTag freshTag = new FormTag(); + freshTag.setPerformClearTagStateForTagPoolingServers(true); + 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)); } @@ -128,13 +205,38 @@ public class FormTagTest extends AbstractUITagTest { // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). FormTag freshTag = new FormTag(); freshTag.setPageContext(pageContext); - assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + 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 testFormWithContext_clearTagStateSet() throws Exception { + request.setupGetContext("/testNamespace"); + + FormTag tag = new FormTag(); + tag.setPerformClearTagStateForTagPoolingServers(true); // Explicitly request tag state clearing. + tag.setTheme("xhtml"); + tag.setPageContext(pageContext); + tag.setAction("testAction"); + tag.doStartTag(); + setComponentTagClearTagState(tag, true); // Ensure component tag state clearing is set true (to match tag). + tag.doEndTag(); + + + verify(FormTag.class.getResource("Formtag-13.txt")); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + FormTag freshTag = new FormTag(); + freshTag.setPerformClearTagStateForTagPoolingServers(true); + 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)); } public void testFormWithActionAttributeContainingBothActionAndDMIMethod() throws Exception { FormTag tag = new FormTag(); + tag.setPerformClearTagStateForTagPoolingServers(true); // Explicitly request tag state clearing. tag.setPageContext(pageContext); tag.setName("myForm"); tag.setMethod("post"); @@ -154,13 +256,43 @@ public class FormTagTest extends AbstractUITagTest { // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). FormTag freshTag = new FormTag(); freshTag.setPageContext(pageContext); - assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + 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 testFormWithActionAttributeContainingBothActionAndDMIMethod_clearTagStateSet() throws Exception { + FormTag tag = new FormTag(); + tag.setPerformClearTagStateForTagPoolingServers(true); // Explicitly request tag state clearing. + tag.setPageContext(pageContext); + tag.setName("myForm"); + tag.setMethod("post"); + tag.setAcceptcharset("UTF-8"); + tag.setAction("testAction!testMethod"); + tag.setEnctype("myEncType"); + tag.setTitle("mytitle"); + tag.setOnsubmit("submitMe()"); + + ((DefaultActionMapper)container.getInstance(ActionMapper.class)).setAllowDynamicMethodCalls("true"); + + tag.doStartTag(); + setComponentTagClearTagState(tag, true); // Ensure component tag state clearing is set true (to match tag). + tag.doEndTag(); + + verify(FormTag.class.getResource("Formtag-23.txt")); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + FormTag freshTag = new FormTag(); + freshTag.setPerformClearTagStateForTagPoolingServers(true); + 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)); + } + public void testFormWithFocusElement() throws Exception { FormTag tag = new FormTag(); + tag.setPerformClearTagStateForTagPoolingServers(true); // Explicitly request tag state clearing. tag.setTheme("xhtml"); tag.setPageContext(pageContext); tag.setAction("testAction"); @@ -173,13 +305,36 @@ public class FormTagTest extends AbstractUITagTest { // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). FormTag freshTag = new FormTag(); freshTag.setPageContext(pageContext); - assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + 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 testFormWithFocusElement_clearTagStateSet() throws Exception { + FormTag tag = new FormTag(); + tag.setPerformClearTagStateForTagPoolingServers(true); // Explicitly request tag state clearing. + tag.setTheme("xhtml"); + tag.setPageContext(pageContext); + tag.setAction("testAction"); + tag.setFocusElement("felement"); + tag.doStartTag(); + setComponentTagClearTagState(tag, true); // Ensure component tag state clearing is set true (to match tag). + tag.doEndTag(); + + verify(FormTag.class.getResource("Formtag-12.txt")); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + FormTag freshTag = new FormTag(); + freshTag.setPerformClearTagStateForTagPoolingServers(true); + 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)); } public void testFormWithActionAttributeContainingBothActionAndMethodAndNamespace() throws Exception { FormTag tag = new FormTag(); + tag.setPerformClearTagStateForTagPoolingServers(true); // Explicitly request tag state clearing. tag.setPageContext(pageContext); tag.setName("myForm"); tag.setNamespace("/testNamespace"); @@ -198,11 +353,38 @@ public class FormTagTest extends AbstractUITagTest { // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). FormTag freshTag = new FormTag(); freshTag.setPageContext(pageContext); - assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + 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 testFormWithActionAttributeContainingBothActionAndMethodAndNamespace_clearTagStateSet() throws Exception { + FormTag tag = new FormTag(); + tag.setPerformClearTagStateForTagPoolingServers(true); // Explicitly request tag state clearing. + tag.setPageContext(pageContext); + tag.setName("myForm"); + tag.setNamespace("/testNamespace"); + tag.setMethod("post"); + tag.setAcceptcharset("UTF-8"); + tag.setAction("testNamespaceAction"); + tag.setEnctype("myEncType"); + tag.setTitle("mytitle"); + tag.setOnsubmit("submitMe()"); + + tag.doStartTag(); + setComponentTagClearTagState(tag, true); // Ensure component tag state clearing is set true (to match tag). + tag.doEndTag(); + + verify(FormTag.class.getResource("Formtag-10.txt")); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + FormTag freshTag = new FormTag(); + freshTag.setPerformClearTagStateForTagPoolingServers(true); + 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)); + } public void testForm() throws Exception { @@ -212,6 +394,7 @@ public class FormTagTest extends AbstractUITagTest { testAction.setFoo("bar"); FormTag tag = new FormTag(); + tag.setPerformClearTagStateForTagPoolingServers(true); // Explicitly request tag state clearing. tag.setPageContext(pageContext); tag.setName("myForm"); tag.setMethod("post"); @@ -230,7 +413,41 @@ public class FormTagTest extends AbstractUITagTest { // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). FormTag freshTag = new FormTag(); freshTag.setPageContext(pageContext); - assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + 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 testForm_clearTagStateSet() throws Exception { + + request.setupGetServletPath("/testAction"); + + TestAction testAction = (TestAction) action; + testAction.setFoo("bar"); + + FormTag tag = new FormTag(); + tag.setPerformClearTagStateForTagPoolingServers(true); // Explicitly request tag state clearing. + tag.setPageContext(pageContext); + tag.setName("myForm"); + tag.setMethod("post"); + tag.setAcceptcharset("UTF-8"); + tag.setAction("myAction"); + tag.setEnctype("myEncType"); + tag.setTitle("mytitle"); + tag.setOnsubmit("submitMe()"); + tag.setId("myid"); + + tag.doStartTag(); + setComponentTagClearTagState(tag, true); // Ensure component tag state clearing is set true (to match tag). + tag.doEndTag(); + + verify(FormTag.class.getResource("Formtag-1.txt")); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + FormTag freshTag = new FormTag(); + freshTag.setPerformClearTagStateForTagPoolingServers(true); + 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)); } @@ -243,6 +460,7 @@ public class FormTagTest extends AbstractUITagTest { testAction.setFoo("bar"); FormTag tag = new FormTag(); + tag.setPerformClearTagStateForTagPoolingServers(true); // Explicitly request tag state clearing. tag.setPageContext(pageContext); tag.setMethod("post"); tag.setAction("myAction"); @@ -256,7 +474,36 @@ public class FormTagTest extends AbstractUITagTest { // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). FormTag freshTag = new FormTag(); freshTag.setPageContext(pageContext); - assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + 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 testFormId_clearTagStateSet() throws Exception { + + request.setupGetServletPath("/testAction"); + + TestAction testAction = (TestAction) action; + testAction.setFoo("bar"); + + FormTag tag = new FormTag(); + tag.setPerformClearTagStateForTagPoolingServers(true); // Explicitly request tag state clearing. + tag.setPageContext(pageContext); + tag.setMethod("post"); + tag.setAction("myAction"); + tag.setId("myid-%{foo}"); + + tag.doStartTag(); + setComponentTagClearTagState(tag, true); // Ensure component tag state clearing is set true (to match tag). + tag.doEndTag(); + + verify(FormTag.class.getResource("Formtag-29.txt")); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + FormTag freshTag = new FormTag(); + freshTag.setPerformClearTagStateForTagPoolingServers(true); + 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)); } @@ -285,7 +532,39 @@ public class FormTagTest extends AbstractUITagTest { // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). FormTag freshTag = new FormTag(); freshTag.setPageContext(pageContext); - assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + 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 testFormNoNameOrId_clearTagStateSet() throws Exception { + + request.setupGetServletPath("/testAction"); + + TestAction testAction = (TestAction) action; + testAction.setFoo("bar"); + + FormTag tag = new FormTag(); + tag.setPerformClearTagStateForTagPoolingServers(true); // Explicitly request tag state clearing. + tag.setPageContext(pageContext); + tag.setMethod("post"); + tag.setAcceptcharset("UTF-8"); + tag.setAction("myAction"); + tag.setEnctype("myEncType"); + tag.setTitle("mytitle"); + tag.setOnsubmit("submitMe()"); + + tag.doStartTag(); + setComponentTagClearTagState(tag, true); // Ensure component tag state clearing is set true (to match tag). + tag.doEndTag(); + + verify(FormTag.class.getResource("Formtag-25.txt")); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + FormTag freshTag = new FormTag(); + freshTag.setPerformClearTagStateForTagPoolingServers(true); + 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)); } @@ -326,18 +605,71 @@ public class FormTagTest extends AbstractUITagTest { // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). UpDownSelectTag freshParamTag = new UpDownSelectTag(); freshParamTag.setPageContext(pageContext); - assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + 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(t, freshParamTag)); // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). FormTag freshTag = new FormTag(); freshTag.setPageContext(pageContext); - assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + 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)); } + /** + * This test with form tag validation enabled. Js validation script will appear + * cause action submited by the form is intercepted by validation interceptor which + * "include" all methods. + */ + public void testFormWithCustomOnsubmitEnabledWithValidateEnabled1_clearTagStateSet() throws Exception { + + prepareMockInvocation(); + + FormTag tag = new FormTag(); + tag.setPerformClearTagStateForTagPoolingServers(true); // Explicitly request tag state clearing. + tag.setPageContext(pageContext); + tag.setName("myForm"); + tag.setMethod("post"); + tag.setAction("doubleValidationAction"); + tag.setAcceptcharset("UTF-8"); + tag.setEnctype("myEncType"); + tag.setTitle("mytitle"); + tag.setOnsubmit("submitMe()"); + tag.setValidate("true"); + tag.setNamespace(""); + + UpDownSelectTag t = new UpDownSelectTag(); + t.setPerformClearTagStateForTagPoolingServers(true); // Explicitly request tag state clearing. + t.setPageContext(pageContext); + t.setName("myUpDownSelectTag"); + t.setList("{}"); + + tag.doStartTag(); + setComponentTagClearTagState(tag, true); // Ensure component tag state clearing is set true (to match tag). + t.doStartTag(); + setComponentTagClearTagState(t, true); // Ensure component tag state clearing is set true (to match tag). + t.doEndTag(); + tag.doEndTag(); + + verify(FormTag.class.getResource("Formtag-2.txt")); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + UpDownSelectTag freshParamTag = new UpDownSelectTag(); + freshParamTag.setPerformClearTagStateForTagPoolingServers(true); + freshParamTag.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(t, freshParamTag)); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + FormTag freshTag = new FormTag(); + freshTag.setPerformClearTagStateForTagPoolingServers(true); + 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)); + } /** * This test with form tag validation enabled. Js validation script will not appear @@ -374,14 +706,67 @@ public class FormTagTest extends AbstractUITagTest { // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). UpDownSelectTag freshParamTag = new UpDownSelectTag(); freshParamTag.setPageContext(pageContext); - assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + 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(t, freshParamTag)); // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). FormTag freshTag = new FormTag(); freshTag.setPageContext(pageContext); - assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + 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)); + } + + /** + * This test with form tag validation enabled. Js validation script will not appear + * cause action submited by the form is intercepted by validation interceptor which + * "excludes" all methods. + */ + public void testFormWithCustomOnsubmitEnabledWithValidateEnabled2_clearTagStateSet() throws Exception { + prepareMockInvocation(); + + FormTag tag = new FormTag(); + tag.setPerformClearTagStateForTagPoolingServers(true); // Explicitly request tag state clearing. + tag.setPageContext(pageContext); + tag.setName("myForm"); + tag.setMethod("post"); + tag.setAction("testAction"); + tag.setAcceptcharset("UTF-8"); + tag.setEnctype("myEncType"); + tag.setTitle("mytitle"); + tag.setOnsubmit("submitMe()"); + tag.setValidate("true"); + tag.setNamespace(""); + + UpDownSelectTag t = new UpDownSelectTag(); + t.setPerformClearTagStateForTagPoolingServers(true); // Explicitly request tag state clearing. + t.setPageContext(pageContext); + t.setName("myUpDownSelectTag"); + t.setList("{}"); + + tag.doStartTag(); + setComponentTagClearTagState(tag, true); // Ensure component tag state clearing is set true (to match tag). + t.doStartTag(); + setComponentTagClearTagState(t, true); // Ensure component tag state clearing is set true (to match tag). + t.doEndTag(); + tag.doEndTag(); + + verify(FormTag.class.getResource("Formtag-11.txt")); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + UpDownSelectTag freshParamTag = new UpDownSelectTag(); + freshParamTag.setPerformClearTagStateForTagPoolingServers(true); + freshParamTag.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(t, freshParamTag)); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + FormTag freshTag = new FormTag(); + freshTag.setPerformClearTagStateForTagPoolingServers(true); + 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)); } @@ -420,19 +805,71 @@ public class FormTagTest extends AbstractUITagTest { // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). UpDownSelectTag freshParamTag = new UpDownSelectTag(); freshParamTag.setPageContext(pageContext); - assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + 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(t, freshParamTag)); // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). FormTag freshTag = new FormTag(); freshTag.setPageContext(pageContext); - assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + 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)); } /** + * Tests the numbers are formatted correctly to not break the javascript + */ + public void testFormWithCustomOnsubmitEnabledWithValidateEnabled3_clearTagStateSet() throws Exception { + + prepareMockInvocation(); + FormTag tag = new FormTag(); + tag.setPerformClearTagStateForTagPoolingServers(true); // Explicitly request tag state clearing. + tag.setPageContext(pageContext); + tag.setName("myForm"); + tag.setMethod("post"); + tag.setAction("doubleValidationAction"); + tag.setAcceptcharset("UTF-8"); + tag.setEnctype("myEncType"); + tag.setTitle("mytitle"); + tag.setOnsubmit("submitMe()"); + tag.setValidate("true"); + tag.setNamespace(""); + + UpDownSelectTag t = new UpDownSelectTag(); + t.setPerformClearTagStateForTagPoolingServers(true); // Explicitly request tag state clearing. + t.setPageContext(pageContext); + t.setName("myUpDownSelectTag"); + t.setList("{}"); + + tag.doStartTag(); + setComponentTagClearTagState(tag, true); // Ensure component tag state clearing is set true (to match tag). + tag.getComponent().getParameters().put("actionClass", IntValidationAction.class); + t.doStartTag(); + setComponentTagClearTagState(t, true); // Ensure component tag state clearing is set true (to match tag). + t.doEndTag(); + tag.doEndTag(); + + verify(FormTag.class.getResource("Formtag-22.txt")); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + UpDownSelectTag freshParamTag = new UpDownSelectTag(); + freshParamTag.setPerformClearTagStateForTagPoolingServers(true); + freshParamTag.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(t, freshParamTag)); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + FormTag freshTag = new FormTag(); + freshTag.setPerformClearTagStateForTagPoolingServers(true); + 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)); + } + +/** * Tests the numbers are formatted correctly to not break the javascript, using doubles */ public void testFormWithCustomOnsubmitEnabledWithValidateEnabled4() throws Exception { @@ -466,14 +903,66 @@ public class FormTagTest extends AbstractUITagTest { // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). UpDownSelectTag freshParamTag = new UpDownSelectTag(); freshParamTag.setPageContext(pageContext); - assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + 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(t, freshParamTag)); // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). FormTag freshTag = new FormTag(); freshTag.setPageContext(pageContext); - assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + 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)); + } + +/** + * Tests the numbers are formatted correctly to not break the javascript, using doubles + */ + public void testFormWithCustomOnsubmitEnabledWithValidateEnabled4_clearTagStateSet() throws Exception { + prepareMockInvocation(); + + FormTag tag = new FormTag(); + tag.setPerformClearTagStateForTagPoolingServers(true); // Explicitly request tag state clearing. + tag.setPageContext(pageContext); + tag.setName("myForm"); + tag.setMethod("post"); + tag.setAction("doubleValidationAction"); + tag.setAcceptcharset("UTF-8"); + tag.setEnctype("myEncType"); + tag.setTitle("mytitle"); + tag.setOnsubmit("submitMe()"); + tag.setValidate("true"); + tag.setNamespace(""); + + UpDownSelectTag t = new UpDownSelectTag(); + t.setPerformClearTagStateForTagPoolingServers(true); // Explicitly request tag state clearing. + t.setPageContext(pageContext); + t.setName("myUpDownSelectTag"); + t.setList("{}"); + + tag.doStartTag(); + setComponentTagClearTagState(tag, true); // Ensure component tag state clearing is set true (to match tag). + tag.getComponent().getParameters().put("actionClass", DoubleValidationAction.class); + t.doStartTag(); + setComponentTagClearTagState(t, true); // Ensure component tag state clearing is set true (to match tag). + t.doEndTag(); + tag.doEndTag(); + + verify(FormTag.class.getResource("Formtag-24.txt")); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + UpDownSelectTag freshParamTag = new UpDownSelectTag(); + freshParamTag.setPerformClearTagStateForTagPoolingServers(true); + freshParamTag.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(t, freshParamTag)); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + FormTag freshTag = new FormTag(); + freshTag.setPerformClearTagStateForTagPoolingServers(true); + 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)); } @@ -524,18 +1013,64 @@ public class FormTagTest extends AbstractUITagTest { // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). UpDownSelectTag freshParamTag = new UpDownSelectTag(); freshParamTag.setPageContext(pageContext); - assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + 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(t, freshParamTag)); // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). FormTag freshTag = new FormTag(); freshTag.setPageContext(pageContext); - assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + 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)); } + /** + * This test with form tag validation disabled. + */ + public void testFormWithCustomOnsubmitEnabledWithValidateDisabled_clearTagStateSet() throws Exception { + FormTag tag = new FormTag(); + tag.setPerformClearTagStateForTagPoolingServers(true); // Explicitly request tag state clearing. + tag.setPageContext(pageContext); + tag.setName("myForm"); + tag.setMethod("post"); + tag.setAction("myAction"); + tag.setEnctype("myEncType"); + tag.setTitle("mytitle"); + tag.setOnsubmit("submitMe()"); + tag.setValidate("false"); + + UpDownSelectTag t = new UpDownSelectTag(); + t.setPerformClearTagStateForTagPoolingServers(true); // Explicitly request tag state clearing. + t.setPageContext(pageContext); + t.setName("myUpDownSelectTag"); + t.setList("{}"); + + tag.doStartTag(); + setComponentTagClearTagState(tag, true); // Ensure component tag state clearing is set true (to match tag). + t.doStartTag(); + setComponentTagClearTagState(t, true); // Ensure component tag state clearing is set true (to match tag). + t.doEndTag(); + tag.doEndTag(); + + verify(FormTag.class.getResource("Formtag-6.txt")); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + UpDownSelectTag freshParamTag = new UpDownSelectTag(); + freshParamTag.setPerformClearTagStateForTagPoolingServers(true); + freshParamTag.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(t, freshParamTag)); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + FormTag freshTag = new FormTag(); + freshTag.setPerformClearTagStateForTagPoolingServers(true); + 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)); + } /** *

@@ -572,7 +1107,50 @@ public class FormTagTest extends AbstractUITagTest { // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). FormTag freshTag = new FormTag(); freshTag.setPageContext(pageContext); - assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + 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)); + } + + /** + *

+ * Testing that this: + *

+ *
+     * <a:form name="'myForm'" namespace="'/testNamespace'" action="'testNamespaceAction'" method="'post'">
+     * 
+ *

+ * doesn't create an action of "/testNamespace/testNamespaceAction.action" when the "struts.action.extension" + * config property is set to "jspa". + *

+ */ + public void testFormTagWithDifferentActionExtension_clearTagStateSet() throws Exception { + initDispatcher(new HashMap(){{ + put(StrutsConstants.STRUTS_ACTION_EXTENSION, "jspa"); + put("configProviders", TestConfigurationProvider.class.getName()); + }}); + createMocks(); + request.setupGetServletPath("/testNamespace/testNamespaceAction"); + + FormTag tag = new FormTag(); + tag.setPerformClearTagStateForTagPoolingServers(true); // Explicitly request tag state clearing. + tag.setPageContext(pageContext); + tag.setNamespace("/testNamespace"); + tag.setAction("testNamespaceAction"); + tag.setMethod("post"); + tag.setName("myForm"); + + tag.doStartTag(); + setComponentTagClearTagState(tag, true); // Ensure component tag state clearing is set true (to match tag). + tag.doEndTag(); + + verify(FormTag.class.getResource("Formtag-5.txt")); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + FormTag freshTag = new FormTag(); + freshTag.setPerformClearTagStateForTagPoolingServers(true); + 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)); } @@ -600,7 +1178,38 @@ public class FormTagTest extends AbstractUITagTest { // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). FormTag freshTag = new FormTag(); freshTag.setPageContext(pageContext); - assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + 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)); + } + + /** + * Testing that this:
+ * <a:form name="'myForm'" action="'/testNamespace/testNamespaceAction.jspa'" method="'post'"> + *
+ * doesn't create an action of "/testNamespace/testNamespaceAction.action" + */ + public void testFormTagWithDifferentActionExtensionHardcoded_clearTagStateSet() throws Exception { + request.setupGetServletPath("/testNamespace/testNamespaceAction"); + + FormTag tag = new FormTag(); + tag.setPerformClearTagStateForTagPoolingServers(true); // Explicitly request tag state clearing. + tag.setPageContext(pageContext); + tag.setAction("/testNamespace/testNamespaceAction.jspa"); + tag.setMethod("post"); + tag.setName("myForm"); + + tag.doStartTag(); + setComponentTagClearTagState(tag, true); // Ensure component tag state clearing is set true (to match tag). + tag.doEndTag(); + + verify(FormTag.class.getResource("Formtag-5.txt")); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + FormTag freshTag = new FormTag(); + freshTag.setPerformClearTagStateForTagPoolingServers(true); + 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)); } @@ -625,7 +1234,35 @@ public class FormTagTest extends AbstractUITagTest { // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). FormTag freshTag = new FormTag(); freshTag.setPageContext(pageContext); - assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + 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 testFormWithNamespaceDefaulting_clearTagStateSet() throws Exception { + request.setupGetServletPath("/testNamespace/testNamespaceAction"); + + TestAction testAction = (TestAction) action; + testAction.setFoo("bar"); + + FormTag tag = new FormTag(); + tag.setPerformClearTagStateForTagPoolingServers(true); // Explicitly request tag state clearing. + tag.setPageContext(pageContext); + tag.setName("myForm"); + tag.setMethod("post"); + tag.setAction("testNamespaceAction"); + + tag.doStartTag(); + setComponentTagClearTagState(tag, true); // Ensure component tag state clearing is set true (to match tag). + tag.doEndTag(); + + verify(FormTag.class.getResource("Formtag-3.txt")); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + FormTag freshTag = new FormTag(); + freshTag.setPerformClearTagStateForTagPoolingServers(true); + 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)); } @@ -657,14 +1294,60 @@ public class FormTagTest extends AbstractUITagTest { // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). FormTag freshFormTag = new FormTag(); freshFormTag.setPageContext(pageContext); - assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + // FormTag has no non=default state set here, so it compares as equal with the default tag clear state as well. + assertTrue("Tag state after doEndTag() under default tag clear state is inequal to new Tag with pageContext/parent set. " + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", strutsBodyTagsAreReflectionEqual(form1, freshFormTag)); // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). ActionTag freshTag = new ActionTag(); freshTag.setPageContext(pageContext); - assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + 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 testFormTagForStackOverflowException1_clearTagStateSet() throws Exception { + request.setRequestURI("/testAction"); + + FormTag form1 = new FormTag(); + form1.setPerformClearTagStateForTagPoolingServers(true); // Explicitly request tag state clearing. + form1.setPageContext(pageContext); + form1.doStartTag(); + setComponentTagClearTagState(form1, true); // Ensure component tag state clearing is set true (to match tag). + + assertEquals(form1.getComponent().getComponentStack().size(), 1); + + ActionTag tag = new ActionTag(); + tag.setPerformClearTagStateForTagPoolingServers(true); // Explicitly request tag state clearing. + tag.setPageContext(pageContext); + tag.setName("testAction"); + tag.doStartTag(); + setComponentTagClearTagState(tag, true); // Ensure component tag state clearing is set true (to match tag). + + assertEquals(tag.getComponent().getComponentStack().size(), 2); + + tag.doEndTag(); + + assertEquals(form1.getComponent().getComponentStack().size(), 1); + + form1.doEndTag(); + + assertNull(form1.getComponent()); // component is removed after end tag + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + FormTag freshFormTag = new FormTag(); + freshFormTag.setPerformClearTagStateForTagPoolingServers(true); + freshFormTag.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(form1, freshFormTag)); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + ActionTag freshTag = new ActionTag(); + freshTag.setPerformClearTagStateForTagPoolingServers(true); + 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)); } @@ -706,21 +1389,82 @@ public class FormTagTest extends AbstractUITagTest { // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). FormTag freshFormTag = new FormTag(); freshFormTag.setPageContext(pageContext); - assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + // FormTag has no non=default state set here, so it compares as equal with the default tag clear state as well. + assertTrue("Tag state after doEndTag() under default tag clear state is inequal to new Tag with pageContext/parent set. " + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", strutsBodyTagsAreReflectionEqual(form1, freshFormTag)); - assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + // FormTag has no non=default state set here, so it compares as equal with the default tag clear state as well. + assertTrue("Tag state after doEndTag() under default tag clear state is inequal to new Tag with pageContext/parent set. " + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", strutsBodyTagsAreReflectionEqual(form2, freshFormTag)); // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). ActionTag freshTag = new ActionTag(); freshTag.setPageContext(pageContext); - assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + 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 testFormTagForStackOverflowException2_clearTagStateSet() throws Exception { + request.setRequestURI("/requestUri"); + + FormTag form1 = new FormTag(); + form1.setPerformClearTagStateForTagPoolingServers(true); // Explicitly request tag state clearing. + form1.setPageContext(pageContext); + form1.doStartTag(); + setComponentTagClearTagState(form1, true); // Ensure component tag state clearing is set true (to match tag). + + assertEquals(form1.getComponent().getComponentStack().size(), 1); + + FormTag form2 = new FormTag(); + form2.setPerformClearTagStateForTagPoolingServers(true); // Explicitly request tag state clearing. + form2.setPageContext(pageContext); + form2.doStartTag(); + setComponentTagClearTagState(form2, true); // Ensure component tag state clearing is set true (to match tag). + + assertEquals(form2.getComponent().getComponentStack().size(), 2); + + ActionTag tag = new ActionTag(); + tag.setPerformClearTagStateForTagPoolingServers(true); // Explicitly request tag state clearing. + tag.setPageContext(pageContext); + tag.setName("testAction"); + tag.doStartTag(); + setComponentTagClearTagState(tag, true); // Ensure component tag state clearing is set true (to match tag). + + assertEquals(tag.getComponent().getComponentStack().size(), 3); + + tag.doEndTag(); + + assertEquals(form2.getComponent().getComponentStack().size(), 2); + + form2.doEndTag(); + + assertEquals(form1.getComponent().getComponentStack().size(), 1); + + form1.doEndTag(); + + assertNull(form1.getComponent()); // component is removed after end tag + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + FormTag freshFormTag = new FormTag(); + freshFormTag.setPerformClearTagStateForTagPoolingServers(true); + freshFormTag.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(form1, freshFormTag)); + 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(form2, freshFormTag)); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + ActionTag freshTag = new ActionTag(); + freshTag.setPerformClearTagStateForTagPoolingServers(true); + 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)); + } public void testFormTagForStackOverflowException3() throws Exception { request.setRequestURI("/requestUri"); @@ -769,24 +1513,101 @@ public class FormTagTest extends AbstractUITagTest { // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). FormTag freshFormTag = new FormTag(); freshFormTag.setPageContext(pageContext); - assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + // FormTag has no non=default state set here, so it compares as equal with the default tag clear state as well. + assertTrue("Tag state after doEndTag() under default tag clear state is inequal to new Tag with pageContext/parent set. " + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", strutsBodyTagsAreReflectionEqual(form1, freshFormTag)); - assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + // FormTag has no non=default state set here, so it compares as equal with the default tag clear state as well. + assertTrue("Tag state after doEndTag() under default tag clear state is inequal to new Tag with pageContext/parent set. " + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", strutsBodyTagsAreReflectionEqual(form2, freshFormTag)); - assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + // FormTag has no non=default state set here, so it compares as equal with the default tag clear state as well. + assertTrue("Tag state after doEndTag() under default tag clear state is inequal to new Tag with pageContext/parent set. " + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", strutsBodyTagsAreReflectionEqual(form3, freshFormTag)); // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). ActionTag freshTag = new ActionTag(); freshTag.setPageContext(pageContext); - assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + 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 testFormTagForStackOverflowException3_clearTagStateSet() throws Exception { + request.setRequestURI("/requestUri"); + + FormTag form1 = new FormTag(); + form1.setPerformClearTagStateForTagPoolingServers(true); // Explicitly request tag state clearing. + form1.setPageContext(pageContext); + form1.doStartTag(); + setComponentTagClearTagState(form1, true); // Ensure component tag state clearing is set true (to match tag). + + assertEquals(form1.getComponent().getComponentStack().size(), 1); + + FormTag form2 = new FormTag(); + form2.setPerformClearTagStateForTagPoolingServers(true); // Explicitly request tag state clearing. + form2.setPageContext(pageContext); + form2.doStartTag(); + setComponentTagClearTagState(form2, true); // Ensure component tag state clearing is set true (to match tag). + + assertEquals(form2.getComponent().getComponentStack().size(), 2); + + FormTag form3 = new FormTag(); + form3.setPerformClearTagStateForTagPoolingServers(true); // Explicitly request tag state clearing. + form3.setPageContext(pageContext); + form3.doStartTag(); + setComponentTagClearTagState(form3, true); // Ensure component tag state clearing is set true (to match tag). + + assertEquals(form3.getComponent().getComponentStack().size(), 3); + + ActionTag tag = new ActionTag(); + tag.setPerformClearTagStateForTagPoolingServers(true); // Explicitly request tag state clearing. + tag.setPageContext(pageContext); + tag.setName("testAction"); + tag.doStartTag(); + setComponentTagClearTagState(tag, true); // Ensure component tag state clearing is set true (to match tag). + + assertEquals(tag.getComponent().getComponentStack().size(), 4); + + tag.doEndTag(); + + assertEquals(form3.getComponent().getComponentStack().size(), 3); + + form3.doEndTag(); + + assertEquals(form2.getComponent().getComponentStack().size(), 2); + + form2.doEndTag(); + + assertEquals(form1.getComponent().getComponentStack().size(), 1); + + form1.doEndTag(); + + assertNull(form1.getComponent()); // component is removed after end tag + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + FormTag freshFormTag = new FormTag(); + freshFormTag.setPerformClearTagStateForTagPoolingServers(true); + freshFormTag.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(form1, freshFormTag)); + 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(form2, freshFormTag)); + 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(form3, freshFormTag)); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + ActionTag freshTag = new ActionTag(); + freshTag.setPerformClearTagStateForTagPoolingServers(true); + 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)); + } public void testFormComponentIsRemoved() throws Exception { request.setRequestURI("/requestUri"); @@ -804,11 +1625,35 @@ public class FormTagTest extends AbstractUITagTest { // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). FormTag freshTag = new FormTag(); freshTag.setPageContext(pageContext); - assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + // FormTag has no non=default state set here, so it compares as equal with the default tag clear state as well. + assertTrue("Tag state after doEndTag() under default tag clear state is inequal to new Tag with pageContext/parent set. " + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", strutsBodyTagsAreReflectionEqual(form, freshTag)); } + public void testFormComponentIsRemoved_clearTagStateSet() throws Exception { + request.setRequestURI("/requestUri"); + + FormTag form = new FormTag(); + form.setPerformClearTagStateForTagPoolingServers(true); // Explicitly request tag state clearing. + form.setPageContext(pageContext); + form.doStartTag(); + setComponentTagClearTagState(form, true); // Ensure component tag state clearing is set true (to match tag). + + assertEquals(form.getComponent().getComponentStack().size(), 1); + + form.doEndTag(); + + assertNull(form.getComponent()); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + FormTag freshTag = new FormTag(); + freshTag.setPerformClearTagStateForTagPoolingServers(true); + 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(form, freshTag)); + } public void testFormWithNoAction() throws Exception { request.setupGetServletPath("/"); @@ -825,7 +1670,31 @@ public class FormTagTest extends AbstractUITagTest { // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). FormTag freshTag = new FormTag(); freshTag.setPageContext(pageContext); - assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + // FormTag has no non=default state set here, so it compares as equal with the default tag clear state as well. + assertTrue("Tag state after doEndTag() under default tag clear state is inequal to new Tag with pageContext/parent set. " + + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", + strutsBodyTagsAreReflectionEqual(tag, freshTag)); + } + + public void testFormWithNoAction_clearTagStateSet() throws Exception { + request.setupGetServletPath("/"); + request.setupGetContextPath("/"); + request.setRequestURI("/foo.jsp"); + + FormTag tag = new FormTag(); + tag.setPerformClearTagStateForTagPoolingServers(true); // Explicitly request tag state clearing. + tag.setPageContext(pageContext); + tag.doStartTag(); + setComponentTagClearTagState(tag, true); // Ensure component tag state clearing is set true (to match tag). + tag.doEndTag(); + + verify(FormTag.class.getResource("Formtag-4.txt")); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + FormTag freshTag = new FormTag(); + freshTag.setPerformClearTagStateForTagPoolingServers(true); + 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)); } @@ -846,7 +1715,31 @@ public class FormTagTest extends AbstractUITagTest { // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). FormTag freshTag = new FormTag(); freshTag.setPageContext(pageContext); - assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + 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 testFormWithStaticAction_clearTagStateSet() throws Exception { + request.setupGetServletPath("/"); + request.setupGetContextPath("/"); + request.setRequestURI("/foo.jsp"); + + FormTag tag = new FormTag(); + tag.setPerformClearTagStateForTagPoolingServers(true); // Explicitly request tag state clearing. + tag.setPageContext(pageContext); + tag.setAction("test.html"); + tag.doStartTag(); + setComponentTagClearTagState(tag, true); // Ensure component tag state clearing is set true (to match tag). + tag.doEndTag(); + + verify(FormTag.class.getResource("Formtag-7.txt")); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + FormTag freshTag = new FormTag(); + freshTag.setPerformClearTagStateForTagPoolingServers(true); + 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)); } @@ -868,7 +1761,32 @@ public class FormTagTest extends AbstractUITagTest { // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). FormTag freshTag = new FormTag(); freshTag.setPageContext(pageContext); - assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + 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 testFormWithActionAndExtension_clearTagStateSet() throws Exception { + request.setupGetServletPath("/BLA"); + + FormTag tag = new FormTag(); + tag.setPerformClearTagStateForTagPoolingServers(true); // Explicitly request tag state clearing. + tag.setPageContext(pageContext); + tag.setAction("/testNamespace/testNamespaceAction.jspa"); + tag.setMethod("post"); + tag.setName("myForm"); + + tag.doStartTag(); + setComponentTagClearTagState(tag, true); // Ensure component tag state clearing is set true (to match tag). + tag.doEndTag(); + + verify(FormTag.class.getResource("Formtag-8.txt")); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + FormTag freshTag = new FormTag(); + freshTag.setPerformClearTagStateForTagPoolingServers(true); + 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)); } @@ -895,14 +1813,54 @@ public class FormTagTest extends AbstractUITagTest { // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). FormTag freshFormTag = new FormTag(); freshFormTag.setPageContext(pageContext); - assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + 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(form, freshFormTag)); // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). TextFieldTag freshTag = new TextFieldTag(); freshTag.setPageContext(pageContext); - assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + 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(text, freshTag)); + } + + public void testFormWithTopLabelPosition_clearTagStateSet() throws Exception { + FormTag form = new FormTag(); + form.setPerformClearTagStateForTagPoolingServers(true); // Explicitly request tag state clearing. + form.setTheme("xhtml"); + form.setAction("testAction"); + form.setPageContext(pageContext); + form.setIncludeContext(false); + form.setLabelposition("top"); + + TextFieldTag text = new TextFieldTag(); + text.setPerformClearTagStateForTagPoolingServers(true); // Explicitly request tag state clearing. + text.setPageContext(pageContext); + text.setLabel("label"); + + form.doStartTag(); + setComponentTagClearTagState(form, true); // Ensure component tag state clearing is set true (to match tag). + text.doStartTag(); + setComponentTagClearTagState(text, true); // Ensure component tag state clearing is set true (to match tag). + text.doEndTag(); + form.doEndTag(); + + verify(FormTag.class.getResource("Formtag-27.txt")); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + FormTag freshFormTag = new FormTag(); + freshFormTag.setPerformClearTagStateForTagPoolingServers(true); + freshFormTag.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(form, freshFormTag)); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + TextFieldTag freshTag = new TextFieldTag(); + freshTag.setPerformClearTagStateForTagPoolingServers(true); + 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(text, freshTag)); } @@ -930,14 +1888,55 @@ public class FormTagTest extends AbstractUITagTest { // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). FormTag freshFormTag = new FormTag(); freshFormTag.setPageContext(pageContext); - assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + 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(form, freshFormTag)); // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). TextFieldTag freshTag = new TextFieldTag(); freshTag.setPageContext(pageContext); - assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + 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(text, freshTag)); + } + + public void testFormWithTopLabelPositionWithElementOverride_clearTagStateSet() throws Exception { + FormTag form = new FormTag(); + form.setPerformClearTagStateForTagPoolingServers(true); // Explicitly request tag state clearing. + form.setTheme("xhtml"); + form.setAction("testAction"); + form.setPageContext(pageContext); + form.setIncludeContext(false); + form.setLabelposition("left"); + + TextFieldTag text = new TextFieldTag(); + text.setPerformClearTagStateForTagPoolingServers(true); // Explicitly request tag state clearing. + text.setPageContext(pageContext); + text.setLabel("label"); + text.setLabelposition("top"); + + form.doStartTag(); + setComponentTagClearTagState(form, true); // Ensure component tag state clearing is set true (to match tag). + text.doStartTag(); + setComponentTagClearTagState(text, true); // Ensure component tag state clearing is set true (to match tag). + text.doEndTag(); + form.doEndTag(); + + verify(FormTag.class.getResource("Formtag-27.txt")); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + FormTag freshFormTag = new FormTag(); + freshFormTag.setPerformClearTagStateForTagPoolingServers(true); + freshFormTag.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(form, freshFormTag)); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + TextFieldTag freshTag = new TextFieldTag(); + freshTag.setPerformClearTagStateForTagPoolingServers(true); + 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(text, freshTag)); } @@ -964,14 +1963,54 @@ public class FormTagTest extends AbstractUITagTest { // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). FormTag freshFormTag = new FormTag(); freshFormTag.setPageContext(pageContext); - assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + 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(form, freshFormTag)); // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). TextFieldTag freshTag = new TextFieldTag(); freshTag.setPageContext(pageContext); - assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + 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(text, freshTag)); + } + + public void testFormWithTopLabelPositionCssXhtml_clearTagStateSet() throws Exception { + FormTag form = new FormTag(); + form.setPerformClearTagStateForTagPoolingServers(true); // Explicitly request tag state clearing. + form.setTheme("css_xhtml"); + form.setAction("testAction"); + form.setPageContext(pageContext); + form.setIncludeContext(false); + form.setLabelposition("top"); + + TextFieldTag text = new TextFieldTag(); + text.setPerformClearTagStateForTagPoolingServers(true); // Explicitly request tag state clearing. + text.setPageContext(pageContext); + text.setLabel("label"); + + form.doStartTag(); + setComponentTagClearTagState(form, true); // Ensure component tag state clearing is set true (to match tag). + text.doStartTag(); + setComponentTagClearTagState(text, true); // Ensure component tag state clearing is set true (to match tag). + text.doEndTag(); + form.doEndTag(); + + verify(FormTag.class.getResource("Formtag-28.txt")); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + FormTag freshFormTag = new FormTag(); + freshFormTag.setPerformClearTagStateForTagPoolingServers(true); + freshFormTag.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(form, freshFormTag)); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + TextFieldTag freshTag = new TextFieldTag(); + freshTag.setPerformClearTagStateForTagPoolingServers(true); + 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(text, freshTag)); } @@ -999,14 +2038,55 @@ public class FormTagTest extends AbstractUITagTest { // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). FormTag freshFormTag = new FormTag(); freshFormTag.setPageContext(pageContext); - assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + 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(form, freshFormTag)); // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). TextFieldTag freshTag = new TextFieldTag(); freshTag.setPageContext(pageContext); - assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + 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(text, freshTag)); + } + + public void testFormWithTopLabelPositionWithElementOverrideCssXhtml_clearTagStateSet() throws Exception { + FormTag form = new FormTag(); + form.setPerformClearTagStateForTagPoolingServers(true); // Explicitly request tag state clearing. + form.setTheme("css_xhtml"); + form.setAction("testAction"); + form.setPageContext(pageContext); + form.setIncludeContext(false); + form.setLabelposition("left"); + + TextFieldTag text = new TextFieldTag(); + text.setPerformClearTagStateForTagPoolingServers(true); // Explicitly request tag state clearing. + text.setPageContext(pageContext); + text.setLabel("label"); + text.setLabelposition("top"); + + form.doStartTag(); + setComponentTagClearTagState(form, true); // Ensure component tag state clearing is set true (to match tag). + text.doStartTag(); + setComponentTagClearTagState(text, true); // Ensure component tag state clearing is set true (to match tag). + text.doEndTag(); + form.doEndTag(); + + verify(FormTag.class.getResource("Formtag-28.txt")); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + FormTag freshFormTag = new FormTag(); + freshFormTag.setPerformClearTagStateForTagPoolingServers(true); + freshFormTag.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(form, freshFormTag)); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + TextFieldTag freshTag = new TextFieldTag(); + freshTag.setPerformClearTagStateForTagPoolingServers(true); + 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(text, freshTag)); } diff --git a/core/src/test/java/org/apache/struts2/views/jsp/ui/HeadTagTest.java b/core/src/test/java/org/apache/struts2/views/jsp/ui/HeadTagTest.java index 493515fba..ce113672d 100644 --- a/core/src/test/java/org/apache/struts2/views/jsp/ui/HeadTagTest.java +++ b/core/src/test/java/org/apache/struts2/views/jsp/ui/HeadTagTest.java @@ -43,7 +43,28 @@ public class HeadTagTest extends AbstractUITagTest { // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). HeadTag freshTag = new HeadTag(); freshTag.setPageContext(pageContext); - assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + // HeadTag has no non=default state set here, so it compares as equal with the default tag clear state as well. + assertTrue("Tag state after doEndTag() under default tag clear state is inequal to new Tag with pageContext/parent set. " + + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", + strutsBodyTagsAreReflectionEqual(tag, freshTag)); + } + + public void testHead1_clearTagStateSet() throws Exception { + HeadTag tag = new HeadTag(); + tag.setPerformClearTagStateForTagPoolingServers(true); // Explicitly request tag state clearing. + tag.setPageContext(pageContext); + + tag.doStartTag(); + setComponentTagClearTagState(tag, true); // Ensure component tag state clearing is set true (to match tag). + tag.doEndTag(); + + verify(HeadTagTest.class.getResource("HeadTagTest-1.txt")); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + HeadTag freshTag = new HeadTag(); + freshTag.setPerformClearTagStateForTagPoolingServers(true); + 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)); } diff --git a/core/src/test/java/org/apache/struts2/views/jsp/ui/HiddenTest.java b/core/src/test/java/org/apache/struts2/views/jsp/ui/HiddenTest.java index c2b062852..d6d62e1a0 100644 --- a/core/src/test/java/org/apache/struts2/views/jsp/ui/HiddenTest.java +++ b/core/src/test/java/org/apache/struts2/views/jsp/ui/HiddenTest.java @@ -48,7 +48,33 @@ public class HiddenTest extends AbstractUITagTest { // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). HiddenTag freshTag = new HiddenTag(); freshTag.setPageContext(pageContext); - assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + 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 testSimple_clearTagStateSet() throws Exception { + TestAction testAction = (TestAction) action; + testAction.setFoo("bar"); + + HiddenTag tag = new HiddenTag(); + tag.setPerformClearTagStateForTagPoolingServers(true); // Explicitly request tag state clearing. + tag.setPageContext(pageContext); + tag.setLabel("mylabel"); + tag.setName("myname"); + tag.setValue("%{foo}"); + + tag.doStartTag(); + setComponentTagClearTagState(tag, true); // Ensure component tag state clearing is set true (to match tag). + tag.doEndTag(); + + verify(TextFieldTag.class.getResource("Hidden-1.txt")); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + HiddenTag freshTag = new HiddenTag(); + freshTag.setPerformClearTagStateForTagPoolingServers(true); + 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)); } @@ -72,7 +98,34 @@ public class HiddenTest extends AbstractUITagTest { // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). HiddenTag freshTag = new HiddenTag(); freshTag.setPageContext(pageContext); - assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + 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 testDisabled_clearTagStateSet() throws Exception { + TestAction testAction = (TestAction) action; + testAction.setFoo("bar"); + + HiddenTag tag = new HiddenTag(); + tag.setPerformClearTagStateForTagPoolingServers(true); // Explicitly request tag state clearing. + tag.setPageContext(pageContext); + tag.setLabel("mylabel"); + tag.setName("myname"); + tag.setValue("%{foo}"); + tag.setDisabled("true"); + + tag.doStartTag(); + setComponentTagClearTagState(tag, true); // Ensure component tag state clearing is set true (to match tag). + tag.doEndTag(); + + verify(TextFieldTag.class.getResource("Hidden-2.txt")); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + HiddenTag freshTag = new HiddenTag(); + freshTag.setPerformClearTagStateForTagPoolingServers(true); + 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)); } @@ -103,7 +156,41 @@ public class HiddenTest extends AbstractUITagTest { // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). HiddenTag freshTag = new HiddenTag(); freshTag.setPageContext(pageContext); - assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + 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 testDynamicAttributesWithActionInvocation_clearTagStateSet() throws Exception { + TestAction testAction = (TestAction) action; + testAction.setId(27357L); + + MockActionInvocation ai = new MockActionInvocation(); + ai.setAction(action); + ActionContext.getContext().setActionInvocation(ai); + + HiddenTag tag = new HiddenTag(); + tag.setPerformClearTagStateForTagPoolingServers(true); // Explicitly request tag state clearing. + tag.setPageContext(pageContext); + tag.setId("einszwei"); + tag.setName("first"); + tag.setValue("%{id}"); + tag.setDynamicAttribute("", "data-wuffmiauww", "%{id}"); + + tag.doStartTag(); + setComponentTagClearTagState(tag, true); // Ensure component tag state clearing is set true (to match tag). + tag.doEndTag(); + + assertSame(stack.pop(), testAction); + assertNotSame(stack.pop(), tag); + + verify(TextFieldTag.class.getResource("Hidden-3.txt")); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + HiddenTag freshTag = new HiddenTag(); + freshTag.setPerformClearTagStateForTagPoolingServers(true); + 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)); } @@ -130,7 +217,37 @@ public class HiddenTest extends AbstractUITagTest { // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). HiddenTag freshTag = new HiddenTag(); freshTag.setPageContext(pageContext); - assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + 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 testDynamicAttributesWithStack_clearTagStateSet() throws Exception { + TestAction testAction = (TestAction) action; + testAction.setId(27357L); + + HiddenTag tag = new HiddenTag(); + tag.setPerformClearTagStateForTagPoolingServers(true); // Explicitly request tag state clearing. + tag.setPageContext(pageContext); + tag.setId("einszwei"); + tag.setName("first"); + tag.setValue("%{id}"); + tag.setDynamicAttribute("", "data-wuffmiauww", "%{id}"); + + tag.doStartTag(); + setComponentTagClearTagState(tag, true); // Ensure component tag state clearing is set true (to match tag). + tag.doEndTag(); + + assertSame(stack.pop(), testAction); + assertNotSame(stack.pop(), tag); + + verify(TextFieldTag.class.getResource("Hidden-3.txt")); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + HiddenTag freshTag = new HiddenTag(); + freshTag.setPerformClearTagStateForTagPoolingServers(true); + 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)); } diff --git a/core/src/test/java/org/apache/struts2/views/jsp/ui/InputTransferSelectTagTest.java b/core/src/test/java/org/apache/struts2/views/jsp/ui/InputTransferSelectTagTest.java index eb938798c..ed3ae2483 100644 --- a/core/src/test/java/org/apache/struts2/views/jsp/ui/InputTransferSelectTagTest.java +++ b/core/src/test/java/org/apache/struts2/views/jsp/ui/InputTransferSelectTagTest.java @@ -53,7 +53,38 @@ public class InputTransferSelectTagTest extends AbstractUITagTest { // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). InputTransferSelectTag freshTag = new InputTransferSelectTag(); freshTag.setPageContext(pageContext); - assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + 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 testWithRequired_clearTagStateSet() throws Exception { + List list = new ArrayList(); + list.add("Item One"); + list.add("Item Two"); + + TestAction testaction = (TestAction) action; + testaction.setCollection(list); + + InputTransferSelectTag tag = new InputTransferSelectTag(); + tag.setPerformClearTagStateForTagPoolingServers(true); // Explicitly request tag state clearing. + tag.setPageContext(pageContext); + + tag.setName("collection"); + tag.setList("collection"); + + tag.doStartTag(); + setComponentTagClearTagState(tag, true); // Ensure component tag state clearing is set true (to match tag). + tag.doEndTag(); + + //System.out.println(writer.toString()); + verify(InputTransferSelectTagTest.class.getResource("inputtransferselect-1.txt")); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + InputTransferSelectTag freshTag = new InputTransferSelectTag(); + freshTag.setPerformClearTagStateForTagPoolingServers(true); + 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)); } diff --git a/core/src/test/java/org/apache/struts2/views/jsp/ui/JspTemplateTest.java b/core/src/test/java/org/apache/struts2/views/jsp/ui/JspTemplateTest.java index 9add2d1e5..f0d98ae1d 100644 --- a/core/src/test/java/org/apache/struts2/views/jsp/ui/JspTemplateTest.java +++ b/core/src/test/java/org/apache/struts2/views/jsp/ui/JspTemplateTest.java @@ -51,6 +51,32 @@ public class JspTemplateTest extends AbstractUITagTest { // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). CheckboxTag freshTag = new CheckboxTag(); 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 testCheckBox_clearTagStateSet() throws Exception { + TestAction testAction = (TestAction) action; + testAction.setFoo("true"); + + CheckboxTag tag = new CheckboxTag(); + Mock rdMock = new Mock(RequestDispatcher.class); + rdMock.expect("include",C.args(C.isA(HttpServletRequest.class), C.isA(HttpServletResponse.class))); + RequestDispatcher dispatcher = (RequestDispatcher) rdMock.proxy(); + request.setupGetRequestDispatcher(dispatcher); + tag.setPerformClearTagStateForTagPoolingServers(true); // Explicitly request tag state clearing. + tag.setPageContext(pageContext); + tag.setTemplate("/test/checkbox.jsp"); + tag.doStartTag(); + setComponentTagClearTagState(tag, true); // Ensure component tag state clearing is set true (to match tag). + tag.doEndTag(); + rdMock.verify(); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + CheckboxTag freshTag = new CheckboxTag(); + freshTag.setPerformClearTagStateForTagPoolingServers(true); + freshTag.setPageContext(pageContext); assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", strutsBodyTagsAreReflectionEqual(tag, freshTag)); diff --git a/core/src/test/java/org/apache/struts2/views/jsp/ui/LabelTest.java b/core/src/test/java/org/apache/struts2/views/jsp/ui/LabelTest.java index 6d5689f49..c277ef9ee 100644 --- a/core/src/test/java/org/apache/struts2/views/jsp/ui/LabelTest.java +++ b/core/src/test/java/org/apache/struts2/views/jsp/ui/LabelTest.java @@ -48,7 +48,34 @@ public class LabelTest extends AbstractUITagTest { // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). LabelTag freshTag = new LabelTag(); freshTag.setPageContext(pageContext); - assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + 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 testSimple_clearTagStateSet() throws Exception { + TestAction testAction = (TestAction) action; + testAction.setFoo("bar"); + + LabelTag tag = new LabelTag(); + tag.setPerformClearTagStateForTagPoolingServers(true); // Explicitly request tag state clearing. + tag.setPageContext(pageContext); + tag.setLabel("mylabel"); + tag.setName("myname"); + tag.setTitle("mytitle"); + tag.setValue("%{foo}"); + + tag.doStartTag(); + setComponentTagClearTagState(tag, true); // Ensure component tag state clearing is set true (to match tag). + tag.doEndTag(); + + verify(LabelTest.class.getResource("Label-1.txt")); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + LabelTag freshTag = new LabelTag(); + freshTag.setPerformClearTagStateForTagPoolingServers(true); + 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)); } @@ -72,7 +99,34 @@ public class LabelTest extends AbstractUITagTest { // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). LabelTag freshTag = new LabelTag(); freshTag.setPageContext(pageContext); - assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + 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 testSimpleWithLabelposition_clearTagStateSet() throws Exception { + TestAction testAction = (TestAction) action; + testAction.setFoo("bar"); + + LabelTag tag = new LabelTag(); + tag.setPerformClearTagStateForTagPoolingServers(true); // Explicitly request tag state clearing. + tag.setPageContext(pageContext); + tag.setLabel("mylabel"); + tag.setName("myname"); + tag.setValue("%{foo}"); + tag.setLabelposition("top"); + + tag.doStartTag(); + setComponentTagClearTagState(tag, true); // Ensure component tag state clearing is set true (to match tag). + tag.doEndTag(); + + verify(LabelTest.class.getResource("Label-3.txt")); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + LabelTag freshTag = new LabelTag(); + freshTag.setPerformClearTagStateForTagPoolingServers(true); + 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)); } @@ -114,7 +168,33 @@ public class LabelTest extends AbstractUITagTest { // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). LabelTag freshTag = new LabelTag(); freshTag.setPageContext(pageContext); - assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + 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 testWithNoValue_clearTagStateSet() throws Exception { + TestAction testAction = (TestAction) action; + testAction.setFoo("baz"); + + LabelTag tag = new LabelTag(); + tag.setPerformClearTagStateForTagPoolingServers(true); // Explicitly request tag state clearing. + tag.setPageContext(pageContext); + tag.setLabel("mylabel"); + tag.setName("foo"); + tag.setFor("for"); + + tag.doStartTag(); + setComponentTagClearTagState(tag, true); // Ensure component tag state clearing is set true (to match tag). + tag.doEndTag(); + + verify(LabelTest.class.getResource("Label-5.txt")); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + LabelTag freshTag = new LabelTag(); + freshTag.setPerformClearTagStateForTagPoolingServers(true); + 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)); } @@ -152,7 +232,38 @@ public class LabelTest extends AbstractUITagTest { // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). LabelTag freshTag = new LabelTag(); freshTag.setPageContext(pageContext); - assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + 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 testWithKeyNoValueFromStack_clearTagStateSet() throws Exception { + TestAction testAction = (TestAction) action; + final String key = "labelKey"; + final String value = "baz"; + testAction.setText(key, value); + + testAction.setFoo("notToBeOutput"); + + LabelTag tag = new LabelTag(); + tag.setPerformClearTagStateForTagPoolingServers(true); // Explicitly request tag state clearing. + tag.setPageContext(pageContext); + tag.setLabel("mylabel"); + tag.setFor("for"); + tag.setName("foo2"); + tag.setKey(key); + + tag.doStartTag(); + setComponentTagClearTagState(tag, true); // Ensure component tag state clearing is set true (to match tag). + tag.doEndTag(); + + verify(LabelTest.class.getResource("Label-2.txt")); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + LabelTag freshTag = new LabelTag(); + freshTag.setPerformClearTagStateForTagPoolingServers(true); + 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)); } @@ -180,7 +291,38 @@ public class LabelTest extends AbstractUITagTest { // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). LabelTag freshTag = new LabelTag(); freshTag.setPageContext(pageContext); - assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + 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 testWithKeyValueFromStack_clearTagStateSet() throws Exception { + TestAction testAction = (TestAction) action; + final String key = "labelKey"; + final String value = "baz"; + testAction.setText(key, value); + + testAction.setFoo("output"); + + LabelTag tag = new LabelTag(); + tag.setPerformClearTagStateForTagPoolingServers(true); // Explicitly request tag state clearing. + tag.setPageContext(pageContext); + tag.setLabel("mylabel"); + tag.setFor("for"); + tag.setName("foo"); + tag.setKey(key); + + tag.doStartTag(); + setComponentTagClearTagState(tag, true); // Ensure component tag state clearing is set true (to match tag). + tag.doEndTag(); + + verify(LabelTest.class.getResource("Label-4.txt")); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + LabelTag freshTag = new LabelTag(); + freshTag.setPerformClearTagStateForTagPoolingServers(true); + 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)); } @@ -206,7 +348,36 @@ public class LabelTest extends AbstractUITagTest { // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). LabelTag freshTag = new LabelTag(); freshTag.setPageContext(pageContext); - assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + 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 testWithJustKeyValueFromStack_clearTagStateSet() throws Exception { + TestAction testAction = (TestAction) action; + final String key = "labelKey"; + final String value = "baz"; + + // put key with message in a "resource" + testAction.setText(key, value); + + LabelTag tag = new LabelTag(); + tag.setPerformClearTagStateForTagPoolingServers(true); // Explicitly request tag state clearing. + tag.setPageContext(pageContext); + tag.setKey(key); + tag.setTheme("simple"); + + tag.doStartTag(); + setComponentTagClearTagState(tag, true); // Ensure component tag state clearing is set true (to match tag). + tag.doEndTag(); + + verify(LabelTest.class.getResource("Label-6.txt")); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + LabelTag freshTag = new LabelTag(); + freshTag.setPerformClearTagStateForTagPoolingServers(true); + 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)); } @@ -233,7 +404,37 @@ public class LabelTest extends AbstractUITagTest { // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). LabelTag freshTag = new LabelTag(); freshTag.setPageContext(pageContext); - assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + 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 testWithCssErrorClass_clearTagStateSet() throws Exception { + TestAction testAction = (TestAction) action; + testAction.setFoo("bar"); + + testAction.addFieldError("myname", "error"); + + LabelTag tag = new LabelTag(); + tag.setPerformClearTagStateForTagPoolingServers(true); // Explicitly request tag state clearing. + tag.setPageContext(pageContext); + tag.setLabel("mylabel"); + tag.setName("myname"); + tag.setTitle("mytitle"); + tag.setValue("%{foo}"); + tag.setCssErrorClass("cssErrorClass1"); + + tag.doStartTag(); + setComponentTagClearTagState(tag, true); // Ensure component tag state clearing is set true (to match tag). + tag.doEndTag(); + + verify(LabelTest.class.getResource("Label-7.txt")); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + LabelTag freshTag = new LabelTag(); + freshTag.setPerformClearTagStateForTagPoolingServers(true); + 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)); } @@ -260,7 +461,37 @@ public class LabelTest extends AbstractUITagTest { // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). LabelTag freshTag = new LabelTag(); freshTag.setPageContext(pageContext); - assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + 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 testWithCssErrorStyle_clearTagStateSet() throws Exception { + TestAction testAction = (TestAction) action; + testAction.setFoo("bar"); + + testAction.addFieldError("myname", "error"); + + LabelTag tag = new LabelTag(); + tag.setPerformClearTagStateForTagPoolingServers(true); // Explicitly request tag state clearing. + tag.setPageContext(pageContext); + tag.setLabel("mylabel"); + tag.setName("myname"); + tag.setTitle("mytitle"); + tag.setValue("%{foo}"); + tag.setCssErrorStyle("cssErrorStyle1"); + + tag.doStartTag(); + setComponentTagClearTagState(tag, true); // Ensure component tag state clearing is set true (to match tag). + tag.doEndTag(); + + verify(LabelTest.class.getResource("Label-8.txt")); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + LabelTag freshTag = new LabelTag(); + freshTag.setPerformClearTagStateForTagPoolingServers(true); + 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)); } diff --git a/core/src/test/java/org/apache/struts2/views/jsp/ui/OptGroupTest.java b/core/src/test/java/org/apache/struts2/views/jsp/ui/OptGroupTest.java index b4a6484d4..23ac34c09 100644 --- a/core/src/test/java/org/apache/struts2/views/jsp/ui/OptGroupTest.java +++ b/core/src/test/java/org/apache/struts2/views/jsp/ui/OptGroupTest.java @@ -56,21 +56,74 @@ public class OptGroupTest extends AbstractUITagTest { // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). SelectTag freshTag = new SelectTag(); freshTag.setPageContext(pageContext); - assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + 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(selectTag, freshTag)); // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). OptGroupTag freshOptGroupTag = new OptGroupTag(); freshOptGroupTag.setPageContext(pageContext); - assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + 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(optGroupTag1, freshOptGroupTag)); - assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + 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(optGroupTag2, freshOptGroupTag)); } + public void testOptGroupSimple_clearTagStateSet() throws Exception { + SelectTag selectTag = new SelectTag(); + selectTag.setPerformClearTagStateForTagPoolingServers(true); // Explicitly request tag state clearing. + selectTag.setName("mySelection"); + selectTag.setLabel("My Selection"); + selectTag.setList("%{#{'ONE':'one','TWO':'two','THREE':'three'}}"); + + OptGroupTag optGroupTag1 = new OptGroupTag(); + optGroupTag1.setPerformClearTagStateForTagPoolingServers(true); // Explicitly request tag state clearing. + optGroupTag1.setLabel("My Label 1"); + optGroupTag1.setList("%{#{'AAA':'aaa','BBB':'bbb','CCC':'ccc'}}"); + + OptGroupTag optGroupTag2 = new OptGroupTag(); + optGroupTag2.setPerformClearTagStateForTagPoolingServers(true); // Explicitly request tag state clearing. + optGroupTag2.setLabel("My Label 2"); + optGroupTag2.setList("%{#{'DDD':'ddd','EEE':'eee','FFF':'fff'}}"); + + selectTag.setPageContext(pageContext); + selectTag.doStartTag(); + setComponentTagClearTagState(selectTag, true); // Ensure component tag state clearing is set true (to match tag). + optGroupTag1.setPageContext(pageContext); + optGroupTag1.doStartTag(); + setComponentTagClearTagState(optGroupTag1, true); // Ensure component tag state clearing is set true (to match tag). + optGroupTag1.doEndTag(); + optGroupTag2.setPageContext(pageContext); + optGroupTag2.doStartTag(); + setComponentTagClearTagState(optGroupTag2, true); // Ensure component tag state clearing is set true (to match tag). + optGroupTag2.doEndTag(); + selectTag.doEndTag(); + + + //System.out.println(writer.toString()); + verify(SelectTag.class.getResource("OptGroup-1.txt")); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + SelectTag freshTag = new SelectTag(); + freshTag.setPerformClearTagStateForTagPoolingServers(true); + 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(selectTag, freshTag)); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + OptGroupTag freshOptGroupTag = new OptGroupTag(); + freshOptGroupTag.setPerformClearTagStateForTagPoolingServers(true); + freshOptGroupTag.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(optGroupTag1, freshOptGroupTag)); + 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(optGroupTag2, freshOptGroupTag)); + } public void testOptGroupWithSingleSelect() throws Exception { @@ -105,21 +158,76 @@ public class OptGroupTest extends AbstractUITagTest { // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). SelectTag freshTag = new SelectTag(); freshTag.setPageContext(pageContext); - assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + 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(selectTag, freshTag)); // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). OptGroupTag freshOptGroupTag = new OptGroupTag(); freshOptGroupTag.setPageContext(pageContext); - assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + 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(optGroupTag1, freshOptGroupTag)); - assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + 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(optGroupTag2, freshOptGroupTag)); } + public void testOptGroupWithSingleSelect_clearTagStateSet() throws Exception { + + SelectTag selectTag = new SelectTag(); + selectTag.setPerformClearTagStateForTagPoolingServers(true); // Explicitly request tag state clearing. + selectTag.setName("mySelection"); + selectTag.setLabel("My Selection"); + selectTag.setList("%{#{'ONE':'one','TWO':'two','THREE':'three'}}"); + selectTag.setValue("%{'EEE'}"); + + OptGroupTag optGroupTag1 = new OptGroupTag(); + optGroupTag1.setPerformClearTagStateForTagPoolingServers(true); // Explicitly request tag state clearing. + optGroupTag1.setLabel("My Label 1"); + optGroupTag1.setList("%{#{'AAA':'aaa','BBB':'bbb','CCC':'ccc'}}"); + + OptGroupTag optGroupTag2 = new OptGroupTag(); + optGroupTag2.setPerformClearTagStateForTagPoolingServers(true); // Explicitly request tag state clearing. + optGroupTag2.setLabel("My Label 2"); + optGroupTag2.setList("%{#{'DDD':'ddd','EEE':'eee','FFF':'fff'}}"); + + selectTag.setPageContext(pageContext); + selectTag.doStartTag(); + setComponentTagClearTagState(selectTag, true); // Ensure component tag state clearing is set true (to match tag). + optGroupTag1.setPageContext(pageContext); + optGroupTag1.doStartTag(); + setComponentTagClearTagState(optGroupTag1, true); // Ensure component tag state clearing is set true (to match tag). + optGroupTag1.doEndTag(); + optGroupTag2.setPageContext(pageContext); + optGroupTag2.doStartTag(); + setComponentTagClearTagState(optGroupTag2, true); // Ensure component tag state clearing is set true (to match tag). + optGroupTag2.doEndTag(); + selectTag.doEndTag(); + + + //System.out.println(writer.toString()); + verify(SelectTag.class.getResource("OptGroup-2.txt")); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + SelectTag freshTag = new SelectTag(); + freshTag.setPerformClearTagStateForTagPoolingServers(true); + 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(selectTag, freshTag)); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + OptGroupTag freshOptGroupTag = new OptGroupTag(); + freshOptGroupTag.setPerformClearTagStateForTagPoolingServers(true); + freshOptGroupTag.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(optGroupTag1, freshOptGroupTag)); + 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(optGroupTag2, freshOptGroupTag)); + } public void testOptGroupWithMultipleSelect() throws Exception { SelectTag selectTag = new SelectTag(); @@ -154,21 +262,77 @@ public class OptGroupTest extends AbstractUITagTest { // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). SelectTag freshTag = new SelectTag(); freshTag.setPageContext(pageContext); - assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + 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(selectTag, freshTag)); // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). OptGroupTag freshOptGroupTag = new OptGroupTag(); freshOptGroupTag.setPageContext(pageContext); - assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + 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(optGroupTag1, freshOptGroupTag)); - assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + 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(optGroupTag2, freshOptGroupTag)); } - + + public void testOptGroupWithMultipleSelect_clearTagStateSet() throws Exception { + SelectTag selectTag = new SelectTag(); + selectTag.setPerformClearTagStateForTagPoolingServers(true); // Explicitly request tag state clearing. + selectTag.setMultiple("true"); + selectTag.setName("mySelection"); + selectTag.setLabel("My Selection"); + selectTag.setList("%{#{'ONE':'one','TWO':'two','THREE':'three'}}"); + selectTag.setValue("%{{'EEE','BBB','TWO'}}"); + + OptGroupTag optGroupTag1 = new OptGroupTag(); + optGroupTag1.setPerformClearTagStateForTagPoolingServers(true); // Explicitly request tag state clearing. + optGroupTag1.setLabel("My Label 1"); + optGroupTag1.setList("%{#{'AAA':'aaa','BBB':'bbb','CCC':'ccc'}}"); + + OptGroupTag optGroupTag2 = new OptGroupTag(); + optGroupTag2.setPerformClearTagStateForTagPoolingServers(true); // Explicitly request tag state clearing. + optGroupTag2.setLabel("My Label 2"); + optGroupTag2.setList("%{#{'DDD':'ddd','EEE':'eee','FFF':'fff'}}"); + + selectTag.setPageContext(pageContext); + selectTag.doStartTag(); + setComponentTagClearTagState(selectTag, true); // Ensure component tag state clearing is set true (to match tag). + optGroupTag1.setPageContext(pageContext); + optGroupTag1.doStartTag(); + setComponentTagClearTagState(optGroupTag1, true); // Ensure component tag state clearing is set true (to match tag). + optGroupTag1.doEndTag(); + optGroupTag2.setPageContext(pageContext); + optGroupTag2.doStartTag(); + setComponentTagClearTagState(optGroupTag2, true); // Ensure component tag state clearing is set true (to match tag). + optGroupTag2.doEndTag(); + selectTag.doEndTag(); + + + //System.out.println(writer.toString()); + verify(SelectTag.class.getResource("OptGroup-3.txt")); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + SelectTag freshTag = new SelectTag(); + freshTag.setPerformClearTagStateForTagPoolingServers(true); + 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(selectTag, freshTag)); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + OptGroupTag freshOptGroupTag = new OptGroupTag(); + freshOptGroupTag.setPerformClearTagStateForTagPoolingServers(true); + freshOptGroupTag.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(optGroupTag1, freshOptGroupTag)); + 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(optGroupTag2, freshOptGroupTag)); + } + public void testOptGroupWithMultipleSelectIntKey() throws Exception { SelectTag selectTag = new SelectTag(); selectTag.setMultiple("true"); @@ -202,21 +366,77 @@ public class OptGroupTest extends AbstractUITagTest { // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). SelectTag freshTag = new SelectTag(); freshTag.setPageContext(pageContext); - assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + 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(selectTag, freshTag)); // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). OptGroupTag freshOptGroupTag = new OptGroupTag(); freshOptGroupTag.setPageContext(pageContext); - assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + 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(optGroupTag1, freshOptGroupTag)); - assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + 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(optGroupTag2, freshOptGroupTag)); } - + + public void testOptGroupWithMultipleSelectIntKey_clearTagStateSet() throws Exception { + SelectTag selectTag = new SelectTag(); + selectTag.setPerformClearTagStateForTagPoolingServers(true); // Explicitly request tag state clearing. + selectTag.setMultiple("true"); + selectTag.setName("mySelection"); + selectTag.setLabel("My Selection"); + selectTag.setList("%{#{1:'one',2:'two',3:'three'}}"); + selectTag.setValue("%{{22,12,2}}"); + + OptGroupTag optGroupTag1 = new OptGroupTag(); + optGroupTag1.setPerformClearTagStateForTagPoolingServers(true); // Explicitly request tag state clearing. + optGroupTag1.setLabel("My Label 1"); + optGroupTag1.setList("%{#{11:'aaa',12:'bbb',13:'ccc'}}"); + + OptGroupTag optGroupTag2 = new OptGroupTag(); + optGroupTag2.setPerformClearTagStateForTagPoolingServers(true); // Explicitly request tag state clearing. + optGroupTag2.setLabel("My Label 2"); + optGroupTag2.setList("%{#{21:'ddd',22:'eee',23:'fff'}}"); + + selectTag.setPageContext(pageContext); + selectTag.doStartTag(); + setComponentTagClearTagState(selectTag, true); // Ensure component tag state clearing is set true (to match tag). + optGroupTag1.setPageContext(pageContext); + optGroupTag1.doStartTag(); + setComponentTagClearTagState(optGroupTag1, true); // Ensure component tag state clearing is set true (to match tag). + optGroupTag1.doEndTag(); + optGroupTag2.setPageContext(pageContext); + optGroupTag2.doStartTag(); + setComponentTagClearTagState(optGroupTag2, true); // Ensure component tag state clearing is set true (to match tag). + optGroupTag2.doEndTag(); + selectTag.doEndTag(); + + + //System.out.println(writer.toString()); + verify(SelectTag.class.getResource("OptGroup-7.txt")); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + SelectTag freshTag = new SelectTag(); + freshTag.setPerformClearTagStateForTagPoolingServers(true); + 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(selectTag, freshTag)); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + OptGroupTag freshOptGroupTag = new OptGroupTag(); + freshOptGroupTag.setPerformClearTagStateForTagPoolingServers(true); + freshOptGroupTag.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(optGroupTag1, freshOptGroupTag)); + 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(optGroupTag2, freshOptGroupTag)); + } + public void testOptGroupNumbers() throws Exception { ((TestAction)action).setMap(new LinkedHashMap() {{ @@ -255,17 +475,78 @@ public class OptGroupTest extends AbstractUITagTest { // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). SelectTag freshTag = new SelectTag(); freshTag.setPageContext(pageContext); - assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + 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(selectTag, freshTag)); // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). OptGroupTag freshOptGroupTag = new OptGroupTag(); freshOptGroupTag.setPageContext(pageContext); - assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + 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(optGroupTag1, freshOptGroupTag)); - assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + 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(optGroupTag2, freshOptGroupTag)); + } + + public void testOptGroupNumbers_clearTagStateSet() throws Exception { + + ((TestAction)action).setMap(new LinkedHashMap() {{ + put("AAA", "aaa"); + put(111111L, "bbb"); + put("CCC", "ccc"); + }}); + + SelectTag selectTag = new SelectTag(); + selectTag.setPerformClearTagStateForTagPoolingServers(true); // Explicitly request tag state clearing. + selectTag.setName("mySelection"); + selectTag.setLabel("My Selection"); + selectTag.setList("%{#{'ONE':'one','TWO':'two','THREE':'three'}}"); + + OptGroupTag optGroupTag1 = new OptGroupTag(); + optGroupTag1.setPerformClearTagStateForTagPoolingServers(true); // Explicitly request tag state clearing. + optGroupTag1.setLabel("My Label 1"); + optGroupTag1.setList("map"); + + OptGroupTag optGroupTag2 = new OptGroupTag(); + optGroupTag2.setPerformClearTagStateForTagPoolingServers(true); // Explicitly request tag state clearing. + optGroupTag2.setLabel("My Label 2"); + optGroupTag2.setList("%{#{'DDD':'ddd','EEE':'eee','FFF':'fff'}}"); + + selectTag.setPageContext(pageContext); + selectTag.doStartTag(); + setComponentTagClearTagState(selectTag, true); // Ensure component tag state clearing is set true (to match tag). + optGroupTag1.setPageContext(pageContext); + optGroupTag1.doStartTag(); + setComponentTagClearTagState(optGroupTag1, true); // Ensure component tag state clearing is set true (to match tag). + optGroupTag1.doEndTag(); + optGroupTag2.setPageContext(pageContext); + optGroupTag2.doStartTag(); + setComponentTagClearTagState(optGroupTag2, true); // Ensure component tag state clearing is set true (to match tag). + optGroupTag2.doEndTag(); + selectTag.doEndTag(); + + + //System.out.println(writer.toString()); + verify(SelectTag.class.getResource("OptGroup-4.txt")); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + SelectTag freshTag = new SelectTag(); + freshTag.setPerformClearTagStateForTagPoolingServers(true); + 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(selectTag, freshTag)); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + OptGroupTag freshOptGroupTag = new OptGroupTag(); + freshOptGroupTag.setPerformClearTagStateForTagPoolingServers(true); + freshOptGroupTag.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(optGroupTag1, freshOptGroupTag)); + 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(optGroupTag2, freshOptGroupTag)); } @@ -303,17 +584,73 @@ public class OptGroupTest extends AbstractUITagTest { // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). SelectTag freshTag = new SelectTag(); freshTag.setPageContext(pageContext); - assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + 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(selectTag, freshTag)); // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). OptGroupTag freshOptGroupTag = new OptGroupTag(); freshOptGroupTag.setPageContext(pageContext); - assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + 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(optGroupTag1, freshOptGroupTag)); - assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + 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(optGroupTag2, freshOptGroupTag)); + } + + public void testOptGroupForHtmlEncoding_clearTagStateSet() throws Exception { + SelectTag selectTag = new SelectTag(); + selectTag.setPerformClearTagStateForTagPoolingServers(true); // Explicitly request tag state clearing. + selectTag.setMultiple("true"); + selectTag.setName("mySelection"); + selectTag.setLabel("My Selection"); + selectTag.setList("%{#{'ONE':'one','TWO':'two','THREE':'three'}}"); + selectTag.setValue("%{{'EEE','TWO'}}"); + + OptGroupTag optGroupTag1 = new OptGroupTag(); + optGroupTag1.setPerformClearTagStateForTagPoolingServers(true); // Explicitly request tag state clearing. + optGroupTag1.setLabel("My Label 1"); + optGroupTag1.setList("%{#{'&':'aaa','<':'bbb','CCC':'':'ddd','EEE':'eee','FFF':'fff'}}"); + + selectTag.setPageContext(pageContext); + selectTag.doStartTag(); + setComponentTagClearTagState(selectTag, true); // Ensure component tag state clearing is set true (to match tag). + optGroupTag1.setPageContext(pageContext); + optGroupTag1.doStartTag(); + setComponentTagClearTagState(optGroupTag1, true); // Ensure component tag state clearing is set true (to match tag). + optGroupTag1.doEndTag(); + optGroupTag2.setPageContext(pageContext); + optGroupTag2.doStartTag(); + setComponentTagClearTagState(optGroupTag2, true); // Ensure component tag state clearing is set true (to match tag). + optGroupTag2.doEndTag(); + selectTag.doEndTag(); + + + //System.out.println(writer.toString()); + verify(SelectTag.class.getResource("OptGroup-5.txt")); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + SelectTag freshTag = new SelectTag(); + freshTag.setPerformClearTagStateForTagPoolingServers(true); + 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(selectTag, freshTag)); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + OptGroupTag freshOptGroupTag = new OptGroupTag(); + freshOptGroupTag.setPerformClearTagStateForTagPoolingServers(true); + freshOptGroupTag.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(optGroupTag1, freshOptGroupTag)); + 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(optGroupTag2, freshOptGroupTag)); } @@ -357,17 +694,79 @@ public class OptGroupTest extends AbstractUITagTest { // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). SelectTag freshTag = new SelectTag(); freshTag.setPageContext(pageContext); - assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + 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(selectTag, freshTag)); // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). OptGroupTag freshOptGroupTag = new OptGroupTag(); freshOptGroupTag.setPageContext(pageContext); - assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + 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(optGroupTag1, freshOptGroupTag)); - assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + 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(optGroupTag2, freshOptGroupTag)); + } + + public void testOptGroupWithValueKey_clearTagStateSet() throws Exception { + SelectTag selectTag = new SelectTag(); + selectTag.setPerformClearTagStateForTagPoolingServers(true); // Explicitly request tag state clearing. + selectTag.setName("mySelection"); + selectTag.setLabel("My Selection"); + selectTag.setList("selectValues"); + selectTag.setListValueKey("valueKey"); + + LocaleTestAction localeTestAction = new LocaleTestAction(); + container.inject(localeTestAction); + + localeTestAction.setText("LocaleKeyValueTest.ONE","Edno"); + localeTestAction.setText("LocaleKeyValueTest.TWO","Dve"); + stack.push(localeTestAction); + + OptGroupTag optGroupTag1 = new OptGroupTag(); + optGroupTag1.setPerformClearTagStateForTagPoolingServers(true); // Explicitly request tag state clearing. + optGroupTag1.setLabel("My Label 1"); + optGroupTag1.setList("%{#{'AAA':'aaa','BBB':'bbb','CCC':'ccc'}}"); + + OptGroupTag optGroupTag2 = new OptGroupTag(); + optGroupTag2.setPerformClearTagStateForTagPoolingServers(true); // Explicitly request tag state clearing. + optGroupTag2.setLabel("My Label 2"); + optGroupTag2.setList("%{#{'DDD':'ddd','EEE':'eee','FFF':'fff'}}"); + + selectTag.setPageContext(pageContext); + selectTag.doStartTag(); + setComponentTagClearTagState(selectTag, true); // Ensure component tag state clearing is set true (to match tag). + optGroupTag1.setPageContext(pageContext); + optGroupTag1.doStartTag(); + setComponentTagClearTagState(optGroupTag1, true); // Ensure component tag state clearing is set true (to match tag). + optGroupTag1.doEndTag(); + optGroupTag2.setPageContext(pageContext); + optGroupTag2.doStartTag(); + setComponentTagClearTagState(optGroupTag2, true); // Ensure component tag state clearing is set true (to match tag). + optGroupTag2.doEndTag(); + selectTag.doEndTag(); + + + //System.out.println(writer.toString()); + verify(SelectTag.class.getResource("OptGroup-6.txt")); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + SelectTag freshTag = new SelectTag(); + freshTag.setPerformClearTagStateForTagPoolingServers(true); + 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(selectTag, freshTag)); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + OptGroupTag freshOptGroupTag = new OptGroupTag(); + freshOptGroupTag.setPerformClearTagStateForTagPoolingServers(true); + freshOptGroupTag.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(optGroupTag1, freshOptGroupTag)); + 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(optGroupTag2, freshOptGroupTag)); } @@ -382,6 +781,7 @@ public class OptGroupTest extends AbstractUITagTest { selectTag.setListTitle("'option-title' + key"); OptGroupTag optGroupTag1 = new OptGroupTag(); + optGroupTag1.setPerformClearTagStateForTagPoolingServers(true); // Explicitly request tag state clearing. optGroupTag1.setLabel("My Label 1"); optGroupTag1.setList("#{'AAA':'aaa','BBB':'bbb','CCC':'ccc'}"); optGroupTag1.setListCssClass("'optgroup-option-css-class ' + key"); @@ -389,6 +789,7 @@ public class OptGroupTest extends AbstractUITagTest { optGroupTag1.setListTitle("'optgroup-option-title' + key"); OptGroupTag optGroupTag2 = new OptGroupTag(); + optGroupTag2.setPerformClearTagStateForTagPoolingServers(true); // Explicitly request tag state clearing. optGroupTag2.setLabel("My Label 2"); optGroupTag2.setList("#{'DDD':'ddd','EEE':'eee','FFF':'fff'}"); optGroupTag2.setListCssClass("notExistingProperty"); @@ -411,17 +812,79 @@ public class OptGroupTest extends AbstractUITagTest { // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). SelectTag freshTag = new SelectTag(); freshTag.setPageContext(pageContext); - assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + 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(selectTag, freshTag)); // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). OptGroupTag freshOptGroupTag = new OptGroupTag(); freshOptGroupTag.setPageContext(pageContext); - assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + 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(optGroupTag1, freshOptGroupTag)); - assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + 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(optGroupTag2, freshOptGroupTag)); + } + + public void testOptGroupListAttributes_clearTagStateSet() throws Exception { + SelectTag selectTag = new SelectTag(); + selectTag.setPerformClearTagStateForTagPoolingServers(true); // Explicitly request tag state clearing. + selectTag.setName("mySelection"); + selectTag.setLabel("My Selection"); + selectTag.setList("#{'ONE':'one','TWO':'two','THREE':'three'}"); + selectTag.setListCssClass("'option-css-class ' + key"); + selectTag.setListCssStyle("'background-color: green; font-family: ' + key"); + selectTag.setListTitle("'option-title' + key"); + + OptGroupTag optGroupTag1 = new OptGroupTag(); + optGroupTag1.setPerformClearTagStateForTagPoolingServers(true); // Explicitly request tag state clearing. + optGroupTag1.setLabel("My Label 1"); + optGroupTag1.setList("#{'AAA':'aaa','BBB':'bbb','CCC':'ccc'}"); + optGroupTag1.setListCssClass("'optgroup-option-css-class ' + key"); + optGroupTag1.setListCssStyle("'background-color: blue; font-family: ' + key"); + optGroupTag1.setListTitle("'optgroup-option-title' + key"); + + OptGroupTag optGroupTag2 = new OptGroupTag(); + optGroupTag2.setPerformClearTagStateForTagPoolingServers(true); // Explicitly request tag state clearing. + optGroupTag2.setLabel("My Label 2"); + optGroupTag2.setList("#{'DDD':'ddd','EEE':'eee','FFF':'fff'}"); + optGroupTag2.setListCssClass("notExistingProperty"); + optGroupTag2.setListCssStyle("notExistingProperty"); + optGroupTag2.setListTitle("notExistingProperty"); + + selectTag.setPageContext(pageContext); + selectTag.doStartTag(); + setComponentTagClearTagState(selectTag, true); // Ensure component tag state clearing is set true (to match tag). + optGroupTag1.setPageContext(pageContext); + optGroupTag1.doStartTag(); + setComponentTagClearTagState(optGroupTag1, true); // Ensure component tag state clearing is set true (to match tag). + optGroupTag1.doEndTag(); + optGroupTag2.setPageContext(pageContext); + optGroupTag2.doStartTag(); + setComponentTagClearTagState(optGroupTag2, true); // Ensure component tag state clearing is set true (to match tag). + optGroupTag2.doEndTag(); + selectTag.doEndTag(); + + //System.out.println(writer.toString()); + verify(SelectTag.class.getResource("OptGroup-8.txt")); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + SelectTag freshTag = new SelectTag(); + freshTag.setPerformClearTagStateForTagPoolingServers(true); + 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(selectTag, freshTag)); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + OptGroupTag freshOptGroupTag = new OptGroupTag(); + freshOptGroupTag.setPerformClearTagStateForTagPoolingServers(true); + freshOptGroupTag.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(optGroupTag1, freshOptGroupTag)); + 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(optGroupTag2, freshOptGroupTag)); } diff --git a/core/src/test/java/org/apache/struts2/views/jsp/ui/OptionTransferSelectTagTest.java b/core/src/test/java/org/apache/struts2/views/jsp/ui/OptionTransferSelectTagTest.java index 31463e5f9..c8892773c 100644 --- a/core/src/test/java/org/apache/struts2/views/jsp/ui/OptionTransferSelectTagTest.java +++ b/core/src/test/java/org/apache/struts2/views/jsp/ui/OptionTransferSelectTagTest.java @@ -96,7 +96,80 @@ public class OptionTransferSelectTagTest extends AbstractUITagTest { // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). OptionTransferSelectTag freshTag = new OptionTransferSelectTag(); freshTag.setPageContext(pageContext); - assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + 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 testWithAllSelected_clearTagStateSet() throws Exception { + List left = new ArrayList(); + left.add("Left1"); + left.add("Left2"); + + List right = new ArrayList(); + right.add("Right1"); + right.add("Right2"); + + TestAction testaction = (TestAction) action; + testaction.setCollection(left); + testaction.setList2(right); + + OptionTransferSelectTag tag = new OptionTransferSelectTag(); + tag.setPerformClearTagStateForTagPoolingServers(true); // Explicitly request tag state clearing. + tag.setPageContext(pageContext); + + tag.setName("collection"); + tag.setId("id"); + tag.setList("collection"); + tag.setSize("20"); + tag.setMultiple("true"); + tag.setEmptyOption("true"); + + tag.setDoubleName("list2"); + tag.setDoubleList("list2"); + tag.setDoubleId("doubleId"); + tag.setDoubleSize("20"); + tag.setMultiple("true"); + tag.setDoubleEmptyOption("true"); + tag.setDoubleCssClass("c2"); + tag.setDoubleCssStyle("s2"); + + tag.setAllowAddAllToLeft("true"); + tag.setAllowAddAllToRight("true"); + tag.setAllowAddToLeft("true"); + tag.setAllowAddToRight("true"); + tag.setAllowSelectAll("true"); + + tag.setAddAllToLeftLabel("All Left"); + tag.setAddAllToRightLabel("All Right"); + tag.setAddToLeftLabel("Left"); + tag.setAddToRightLabel("Right"); + tag.setSelectAllLabel("Select All"); + + tag.setLeftTitle("Title Left"); + tag.setRightTitle("Title Right"); + + tag.setButtonCssClass("buttonCssClass"); + tag.setButtonCssStyle("buttonCssStyle"); + + tag.setHeaderKey("Header Key"); + tag.setHeaderValue("Header Value"); + + tag.setDoubleHeaderKey("Double Header Key"); + tag.setDoubleHeaderValue("Double Header Value"); + + tag.doStartTag(); + setComponentTagClearTagState(tag, true); // Ensure component tag state clearing is set true (to match tag). + tag.doEndTag(); + + //System.out.println(writer.toString()); + verify(OptionTransferSelectTagTest.class.getResource("optiontransferselect-1.txt")); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + OptionTransferSelectTag freshTag = new OptionTransferSelectTag(); + freshTag.setPerformClearTagStateForTagPoolingServers(true); + 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)); } @@ -176,7 +249,90 @@ public class OptionTransferSelectTagTest extends AbstractUITagTest { // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). OptionTransferSelectTag freshTag = new OptionTransferSelectTag(); freshTag.setPageContext(pageContext); - assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + 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 testWithPartialSelectedOnBothSides_clearTagStateSet() throws Exception { + List left = new ArrayList(); + left.add("Left2"); + + List right = new ArrayList(); + right.add("Right2"); + + List leftVal = new ArrayList(); + leftVal.add("Left1"); + leftVal.add("Left2"); + leftVal.add("Left3"); + + List rightVal = new ArrayList(); + rightVal.add("Right1"); + rightVal.add("Right2"); + rightVal.add("Right3"); + + + TestAction testaction = (TestAction) action; + testaction.setCollection(left); + testaction.setList2(right); + testaction.setCollection2(leftVal); + testaction.setList3(rightVal); + + + OptionTransferSelectTag tag = new OptionTransferSelectTag(); + tag.setPerformClearTagStateForTagPoolingServers(true); // Explicitly request tag state clearing. + tag.setPageContext(pageContext); + + tag.setName("collection"); + tag.setId("id"); + tag.setList("collection2"); + tag.setSize("20"); + tag.setMultiple("true"); + tag.setEmptyOption("true"); + + tag.setDoubleName("list2"); + tag.setDoubleList("list3"); + tag.setDoubleId("doubleId"); + tag.setDoubleSize("20"); + tag.setMultiple("true"); + tag.setDoubleEmptyOption("true"); + + tag.setAllowAddAllToLeft("true"); + tag.setAllowAddAllToRight("true"); + tag.setAllowAddToLeft("true"); + tag.setAllowAddToRight("true"); + tag.setAllowSelectAll("true"); + + tag.setAddAllToLeftLabel("All Left"); + tag.setAddAllToRightLabel("All Right"); + tag.setAddToLeftLabel("Left"); + tag.setAddToRightLabel("Right"); + tag.setSelectAllLabel("Select All"); + + tag.setLeftTitle("Title Left"); + tag.setRightTitle("Title Right"); + + tag.setButtonCssClass("buttonCssClass"); + tag.setButtonCssStyle("buttonCssStyle"); + + tag.setHeaderKey("Header Key"); + tag.setHeaderValue("Header Value"); + + tag.setDoubleHeaderKey("Double Header Key"); + tag.setDoubleHeaderValue("Double Header Value"); + + tag.doStartTag(); + setComponentTagClearTagState(tag, true); // Ensure component tag state clearing is set true (to match tag). + tag.doEndTag(); + + //System.out.println(writer.toString()); + verify(OptionTransferSelectTagTest.class.getResource("optiontransferselect-2.txt")); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + OptionTransferSelectTag freshTag = new OptionTransferSelectTag(); + freshTag.setPerformClearTagStateForTagPoolingServers(true); + 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)); } @@ -250,7 +406,84 @@ public class OptionTransferSelectTagTest extends AbstractUITagTest { // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). OptionTransferSelectTag freshTag = new OptionTransferSelectTag(); freshTag.setPageContext(pageContext); - assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + 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 testWithoutHeaderOnBothSides_clearTagStateSet() throws Exception { + List left = new ArrayList(); + left.add("Left2"); + + List right = new ArrayList(); + right.add("Right2"); + + List leftVal = new ArrayList(); + leftVal.add("Left1"); + leftVal.add("Left2"); + leftVal.add("Left3"); + + List rightVal = new ArrayList(); + rightVal.add("Right1"); + rightVal.add("Right2"); + rightVal.add("Right3"); + + + TestAction testaction = (TestAction) action; + testaction.setCollection(left); + testaction.setList2(right); + testaction.setCollection2(leftVal); + testaction.setList3(rightVal); + + + OptionTransferSelectTag tag = new OptionTransferSelectTag(); + tag.setPerformClearTagStateForTagPoolingServers(true); // Explicitly request tag state clearing. + tag.setPageContext(pageContext); + + tag.setName("collection"); + tag.setId("id"); + tag.setList("collection2"); + tag.setSize("20"); + tag.setMultiple("true"); + tag.setEmptyOption("true"); + + tag.setDoubleName("list2"); + tag.setDoubleList("list3"); + tag.setDoubleId("doubleId"); + tag.setDoubleSize("20"); + tag.setMultiple("true"); + tag.setDoubleEmptyOption("true"); + + tag.setAllowAddAllToLeft("true"); + tag.setAllowAddAllToRight("true"); + tag.setAllowAddToLeft("true"); + tag.setAllowAddToRight("true"); + tag.setAllowSelectAll("true"); + + tag.setAddAllToLeftLabel("All Left"); + tag.setAddAllToRightLabel("All Right"); + tag.setAddToLeftLabel("Left"); + tag.setAddToRightLabel("Right"); + tag.setSelectAllLabel("Select All"); + + tag.setLeftTitle("Title Left"); + tag.setRightTitle("Title Right"); + + tag.setButtonCssClass("buttonCssClass"); + tag.setButtonCssStyle("buttonCssStyle"); + + tag.doStartTag(); + setComponentTagClearTagState(tag, true); // Ensure component tag state clearing is set true (to match tag). + tag.doEndTag(); + + //System.out.println(writer.toString()); + verify(OptionTransferSelectTagTest.class.getResource("optiontransferselect-3.txt")); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + OptionTransferSelectTag freshTag = new OptionTransferSelectTag(); + freshTag.setPerformClearTagStateForTagPoolingServers(true); + 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)); } @@ -327,7 +560,87 @@ public class OptionTransferSelectTagTest extends AbstractUITagTest { // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). OptionTransferSelectTag freshTag = new OptionTransferSelectTag(); freshTag.setPageContext(pageContext); - assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + 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 testWithoutHeaderOnOneSide_clearTagStateSet() throws Exception { + List left = new ArrayList(); + left.add("Left2"); + + List right = new ArrayList(); + right.add("Right2"); + + List leftVal = new ArrayList(); + leftVal.add("Left1"); + leftVal.add("Left2"); + leftVal.add("Left3"); + + List rightVal = new ArrayList(); + rightVal.add("Right1"); + rightVal.add("Right2"); + rightVal.add("Right3"); + + + TestAction testaction = (TestAction) action; + testaction.setCollection(left); + testaction.setList2(right); + testaction.setCollection2(leftVal); + testaction.setList3(rightVal); + + + OptionTransferSelectTag tag = new OptionTransferSelectTag(); + tag.setPerformClearTagStateForTagPoolingServers(true); // Explicitly request tag state clearing. + tag.setPageContext(pageContext); + + tag.setName("collection"); + tag.setId("id"); + tag.setList("collection2"); + tag.setSize("20"); + tag.setMultiple("true"); + tag.setEmptyOption("true"); + + tag.setDoubleName("list2"); + tag.setDoubleList("list3"); + tag.setDoubleId("doubleId"); + tag.setDoubleSize("20"); + tag.setMultiple("true"); + tag.setDoubleEmptyOption("true"); + + tag.setAllowAddAllToLeft("true"); + tag.setAllowAddAllToRight("true"); + tag.setAllowAddToLeft("true"); + tag.setAllowAddToRight("true"); + tag.setAllowSelectAll("true"); + + tag.setAddAllToLeftLabel("All Left"); + tag.setAddAllToRightLabel("All Right"); + tag.setAddToLeftLabel("Left"); + tag.setAddToRightLabel("Right"); + tag.setSelectAllLabel("Select All"); + + tag.setLeftTitle("Title Left"); + tag.setRightTitle("Title Right"); + + tag.setButtonCssClass("buttonCssClass"); + tag.setButtonCssStyle("buttonCssStyle"); + + tag.setHeaderKey("Header Key"); + tag.setHeaderValue("Header Value"); + + tag.doStartTag(); + setComponentTagClearTagState(tag, true); // Ensure component tag state clearing is set true (to match tag). + tag.doEndTag(); + + //System.out.println(writer.toString()); + verify(OptionTransferSelectTagTest.class.getResource("optiontransferselect-4.txt")); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + OptionTransferSelectTag freshTag = new OptionTransferSelectTag(); + freshTag.setPerformClearTagStateForTagPoolingServers(true); + 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)); } @@ -407,7 +720,90 @@ public class OptionTransferSelectTagTest extends AbstractUITagTest { // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). OptionTransferSelectTag freshTag = new OptionTransferSelectTag(); freshTag.setPageContext(pageContext); - assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + 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 testWithoutEmptyOptionOnBothSides_clearTagStateSet() throws Exception { + List left = new ArrayList(); + left.add("Left2"); + + List right = new ArrayList(); + right.add("Right2"); + + List leftVal = new ArrayList(); + leftVal.add("Left1"); + leftVal.add("Left2"); + leftVal.add("Left3"); + + List rightVal = new ArrayList(); + rightVal.add("Right1"); + rightVal.add("Right2"); + rightVal.add("Right3"); + + + TestAction testaction = (TestAction) action; + testaction.setCollection(left); + testaction.setList2(right); + testaction.setCollection2(leftVal); + testaction.setList3(rightVal); + + + OptionTransferSelectTag tag = new OptionTransferSelectTag(); + tag.setPerformClearTagStateForTagPoolingServers(true); // Explicitly request tag state clearing. + tag.setPageContext(pageContext); + + tag.setName("collection"); + tag.setId("id"); + tag.setList("collection2"); + tag.setSize("20"); + tag.setMultiple("true"); + tag.setEmptyOption("false"); + + tag.setDoubleName("list2"); + tag.setDoubleList("list3"); + tag.setDoubleId("doubleId"); + tag.setDoubleSize("20"); + tag.setMultiple("true"); + tag.setDoubleEmptyOption("false"); + + tag.setAllowAddAllToLeft("true"); + tag.setAllowAddAllToRight("true"); + tag.setAllowAddToLeft("true"); + tag.setAllowAddToRight("true"); + tag.setAllowSelectAll("true"); + + tag.setAddAllToLeftLabel("All Left"); + tag.setAddAllToRightLabel("All Right"); + tag.setAddToLeftLabel("Left"); + tag.setAddToRightLabel("Right"); + tag.setSelectAllLabel("Select All"); + + tag.setLeftTitle("Title Left"); + tag.setRightTitle("Title Right"); + + tag.setButtonCssClass("buttonCssClass"); + tag.setButtonCssStyle("buttonCssStyle"); + + tag.setHeaderKey("Header Key"); + tag.setHeaderValue("Header Value"); + + tag.setDoubleHeaderKey("Double Header Key"); + tag.setDoubleHeaderValue("Double Header Value"); + + tag.doStartTag(); + setComponentTagClearTagState(tag, true); // Ensure component tag state clearing is set true (to match tag). + tag.doEndTag(); + + //System.out.println(writer.toString()); + verify(OptionTransferSelectTagTest.class.getResource("optiontransferselect-5.txt")); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + OptionTransferSelectTag freshTag = new OptionTransferSelectTag(); + freshTag.setPerformClearTagStateForTagPoolingServers(true); + 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)); } @@ -487,7 +883,90 @@ public class OptionTransferSelectTagTest extends AbstractUITagTest { // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). OptionTransferSelectTag freshTag = new OptionTransferSelectTag(); freshTag.setPageContext(pageContext); - assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + 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 testWithoutEmptyOptionOnOneSide_clearTagStateSet() throws Exception { + List left = new ArrayList(); + left.add("Left2"); + + List right = new ArrayList(); + right.add("Right2"); + + List leftVal = new ArrayList(); + leftVal.add("Left1"); + leftVal.add("Left2"); + leftVal.add("Left3"); + + List rightVal = new ArrayList(); + rightVal.add("Right1"); + rightVal.add("Right2"); + rightVal.add("Right3"); + + + TestAction testaction = (TestAction) action; + testaction.setCollection(left); + testaction.setList2(right); + testaction.setCollection2(leftVal); + testaction.setList3(rightVal); + + + OptionTransferSelectTag tag = new OptionTransferSelectTag(); + tag.setPerformClearTagStateForTagPoolingServers(true); // Explicitly request tag state clearing. + tag.setPageContext(pageContext); + + tag.setName("collection"); + tag.setId("id"); + tag.setList("collection2"); + tag.setSize("20"); + tag.setMultiple("true"); + tag.setEmptyOption("true"); + + tag.setDoubleName("list2"); + tag.setDoubleList("list3"); + tag.setDoubleId("doubleId"); + tag.setDoubleSize("20"); + tag.setMultiple("true"); + tag.setDoubleEmptyOption("false"); + + tag.setAllowAddAllToLeft("true"); + tag.setAllowAddAllToRight("true"); + tag.setAllowAddToLeft("true"); + tag.setAllowAddToRight("true"); + tag.setAllowSelectAll("true"); + + tag.setAddAllToLeftLabel("All Left"); + tag.setAddAllToRightLabel("All Right"); + tag.setAddToLeftLabel("Left"); + tag.setAddToRightLabel("Right"); + tag.setSelectAllLabel("Select All"); + + tag.setLeftTitle("Title Left"); + tag.setRightTitle("Title Right"); + + tag.setButtonCssClass("buttonCssClass"); + tag.setButtonCssStyle("buttonCssStyle"); + + tag.setHeaderKey("Header Key"); + tag.setHeaderValue("Header Value"); + + tag.setDoubleHeaderKey("Double Header Key"); + tag.setDoubleHeaderValue("Double Header Value"); + + tag.doStartTag(); + setComponentTagClearTagState(tag, true); // Ensure component tag state clearing is set true (to match tag). + tag.doEndTag(); + + //System.out.println(writer.toString()); + verify(OptionTransferSelectTagTest.class.getResource("optiontransferselect-6.txt")); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + OptionTransferSelectTag freshTag = new OptionTransferSelectTag(); + freshTag.setPerformClearTagStateForTagPoolingServers(true); + 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)); } @@ -570,8 +1049,95 @@ public class OptionTransferSelectTagTest extends AbstractUITagTest { // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). OptionTransferSelectTag freshTag = new OptionTransferSelectTag(); freshTag.setPageContext(pageContext); - assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + 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 testDisableSomeButtons_clearTagStateSet() throws Exception { + List left = new ArrayList(); + left.add("Left2"); + + List right = new ArrayList(); + right.add("Right2"); + + List leftVal = new ArrayList(); + leftVal.add("Left1"); + leftVal.add("Left2"); + leftVal.add("Left3"); + + List rightVal = new ArrayList(); + rightVal.add("Right1"); + rightVal.add("Right2"); + rightVal.add("Right3"); + + + TestAction testaction = (TestAction) action; + testaction.setCollection(left); + testaction.setList2(right); + testaction.setCollection2(leftVal); + testaction.setList3(rightVal); + + + OptionTransferSelectTag tag = new OptionTransferSelectTag(); + tag.setPerformClearTagStateForTagPoolingServers(true); // Explicitly request tag state clearing. + tag.setPageContext(pageContext); + + tag.setName("collection"); + tag.setId("id"); + tag.setList("collection2"); + tag.setSize("20"); + tag.setMultiple("true"); + tag.setEmptyOption("true"); + + tag.setDoubleName("list2"); + tag.setDoubleList("list3"); + tag.setDoubleId("doubleId"); + tag.setDoubleSize("20"); + tag.setMultiple("true"); + tag.setDoubleEmptyOption("true"); + + tag.setAllowAddAllToLeft("false"); + tag.setAllowAddAllToRight("false"); + tag.setAllowAddToLeft("true"); + tag.setAllowAddToRight("true"); + tag.setAllowSelectAll("false"); + + tag.setAddAllToLeftLabel("All Left"); + tag.setAddAllToRightLabel("All Right"); + tag.setAddToLeftLabel("Left"); + tag.setAddToRightLabel("Right"); + tag.setSelectAllLabel("Select All"); + + tag.setLeftTitle("Title Left"); + tag.setRightTitle("Title Right"); + + tag.setButtonCssClass("buttonCssClass"); + tag.setButtonCssStyle("buttonCssStyle"); + + tag.setHeaderKey("Header Key"); + tag.setHeaderValue("Header Value"); + + tag.setDoubleHeaderKey("Double Header Key"); + tag.setDoubleHeaderValue("Double Header Value"); + + tag.setAddToLeftOnclick("alert('Moving Left')"); + tag.setAddToRightOnclick("alert('Moving Right')"); + + tag.doStartTag(); + setComponentTagClearTagState(tag, true); // Ensure component tag state clearing is set true (to match tag). + tag.doEndTag(); + + //System.out.println(writer.toString()); + verify(OptionTransferSelectTagTest.class.getResource("optiontransferselect-7.txt")); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + OptionTransferSelectTag freshTag = new OptionTransferSelectTag(); + freshTag.setPerformClearTagStateForTagPoolingServers(true); + 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)); + } + } diff --git a/core/src/test/java/org/apache/struts2/views/jsp/ui/PasswordTest.java b/core/src/test/java/org/apache/struts2/views/jsp/ui/PasswordTest.java index 91628a742..a4d5cf236 100644 --- a/core/src/test/java/org/apache/struts2/views/jsp/ui/PasswordTest.java +++ b/core/src/test/java/org/apache/struts2/views/jsp/ui/PasswordTest.java @@ -44,7 +44,33 @@ public class PasswordTest extends AbstractUITagTest { // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). PasswordTag freshTag = new PasswordTag(); freshTag.setPageContext(pageContext); - assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + 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 testSimple_clearTagStateSet() throws Exception { + TestAction testAction = (TestAction) action; + testAction.setFoo("bar"); + + PasswordTag tag = new PasswordTag(); + tag.setPerformClearTagStateForTagPoolingServers(true); // Explicitly request tag state clearing. + tag.setPageContext(pageContext); + tag.setLabel("mylabel"); + tag.setName("myname"); + tag.setTitle("mytitle"); + + tag.doStartTag(); + setComponentTagClearTagState(tag, true); // Ensure component tag state clearing is set true (to match tag). + tag.doEndTag(); + + verify(PasswordTag.class.getResource("Password-1.txt")); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + PasswordTag freshTag = new PasswordTag(); + freshTag.setPerformClearTagStateForTagPoolingServers(true); + 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)); } diff --git a/core/src/test/java/org/apache/struts2/views/jsp/ui/RadioTest.java b/core/src/test/java/org/apache/struts2/views/jsp/ui/RadioTest.java index c03cfc6d3..8a8cbaa0f 100644 --- a/core/src/test/java/org/apache/struts2/views/jsp/ui/RadioTest.java +++ b/core/src/test/java/org/apache/struts2/views/jsp/ui/RadioTest.java @@ -54,11 +54,42 @@ public class RadioTest extends AbstractUITagTest { // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). RadioTag freshTag = new RadioTag(); freshTag.setPageContext(pageContext); - assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + 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 testMapWithBooleanAsKey_clearTagStateSet() throws Exception { + TestAction testAction = (TestAction) action; + + HashMap map = new LinkedHashMap(); + map.put(Boolean.TRUE, "male"); + map.put(Boolean.FALSE, "female"); + testAction.setMap(map); + + RadioTag tag = new RadioTag(); + tag.setPerformClearTagStateForTagPoolingServers(true); // Explicitly request tag state clearing. + tag.setPageContext(pageContext); + tag.setLabel("mylabel"); + tag.setName("myname"); + tag.setValue("%{true}"); + tag.setList("map"); + + tag.doStartTag(); + setComponentTagClearTagState(tag, true); // Ensure component tag state clearing is set true (to match tag). + tag.doEndTag(); + + verify(RadioTag.class.getResource("Radio-3.txt")); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + RadioTag freshTag = new RadioTag(); + freshTag.setPerformClearTagStateForTagPoolingServers(true); + 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)); + } + public void testMapChecked() throws Exception { TestAction testAction = (TestAction) action; testAction.setFoo("bar"); @@ -85,11 +116,45 @@ public class RadioTest extends AbstractUITagTest { // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). RadioTag freshTag = new RadioTag(); freshTag.setPageContext(pageContext); - assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + 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 testMapChecked_clearTagStateSet() throws Exception { + TestAction testAction = (TestAction) action; + testAction.setFoo("bar"); + + Map map = new LinkedHashMap<>(); + map.put("1", "One"); + map.put("2", "Two"); + testAction.setMap(map); + + RadioTag tag = new RadioTag(); + tag.setPerformClearTagStateForTagPoolingServers(true); // Explicitly request tag state clearing. + tag.setPageContext(pageContext); + tag.setLabel("mylabel"); + tag.setName("myname"); + tag.setValue("\"1\""); + tag.setList("map"); + tag.setListKey("key"); + tag.setListValue("value"); + + tag.doStartTag(); + setComponentTagClearTagState(tag, true); // Ensure component tag state clearing is set true (to match tag). + tag.doEndTag(); + + verify(RadioTag.class.getResource("Radio-2.txt")); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + RadioTag freshTag = new RadioTag(); + freshTag.setPerformClearTagStateForTagPoolingServers(true); + 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)); + } + public void testMapCheckedNull() throws Exception { TestAction testAction = (TestAction) action; testAction.setFoo("bar"); @@ -114,7 +179,39 @@ public class RadioTest extends AbstractUITagTest { // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). RadioTag freshTag = new RadioTag(); freshTag.setPageContext(pageContext); - assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + 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 testMapCheckedNull_clearTagStateSet() throws Exception { + TestAction testAction = (TestAction) action; + testAction.setFoo("bar"); + + HashMap map = new HashMap(); + map.put("1", "One"); + map.put("2", "Two"); + testAction.setMap(map); + + RadioTag tag = new RadioTag(); + tag.setPerformClearTagStateForTagPoolingServers(true); // Explicitly request tag state clearing. + tag.setPageContext(pageContext); + tag.setLabel("mylabel"); + tag.setName("myname"); + tag.setValue("%{map['3']}"); + tag.setList("#@java.util.TreeMap@{\"1\":\"One\", \"2\":\"Two\", \"\":\"N/A\"}"); + + tag.doStartTag(); + setComponentTagClearTagState(tag, true); // Ensure component tag state clearing is set true (to match tag). + tag.doEndTag(); + + verify(RadioTag.class.getResource("Radio-4.txt")); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + RadioTag freshTag = new RadioTag(); + freshTag.setPerformClearTagStateForTagPoolingServers(true); + 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)); } @@ -144,7 +241,40 @@ public class RadioTest extends AbstractUITagTest { // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). RadioTag freshTag = new RadioTag(); freshTag.setPageContext(pageContext); - assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + 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 testSimple_clearTagStateSet() throws Exception { + TestAction testAction = (TestAction) action; + testAction.setFoo("bar"); + testAction.setList(new String[][]{ + {"hello", "world"}, + {"foo", "bar"} + }); + + RadioTag tag = new RadioTag(); + tag.setPerformClearTagStateForTagPoolingServers(true); // Explicitly request tag state clearing. + tag.setPageContext(pageContext); + tag.setLabel("mylabel"); + tag.setName("myname"); + tag.setValue(""); + tag.setList("list"); + tag.setListKey("top[0]"); + tag.setListValue("top[1]"); + + tag.doStartTag(); + setComponentTagClearTagState(tag, true); // Ensure component tag state clearing is set true (to match tag). + tag.doEndTag(); + + verify(RadioTag.class.getResource("Radio-1.txt")); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + RadioTag freshTag = new RadioTag(); + freshTag.setPerformClearTagStateForTagPoolingServers(true); + 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)); } @@ -166,7 +296,32 @@ public class RadioTest extends AbstractUITagTest { // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). RadioTag freshTag = new RadioTag(); freshTag.setPageContext(pageContext); - assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + 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 testSimpleWithStringMap_clearTagStateSet() throws Exception { + final Map myMap = new TreeMap(); + myMap.put("name", "Std."); + stack.push(new HashMap() {{ put ("myMap", myMap); }}); + + RadioTag tag = new RadioTag(); + tag.setPerformClearTagStateForTagPoolingServers(true); // Explicitly request tag state clearing. + tag.setPageContext(pageContext); + tag.setName("myMap['name']"); + tag.setList("#@java.util.TreeMap@{\"Opt.\":\"Opt.\", \"Std.\":\"Std.\", \"\":\"N/A\"}"); + tag.doStartTag(); + setComponentTagClearTagState(tag, true); // Ensure component tag state clearing is set true (to match tag). + tag.doEndTag(); + + verify(RadioTag.class.getResource("Radio-6.txt")); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + RadioTag freshTag = new RadioTag(); + freshTag.setPerformClearTagStateForTagPoolingServers(true); + 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)); } @@ -197,7 +352,41 @@ public class RadioTest extends AbstractUITagTest { // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). RadioTag freshTag = new RadioTag(); freshTag.setPageContext(pageContext); - assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + 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 testSimpleWithLabelSeparator_clearTagStateSet() throws Exception { + TestAction testAction = (TestAction) action; + testAction.setFoo("bar"); + testAction.setList(new String[][]{ + {"hello", "world"}, + {"foo", "bar"} + }); + + RadioTag tag = new RadioTag(); + tag.setPerformClearTagStateForTagPoolingServers(true); // Explicitly request tag state clearing. + tag.setPageContext(pageContext); + tag.setLabel("mylabel"); + tag.setName("myname"); + tag.setValue(""); + tag.setList("list"); + tag.setListKey("top[0]"); + tag.setListValue("top[1]"); + tag.setLabelSeparator("--"); + + tag.doStartTag(); + setComponentTagClearTagState(tag, true); // Ensure component tag state clearing is set true (to match tag). + tag.doEndTag(); + + verify(RadioTag.class.getResource("Radio-5.txt")); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + RadioTag freshTag = new RadioTag(); + freshTag.setPerformClearTagStateForTagPoolingServers(true); + 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)); } @@ -240,7 +429,41 @@ public class RadioTest extends AbstractUITagTest { // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). RadioTag freshTag = new RadioTag(); freshTag.setPageContext(pageContext); - assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + 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 testDynamicAttributes_clearTagStateSet() throws Exception { + TestAction testAction = (TestAction) action; + testAction.setFoo("bar"); + testAction.setList(new String[][]{ + {"hello", "world"}, + {"foo", "bar"} + }); + + RadioTag tag = new RadioTag(); + tag.setPerformClearTagStateForTagPoolingServers(true); // Explicitly request tag state clearing. + tag.setPageContext(pageContext); + tag.setLabel("mylabel"); + tag.setName("myname"); + tag.setValue(""); + tag.setList("list"); + tag.setListKey("top[0]"); + tag.setListValue("top[1]"); + tag.setDynamicAttribute(null, "dojo", "checked: %{top[0]}"); + + tag.doStartTag(); + setComponentTagClearTagState(tag, true); // Ensure component tag state clearing is set true (to match tag). + tag.doEndTag(); + + verify(RadioTag.class.getResource("Radio-7.txt")); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + RadioTag freshTag = new RadioTag(); + freshTag.setPerformClearTagStateForTagPoolingServers(true); + 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)); } @@ -262,7 +485,32 @@ public class RadioTest extends AbstractUITagTest { // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). RadioTag freshTag = new RadioTag(); freshTag.setPageContext(pageContext); - assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + 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 testNotExistingListValueKey_clearTagStateSet() throws Exception { + RadioTag tag = new RadioTag(); + tag.setPerformClearTagStateForTagPoolingServers(true); // Explicitly request tag state clearing. + tag.setName("myname"); + tag.setLabel("mylabel"); + tag.setList("#{'a':'aaa', 'b':'bbb', 'c':'ccc'}"); + tag.setListValueKey("notExistingProperty"); + + tag.setPageContext(pageContext); + + tag.doStartTag(); + setComponentTagClearTagState(tag, true); // Ensure component tag state clearing is set true (to match tag). + tag.doEndTag(); + + verify(SelectTag.class.getResource("Radio-8.txt")); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + RadioTag freshTag = new RadioTag(); + freshTag.setPerformClearTagStateForTagPoolingServers(true); + 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)); } diff --git a/core/src/test/java/org/apache/struts2/views/jsp/ui/ResetTest.java b/core/src/test/java/org/apache/struts2/views/jsp/ui/ResetTest.java index d3194757c..c297b86cc 100644 --- a/core/src/test/java/org/apache/struts2/views/jsp/ui/ResetTest.java +++ b/core/src/test/java/org/apache/struts2/views/jsp/ui/ResetTest.java @@ -49,7 +49,34 @@ public class ResetTest extends AbstractUITagTest { // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). ResetTag freshTag = new ResetTag(); freshTag.setPageContext(pageContext); - assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + 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 testDefaultValues_clearTagStateSet() throws Exception { + TestAction testAction = (TestAction) action; + testAction.setFoo("bar"); + + ResetTag tag = new ResetTag(); + tag.setPerformClearTagStateForTagPoolingServers(true); // Explicitly request tag state clearing. + tag.setPageContext(pageContext); + tag.setLabel("mylabel"); + tag.setName("myname"); + tag.setTitle("mytitle"); + tag.setSrc("/images/test.png"); + + tag.doStartTag(); + setComponentTagClearTagState(tag, true); // Ensure component tag state clearing is set true (to match tag). + tag.doEndTag(); + + verify(TextFieldTag.class.getResource("Reset-2.txt")); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + ResetTag freshTag = new ResetTag(); + freshTag.setPerformClearTagStateForTagPoolingServers(true); + 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)); } @@ -73,7 +100,34 @@ public class ResetTest extends AbstractUITagTest { // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). ResetTag freshTag = new ResetTag(); freshTag.setPageContext(pageContext); - assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + 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 testSimple_clearTagStateSet() throws Exception { + TestAction testAction = (TestAction) action; + testAction.setFoo("bar"); + + ResetTag tag = new ResetTag(); + tag.setPerformClearTagStateForTagPoolingServers(true); // Explicitly request tag state clearing. + tag.setPageContext(pageContext); + tag.setLabel("mylabel"); + tag.setName("myname"); + tag.setValue("%{foo}"); + tag.setTabindex("1"); + + tag.doStartTag(); + setComponentTagClearTagState(tag, true); // Ensure component tag state clearing is set true (to match tag). + tag.doEndTag(); + + verify(TextFieldTag.class.getResource("Reset-1.txt")); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + ResetTag freshTag = new ResetTag(); + freshTag.setPerformClearTagStateForTagPoolingServers(true); + 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)); } @@ -97,7 +151,34 @@ public class ResetTest extends AbstractUITagTest { // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). ResetTag freshTag = new ResetTag(); freshTag.setPageContext(pageContext); - assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + 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 testButtonSimple_clearTagStateSet() throws Exception { + TestAction testAction = (TestAction) action; + testAction.setFoo("bar"); + + ResetTag tag = new ResetTag(); + tag.setPerformClearTagStateForTagPoolingServers(true); // Explicitly request tag state clearing. + tag.setPageContext(pageContext); + tag.setType("button"); + tag.setName("myname"); + tag.setValue("%{foo}"); + tag.setTabindex("1"); + + tag.doStartTag(); + setComponentTagClearTagState(tag, true); // Ensure component tag state clearing is set true (to match tag). + tag.doEndTag(); + + verify(TextFieldTag.class.getResource("Reset-3.txt")); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + ResetTag freshTag = new ResetTag(); + freshTag.setPerformClearTagStateForTagPoolingServers(true); + 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)); } @@ -121,7 +202,34 @@ public class ResetTest extends AbstractUITagTest { // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). ResetTag freshTag = new ResetTag(); freshTag.setPageContext(pageContext); - assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + 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 testButtonWithLabel_clearTagStateSet() throws Exception { + TestAction testAction = (TestAction) action; + testAction.setFoo("bar"); + + ResetTag tag = new ResetTag(); + tag.setPerformClearTagStateForTagPoolingServers(true); // Explicitly request tag state clearing. + tag.setPageContext(pageContext); + tag.setLabel("mylabel"); + tag.setType("button"); + tag.setName("myname"); + tag.setValue("%{foo}"); + + tag.doStartTag(); + setComponentTagClearTagState(tag, true); // Ensure component tag state clearing is set true (to match tag). + tag.doEndTag(); + + verify(TextFieldTag.class.getResource("Reset-4.txt")); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + ResetTag freshTag = new ResetTag(); + freshTag.setPerformClearTagStateForTagPoolingServers(true); + 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)); } @@ -145,7 +253,34 @@ public class ResetTest extends AbstractUITagTest { // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). ResetTag freshTag = new ResetTag(); freshTag.setPageContext(pageContext); - assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + 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 testImageSimple_clearTagStateSet() throws Exception { + TestAction testAction = (TestAction) action; + testAction.setFoo("bar"); + + ResetTag tag = new ResetTag(); + tag.setPerformClearTagStateForTagPoolingServers(true); // Explicitly request tag state clearing. + tag.setPageContext(pageContext); + tag.setType("button"); + tag.setName("myname"); + tag.setValue("%{foo}"); + tag.setDisabled("true"); + + tag.doStartTag(); + setComponentTagClearTagState(tag, true); // Ensure component tag state clearing is set true (to match tag). + tag.doEndTag(); + + verify(TextFieldTag.class.getResource("Reset-5.txt")); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + ResetTag freshTag = new ResetTag(); + freshTag.setPerformClearTagStateForTagPoolingServers(true); + 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)); } @@ -170,7 +305,35 @@ public class ResetTest extends AbstractUITagTest { // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). ResetTag freshTag = new ResetTag(); freshTag.setPageContext(pageContext); - assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + 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 testImageWithSrc_clearTagStateSet() throws Exception { + TestAction testAction = (TestAction) action; + testAction.setFoo("bar"); + + ResetTag tag = new ResetTag(); + tag.setPerformClearTagStateForTagPoolingServers(true); // Explicitly request tag state clearing. + tag.setPageContext(pageContext); + tag.setType("button"); + tag.setName("myname"); + tag.setLabel("mylabel"); + tag.setValue("%{foo}"); + tag.setSrc("some.gif"); + + tag.doStartTag(); + setComponentTagClearTagState(tag, true); // Ensure component tag state clearing is set true (to match tag). + tag.doEndTag(); + + verify(TextFieldTag.class.getResource("Reset-6.txt")); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + ResetTag freshTag = new ResetTag(); + freshTag.setPerformClearTagStateForTagPoolingServers(true); + 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)); } @@ -195,7 +358,35 @@ public class ResetTest extends AbstractUITagTest { // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). ResetTag freshTag = new ResetTag(); freshTag.setPageContext(pageContext); - assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + 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 testImageWithExpressionSrc_clearTagStateSet() throws Exception { + TestAction testAction = (TestAction) action; + testAction.setFoo("bar"); + + ResetTag tag = new ResetTag(); + tag.setPerformClearTagStateForTagPoolingServers(true); // Explicitly request tag state clearing. + tag.setPageContext(pageContext); + tag.setType("button"); + tag.setName("myname"); + tag.setLabel("mylabel"); + tag.setValue("%{foo}"); + tag.setSrc("%{getText(\"some.image.from.properties\")}"); + + tag.doStartTag(); + setComponentTagClearTagState(tag, true); // Ensure component tag state clearing is set true (to match tag). + tag.doEndTag(); + + verify(TextFieldTag.class.getResource("Reset-6.txt")); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + ResetTag freshTag = new ResetTag(); + freshTag.setPerformClearTagStateForTagPoolingServers(true); + 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)); } @@ -221,7 +412,36 @@ public class ResetTest extends AbstractUITagTest { // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). ResetTag freshTag = new ResetTag(); freshTag.setPageContext(pageContext); - assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + 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 testSimpleThemeImageUsingActionAndMethod_clearTagStateSet() throws Exception { + TestAction testAction = (TestAction) action; + testAction.setFoo("bar"); + + ResetTag tag = new ResetTag(); + tag.setPerformClearTagStateForTagPoolingServers(true); // Explicitly request tag state clearing. + tag.setPageContext(pageContext); + tag.setTheme("simple"); + tag.setType("button"); + tag.setName("myname"); + tag.setLabel("mylabel"); + tag.setAction("manager"); + tag.setMethod("update"); + + tag.doStartTag(); + setComponentTagClearTagState(tag, true); // Ensure component tag state clearing is set true (to match tag). + tag.doEndTag(); + + verify(TextFieldTag.class.getResource("Reset-7.txt")); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + ResetTag freshTag = new ResetTag(); + freshTag.setPerformClearTagStateForTagPoolingServers(true); + 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)); } @@ -247,7 +467,36 @@ public class ResetTest extends AbstractUITagTest { // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). ResetTag freshTag = new ResetTag(); freshTag.setPageContext(pageContext); - assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + 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 testSimpleThemeImageUsingActionOnly_clearTagStateSet() throws Exception { + TestAction testAction = (TestAction) action; + testAction.setFoo("bar"); + + ResetTag tag = new ResetTag(); + tag.setPerformClearTagStateForTagPoolingServers(true); // Explicitly request tag state clearing. + tag.setPageContext(pageContext); + tag.setTheme("simple"); + tag.setType("button"); + tag.setName("myname"); + tag.setLabel("mylabel"); + tag.setAction("manager"); + tag.setMethod(null); // no method + + tag.doStartTag(); + setComponentTagClearTagState(tag, true); // Ensure component tag state clearing is set true (to match tag). + tag.doEndTag(); + + verify(TextFieldTag.class.getResource("Reset-8.txt")); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + ResetTag freshTag = new ResetTag(); + freshTag.setPerformClearTagStateForTagPoolingServers(true); + 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)); } @@ -273,11 +522,40 @@ public class ResetTest extends AbstractUITagTest { // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). ResetTag freshTag = new ResetTag(); freshTag.setPageContext(pageContext); - assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + 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 testSimpleThemeImageUsingMethodOnly_clearTagStateSet() throws Exception { + TestAction testAction = (TestAction) action; + testAction.setFoo("bar"); + + ResetTag tag = new ResetTag(); + tag.setPerformClearTagStateForTagPoolingServers(true); // Explicitly request tag state clearing. + tag.setPageContext(pageContext); + tag.setTheme("simple"); + tag.setType("button"); + tag.setName("myname"); + tag.setLabel("mylabel"); + tag.setAction(null); // no action + tag.setMethod("update"); + + tag.doStartTag(); + setComponentTagClearTagState(tag, true); // Ensure component tag state clearing is set true (to match tag). + tag.doEndTag(); + + verify(TextFieldTag.class.getResource("Reset-9.txt")); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + ResetTag freshTag = new ResetTag(); + freshTag.setPerformClearTagStateForTagPoolingServers(true); + 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)); + } + /** * Initialize a map of {@link org.apache.struts2.views.jsp.AbstractUITagTest.PropertyHolder} for generic tag * property testing. Will be used when calling {@link #verifyGenericProperties(AbstractUITag, diff --git a/core/src/test/java/org/apache/struts2/views/jsp/ui/SelectTest.java b/core/src/test/java/org/apache/struts2/views/jsp/ui/SelectTest.java index ad8a7e378..e739ffe01 100644 --- a/core/src/test/java/org/apache/struts2/views/jsp/ui/SelectTest.java +++ b/core/src/test/java/org/apache/struts2/views/jsp/ui/SelectTest.java @@ -50,7 +50,33 @@ public class SelectTest extends AbstractUITagTest { // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). SelectTag freshTag = new SelectTag(); freshTag.setPageContext(pageContext); - assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + 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 testHeaderCanBePreselected_clearTagStateSet() throws Exception { + SelectTag tag = new SelectTag(); + tag.setPerformClearTagStateForTagPoolingServers(true); // Explicitly request tag state clearing. + tag.setPageContext(pageContext); + tag.setLabel("myLabel"); + tag.setList("#{1:'Cat',2:'Dog'}"); + tag.setName("myPet"); + tag.setHeaderKey("-1"); + tag.setHeaderValue("--- Please Select ---"); + tag.setValue("%{'-1'}"); + + tag.doStartTag(); + setComponentTagClearTagState(tag, true); // Ensure component tag state clearing is set true (to match tag). + tag.doEndTag(); + + verify(SelectTag.class.getResource("Select-8.txt")); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + SelectTag freshTag = new SelectTag(); + freshTag.setPerformClearTagStateForTagPoolingServers(true); + 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)); } @@ -98,11 +124,61 @@ public class SelectTest extends AbstractUITagTest { // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). SelectTag freshTag = new SelectTag(); freshTag.setPageContext(pageContext); - assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + 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)); } + /** + * Tests WW-1601: Select tag template does not work properly for Object like Byte. + */ + public void testByte_clearTagStateSet() throws Exception { + ByteObject hello = new ByteObject(new Byte((byte)1), "hello"); + ByteObject foo = new ByteObject(new Byte((byte)2), "foo"); + + TestAction testAction = (TestAction) action; + + Collection collection = new ArrayList(2); + // expect strings to be returned, we're still dealing with HTTP here! + collection.add("1"); + collection.add("2"); + testAction.setCollection(collection); + + List list2 = new ArrayList(); + list2.add(hello); + list2.add(foo); + testAction.setList2(list2); + + SelectTag tag = new SelectTag(); + tag.setPerformClearTagStateForTagPoolingServers(true); // Explicitly request tag state clearing. + tag.setPageContext(pageContext); + tag.setLabel("mylabel"); + tag.setName("collection"); + tag.setList("list2"); + tag.setListKey("byte"); + tag.setListValue("name"); + tag.setMultiple("true"); + tag.setTitle("mytitle"); + tag.setOnmousedown("alert('onmousedown');"); + tag.setOnmousemove("alert('onmousemove');"); + tag.setOnmouseout("alert('onmouseout');"); + tag.setOnmouseover("alert('onmouseover');"); + tag.setOnmouseup("alert('onmouseup');"); + + tag.doStartTag(); + setComponentTagClearTagState(tag, true); // Ensure component tag state clearing is set true (to match tag). + tag.doEndTag(); + + verify(SelectTag.class.getResource("Select-10.txt")); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + SelectTag freshTag = new SelectTag(); + freshTag.setPerformClearTagStateForTagPoolingServers(true); + 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)); + } /** * Tests WW-455: Select tag template does not work properly for Object like BigDecimal. @@ -148,7 +224,59 @@ public class SelectTest extends AbstractUITagTest { // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). SelectTag freshTag = new SelectTag(); freshTag.setPageContext(pageContext); - assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + 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)); + } + + /** + * Tests WW-455: Select tag template does not work properly for Object like BigDecimal. + */ + public void testBigDecimal_clearTagStateSet() throws Exception { + BigDecimalObject hello = new BigDecimalObject("hello", new BigDecimal(1)); + BigDecimalObject foo = new BigDecimalObject("foo", new BigDecimal(2)); + + TestAction testAction = (TestAction) action; + + Collection collection = new ArrayList(2); + // expect strings to be returned, we're still dealing with HTTP here! + collection.add("hello"); + collection.add("foo"); + testAction.setCollection(collection); + + List list2 = new ArrayList(); + list2.add(hello); + list2.add(foo); + list2.add(new BigDecimalObject("", new BigDecimal(1.500))); + testAction.setList2(list2); + + SelectTag tag = new SelectTag(); + tag.setPerformClearTagStateForTagPoolingServers(true); // Explicitly request tag state clearing. + tag.setPageContext(pageContext); + tag.setLabel("mylabel"); + tag.setName("collection"); + tag.setList("list2"); + tag.setListKey("name"); + tag.setListValue("bigDecimal"); + tag.setMultiple("true"); + tag.setTitle("mytitle"); + tag.setOnmousedown("alert('onmousedown');"); + tag.setOnmousemove("alert('onmousemove');"); + tag.setOnmouseout("alert('onmouseout');"); + tag.setOnmouseover("alert('onmouseover');"); + tag.setOnmouseup("alert('onmouseup');"); + + tag.doStartTag(); + setComponentTagClearTagState(tag, true); // Ensure component tag state clearing is set true (to match tag). + tag.doEndTag(); + + verify(SelectTag.class.getResource("Select-3.txt")); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + SelectTag freshTag = new SelectTag(); + freshTag.setPerformClearTagStateForTagPoolingServers(true); + 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)); } @@ -194,7 +322,56 @@ public class SelectTest extends AbstractUITagTest { // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). SelectTag freshTag = new SelectTag(); freshTag.setPageContext(pageContext); - assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + 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 testInteger_clearTagStateSet() throws Exception { + IntegerObject hello = new IntegerObject("hello", 1); + IntegerObject foo = new IntegerObject("foo", 2); + + TestAction testAction = (TestAction) action; + + Collection collection = new ArrayList(2); + // expect strings to be returned, we're still dealing with HTTP here! + collection.add("hello"); + collection.add("foo"); + testAction.setCollection(collection); + + List list2 = new ArrayList(); + list2.add(hello); + list2.add(foo); + list2.add(new IntegerObject("", 3)); + testAction.setList2(list2); + + SelectTag tag = new SelectTag(); + tag.setPerformClearTagStateForTagPoolingServers(true); // Explicitly request tag state clearing. + tag.setPageContext(pageContext); + tag.setLabel("mylabel"); + tag.setName("collection"); + tag.setList("list2"); + tag.setListKey("name"); + tag.setListValue("integer"); + tag.setMultiple("true"); + tag.setTitle("mytitle"); + tag.setOnmousedown("alert('onmousedown');"); + tag.setOnmousemove("alert('onmousemove');"); + tag.setOnmouseout("alert('onmouseout');"); + tag.setOnmouseover("alert('onmouseover');"); + tag.setOnmouseup("alert('onmouseup');"); + + tag.doStartTag(); + setComponentTagClearTagState(tag, true); // Ensure component tag state clearing is set true (to match tag). + tag.doEndTag(); + + verify(SelectTag.class.getResource("Select-14.txt")); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + SelectTag freshTag = new SelectTag(); + freshTag.setPerformClearTagStateForTagPoolingServers(true); + 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)); } @@ -241,7 +418,57 @@ public class SelectTest extends AbstractUITagTest { // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). SelectTag freshTag = new SelectTag(); freshTag.setPageContext(pageContext); - assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + 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 testNumericString_clearTagStateSet() throws Exception { + StringObject hello = new StringObject("hello", "1"); + StringObject foo = new StringObject("foo", "2"); + + TestAction testAction = (TestAction) action; + + Collection collection = new ArrayList(2); + // expect strings to be returned, we're still dealing with HTTP here! + collection.add("hello"); + collection.add("foo"); + testAction.setCollection(collection); + + List list2 = new ArrayList(); + list2.add(hello); + list2.add(foo); + list2.add(new StringObject("", "1.5")); + list2.add(new StringObject("", "2,5")); + testAction.setList2(list2); + + SelectTag tag = new SelectTag(); + tag.setPerformClearTagStateForTagPoolingServers(true); // Explicitly request tag state clearing. + tag.setPageContext(pageContext); + tag.setLabel("mylabel"); + tag.setName("collection"); + tag.setList("list2"); + tag.setListKey("name"); + tag.setListValue("number"); + tag.setMultiple("true"); + tag.setTitle("mytitle"); + tag.setOnmousedown("alert('onmousedown');"); + tag.setOnmousemove("alert('onmousemove');"); + tag.setOnmouseout("alert('onmouseout');"); + tag.setOnmouseover("alert('onmouseover');"); + tag.setOnmouseup("alert('onmouseup');"); + + tag.doStartTag(); + setComponentTagClearTagState(tag, true); // Ensure component tag state clearing is set true (to match tag). + tag.doEndTag(); + + verify(SelectTag.class.getResource("Select-15.txt")); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + SelectTag freshTag = new SelectTag(); + freshTag.setPerformClearTagStateForTagPoolingServers(true); + 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)); } @@ -384,7 +611,33 @@ public class SelectTest extends AbstractUITagTest { // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). SelectTag freshTag = new SelectTag(); freshTag.setPageContext(pageContext); - assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + 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 testEmptyList_clearTagStateSet() throws Exception { + TestAction testAction = (TestAction) action; + testAction.setList2(new ArrayList()); + + SelectTag tag = new SelectTag(); + tag.setPerformClearTagStateForTagPoolingServers(true); // Explicitly request tag state clearing. + tag.setName("collection"); + tag.setList("list2"); + tag.setLabel("tmjee_name"); + + tag.setPageContext(pageContext); + tag.doStartTag(); + setComponentTagClearTagState(tag, true); // Ensure component tag state clearing is set true (to match tag). + tag.doEndTag(); + + verify(SelectTag.class.getResource("Select-4.txt")); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + SelectTag freshTag = new SelectTag(); + freshTag.setPerformClearTagStateForTagPoolingServers(true); + 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)); } @@ -423,7 +676,49 @@ public class SelectTest extends AbstractUITagTest { // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). SelectTag freshTag = new SelectTag(); freshTag.setPageContext(pageContext); - assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + 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 testMultiple_clearTagStateSet() throws Exception { + TestAction testAction = (TestAction) action; + Collection collection = new ArrayList(2); + collection.add("hello"); + collection.add("foo"); + testAction.setCollection(collection); + testAction.setList(new String[][]{ + {"hello", "world"}, + {"foo", "bar"}, + {"cat", "dog"} + }); + + SelectTag tag = new SelectTag(); + tag.setPerformClearTagStateForTagPoolingServers(true); // Explicitly request tag state clearing. + tag.setPageContext(pageContext); + tag.setLabel("mylabel"); + tag.setName("collection"); + tag.setList("list"); + tag.setListKey("top[0]"); + tag.setListValue("top[1]"); + tag.setMultiple("true"); + tag.setOnmousedown("alert('onmousedown');"); + tag.setOnmousemove("alert('onmousemove');"); + tag.setOnmouseout("alert('onmouseout');"); + tag.setOnmouseover("alert('onmouseover');"); + tag.setOnmouseup("alert('onmouseup');"); + + tag.doStartTag(); + setComponentTagClearTagState(tag, true); // Ensure component tag state clearing is set true (to match tag). + tag.doEndTag(); + + verify(SelectTag.class.getResource("Select-2.txt")); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + SelectTag freshTag = new SelectTag(); + freshTag.setPerformClearTagStateForTagPoolingServers(true); + 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)); } @@ -468,7 +763,55 @@ public class SelectTest extends AbstractUITagTest { // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). SelectTag freshTag = new SelectTag(); freshTag.setPageContext(pageContext); - assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + 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)); + } + + /** + * WW-1747 - should be a valid test case for the described issue + * @throws Exception + */ + public void testMultipleWithLists_clearTagStateSet() throws Exception { + TestAction testAction = (TestAction) action; + Collection collection = new ArrayList(2); + + collection.add(1l); + collection.add(300000000l); + testAction.setCollection(collection); + + List selectList = new ArrayList(); + selectList.add(new LongObject(1l, "foo")); + selectList.add(new LongObject(2l, "bar")); + selectList.add(new LongObject(300000000l, "foobar")); + testAction.setList2(selectList); + + SelectTag tag = new SelectTag(); + tag.setPerformClearTagStateForTagPoolingServers(true); // Explicitly request tag state clearing. + tag.setPageContext(pageContext); + tag.setLabel("mylabel"); + tag.setName("collection"); + tag.setList("list2"); + tag.setListKey("id"); + tag.setListValue("value"); + tag.setMultiple("true"); + tag.setOnmousedown("alert('onmousedown');"); + tag.setOnmousemove("alert('onmousemove');"); + tag.setOnmouseout("alert('onmouseout');"); + tag.setOnmouseover("alert('onmouseover');"); + tag.setOnmouseup("alert('onmouseup');"); + + tag.doStartTag(); + setComponentTagClearTagState(tag, true); // Ensure component tag state clearing is set true (to match tag). + tag.doEndTag(); + + verify(SelectTag.class.getResource("Select-12.txt")); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + SelectTag freshTag = new SelectTag(); + freshTag.setPerformClearTagStateForTagPoolingServers(true); + 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)); } @@ -505,11 +848,51 @@ public class SelectTest extends AbstractUITagTest { // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). SelectTag freshTag = new SelectTag(); freshTag.setPageContext(pageContext); - assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + 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 testSimple_clearTagStateSet() throws Exception { + TestAction testAction = (TestAction) action; + testAction.setFoo("hello"); + testAction.setList(new String[][]{ + {"hello", "world"}, + {"foo", "bar"} + }); + + SelectTag tag = new SelectTag(); + tag.setPerformClearTagStateForTagPoolingServers(true); // Explicitly request tag state clearing. + tag.setPageContext(pageContext); + tag.setEmptyOption("true"); + tag.setLabel("mylabel"); + tag.setName("foo"); + tag.setList("list"); + tag.setListKey("top[0]"); + tag.setListValue("top[1]"); + + // header stuff + tag.setHeaderKey("headerKey"); + tag.setHeaderValue("headerValue"); + + // empty option + tag.setEmptyOption("true"); + + tag.doStartTag(); + setComponentTagClearTagState(tag, true); // Ensure component tag state clearing is set true (to match tag). + tag.doEndTag(); + + verify(SelectTag.class.getResource("Select-1.txt")); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + SelectTag freshTag = new SelectTag(); + freshTag.setPerformClearTagStateForTagPoolingServers(true); + 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)); + } + public void testSimpleWithNulls() throws Exception { TestAction testAction = (TestAction) action; testAction.setFoo("hello"); @@ -542,7 +925,47 @@ public class SelectTest extends AbstractUITagTest { // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). SelectTag freshTag = new SelectTag(); freshTag.setPageContext(pageContext); - assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + 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 testSimpleWithNulls_clearTagStateSet() throws Exception { + TestAction testAction = (TestAction) action; + testAction.setFoo("hello"); + testAction.setList(new String[][]{ + {"hello", null}, + {null, "bar"} + }); + + SelectTag tag = new SelectTag(); + tag.setPerformClearTagStateForTagPoolingServers(true); // Explicitly request tag state clearing. + tag.setPageContext(pageContext); + tag.setEmptyOption("true"); + tag.setLabel("mylabel"); + tag.setName("foo"); + tag.setList("list"); + tag.setListKey("top[0]"); + tag.setListValue("top[1]"); + + // header stuff + tag.setHeaderKey("headerKey"); + tag.setHeaderValue("headerValue"); + + // empty option + tag.setEmptyOption("true"); + + tag.doStartTag(); + setComponentTagClearTagState(tag, true); // Ensure component tag state clearing is set true (to match tag). + tag.doEndTag(); + + verify(SelectTag.class.getResource("Select-9.txt")); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + SelectTag freshTag = new SelectTag(); + freshTag.setPerformClearTagStateForTagPoolingServers(true); + 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)); } @@ -579,7 +1002,47 @@ public class SelectTest extends AbstractUITagTest { // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). SelectTag freshTag = new SelectTag(); freshTag.setPageContext(pageContext); - assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + 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 testExtended_clearTagStateSet() throws Exception { + TestAction testAction = (TestAction) action; + testAction.setFoo("hello"); + testAction.setList(new String[][]{ + {"hello", "world"}, + {"foo", "bar"} + }); + + SelectTag tag = new SelectTag(); + tag.setPerformClearTagStateForTagPoolingServers(true); // Explicitly request tag state clearing. + tag.setPageContext(pageContext); + tag.setEmptyOption("true"); + tag.setLabel("mylabel"); + tag.setName("foo"); + tag.setList("list"); + tag.setListKey("top[0]"); + tag.setListValue("%{top[0] + ' - ' + top[1]}"); + + // header stuff + tag.setHeaderKey("headerKey"); + tag.setHeaderValue("%{foo + ': headerValue'}"); + + // empty option + tag.setEmptyOption("true"); + + tag.doStartTag(); + setComponentTagClearTagState(tag, true); // Ensure component tag state clearing is set true (to match tag). + tag.doEndTag(); + + verify(SelectTag.class.getResource("Select-7.txt")); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + SelectTag freshTag = new SelectTag(); + freshTag.setPerformClearTagStateForTagPoolingServers(true); + 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)); } @@ -614,7 +1077,33 @@ public class SelectTest extends AbstractUITagTest { // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). SelectTag freshTag = new SelectTag(); freshTag.setPageContext(pageContext); - assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + 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 testMultipleOn_clearTagStateSet() throws Exception { + SelectTag tag = new SelectTag(); + tag.setPerformClearTagStateForTagPoolingServers(true); // Explicitly request tag state clearing. + tag.setPageContext(pageContext); + tag.setLabel("media1"); + tag.setId("myId"); + tag.setEmptyOption("true"); + tag.setName("myName"); + tag.setMultiple("true"); + tag.setList("{'aaa','bbb'}"); + + tag.doStartTag(); + setComponentTagClearTagState(tag, true); // Ensure component tag state clearing is set true (to match tag). + tag.doEndTag(); + + verify(SelectTag.class.getResource("Select-5.txt")); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + SelectTag freshTag = new SelectTag(); + freshTag.setPerformClearTagStateForTagPoolingServers(true); + 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)); } @@ -637,11 +1126,36 @@ public class SelectTest extends AbstractUITagTest { // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). SelectTag freshTag = new SelectTag(); freshTag.setPageContext(pageContext); - assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + 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 testMultipleOff_clearTagStateSet() throws Exception { + SelectTag tag = new SelectTag(); + tag.setPerformClearTagStateForTagPoolingServers(true); // Explicitly request tag state clearing. + tag.setPageContext(pageContext); + tag.setLabel("media2"); + tag.setId("myId"); + tag.setEmptyOption("true"); + tag.setName("myName"); + tag.setMultiple("false"); + tag.setList("{'aaa','bbb'}"); + + tag.doStartTag(); + setComponentTagClearTagState(tag, true); // Ensure component tag state clearing is set true (to match tag). + tag.doEndTag(); + + verify(SelectTag.class.getResource("Select-6.txt")); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + SelectTag freshTag = new SelectTag(); + freshTag.setPerformClearTagStateForTagPoolingServers(true); + 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)); + } public void testSimpleInteger() throws Exception { TestAction testAction = (TestAction) action; @@ -679,7 +1193,51 @@ public class SelectTest extends AbstractUITagTest { // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). SelectTag freshTag = new SelectTag(); freshTag.setPageContext(pageContext); - assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + 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 testSimpleInteger_clearTagStateSet() throws Exception { + TestAction testAction = (TestAction) action; + + IdName hello = new IdName(new Integer(1), "hello"); + IdName world = new IdName(new Integer(2), "world"); + List list2 = new ArrayList(); + list2.add(hello); + list2.add(world); + testAction.setList2(list2); + + testAction.setFooInt(new Integer(1)); + + SelectTag tag = new SelectTag(); + tag.setPerformClearTagStateForTagPoolingServers(true); // Explicitly request tag state clearing. + tag.setPageContext(pageContext); + tag.setEmptyOption("true"); + tag.setLabel("mylabel"); + tag.setName("fooInt"); + tag.setList("list2"); + tag.setListKey("id"); + tag.setListValue("name"); + + // header stuff + tag.setHeaderKey("headerKey"); + tag.setHeaderValue("headerValue"); + + // empty option + tag.setEmptyOption("true"); + + tag.doStartTag(); + setComponentTagClearTagState(tag, true); // Ensure component tag state clearing is set true (to match tag). + tag.doEndTag(); + + verify(SelectTag.class.getResource("Select-11.txt")); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + SelectTag freshTag = new SelectTag(); + freshTag.setPerformClearTagStateForTagPoolingServers(true); + 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)); } @@ -721,11 +1279,56 @@ public class SelectTest extends AbstractUITagTest { // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). SelectTag freshTag = new SelectTag(); freshTag.setPageContext(pageContext); - assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + 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 testSimpleIntegerWithValueWorkaround_clearTagStateSet() throws Exception { + TestAction testAction = (TestAction) action; + + IdName hello = new IdName(new Integer(1), "hello"); + IdName world = new IdName(new Integer(2), "world"); + List list2 = new ArrayList(); + list2.add(hello); + list2.add(world); + testAction.setList2(list2); + + testAction.setFooInt(new Integer(1)); + + SelectTag tag = new SelectTag(); + tag.setPerformClearTagStateForTagPoolingServers(true); // Explicitly request tag state clearing. + tag.setPageContext(pageContext); + tag.setEmptyOption("true"); + tag.setLabel("mylabel"); + tag.setName("fooInt"); + tag.setList("list2"); + tag.setListKey("id"); + tag.setListValue("name"); + tag.setValue("fooInt"); + + // header stuff + tag.setHeaderKey("headerKey"); + tag.setHeaderValue("headerValue"); + + // empty option + tag.setEmptyOption("true"); + + tag.doStartTag(); + setComponentTagClearTagState(tag, true); // Ensure component tag state clearing is set true (to match tag). + tag.doEndTag(); + + verify(SelectTag.class.getResource("Select-11.txt")); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + SelectTag freshTag = new SelectTag(); + freshTag.setPerformClearTagStateForTagPoolingServers(true); + 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)); + } + public void testEnumList() throws Exception { SelectTag tag = new SelectTag(); @@ -744,7 +1347,33 @@ public class SelectTest extends AbstractUITagTest { // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). SelectTag freshTag = new SelectTag(); freshTag.setPageContext(pageContext); - assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + 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 testEnumList_clearTagStateSet() throws Exception { + + SelectTag tag = new SelectTag(); + tag.setPerformClearTagStateForTagPoolingServers(true); // Explicitly request tag state clearing. + tag.setPageContext(pageContext); + tag.setLabel("mylabel"); + tag.setName("status"); + tag.setList("statusList"); + tag.setListKey("name"); + tag.setListValue("displayName"); + + tag.doStartTag(); + setComponentTagClearTagState(tag, true); // Ensure component tag state clearing is set true (to match tag). + tag.doEndTag(); + + verify(SelectTag.class.getResource("Select-13.txt")); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + SelectTag freshTag = new SelectTag(); + freshTag.setPerformClearTagStateForTagPoolingServers(true); + 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)); } @@ -766,7 +1395,32 @@ public class SelectTest extends AbstractUITagTest { // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). SelectTag freshTag = new SelectTag(); freshTag.setPageContext(pageContext); - assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + 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 testNotExistingListValueKey_clearTagStateSet() throws Exception { + SelectTag tag = new SelectTag(); + tag.setPerformClearTagStateForTagPoolingServers(true); // Explicitly request tag state clearing. + tag.setName("foo"); + tag.setLabel("mylabel"); + tag.setList("#{'a':'aaa', 'b':'bbb', 'c':'ccc'}"); + tag.setListValueKey("notExistingProperty"); + + tag.setPageContext(pageContext); + + tag.doStartTag(); + setComponentTagClearTagState(tag, true); // Ensure component tag state clearing is set true (to match tag). + tag.doEndTag(); + + verify(SelectTag.class.getResource("Select-16.txt")); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + SelectTag freshTag = new SelectTag(); + freshTag.setPerformClearTagStateForTagPoolingServers(true); + 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)); } diff --git a/core/src/test/java/org/apache/struts2/views/jsp/ui/SubmitTest.java b/core/src/test/java/org/apache/struts2/views/jsp/ui/SubmitTest.java index 2ebe68c60..6f573ae07 100644 --- a/core/src/test/java/org/apache/struts2/views/jsp/ui/SubmitTest.java +++ b/core/src/test/java/org/apache/struts2/views/jsp/ui/SubmitTest.java @@ -54,7 +54,38 @@ public class SubmitTest extends AbstractUITagTest { // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). SubmitTag freshTag = new SubmitTag(); freshTag.setPageContext(pageContext); - assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + 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 testButtonSimpleWithBody_clearTagStateSet() throws Exception { + TestAction testAction = (TestAction) action; + testAction.setFoo("bar"); + + SubmitTag tag = new SubmitTag(); + tag.setPerformClearTagStateForTagPoolingServers(true); // Explicitly request tag state clearing. + tag.setTheme("simple"); + tag.setPageContext(pageContext); + tag.setType("button"); + tag.setName("myname"); + tag.setLabel("yoyoyoyoy"); + tag.setValue("%{foo}"); + + StrutsBodyContent body = new StrutsBodyContent(null); + body.print("foo"); + tag.setBodyContent(body); + tag.doStartTag(); + setComponentTagClearTagState(tag, true); // Ensure component tag state clearing is set true (to match tag). + tag.doEndTag(); + + verify(TextFieldTag.class.getResource("Submit-10.txt")); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + SubmitTag freshTag = new SubmitTag(); + freshTag.setPerformClearTagStateForTagPoolingServers(true); + 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)); } @@ -64,6 +95,7 @@ public class SubmitTest extends AbstractUITagTest { testAction.setFoo("bar"); SubmitTag tag = new SubmitTag(); + tag.setPerformClearTagStateForTagPoolingServers(true); // Explicitly request tag state clearing. tag.setPageContext(pageContext); tag.setLabel("mylabel"); tag.setName("myname"); @@ -77,7 +109,33 @@ public class SubmitTest extends AbstractUITagTest { // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). SubmitTag freshTag = new SubmitTag(); freshTag.setPageContext(pageContext); - assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + 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 testDefaultValues_clearTagStateSet() throws Exception { + TestAction testAction = (TestAction) action; + testAction.setFoo("bar"); + + SubmitTag tag = new SubmitTag(); + tag.setPerformClearTagStateForTagPoolingServers(true); // Explicitly request tag state clearing. + tag.setPageContext(pageContext); + tag.setLabel("mylabel"); + tag.setName("myname"); + tag.setTitle("mytitle"); + + tag.doStartTag(); + setComponentTagClearTagState(tag, true); // Ensure component tag state clearing is set true (to match tag). + tag.doEndTag(); + + verify(TextFieldTag.class.getResource("Submit-2.txt")); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + SubmitTag freshTag = new SubmitTag(); + freshTag.setPerformClearTagStateForTagPoolingServers(true); + 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)); } @@ -102,7 +160,35 @@ public class SubmitTest extends AbstractUITagTest { // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). SubmitTag freshTag = new SubmitTag(); freshTag.setPageContext(pageContext); - assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + 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 testSimple_clearTagStateSet() throws Exception { + TestAction testAction = (TestAction) action; + testAction.setFoo("bar"); + + SubmitTag tag = new SubmitTag(); + tag.setPerformClearTagStateForTagPoolingServers(true); // Explicitly request tag state clearing. + tag.setPageContext(pageContext); + tag.setLabel("mylabel"); + tag.setName("myname"); + tag.setValue("%{foo}"); + tag.setDisabled("true"); + tag.setTabindex("1"); + + tag.doStartTag(); + setComponentTagClearTagState(tag, true); // Ensure component tag state clearing is set true (to match tag). + tag.doEndTag(); + + verify(TextFieldTag.class.getResource("Submit-1.txt")); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + SubmitTag freshTag = new SubmitTag(); + freshTag.setPerformClearTagStateForTagPoolingServers(true); + 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)); } @@ -127,7 +213,35 @@ public class SubmitTest extends AbstractUITagTest { // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). SubmitTag freshTag = new SubmitTag(); freshTag.setPageContext(pageContext); - assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + 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 testButtonSimple_clearTagStateSet() throws Exception { + TestAction testAction = (TestAction) action; + testAction.setFoo("bar"); + + SubmitTag tag = new SubmitTag(); + tag.setPerformClearTagStateForTagPoolingServers(true); // Explicitly request tag state clearing. + tag.setPageContext(pageContext); + tag.setType("button"); + tag.setName("myname"); + tag.setValue("%{foo}"); + tag.setDisabled("true"); + tag.setTabindex("1"); + + tag.doStartTag(); + setComponentTagClearTagState(tag, true); // Ensure component tag state clearing is set true (to match tag). + tag.doEndTag(); + + verify(TextFieldTag.class.getResource("Submit-3.txt")); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + SubmitTag freshTag = new SubmitTag(); + freshTag.setPerformClearTagStateForTagPoolingServers(true); + 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)); } @@ -151,7 +265,34 @@ public class SubmitTest extends AbstractUITagTest { // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). SubmitTag freshTag = new SubmitTag(); freshTag.setPageContext(pageContext); - assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + 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 testButtonWithLabel_clearTagStateSet() throws Exception { + TestAction testAction = (TestAction) action; + testAction.setFoo("bar"); + + SubmitTag tag = new SubmitTag(); + tag.setPerformClearTagStateForTagPoolingServers(true); // Explicitly request tag state clearing. + tag.setPageContext(pageContext); + tag.setLabel("mylabel"); + tag.setType("button"); + tag.setName("myname"); + tag.setValue("%{foo}"); + + tag.doStartTag(); + setComponentTagClearTagState(tag, true); // Ensure component tag state clearing is set true (to match tag). + tag.doEndTag(); + + verify(TextFieldTag.class.getResource("Submit-4.txt")); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + SubmitTag freshTag = new SubmitTag(); + freshTag.setPerformClearTagStateForTagPoolingServers(true); + 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)); } @@ -175,7 +316,34 @@ public class SubmitTest extends AbstractUITagTest { // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). SubmitTag freshTag = new SubmitTag(); freshTag.setPageContext(pageContext); - assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + 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 testImageSimple_clearTagStateSet() throws Exception { + TestAction testAction = (TestAction) action; + testAction.setFoo("bar"); + + SubmitTag tag = new SubmitTag(); + tag.setPerformClearTagStateForTagPoolingServers(true); // Explicitly request tag state clearing. + tag.setPageContext(pageContext); + tag.setType("image"); + tag.setName("myname"); + tag.setValue("%{foo}"); + tag.setDisabled("true"); + + tag.doStartTag(); + setComponentTagClearTagState(tag, true); // Ensure component tag state clearing is set true (to match tag). + tag.doEndTag(); + + verify(TextFieldTag.class.getResource("Submit-5.txt")); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + SubmitTag freshTag = new SubmitTag(); + freshTag.setPerformClearTagStateForTagPoolingServers(true); + 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)); } @@ -200,7 +368,35 @@ public class SubmitTest extends AbstractUITagTest { // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). SubmitTag freshTag = new SubmitTag(); freshTag.setPageContext(pageContext); - assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + 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 testImageWithSrc_clearTagStateSet() throws Exception { + TestAction testAction = (TestAction) action; + testAction.setFoo("bar"); + + SubmitTag tag = new SubmitTag(); + tag.setPerformClearTagStateForTagPoolingServers(true); // Explicitly request tag state clearing. + tag.setPageContext(pageContext); + tag.setType("image"); + tag.setName("myname"); + tag.setLabel("mylabel"); + tag.setValue("%{foo}"); + tag.setSrc("some.gif"); + + tag.doStartTag(); + setComponentTagClearTagState(tag, true); // Ensure component tag state clearing is set true (to match tag). + tag.doEndTag(); + + verify(TextFieldTag.class.getResource("Submit-6.txt")); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + SubmitTag freshTag = new SubmitTag(); + freshTag.setPerformClearTagStateForTagPoolingServers(true); + 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)); } @@ -226,7 +422,36 @@ public class SubmitTest extends AbstractUITagTest { // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). SubmitTag freshTag = new SubmitTag(); freshTag.setPageContext(pageContext); - assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + 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 testSimpleThemeImageUsingActionAndMethod_clearTagStateSet() throws Exception { + TestAction testAction = (TestAction) action; + testAction.setFoo("bar"); + + SubmitTag tag = new SubmitTag(); + tag.setPerformClearTagStateForTagPoolingServers(true); // Explicitly request tag state clearing. + tag.setPageContext(pageContext); + tag.setTheme("simple"); + tag.setType("button"); + tag.setName("myname"); + tag.setLabel("mylabel"); + tag.setAction("manager"); + tag.setMethod("update"); + + tag.doStartTag(); + setComponentTagClearTagState(tag, true); // Ensure component tag state clearing is set true (to match tag). + tag.doEndTag(); + + verify(TextFieldTag.class.getResource("Submit-7.txt")); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + SubmitTag freshTag = new SubmitTag(); + freshTag.setPerformClearTagStateForTagPoolingServers(true); + 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)); } @@ -252,7 +477,36 @@ public class SubmitTest extends AbstractUITagTest { // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). SubmitTag freshTag = new SubmitTag(); freshTag.setPageContext(pageContext); - assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + 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 testSimpleThemeImageUsingActionOnly_clearTagStateSet() throws Exception { + TestAction testAction = (TestAction) action; + testAction.setFoo("bar"); + + SubmitTag tag = new SubmitTag(); + tag.setPerformClearTagStateForTagPoolingServers(true); // Explicitly request tag state clearing. + tag.setPageContext(pageContext); + tag.setTheme("simple"); + tag.setType("button"); + tag.setName("myname"); + tag.setLabel("mylabel"); + tag.setAction("manager"); + tag.setMethod(null); // no method + + tag.doStartTag(); + setComponentTagClearTagState(tag, true); // Ensure component tag state clearing is set true (to match tag). + tag.doEndTag(); + + verify(TextFieldTag.class.getResource("Submit-8.txt")); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + SubmitTag freshTag = new SubmitTag(); + freshTag.setPerformClearTagStateForTagPoolingServers(true); + 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)); } @@ -278,7 +532,36 @@ public class SubmitTest extends AbstractUITagTest { // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). SubmitTag freshTag = new SubmitTag(); freshTag.setPageContext(pageContext); - assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + 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 testSimpleThemeImageUsingMethodOnly_clearTagStateSet() throws Exception { + TestAction testAction = (TestAction) action; + testAction.setFoo("bar"); + + SubmitTag tag = new SubmitTag(); + tag.setPerformClearTagStateForTagPoolingServers(true); // Explicitly request tag state clearing. + tag.setPageContext(pageContext); + tag.setTheme("simple"); + tag.setType("button"); + tag.setName("myname"); + tag.setLabel("mylabel"); + tag.setAction(null); // no action + tag.setMethod("update"); + + tag.doStartTag(); + setComponentTagClearTagState(tag, true); // Ensure component tag state clearing is set true (to match tag). + tag.doEndTag(); + + verify(TextFieldTag.class.getResource("Submit-9.txt")); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + SubmitTag freshTag = new SubmitTag(); + freshTag.setPerformClearTagStateForTagPoolingServers(true); + 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)); } @@ -304,7 +587,36 @@ public class SubmitTest extends AbstractUITagTest { // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). SubmitTag freshTag = new SubmitTag(); freshTag.setPageContext(pageContext); - assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + 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 testSimpleThemeInput_clearTagStateSet() throws Exception { + TestAction testAction = (TestAction) action; + testAction.setFoo("bar"); + + SubmitTag tag = new SubmitTag(); + tag.setPerformClearTagStateForTagPoolingServers(true); // Explicitly request tag state clearing. + tag.setPageContext(pageContext); + tag.setTheme("simple"); + tag.setType("input"); + tag.setName("myname"); + tag.setLabel("mylabel"); + tag.setAction(null); + tag.setMethod(null); + + tag.doStartTag(); + setComponentTagClearTagState(tag, true); // Ensure component tag state clearing is set true (to match tag). + tag.doEndTag(); + + assertEquals("", writer.toString().trim()); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + SubmitTag freshTag = new SubmitTag(); + freshTag.setPerformClearTagStateForTagPoolingServers(true); + 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)); } diff --git a/core/src/test/java/org/apache/struts2/views/jsp/ui/TextareaTest.java b/core/src/test/java/org/apache/struts2/views/jsp/ui/TextareaTest.java index c52435b79..54fa4787a 100644 --- a/core/src/test/java/org/apache/struts2/views/jsp/ui/TextareaTest.java +++ b/core/src/test/java/org/apache/struts2/views/jsp/ui/TextareaTest.java @@ -56,7 +56,43 @@ public class TextareaTest extends AbstractUITagTest { // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). TextareaTag freshTag = new TextareaTag(); freshTag.setPageContext(pageContext); - assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + 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 testSimple_clearTagStateSet() throws Exception { + TestAction testAction = (TestAction) action; + testAction.setFoo("bar"); + + TextareaTag tag = new TextareaTag(); + tag.setPerformClearTagStateForTagPoolingServers(true); // Explicitly request tag state clearing. + tag.setPageContext(pageContext); + tag.setLabel("mylabel"); + tag.setName("myname"); + tag.setValue("%{foo}"); + tag.setRows("30"); + tag.setCols("20"); + tag.setTitle("mytitle"); + tag.setDisabled("true"); + tag.setTabindex("5"); + tag.setOnchange("alert('goodbye');"); + tag.setOnclick("alert('onclick');"); + tag.setId("the_id"); + tag.setOnkeyup("alert('hello');"); + tag.setReadonly("true"); + + tag.doStartTag(); + setComponentTagClearTagState(tag, true); // Ensure component tag state clearing is set true (to match tag). + tag.doEndTag(); + + verify(TextareaTag.class.getResource("Textarea-1.txt")); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + TextareaTag freshTag = new TextareaTag(); + freshTag.setPerformClearTagStateForTagPoolingServers(true); + 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)); } diff --git a/core/src/test/java/org/apache/struts2/views/jsp/ui/TextfieldTest.java b/core/src/test/java/org/apache/struts2/views/jsp/ui/TextfieldTest.java index 568484aab..d395e3166 100644 --- a/core/src/test/java/org/apache/struts2/views/jsp/ui/TextfieldTest.java +++ b/core/src/test/java/org/apache/struts2/views/jsp/ui/TextfieldTest.java @@ -79,7 +79,36 @@ public class TextfieldTest extends AbstractUITagTest { // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). TextFieldTag freshTag = new TextFieldTag(); freshTag.setPageContext(pageContext); - assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + 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 testErrors_clearTagStateSet() throws Exception { + TestAction testAction = (TestAction) action; + testAction.setFoo("bar"); + + TextFieldTag tag = new TextFieldTag(); + tag.setPerformClearTagStateForTagPoolingServers(true); // Explicitly request tag state clearing. + tag.setPageContext(pageContext); + tag.setId("myId"); + tag.setLabel("mylabel"); + tag.setName("foo"); + tag.setValue("bar"); + tag.setTitle("mytitle"); + + testAction.addFieldError("foo", "bar error message"); + tag.doStartTag(); + setComponentTagClearTagState(tag, true); // Ensure component tag state clearing is set true (to match tag). + tag.doEndTag(); + + verify(TextFieldTag.class.getResource("Textfield-2.txt")); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + TextFieldTag freshTag = new TextFieldTag(); + freshTag.setPerformClearTagStateForTagPoolingServers(true); + 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)); } @@ -103,11 +132,38 @@ public class TextfieldTest extends AbstractUITagTest { // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). TextFieldTag freshTag = new TextFieldTag(); freshTag.setPageContext(pageContext); - assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + 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 testNoLabelJsp_clearTagStateSet() throws Exception { + TestAction testAction = (TestAction) action; + testAction.setFoo("bar"); + + TextFieldTag tag = new TextFieldTag(); + tag.setPerformClearTagStateForTagPoolingServers(true); // Explicitly request tag state clearing. + tag.setPageContext(pageContext); + tag.setName("myname"); + tag.setValue("%{foo}"); + tag.setSize("10"); + tag.setOnblur("blahescape('somevalue');"); + + tag.doStartTag(); + setComponentTagClearTagState(tag, true); // Ensure component tag state clearing is set true (to match tag). + tag.doEndTag(); + + verify(TextFieldTag.class.getResource("Textfield-3.txt")); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + TextFieldTag freshTag = new TextFieldTag(); + freshTag.setPerformClearTagStateForTagPoolingServers(true); + 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)); + } + public void testLabelSeparatorJsp() throws Exception { TestAction testAction = (TestAction) action; testAction.setFoo("bar"); @@ -129,7 +185,36 @@ public class TextfieldTest extends AbstractUITagTest { // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). TextFieldTag freshTag = new TextFieldTag(); freshTag.setPageContext(pageContext); - assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + 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 testLabelSeparatorJsp_clearTagStateSet() throws Exception { + TestAction testAction = (TestAction) action; + testAction.setFoo("bar"); + + TextFieldTag tag = new TextFieldTag(); + tag.setPerformClearTagStateForTagPoolingServers(true); // Explicitly request tag state clearing. + tag.setPageContext(pageContext); + tag.setName("myname"); + tag.setValue("%{foo}"); + tag.setSize("10"); + tag.setOnblur("blahescape('somevalue');"); + tag.setLabelSeparator("??"); + tag.setLabel("label"); + + tag.doStartTag(); + setComponentTagClearTagState(tag, true); // Ensure component tag state clearing is set true (to match tag). + tag.doEndTag(); + + verify(TextFieldTag.class.getResource("Textfield-4.txt")); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + TextFieldTag freshTag = new TextFieldTag(); + freshTag.setPerformClearTagStateForTagPoolingServers(true); + 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)); } @@ -170,7 +255,34 @@ public class TextfieldTest extends AbstractUITagTest { // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). TextFieldTag freshTag = new TextFieldTag(); freshTag.setPageContext(pageContext); - assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + 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 testSimple_clearTagStateSet() throws Exception { + TestAction testAction = (TestAction) action; + testAction.setFoo("bar"); + + TextFieldTag tag = new TextFieldTag(); + tag.setPerformClearTagStateForTagPoolingServers(true); // Explicitly request tag state clearing. + tag.setPageContext(pageContext); + tag.setLabel("mylabel"); + tag.setName("myname"); + tag.setValue("%{foo}"); + tag.setSize("10"); + + tag.doStartTag(); + setComponentTagClearTagState(tag, true); // Ensure component tag state clearing is set true (to match tag). + tag.doEndTag(); + + verify(TextFieldTag.class.getResource("Textfield-1.txt")); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + TextFieldTag freshTag = new TextFieldTag(); + freshTag.setPerformClearTagStateForTagPoolingServers(true); + 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)); } @@ -190,7 +302,33 @@ public class TextfieldTest extends AbstractUITagTest { // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). TextFieldTag freshTag = new TextFieldTag(); freshTag.setPageContext(pageContext); - assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + 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)); + } + + verify(TextFieldTag.class.getResource("Textfield-WW-5125.txt")); + } + + public void testWW5125_clearTagStateSet() throws Exception { + TestAction testAction = (TestAction) action; + + for(String fieldName : new String[] {"clone", "size", "clear", "values", "hashCode", "isEmpty", "keySet", "entrySet"}) { + testAction.addFieldError(fieldName, fieldName + " error"); + + TextFieldTag tag = new TextFieldTag(); + tag.setPerformClearTagStateForTagPoolingServers(true); // Explicitly request tag state clearing. + tag.setPageContext(pageContext); + tag.setName(fieldName); + tag.doStartTag(); + setComponentTagClearTagState(tag, true); // Ensure component tag state clearing is set true (to match tag). + tag.doEndTag(); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + TextFieldTag freshTag = new TextFieldTag(); + freshTag.setPerformClearTagStateForTagPoolingServers(true); + 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)); } @@ -217,11 +355,38 @@ public class TextfieldTest extends AbstractUITagTest { // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). TextFieldTag freshTag = new TextFieldTag(); freshTag.setPageContext(pageContext); - assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + 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 testSimple_recursionTest_clearTagStateSet() throws Exception { + TestAction testAction = (TestAction) action; + testAction.setFoo("%{1+1}"); + + TextFieldTag tag = new TextFieldTag(); + tag.setPerformClearTagStateForTagPoolingServers(true); // Explicitly request tag state clearing. + tag.setPageContext(pageContext); + tag.setLabel("mylabel"); + tag.setName("myname"); + tag.setValue("%{foo}"); + tag.setSize("10"); + + tag.doStartTag(); + setComponentTagClearTagState(tag, true); // Ensure component tag state clearing is set true (to match tag). + tag.doEndTag(); + + verify(TextFieldTag.class.getResource("Textfield-5.txt")); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + TextFieldTag freshTag = new TextFieldTag(); + freshTag.setPerformClearTagStateForTagPoolingServers(true); + 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)); + } + public void testSimple_recursionTestNoValue() throws Exception { TestAction testAction = (TestAction) action; testAction.setFoo("%{1+1}"); @@ -240,7 +405,33 @@ public class TextfieldTest extends AbstractUITagTest { // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). TextFieldTag freshTag = new TextFieldTag(); freshTag.setPageContext(pageContext); - assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + 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 testSimple_recursionTestNoValue_clearTagStateSet() throws Exception { + TestAction testAction = (TestAction) action; + testAction.setFoo("%{1+1}"); + + TextFieldTag tag = new TextFieldTag(); + tag.setPerformClearTagStateForTagPoolingServers(true); // Explicitly request tag state clearing. + tag.setPageContext(pageContext); + tag.setLabel("mylabel"); + tag.setName("foo"); + tag.setSize("10"); + + tag.doStartTag(); + setComponentTagClearTagState(tag, true); // Ensure component tag state clearing is set true (to match tag). + tag.doEndTag(); + + verify(TextFieldTag.class.getResource("Textfield-6.txt")); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + TextFieldTag freshTag = new TextFieldTag(); + freshTag.setPerformClearTagStateForTagPoolingServers(true); + 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)); } @@ -264,7 +455,34 @@ public class TextfieldTest extends AbstractUITagTest { // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). TextFieldTag freshTag = new TextFieldTag(); freshTag.setPageContext(pageContext); - assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + 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 testHtml5EmailTag_clearTagStateSet() throws Exception { + TestAction testAction = (TestAction) action; + testAction.setFoo("bar"); + + TextFieldTag tag = new TextFieldTag(); + tag.setPerformClearTagStateForTagPoolingServers(true); // Explicitly request tag state clearing. + tag.setPageContext(pageContext); + tag.setLabel("myemaillabel"); + tag.setName("foo"); + tag.setSize("50"); + tag.setType("email"); + + tag.doStartTag(); + setComponentTagClearTagState(tag, true); // Ensure component tag state clearing is set true (to match tag). + tag.doEndTag(); + + verify(TextFieldTag.class.getResource("Textfield-7.txt")); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + TextFieldTag freshTag = new TextFieldTag(); + freshTag.setPerformClearTagStateForTagPoolingServers(true); + 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)); } @@ -291,7 +509,37 @@ public class TextfieldTest extends AbstractUITagTest { // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). TextFieldTag freshTag = new TextFieldTag(); freshTag.setPageContext(pageContext); - assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + 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 testErrorPositionBottom_clearTagStateSet() throws Exception { + TestAction testAction = (TestAction) action; + testAction.setFoo("bar"); + + TextFieldTag tag = new TextFieldTag(); + tag.setPerformClearTagStateForTagPoolingServers(true); // Explicitly request tag state clearing. + tag.setPageContext(pageContext); + tag.setId("myId"); + tag.setLabel("mylabel"); + tag.setName("foo"); + tag.setValue("bar"); + tag.setTitle("mytitle"); + tag.setErrorPosition("bottom"); + + testAction.addFieldError("foo", "bar error message"); + tag.doStartTag(); + setComponentTagClearTagState(tag, true); // Ensure component tag state clearing is set true (to match tag). + tag.doEndTag(); + + verify(TextFieldTag.class.getResource("Textfield-8.txt")); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + TextFieldTag freshTag = new TextFieldTag(); + freshTag.setPerformClearTagStateForTagPoolingServers(true); + 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)); } @@ -318,7 +566,37 @@ public class TextfieldTest extends AbstractUITagTest { // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). TextFieldTag freshTag = new TextFieldTag(); freshTag.setPageContext(pageContext); - assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + 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 testErrorPositionTop_clearTagStateSet() throws Exception { + TestAction testAction = (TestAction) action; + testAction.setFoo("bar"); + + TextFieldTag tag = new TextFieldTag(); + tag.setPerformClearTagStateForTagPoolingServers(true); // Explicitly request tag state clearing. + tag.setPageContext(pageContext); + tag.setId("myId"); + tag.setLabel("mylabel"); + tag.setName("foo"); + tag.setValue("bar"); + tag.setTitle("mytitle"); + tag.setErrorPosition("top"); + + testAction.addFieldError("foo", "bar error message"); + tag.doStartTag(); + setComponentTagClearTagState(tag, true); // Ensure component tag state clearing is set true (to match tag). + tag.doEndTag(); + + verify(TextFieldTag.class.getResource("Textfield-9.txt")); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + TextFieldTag freshTag = new TextFieldTag(); + freshTag.setPerformClearTagStateForTagPoolingServers(true); + 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)); } @@ -343,7 +621,35 @@ public class TextfieldTest extends AbstractUITagTest { // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). TextFieldTag freshTag = new TextFieldTag(); freshTag.setPageContext(pageContext); - assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + 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 testRequiredLabelPositionDefault_clearTagStateSet() throws Exception { + TestAction testAction = (TestAction) action; + testAction.setFoo("bar"); + + TextFieldTag tag = new TextFieldTag(); + tag.setPerformClearTagStateForTagPoolingServers(true); // Explicitly request tag state clearing. + tag.setPageContext(pageContext); + tag.setId("myId"); + tag.setLabel("mylabel"); + tag.setName("foo"); + tag.setValue("bar"); + tag.setRequiredLabel("true"); + + tag.doStartTag(); + setComponentTagClearTagState(tag, true); // Ensure component tag state clearing is set true (to match tag). + tag.doEndTag(); + + verify(TextFieldTag.class.getResource("Textfield-12.txt")); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + TextFieldTag freshTag = new TextFieldTag(); + freshTag.setPerformClearTagStateForTagPoolingServers(true); + 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)); } @@ -369,7 +675,36 @@ public class TextfieldTest extends AbstractUITagTest { // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). TextFieldTag freshTag = new TextFieldTag(); freshTag.setPageContext(pageContext); - assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + 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 testRequiredLabelPositionRight_clearTagStateSet() throws Exception { + TestAction testAction = (TestAction) action; + testAction.setFoo("bar"); + + TextFieldTag tag = new TextFieldTag(); + tag.setPerformClearTagStateForTagPoolingServers(true); // Explicitly request tag state clearing. + tag.setPageContext(pageContext); + tag.setId("myId"); + tag.setLabel("mylabel"); + tag.setName("foo"); + tag.setValue("bar"); + tag.setRequiredLabel("true"); + tag.setRequiredPosition("right"); + + tag.doStartTag(); + setComponentTagClearTagState(tag, true); // Ensure component tag state clearing is set true (to match tag). + tag.doEndTag(); + + verify(TextFieldTag.class.getResource("Textfield-12.txt")); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + TextFieldTag freshTag = new TextFieldTag(); + freshTag.setPerformClearTagStateForTagPoolingServers(true); + 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)); } @@ -395,7 +730,37 @@ public class TextfieldTest extends AbstractUITagTest { // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). TextFieldTag freshTag = new TextFieldTag(); freshTag.setPageContext(pageContext); - assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + 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 testRequiredLabelPositionLeft_clearTagStateSet() throws Exception { + TestAction testAction = (TestAction) action; + testAction.setFoo("bar"); + + TextFieldTag tag = new TextFieldTag(); + tag.setPerformClearTagStateForTagPoolingServers(true); // Explicitly request tag state clearing. + tag.setPageContext(pageContext); + tag.setId("myId"); + tag.setLabel("mylabel"); + tag.setName("foo"); + tag.setValue("bar"); + tag.setRequiredLabel("true"); + tag.setRequiredPosition("left"); + + tag.doStartTag(); + setComponentTagClearTagState(tag, true); // Ensure component tag state clearing is set true (to match tag). + tag.doEndTag(); + + verify(TextFieldTag.class.getResource("Textfield-13.txt")); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + TextFieldTag freshTag = new TextFieldTag(); + freshTag.setPerformClearTagStateForTagPoolingServers(true); + 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)); } @@ -423,7 +788,38 @@ public class TextfieldTest extends AbstractUITagTest { // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). TextFieldTag freshTag = new TextFieldTag(); freshTag.setPageContext(pageContext); - assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + 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 testErrorPositionBottomCssXhtmlTheme_clearTagStateSet() throws Exception { + TestAction testAction = (TestAction) action; + testAction.setFoo("bar"); + + TextFieldTag tag = new TextFieldTag(); + tag.setPerformClearTagStateForTagPoolingServers(true); // Explicitly request tag state clearing. + tag.setPageContext(pageContext); + tag.setId("myId"); + tag.setLabel("mylabel"); + tag.setName("foo"); + tag.setValue("bar"); + tag.setTitle("mytitle"); + tag.setErrorPosition("bottom"); + tag.setTheme("css_xhtml"); + + testAction.addFieldError("foo", "bar error message"); + tag.doStartTag(); + setComponentTagClearTagState(tag, true); // Ensure component tag state clearing is set true (to match tag). + tag.doEndTag(); + + verify(TextFieldTag.class.getResource("Textfield-10.txt")); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + TextFieldTag freshTag = new TextFieldTag(); + freshTag.setPerformClearTagStateForTagPoolingServers(true); + 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)); } @@ -451,7 +847,38 @@ public class TextfieldTest extends AbstractUITagTest { // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). TextFieldTag freshTag = new TextFieldTag(); freshTag.setPageContext(pageContext); - assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + 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 testErrorPositionTopCssXhtmlTheme_clearTagStateSet() throws Exception { + TestAction testAction = (TestAction) action; + testAction.setFoo("bar"); + + TextFieldTag tag = new TextFieldTag(); + tag.setPerformClearTagStateForTagPoolingServers(true); // Explicitly request tag state clearing. + tag.setPageContext(pageContext); + tag.setId("myId"); + tag.setLabel("mylabel"); + tag.setName("foo"); + tag.setValue("bar"); + tag.setTitle("mytitle"); + tag.setErrorPosition("top"); + tag.setTheme("css_xhtml"); + + testAction.addFieldError("foo", "bar error message"); + tag.doStartTag(); + setComponentTagClearTagState(tag, true); // Ensure component tag state clearing is set true (to match tag). + tag.doEndTag(); + + verify(TextFieldTag.class.getResource("Textfield-11.txt")); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + TextFieldTag freshTag = new TextFieldTag(); + freshTag.setPerformClearTagStateForTagPoolingServers(true); + 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)); } @@ -473,10 +900,34 @@ public class TextfieldTest extends AbstractUITagTest { // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). TextFieldTag freshTag = new TextFieldTag(); freshTag.setPageContext(pageContext); - assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + 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 testNameEvaluation_clearTagStateSet() throws Exception { + TestAction testAction = (TestAction) action; + testAction.setArray(new String[]{"test", "bar"}); + testAction.setFooInt(1); + + TextFieldTag tag = new TextFieldTag(); + tag.setPerformClearTagStateForTagPoolingServers(true); // Explicitly request tag state clearing. + tag.setPageContext(pageContext); + tag.setName("array[%{fooInt}]"); + + tag.doStartTag(); + setComponentTagClearTagState(tag, true); // Ensure component tag state clearing is set true (to match tag). + tag.doEndTag(); + + verify(TextFieldTag.class.getResource("Textfield-14.txt")); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + TextFieldTag freshTag = new TextFieldTag(); + freshTag.setPerformClearTagStateForTagPoolingServers(true); + 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)); + } } diff --git a/core/src/test/java/org/apache/struts2/views/jsp/ui/TokenTagTest.java b/core/src/test/java/org/apache/struts2/views/jsp/ui/TokenTagTest.java index a2eb22fdb..d265eacfb 100644 --- a/core/src/test/java/org/apache/struts2/views/jsp/ui/TokenTagTest.java +++ b/core/src/test/java/org/apache/struts2/views/jsp/ui/TokenTagTest.java @@ -33,7 +33,8 @@ public class TokenTagTest extends AbstractUITagTest { public void testDefaultName() { String tokenName = TokenHelper.DEFAULT_TOKEN_NAME; TokenTag tag = new TokenTag(); - doTokenTest(tokenName, tag); + doTokenTest(tokenName, tag, false); + doTokenTest_clearTagStateSet(tokenName, tag); } public void testMultipleTagsWithSameName() { @@ -41,13 +42,16 @@ public class TokenTagTest extends AbstractUITagTest { TokenTag tag = new TokenTag(); tag.setName(tokenName); - String token = doTokenTest(tokenName, tag); + String token = doTokenTest(tokenName, tag, true); TokenTag anotherTag = new TokenTag(); anotherTag.setName(tokenName); - String anotherToken = doTokenTest(tokenName, anotherTag); + String anotherToken = doTokenTest(tokenName, anotherTag, true); assertEquals(token, anotherToken); + + doTokenTest_clearTagStateSet(tokenName, tag); + doTokenTest_clearTagStateSet(tokenName, anotherTag); } /** @@ -57,7 +61,7 @@ public class TokenTagTest extends AbstractUITagTest { String tokenName = "foo"; TokenTag tag = new TokenTag(); tag.setName(tokenName); - doTokenTest(tokenName, tag); + doTokenTest(tokenName, tag, true); String s = writer.toString(); assertTrue(s.indexOf("name=\"" + TokenHelper.TOKEN_NAME_FIELD) > -1); @@ -65,16 +69,18 @@ public class TokenTagTest extends AbstractUITagTest { assertTrue(s.indexOf("name=\"" + tokenName + "\"") > -1); //System.out.println(s); + doTokenTest_clearTagStateSet(tokenName, tag); } public void testSuppliedName() { String tokenName = "my.very.long.token.name"; TokenTag tag = new TokenTag(); tag.setName(tokenName); - doTokenTest(tokenName, tag); + doTokenTest(tokenName, tag, true); + doTokenTest_clearTagStateSet(tokenName, tag); } - private String doTokenTest(String tokenName, TokenTag tag) { + private String doTokenTest(String tokenName, TokenTag tag, boolean tagNameWasSet) { tag.setPageContext(pageContext); String token = null; @@ -91,7 +97,45 @@ public class TokenTagTest extends AbstractUITagTest { // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). TokenTag freshTag = new TokenTag(); freshTag.setPageContext(pageContext); - assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + if (tagNameWasSet) { + 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)); + } else { + // TokenTag has no non=default state set here, so it compares as equal with the default tag clear state as well. + assertTrue("Tag state after doEndTag() under default tag clear state is inequal to new Tag with pageContext/parent set. " + + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", + strutsBodyTagsAreReflectionEqual(tag, freshTag)); + } + } catch (JspException e) { + e.printStackTrace(); + fail(); + } + + return token; + } + + private String doTokenTest_clearTagStateSet(String tokenName, TokenTag tag) { + tag.setPerformClearTagStateForTagPoolingServers(true); // Explicitly request tag state clearing. + tag.setPageContext(pageContext); + + String token = null; + + try { + tag.doStartTag(); + setComponentTagClearTagState(tag, true); // Ensure component tag state clearing is set true (to match tag). + tag.doEndTag(); + + token = (String) context.get(tokenName); + assertNotNull(token); + final String sessionTokenName = TokenHelper.buildTokenSessionAttributeName(tokenName); + assertEquals(token, pageContext.getSession().getAttribute(sessionTokenName)); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + TokenTag freshTag = new TokenTag(); + freshTag.setPerformClearTagStateForTagPoolingServers(true); + 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)); } catch (JspException e) { @@ -101,4 +145,5 @@ public class TokenTagTest extends AbstractUITagTest { return token; } + } diff --git a/core/src/test/java/org/apache/struts2/views/jsp/ui/TooltipTest.java b/core/src/test/java/org/apache/struts2/views/jsp/ui/TooltipTest.java index 6a8578023..8ea723976 100644 --- a/core/src/test/java/org/apache/struts2/views/jsp/ui/TooltipTest.java +++ b/core/src/test/java/org/apache/struts2/views/jsp/ui/TooltipTest.java @@ -68,14 +68,68 @@ public class TooltipTest extends AbstractUITagTest { // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). TextFieldTag freshTag = new TextFieldTag(); freshTag.setPageContext(pageContext); - assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + 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)); // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). FormTag freshFormTag = new FormTag(); freshFormTag.setPageContext(pageContext); - assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + 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(formTag, freshFormTag)); + } + + public void testWithoutFormOverriding_clearTagStateSet() throws Exception { + + // we test it on textfield component, but since the tooltip are common to + // all components, it will be the same for other components as well. + FormTag formTag = new FormTag(); + formTag.setPerformClearTagStateForTagPoolingServers(true); // Explicitly request tag state clearing. + formTag.setPageContext(pageContext); + formTag.setId("myFormId"); + formTag.setAction("testAction"); + formTag.setName("myForm"); + + + TextFieldTag tag = new TextFieldTag(); + tag.setPerformClearTagStateForTagPoolingServers(true); // Explicitly request tag state clearing. + tag.setPageContext(pageContext); + tag.setLabel("MyLabel"); + tag.setId("myId"); + + + tag.setTooltip("myTooltip"); + tag.setTooltipConfig( + "#{" + + "'tooltipIcon':'/struts/tooltip/myTooltip.gif', " + + "'tooltipDelay':'500', " + + "'jsTooltipEnabled':'true' "+ + "}" + ); + + formTag.doStartTag(); + setComponentTagClearTagState(formTag, true); // Ensure component tag state clearing is set true (to match tag). + tag.doStartTag(); + setComponentTagClearTagState(tag, true); // Ensure component tag state clearing is set true (to match tag). + tag.doEndTag(); + formTag.doEndTag(); + + verify(TooltipTest.class.getResource("tooltip-1.txt")); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + TextFieldTag freshTag = new TextFieldTag(); + freshTag.setPerformClearTagStateForTagPoolingServers(true); + 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)); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + FormTag freshFormTag = new FormTag(); + freshFormTag.setPerformClearTagStateForTagPoolingServers(true); + freshFormTag.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(formTag, freshFormTag)); } @@ -116,18 +170,72 @@ public class TooltipTest extends AbstractUITagTest { // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). TextFieldTag freshTag = new TextFieldTag(); freshTag.setPageContext(pageContext); - assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + 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)); // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). FormTag freshFormTag = new FormTag(); freshFormTag.setPageContext(pageContext); - assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + 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(formTag, freshFormTag)); } - + + public void testWithoutFormOverridingNoJS_clearTagStateSet() throws Exception { + + // we test it on textfield component, but since the tooltip are common to + // all components, it will be the same for other components as well. + FormTag formTag = new FormTag(); + formTag.setPerformClearTagStateForTagPoolingServers(true); // Explicitly request tag state clearing. + formTag.setPageContext(pageContext); + formTag.setId("myFormId"); + formTag.setAction("testAction"); + formTag.setName("myForm"); + + + TextFieldTag tag = new TextFieldTag(); + tag.setPerformClearTagStateForTagPoolingServers(true); // Explicitly request tag state clearing. + tag.setPageContext(pageContext); + tag.setLabel("MyLabel"); + tag.setId("myId"); + + + tag.setTooltip("myTooltip"); + tag.setTooltipConfig( + "#{" + + "'tooltipIcon':'/struts/tooltip/myTooltip.gif', " + + "'tooltipDelay':'500', " + + "'jsTooltipEnabled':'false' "+ + "}" + ); + + formTag.doStartTag(); + setComponentTagClearTagState(formTag, true); // Ensure component tag state clearing is set true (to match tag). + tag.doStartTag(); + setComponentTagClearTagState(tag, true); // Ensure component tag state clearing is set true (to match tag). + tag.doEndTag(); + formTag.doEndTag(); + + verify(TooltipTest.class.getResource("tooltip-4.txt")); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + TextFieldTag freshTag = new TextFieldTag(); + freshTag.setPerformClearTagStateForTagPoolingServers(true); + 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)); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + FormTag freshFormTag = new FormTag(); + freshFormTag.setPerformClearTagStateForTagPoolingServers(true); + freshFormTag.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(formTag, freshFormTag)); + } + public void testWithoutFormOverridingNew() throws Exception { // we test it on textfield component, but since the tooltip are common to @@ -162,14 +270,66 @@ public class TooltipTest extends AbstractUITagTest { // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). TextFieldTag freshTag = new TextFieldTag(); freshTag.setPageContext(pageContext); - assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + 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)); // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). FormTag freshFormTag = new FormTag(); freshFormTag.setPageContext(pageContext); - assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + 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(formTag, freshFormTag)); + } + + public void testWithoutFormOverridingNew_clearTagStateSet() throws Exception { + + // we test it on textfield component, but since the tooltip are common to + // all components, it will be the same for other components as well. + FormTag formTag = new FormTag(); + formTag.setPerformClearTagStateForTagPoolingServers(true); // Explicitly request tag state clearing. + formTag.setPageContext(pageContext); + formTag.setId("myFormId"); + formTag.setAction("testAction"); + formTag.setName("myForm"); + + + TextFieldTag tag = new TextFieldTag(); + tag.setPerformClearTagStateForTagPoolingServers(true); // Explicitly request tag state clearing. + tag.setPageContext(pageContext); + tag.setLabel("MyLabel"); + tag.setId("myId"); + + + //same parameters as the OGNL map configuration, output must be the same + tag.setTooltip("myTooltip"); + tag.setTooltipIconPath("/struts/tooltip/myTooltip.gif"); + tag.setTooltipDelay("500"); + tag.setJavascriptTooltip("true"); + + + formTag.doStartTag(); + setComponentTagClearTagState(formTag, true); // Ensure component tag state clearing is set true (to match tag). + tag.doStartTag(); + setComponentTagClearTagState(tag, true); // Ensure component tag state clearing is set true (to match tag). + tag.doEndTag(); + formTag.doEndTag(); + + verify(TooltipTest.class.getResource("tooltip-1.txt")); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + TextFieldTag freshTag = new TextFieldTag(); + freshTag.setPerformClearTagStateForTagPoolingServers(true); + 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)); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + FormTag freshFormTag = new FormTag(); + freshFormTag.setPerformClearTagStateForTagPoolingServers(true); + freshFormTag.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(formTag, freshFormTag)); } @@ -208,18 +368,70 @@ public class TooltipTest extends AbstractUITagTest { // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). TextFieldTag freshTag = new TextFieldTag(); freshTag.setPageContext(pageContext); - assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + 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)); // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). FormTag freshFormTag = new FormTag(); freshFormTag.setPageContext(pageContext); - assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + 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(formTag, freshFormTag)); } - + + public void testWithFormOverriding_clearTagStateSet() throws Exception { + + FormTag formTag = new FormTag(); + formTag.setPerformClearTagStateForTagPoolingServers(true); // Explicitly request tag state clearing. + formTag.setPageContext(pageContext); + formTag.setName("myForm"); + formTag.setId("myFormId"); + formTag.setAction("testAction"); + + formTag.setTooltipConfig( + "#{" + + "'tooltipIcon':'/struts/tooltip/myTooltip.gif', " + + "'tooltipDelay':'500', " + + "'jsTooltipEnabled':'true' "+ + "}" + ); + + + TextFieldTag tag = new TextFieldTag(); + tag.setPerformClearTagStateForTagPoolingServers(true); // Explicitly request tag state clearing. + tag.setPageContext(pageContext); + tag.setLabel("MyLabel"); + tag.setId("myId"); + + tag.setTooltip("myTooltip"); + + formTag.doStartTag(); + setComponentTagClearTagState(formTag, true); // Ensure component tag state clearing is set true (to match tag). + tag.doStartTag(); + setComponentTagClearTagState(tag, true); // Ensure component tag state clearing is set true (to match tag). + tag.doEndTag(); + formTag.doEndTag(); + + verify(TooltipTest.class.getResource("tooltip-2.txt")); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + TextFieldTag freshTag = new TextFieldTag(); + freshTag.setPerformClearTagStateForTagPoolingServers(true); + 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)); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + FormTag freshFormTag = new FormTag(); + freshFormTag.setPerformClearTagStateForTagPoolingServers(true); + freshFormTag.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(formTag, freshFormTag)); + } + public void testWithFormOverridingNew() throws Exception { FormTag formTag = new FormTag(); @@ -252,14 +464,64 @@ public class TooltipTest extends AbstractUITagTest { // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). TextFieldTag freshTag = new TextFieldTag(); freshTag.setPageContext(pageContext); - assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + 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)); // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). FormTag freshFormTag = new FormTag(); freshFormTag.setPageContext(pageContext); - assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + 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(formTag, freshFormTag)); + } + + public void testWithFormOverridingNew_clearTagStateSet() throws Exception { + + FormTag formTag = new FormTag(); + formTag.setPerformClearTagStateForTagPoolingServers(true); // Explicitly request tag state clearing. + formTag.setPageContext(pageContext); + formTag.setName("myForm"); + formTag.setId("myFormId"); + formTag.setAction("testAction"); + + // same parameters as the OGNL map configuration, output must be the same + formTag.setTooltip("myTooltip"); + formTag.setTooltipIconPath("/struts/tooltip/myTooltip.gif"); + formTag.setTooltipDelay("500"); + formTag.setJavascriptTooltip("true"); + + + TextFieldTag tag = new TextFieldTag(); + tag.setPerformClearTagStateForTagPoolingServers(true); // Explicitly request tag state clearing. + tag.setPageContext(pageContext); + tag.setLabel("MyLabel"); + tag.setId("myId"); + + tag.setTooltip("myTooltip"); + + formTag.doStartTag(); + setComponentTagClearTagState(formTag, true); // Ensure component tag state clearing is set true (to match tag). + tag.doStartTag(); + setComponentTagClearTagState(tag, true); // Ensure component tag state clearing is set true (to match tag). + tag.doEndTag(); + formTag.doEndTag(); + + verify(TooltipTest.class.getResource("tooltip-2.txt")); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + TextFieldTag freshTag = new TextFieldTag(); + freshTag.setPerformClearTagStateForTagPoolingServers(true); + 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)); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + FormTag freshFormTag = new FormTag(); + freshFormTag.setPerformClearTagStateForTagPoolingServers(true); + freshFormTag.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(formTag, freshFormTag)); } @@ -304,14 +566,72 @@ public class TooltipTest extends AbstractUITagTest { // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). TextFieldTag freshTag = new TextFieldTag(); freshTag.setPageContext(pageContext); - assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + 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)); // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). FormTag freshFormTag = new FormTag(); freshFormTag.setPageContext(pageContext); - assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + 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(formTag, freshFormTag)); + } + + public void testWithPartialFormOverriding_clearTagStateSet() throws Exception { + + FormTag formTag = new FormTag(); + formTag.setPerformClearTagStateForTagPoolingServers(true); // Explicitly request tag state clearing. + formTag.setName("myForm"); + formTag.setPageContext(pageContext); + formTag.setId("myFormId"); + formTag.setAction("testAction"); + + formTag.setTooltipConfig( + "#{" + + "'tooltipIcon':'/struts/tooltip/myTooltip.gif', " + + "'tooltipDelay':'500', " + + "'jsTooltipEnabled':'true' "+ + "}" + ); + + + TextFieldTag tag = new TextFieldTag(); + tag.setPerformClearTagStateForTagPoolingServers(true); // Explicitly request tag state clearing. + tag.setPageContext(pageContext); + tag.setLabel("MyLabel"); + tag.setId("myId"); + + tag.setTooltip("myTooltip"); + tag.setTooltipConfig( + "#{" + + "'tooltipIcon':'/struts/tooltip/myTooltip2.gif', " + + "'tooltipDelay':'5000' " + + "}" + ); + + formTag.doStartTag(); + setComponentTagClearTagState(formTag, true); // Ensure component tag state clearing is set true (to match tag). + tag.doStartTag(); + setComponentTagClearTagState(tag, true); // Ensure component tag state clearing is set true (to match tag). + tag.doEndTag(); + formTag.doEndTag(); + + verify(TooltipTest.class.getResource("tooltip-3.txt")); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + TextFieldTag freshTag = new TextFieldTag(); + freshTag.setPerformClearTagStateForTagPoolingServers(true); + 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)); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + FormTag freshFormTag = new FormTag(); + freshFormTag.setPerformClearTagStateForTagPoolingServers(true); + freshFormTag.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(formTag, freshFormTag)); } @@ -353,14 +673,69 @@ public class TooltipTest extends AbstractUITagTest { // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). TextFieldTag freshTag = new TextFieldTag(); freshTag.setPageContext(pageContext); - assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + 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)); // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). FormTag freshFormTag = new FormTag(); freshFormTag.setPageContext(pageContext); - assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + 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(formTag, freshFormTag)); + } + + public void testWithPartialFormOverridingNew_clearTagStateSet() throws Exception { + + FormTag formTag = new FormTag(); + formTag.setPerformClearTagStateForTagPoolingServers(true); // Explicitly request tag state clearing. + formTag.setName("myForm"); + formTag.setPageContext(pageContext); + formTag.setId("myFormId"); + formTag.setAction("testAction"); + + // same parameters as the OGNL map configuration, output must be the same + formTag.setTooltip("myTooltip"); + formTag.setTooltipIconPath("/struts/tooltip/myTooltip.gif"); + formTag.setTooltipDelay("500"); + formTag.setJavascriptTooltip("true"); + + + TextFieldTag tag = new TextFieldTag(); + tag.setPerformClearTagStateForTagPoolingServers(true); // Explicitly request tag state clearing. + tag.setPageContext(pageContext); + tag.setLabel("MyLabel"); + tag.setId("myId"); + + + //same parameters as the OGNL map configuration, output must be the same + tag.setTooltip("myTooltip"); + tag.setTooltipIconPath("/struts/tooltip/myTooltip2.gif"); + tag.setTooltipDelay("5000"); + tag.setJavascriptTooltip("true"); + + formTag.doStartTag(); + setComponentTagClearTagState(formTag, true); // Ensure component tag state clearing is set true (to match tag). + tag.doStartTag(); + setComponentTagClearTagState(tag, true); // Ensure component tag state clearing is set true (to match tag). + tag.doEndTag(); + formTag.doEndTag(); + + verify(TooltipTest.class.getResource("tooltip-3.txt")); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + TextFieldTag freshTag = new TextFieldTag(); + freshTag.setPerformClearTagStateForTagPoolingServers(true); + 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)); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + FormTag freshFormTag = new FormTag(); + freshFormTag.setPerformClearTagStateForTagPoolingServers(true); + freshFormTag.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(formTag, freshFormTag)); } @@ -415,18 +790,86 @@ public class TooltipTest extends AbstractUITagTest { // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). TextFieldTag freshTag = new TextFieldTag(); freshTag.setPageContext(pageContext); - assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + 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)); // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). FormTag freshFormTag = new FormTag(); freshFormTag.setPageContext(pageContext); - assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + 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(formTag, freshFormTag)); } + public void testUsingParamValueToSetConfigurations_clearTagStateSet() throws Exception { + FormTag formTag = new FormTag(); + formTag.setPerformClearTagStateForTagPoolingServers(true); // Explicitly request tag state clearing. + formTag.setName("myForm"); + formTag.setPageContext(pageContext); + formTag.setId("myFormId"); + formTag.setAction("testAction"); + + + ParamTag formParamTag = new ParamTag(); + formParamTag.setPageContext(pageContext); + formParamTag.setName("tooltipConfig"); + formParamTag.setValue( + "#{" + + "'tooltipIcon':'/struts/tooltip/myTooltip.gif', " + + "'tooltipDelay':'500', " + + "'jsTooltipEnabled':'true' "+ + "}" + ); + + + TextFieldTag tag = new TextFieldTag(); + tag.setPerformClearTagStateForTagPoolingServers(true); // Explicitly request tag state clearing. + tag.setPageContext(pageContext); + tag.setLabel("MyLabel"); + tag.setId("myId"); + tag.setTooltip("myTooltip"); + + ParamTag textFieldParamTag = new ParamTag(); + textFieldParamTag.setPageContext(pageContext); + textFieldParamTag.setName("tooltipConfig"); + textFieldParamTag.setValue( + "#{" + + "'tooltipIcon':'/struts/tooltip/myTooltip2.gif', " + + "'tooltipDelay':'5000' "+ + "}" + ); + + formTag.doStartTag(); + setComponentTagClearTagState(formTag, true); // Ensure component tag state clearing is set true (to match tag). + formParamTag.doStartTag(); + setComponentTagClearTagState(formParamTag, true); // Ensure component tag state clearing is set true (to match tag). + formParamTag.doEndTag(); + tag.doStartTag(); + setComponentTagClearTagState(tag, true); // Ensure component tag state clearing is set true (to match tag). + textFieldParamTag.doStartTag(); + textFieldParamTag.doEndTag(); + tag.doEndTag(); + formTag.doEndTag(); + + verify(TooltipTest.class.getResource("tooltip-3.txt")); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + TextFieldTag freshTag = new TextFieldTag(); + freshTag.setPerformClearTagStateForTagPoolingServers(true); + 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)); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + FormTag freshFormTag = new FormTag(); + freshFormTag.setPerformClearTagStateForTagPoolingServers(true); + freshFormTag.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(formTag, freshFormTag)); + } public void testUsingParamBodyValueToSetConfigurations() throws Exception { @@ -481,21 +924,103 @@ public class TooltipTest extends AbstractUITagTest { // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). TextFieldTag freshTag = new TextFieldTag(); freshTag.setPageContext(pageContext); - assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + 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)); // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). ParamTag freshParamTag = new ParamTag(); freshParamTag.setPageContext(pageContext); - assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + 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(textFieldParamTag, freshParamTag)); // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). FormTag freshFormTag = new FormTag(); freshFormTag.setPageContext(pageContext); - assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + 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(formTag, freshFormTag)); + } + + public void testUsingParamBodyValueToSetConfigurations_clearTagStateSet() throws Exception { + + FormTag formTag = new FormTag(); + formTag.setPerformClearTagStateForTagPoolingServers(true); // Explicitly request tag state clearing. + formTag.setName("myForm"); + formTag.setPageContext(pageContext); + formTag.setId("myFormId"); + formTag.setAction("testAction"); + + + ParamTag formParamTag = new ParamTag(); + formParamTag.setPageContext(pageContext); + formParamTag.setName("tooltipConfig"); + StrutsMockBodyContent bodyContent = new StrutsMockBodyContent(new MockJspWriter()); + bodyContent.setString( + "tooltipIcon=/struts/tooltip/myTooltip.gif| " + + "tooltipDelay=500| " + + "jsTooltipEnabled=true " + ); + formParamTag.setBodyContent(bodyContent); + + TextFieldTag tag = new TextFieldTag(); + tag.setPerformClearTagStateForTagPoolingServers(true); // Explicitly request tag state clearing. + tag.setPageContext(pageContext); + tag.setLabel("MyLabel"); + tag.setId("myId"); + tag.setTooltip("myTooltip"); + + + ParamTag textFieldParamTag = new ParamTag(); + textFieldParamTag.setPerformClearTagStateForTagPoolingServers(true); // Explicitly request tag state clearing. + textFieldParamTag.setPageContext(pageContext); + textFieldParamTag.setName("tooltipConfig"); + StrutsMockBodyContent bodyContent2 = new StrutsMockBodyContent(new MockJspWriter()); + bodyContent2.setString( + "tooltipIcon=/struts/tooltip/myTooltip2.gif| " + + "tooltipDelay=5000 " + ); + textFieldParamTag.setBodyContent(bodyContent2); + + formTag.doStartTag(); + setComponentTagClearTagState(formTag, true); // Ensure component tag state clearing is set true (to match tag). + formParamTag.doStartTag(); + setComponentTagClearTagState(formParamTag, true); // Ensure component tag state clearing is set true (to match tag). + formParamTag.doEndTag(); + tag.doStartTag(); + setComponentTagClearTagState(tag, true); // Ensure component tag state clearing is set true (to match tag). + textFieldParamTag.doStartTag(); + setComponentTagClearTagState(textFieldParamTag, true); // Ensure component tag state clearing is set true (to match tag). + textFieldParamTag.doEndTag(); + tag.doEndTag(); + formTag.doEndTag(); + + System.out.println(writer.toString()); + + verify(TooltipTest.class.getResource("tooltip-3.txt")); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + TextFieldTag freshTag = new TextFieldTag(); + freshTag.setPerformClearTagStateForTagPoolingServers(true); + 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)); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + ParamTag freshParamTag = new ParamTag(); + freshParamTag.setPerformClearTagStateForTagPoolingServers(true); + freshParamTag.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(textFieldParamTag, freshParamTag)); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + FormTag freshFormTag = new FormTag(); + freshFormTag.setPerformClearTagStateForTagPoolingServers(true); + freshFormTag.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(formTag, freshFormTag)); } diff --git a/core/src/test/java/org/apache/struts2/views/jsp/ui/UpDownSelectTagTest.java b/core/src/test/java/org/apache/struts2/views/jsp/ui/UpDownSelectTagTest.java index f71fa2826..d39cef8d3 100644 --- a/core/src/test/java/org/apache/struts2/views/jsp/ui/UpDownSelectTagTest.java +++ b/core/src/test/java/org/apache/struts2/views/jsp/ui/UpDownSelectTagTest.java @@ -52,7 +52,33 @@ public class UpDownSelectTagTest extends AbstractUITagTest { // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). UpDownSelectTag freshTag = new UpDownSelectTag(); freshTag.setPageContext(pageContext); - assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + 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 testWithAllSelected_clearTagStateSet() throws Exception { + + UpDownSelectTag tag = new UpDownSelectTag(); + tag.setPerformClearTagStateForTagPoolingServers(true); // Explicitly request tag state clearing. + tag.setPageContext(pageContext); + tag.setId("myId"); + tag.setName("myName"); + tag.setList("myMap"); + tag.setValue("myAllSelectedMapIds"); + tag.setEmptyOption("true"); + + tag.doStartTag(); + setComponentTagClearTagState(tag, true); // Ensure component tag state clearing is set true (to match tag). + tag.doEndTag(); + + verify(UpDownSelectTagTest.class.getResource("updownselecttag-1.txt")); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + UpDownSelectTag freshTag = new UpDownSelectTag(); + freshTag.setPerformClearTagStateForTagPoolingServers(true); + 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)); } @@ -77,7 +103,33 @@ public class UpDownSelectTagTest extends AbstractUITagTest { // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). UpDownSelectTag freshTag = new UpDownSelectTag(); freshTag.setPageContext(pageContext); - assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + 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 testWithPartialSelected_clearTagStateSet() throws Exception { + + UpDownSelectTag tag = new UpDownSelectTag(); + tag.setPerformClearTagStateForTagPoolingServers(true); // Explicitly request tag state clearing. + tag.setPageContext(pageContext); + tag.setId("myId"); + tag.setName("myName"); + tag.setList("myMap"); + tag.setValue("mySelectedMapIds"); + tag.setEmptyOption("false"); + + tag.doStartTag(); + setComponentTagClearTagState(tag, true); // Ensure component tag state clearing is set true (to match tag). + tag.doEndTag(); + + verify(UpDownSelectTagTest.class.getResource("updownselecttag-2.txt")); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + UpDownSelectTag freshTag = new UpDownSelectTag(); + freshTag.setPerformClearTagStateForTagPoolingServers(true); + 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)); } @@ -102,7 +154,35 @@ public class UpDownSelectTagTest extends AbstractUITagTest { // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). UpDownSelectTag freshTag = new UpDownSelectTag(); freshTag.setPageContext(pageContext); - assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + 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 testWithHeaderAndEmptyOption_clearTagStateSet() throws Exception { + + UpDownSelectTag tag = new UpDownSelectTag(); + tag.setPerformClearTagStateForTagPoolingServers(true); // Explicitly request tag state clearing. + tag.setPageContext(pageContext); + tag.setId("myId"); + tag.setName("myName"); + tag.setList("myMap"); + tag.setValue("mySelectedMapIds"); + tag.setEmptyOption("true"); + tag.setHeaderKey("-1"); + tag.setHeaderValue("--- Please Order ---"); + + tag.doStartTag(); + setComponentTagClearTagState(tag, true); // Ensure component tag state clearing is set true (to match tag). + tag.doEndTag(); + + verify(UpDownSelectTagTest.class.getResource("updownselecttag-3.txt")); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + UpDownSelectTag freshTag = new UpDownSelectTag(); + freshTag.setPerformClearTagStateForTagPoolingServers(true); + 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)); } @@ -127,7 +207,35 @@ public class UpDownSelectTagTest extends AbstractUITagTest { // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). UpDownSelectTag freshTag = new UpDownSelectTag(); freshTag.setPageContext(pageContext); - assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + 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 testWithHeaderOnly_clearTagStateSet() throws Exception { + + UpDownSelectTag tag = new UpDownSelectTag(); + tag.setPerformClearTagStateForTagPoolingServers(true); // Explicitly request tag state clearing. + tag.setPageContext(pageContext); + tag.setId("myId"); + tag.setName("myName"); + tag.setList("myMap"); + tag.setValue("mySelectedMapIds"); + tag.setEmptyOption("false"); + tag.setHeaderKey("-1"); + tag.setHeaderValue("--- Please Order ---"); + + tag.doStartTag(); + setComponentTagClearTagState(tag, true); // Ensure component tag state clearing is set true (to match tag). + tag.doEndTag(); + + verify(UpDownSelectTagTest.class.getResource("updownselecttag-4.txt")); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + UpDownSelectTag freshTag = new UpDownSelectTag(); + freshTag.setPerformClearTagStateForTagPoolingServers(true); + 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)); } @@ -150,11 +258,36 @@ public class UpDownSelectTagTest extends AbstractUITagTest { // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). UpDownSelectTag freshTag = new UpDownSelectTag(); freshTag.setPageContext(pageContext); - assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + 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 testWithEmptyOptionOnly_clearTagStateSet() throws Exception { + + UpDownSelectTag tag = new UpDownSelectTag(); + tag.setPerformClearTagStateForTagPoolingServers(true); // Explicitly request tag state clearing. + tag.setPageContext(pageContext); + tag.setId("myId"); + tag.setName("myName"); + tag.setList("myMap"); + tag.setValue("mySelectedMapIds"); + tag.setEmptyOption("true"); + + tag.doStartTag(); + setComponentTagClearTagState(tag, true); // Ensure component tag state clearing is set true (to match tag). + tag.doEndTag(); + + verify(UpDownSelectTagTest.class.getResource("updownselecttag-5.txt")); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + UpDownSelectTag freshTag = new UpDownSelectTag(); + freshTag.setPerformClearTagStateForTagPoolingServers(true); + 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)); + } public void testDisableSomeSelectAllButton() throws Exception { @@ -175,7 +308,34 @@ public class UpDownSelectTagTest extends AbstractUITagTest { // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). UpDownSelectTag freshTag = new UpDownSelectTag(); freshTag.setPageContext(pageContext); - assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + 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 testDisableSomeSelectAllButton_clearTagStateSet() throws Exception { + + UpDownSelectTag tag = new UpDownSelectTag(); + tag.setPerformClearTagStateForTagPoolingServers(true); // Explicitly request tag state clearing. + tag.setPageContext(pageContext); + tag.setId("myId"); + tag.setName("myName"); + tag.setList("myMap"); + tag.setValue("mySelectedMapIds"); + tag.setEmptyOption("true"); + tag.setAllowSelectAll("false"); + + tag.doStartTag(); + setComponentTagClearTagState(tag, true); // Ensure component tag state clearing is set true (to match tag). + tag.doEndTag(); + + verify(UpDownSelectTagTest.class.getResource("updownselecttag-6.txt")); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + UpDownSelectTag freshTag = new UpDownSelectTag(); + freshTag.setPerformClearTagStateForTagPoolingServers(true); + 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)); } @@ -198,7 +358,33 @@ public class UpDownSelectTagTest extends AbstractUITagTest { // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). UpDownSelectTag freshTag = new UpDownSelectTag(); freshTag.setPageContext(pageContext); - assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + 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 testDisableMoveUpButton_clearTagStateSet() throws Exception { + UpDownSelectTag tag = new UpDownSelectTag(); + tag.setPerformClearTagStateForTagPoolingServers(true); // Explicitly request tag state clearing. + tag.setPageContext(pageContext); + tag.setId("myId"); + tag.setName("myName"); + tag.setList("myMap"); + tag.setValue("mySelectedMapIds"); + tag.setEmptyOption("true"); + tag.setAllowMoveUp("false"); + + tag.doStartTag(); + setComponentTagClearTagState(tag, true); // Ensure component tag state clearing is set true (to match tag). + tag.doEndTag(); + + verify(UpDownSelectTagTest.class.getResource("updownselecttag-7.txt")); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + UpDownSelectTag freshTag = new UpDownSelectTag(); + freshTag.setPerformClearTagStateForTagPoolingServers(true); + 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)); } @@ -221,7 +407,33 @@ public class UpDownSelectTagTest extends AbstractUITagTest { // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). UpDownSelectTag freshTag = new UpDownSelectTag(); freshTag.setPageContext(pageContext); - assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + 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 testDisableMoveDownButton_clearTagStateSet() throws Exception { + UpDownSelectTag tag = new UpDownSelectTag(); + tag.setPerformClearTagStateForTagPoolingServers(true); // Explicitly request tag state clearing. + tag.setPageContext(pageContext); + tag.setId("myId"); + tag.setName("myName"); + tag.setList("myMap"); + tag.setValue("mySelectedMapIds"); + tag.setEmptyOption("true"); + tag.setAllowMoveDown("false"); + + tag.doStartTag(); + setComponentTagClearTagState(tag, true); // Ensure component tag state clearing is set true (to match tag). + tag.doEndTag(); + + verify(UpDownSelectTagTest.class.getResource("updownselecttag-8.txt")); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + UpDownSelectTag freshTag = new UpDownSelectTag(); + freshTag.setPerformClearTagStateForTagPoolingServers(true); + 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)); } @@ -244,7 +456,33 @@ public class UpDownSelectTagTest extends AbstractUITagTest { // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). UpDownSelectTag freshTag = new UpDownSelectTag(); freshTag.setPageContext(pageContext); - assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + 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 testChangeSelectAllButtonText_clearTagStateSet() throws Exception { + UpDownSelectTag tag = new UpDownSelectTag(); + tag.setPerformClearTagStateForTagPoolingServers(true); // Explicitly request tag state clearing. + tag.setPageContext(pageContext); + tag.setId("myId"); + tag.setName("myName"); + tag.setList("myMap"); + tag.setValue("mySelectedMapIds"); + tag.setEmptyOption("true"); + tag.setSelectAllLabel("Select All"); + + tag.doStartTag(); + setComponentTagClearTagState(tag, true); // Ensure component tag state clearing is set true (to match tag). + tag.doEndTag(); + + verify(UpDownSelectTagTest.class.getResource("updownselecttag-9.txt")); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + UpDownSelectTag freshTag = new UpDownSelectTag(); + freshTag.setPerformClearTagStateForTagPoolingServers(true); + 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)); } @@ -267,7 +505,33 @@ public class UpDownSelectTagTest extends AbstractUITagTest { // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). UpDownSelectTag freshTag = new UpDownSelectTag(); freshTag.setPageContext(pageContext); - assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + 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 testChangeMoveUpButtonText_clearTagStateSet() throws Exception { + UpDownSelectTag tag = new UpDownSelectTag(); + tag.setPerformClearTagStateForTagPoolingServers(true); // Explicitly request tag state clearing. + tag.setPageContext(pageContext); + tag.setId("myId"); + tag.setName("myName"); + tag.setList("myMap"); + tag.setValue("mySelectedMapIds"); + tag.setEmptyOption("true"); + tag.setMoveUpLabel("Move Up"); + + tag.doStartTag(); + setComponentTagClearTagState(tag, true); // Ensure component tag state clearing is set true (to match tag). + tag.doEndTag(); + + verify(UpDownSelectTagTest.class.getResource("updownselecttag-10.txt")); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + UpDownSelectTag freshTag = new UpDownSelectTag(); + freshTag.setPerformClearTagStateForTagPoolingServers(true); + 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)); } @@ -290,7 +554,33 @@ public class UpDownSelectTagTest extends AbstractUITagTest { // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). UpDownSelectTag freshTag = new UpDownSelectTag(); freshTag.setPageContext(pageContext); - assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + 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 testChangeMoveDownButtonText_clearTagStateSet() throws Exception { + UpDownSelectTag tag = new UpDownSelectTag(); + tag.setPerformClearTagStateForTagPoolingServers(true); // Explicitly request tag state clearing. + tag.setPageContext(pageContext); + tag.setId("myId"); + tag.setName("myName"); + tag.setList("myMap"); + tag.setValue("mySelectedMapIds"); + tag.setEmptyOption("true"); + tag.setMoveDownLabel("Move Down"); + + tag.doStartTag(); + setComponentTagClearTagState(tag, true); // Ensure component tag state clearing is set true (to match tag). + tag.doEndTag(); + + verify(UpDownSelectTagTest.class.getResource("updownselecttag-11.txt")); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + UpDownSelectTag freshTag = new UpDownSelectTag(); + freshTag.setPerformClearTagStateForTagPoolingServers(true); + 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)); } diff --git a/core/src/test/java/org/apache/struts2/views/jsp/ui/ValidationStylesTest.java b/core/src/test/java/org/apache/struts2/views/jsp/ui/ValidationStylesTest.java index de7632455..3727de771 100644 --- a/core/src/test/java/org/apache/struts2/views/jsp/ui/ValidationStylesTest.java +++ b/core/src/test/java/org/apache/struts2/views/jsp/ui/ValidationStylesTest.java @@ -34,7 +34,25 @@ public class ValidationStylesTest extends AbstractUITagTest { // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). TextFieldTag freshTag = new TextFieldTag(); freshTag.setPageContext(pageContext); - assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + 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 testNormalStyle_clearTagStateSet() throws Exception { + tag.setPerformClearTagStateForTagPoolingServers(true); // Explicitly request tag state clearing. + tag.setCssStyle("style"); + tag.doStartTag(); + setComponentTagClearTagState(tag, true); // Ensure component tag state clearing is set true (to match tag). + tag.doEndTag(); + + verify(ValidationStylesTest.class.getResource("validationstyles-1.txt")); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + TextFieldTag freshTag = new TextFieldTag(); + freshTag.setPerformClearTagStateForTagPoolingServers(true); + 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)); } @@ -49,7 +67,25 @@ public class ValidationStylesTest extends AbstractUITagTest { // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). TextFieldTag freshTag = new TextFieldTag(); freshTag.setPageContext(pageContext); - assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + 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 testErrorStyle_clearTagStateSet() throws Exception { + tag.setPerformClearTagStateForTagPoolingServers(true); // Explicitly request tag state clearing. + tag.setCssErrorStyle("errstyle"); + tag.doStartTag(); + setComponentTagClearTagState(tag, true); // Ensure component tag state clearing is set true (to match tag). + tag.doEndTag(); + + verify(ValidationStylesTest.class.getResource("validationstyles-2.txt")); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + TextFieldTag freshTag = new TextFieldTag(); + freshTag.setPerformClearTagStateForTagPoolingServers(true); + 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)); } @@ -64,7 +100,25 @@ public class ValidationStylesTest extends AbstractUITagTest { // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). TextFieldTag freshTag = new TextFieldTag(); freshTag.setPageContext(pageContext); - assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + 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 testErrorClass_clearTagStateSet() throws Exception { + tag.setPerformClearTagStateForTagPoolingServers(true); // Explicitly request tag state clearing. + tag.setCssErrorClass("errclass"); + tag.doStartTag(); + setComponentTagClearTagState(tag, true); // Ensure component tag state clearing is set true (to match tag). + tag.doEndTag(); + + verify(ValidationStylesTest.class.getResource("validationstyles-3.txt")); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + TextFieldTag freshTag = new TextFieldTag(); + freshTag.setPerformClearTagStateForTagPoolingServers(true); + 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)); } @@ -80,7 +134,26 @@ public class ValidationStylesTest extends AbstractUITagTest { // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). TextFieldTag freshTag = new TextFieldTag(); freshTag.setPageContext(pageContext); - assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + 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 testStyleAndErrorStyle_clearTagStateSet() throws Exception { + tag.setPerformClearTagStateForTagPoolingServers(true); // Explicitly request tag state clearing. + tag.setCssStyle("style"); + tag.setCssErrorStyle("errstyle"); + tag.doStartTag(); + setComponentTagClearTagState(tag, true); // Ensure component tag state clearing is set true (to match tag). + tag.doEndTag(); + + verify(ValidationStylesTest.class.getResource("validationstyles-2.txt")); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + TextFieldTag freshTag = new TextFieldTag(); + freshTag.setPerformClearTagStateForTagPoolingServers(true); + 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)); } @@ -96,7 +169,26 @@ public class ValidationStylesTest extends AbstractUITagTest { // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). TextFieldTag freshTag = new TextFieldTag(); freshTag.setPageContext(pageContext); - assertTrue("Tag state after doEndTag() inequal to new Tag with pageContext/parent set. " + + 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 testStyleAndErrorClass_clearTagStateSet() throws Exception { + tag.setPerformClearTagStateForTagPoolingServers(true); // Explicitly request tag state clearing. + tag.setCssStyle("style"); + tag.setCssErrorClass("errclass"); + tag.doStartTag(); + setComponentTagClearTagState(tag, true); // Ensure component tag state clearing is set true (to match tag). + tag.doEndTag(); + + verify(ValidationStylesTest.class.getResource("validationstyles-3.txt")); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + TextFieldTag freshTag = new TextFieldTag(); + freshTag.setPerformClearTagStateForTagPoolingServers(true); + 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)); } From 25c5a2b4b9004f2fab126863223bbe9285f22031 Mon Sep 17 00:00:00 2001 From: JCgH4164838Gh792C124B5 <43964333+JCgH4164838Gh792C124B5@users.noreply.github.com> Date: Sun, 12 Sep 2021 16:31:13 -0400 Subject: [PATCH 3/7] Update: - Follwing upstream merge, fixed AbstractUITag.java issue that was causing the build to fail. --- .../java/org/apache/struts2/views/jsp/ui/AbstractUITag.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/src/main/java/org/apache/struts2/views/jsp/ui/AbstractUITag.java b/core/src/main/java/org/apache/struts2/views/jsp/ui/AbstractUITag.java index 42f688179..345d37254 100644 --- a/core/src/main/java/org/apache/struts2/views/jsp/ui/AbstractUITag.java +++ b/core/src/main/java/org/apache/struts2/views/jsp/ui/AbstractUITag.java @@ -341,7 +341,7 @@ public abstract class AbstractUITag extends ComponentTagSupport implements Dynam this.disabled = null; this.label = null; this.labelSeparator = null; - this.labelposition = null; + this.labelPosition = null; this.requiredPosition = null; this.errorPosition = null; this.name = null; From 68713648fabbf2df970cf0816f1ec36b8de784a6 Mon Sep 17 00:00:00 2001 From: JCgH4164838Gh792C124B5 <43964333+JCgH4164838Gh792C124B5@users.noreply.github.com> Date: Sun, 26 Sep 2021 18:00:21 -0400 Subject: [PATCH 4/7] Update: - Implement PrepareOperations.clearDevModeOverride() method, to clear any leftover ThreadLocal state, as suggested by Y. Zamani. - Call PrepareOperations.clearDevModeOverride() in the StrutsInternalTestCase.setup() to ensure consistent initial state for every test thread before the tests are executed. - Call PrepareOperations.clearDevModeOverride() at the end of DebugTagTest tests that call PrepareOperations.overrideDevMode(), for better state management in those tests. --- .../apache/struts2/dispatcher/PrepareOperations.java | 11 +++++++++++ .../org/apache/struts2/StrutsInternalTestCase.java | 6 ++++++ .../org/apache/struts2/views/jsp/ui/DebugTagTest.java | 8 ++++++++ 3 files changed, 25 insertions(+) diff --git a/core/src/main/java/org/apache/struts2/dispatcher/PrepareOperations.java b/core/src/main/java/org/apache/struts2/dispatcher/PrepareOperations.java index 5ccc9d64a..1d6981bb1 100644 --- a/core/src/main/java/org/apache/struts2/dispatcher/PrepareOperations.java +++ b/core/src/main/java/org/apache/struts2/dispatcher/PrepareOperations.java @@ -251,4 +251,15 @@ public class PrepareOperations { return devModeOverride.get(); } + /** + * Clear any override of the static devMode value being applied to the current thread. + * + * This can be useful for any situation where {@link #overrideDevMode(boolean)} might be called + * in a flow where {@link #cleanupRequest(javax.servlet.http.HttpServletRequest)} does not get called. + * May be very situational (such as some unit tests), but may have other utility as well. + */ + public static void clearDevModeOverride() { + devModeOverride.remove(); // Remove current thread's value, enxure next read returns it to initialValue (typically null). + } + } diff --git a/core/src/test/java/org/apache/struts2/StrutsInternalTestCase.java b/core/src/test/java/org/apache/struts2/StrutsInternalTestCase.java index 4dc7e78df..30616303f 100644 --- a/core/src/test/java/org/apache/struts2/StrutsInternalTestCase.java +++ b/core/src/test/java/org/apache/struts2/StrutsInternalTestCase.java @@ -21,6 +21,7 @@ package org.apache.struts2; import com.opensymphony.xwork2.XWorkTestCase; import org.apache.commons.lang3.builder.EqualsBuilder; import org.apache.struts2.dispatcher.Dispatcher; +import org.apache.struts2.dispatcher.PrepareOperations; import org.apache.struts2.util.StrutsTestCaseHelper; import org.apache.struts2.views.jsp.StrutsMockServletContext; import java.util.HashMap; @@ -37,9 +38,13 @@ public abstract class StrutsInternalTestCase extends XWorkTestCase { /** * Sets up the configuration settings, XWork configuration, and * message resources + * + * @throws java.lang.Exception */ + @Override protected void setUp() throws Exception { super.setUp(); + PrepareOperations.clearDevModeOverride(); // Clear DevMode override every time (consistent ThreadLocal state for tests). initDispatcher(null); } @@ -66,6 +71,7 @@ public abstract class StrutsInternalTestCase extends XWorkTestCase { return initDispatcher(params); } + @Override protected void tearDown() throws Exception { super.tearDown(); // maybe someone else already destroyed Dispatcher diff --git a/core/src/test/java/org/apache/struts2/views/jsp/ui/DebugTagTest.java b/core/src/test/java/org/apache/struts2/views/jsp/ui/DebugTagTest.java index 5553a4e28..c6b7dea77 100644 --- a/core/src/test/java/org/apache/struts2/views/jsp/ui/DebugTagTest.java +++ b/core/src/test/java/org/apache/struts2/views/jsp/ui/DebugTagTest.java @@ -138,6 +138,8 @@ public class DebugTagTest extends AbstractUITagTest { assertTrue("Tag state after doEndTag() under default tag clear state is inequal to new Tag with pageContext/parent set. " + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", strutsBodyTagsAreReflectionEqual(tag, freshTag)); + + PrepareOperations.clearDevModeOverride(); // Clear DevMode override. Avoid ThreadLocal side-effects if test thread re-used. } public void testTagAttributeOverrideDevModeTrue_clearTagStateSet() throws Exception { @@ -159,6 +161,8 @@ public class DebugTagTest extends AbstractUITagTest { 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)); + + PrepareOperations.clearDevModeOverride(); // Clear DevMode override. Avoid ThreadLocal side-effects if test thread re-used. } public void testTagAttributeOverrideDevModeFalse() throws Exception { @@ -176,6 +180,8 @@ public class DebugTagTest extends AbstractUITagTest { assertTrue("Tag state after doEndTag() under default tag clear state is inequal to new Tag with pageContext/parent set. " + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", strutsBodyTagsAreReflectionEqual(tag, freshTag)); + + PrepareOperations.clearDevModeOverride(); // Clear DevMode override. Avoid ThreadLocal side-effects if test thread re-used. } public void testTagAttributeOverrideDevModeFalse_clearTagStateSet() throws Exception { @@ -195,6 +201,8 @@ public class DebugTagTest extends AbstractUITagTest { 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)); + + PrepareOperations.clearDevModeOverride(); // Clear DevMode override. Avoid ThreadLocal side-effects if test thread re-used. } private void setDevMode(final boolean devMode) { From 86e81c3745f4b6482fa0c8f052e32756ca4d7373 Mon Sep 17 00:00:00 2001 From: JCgH4164838Gh792C124B5 <43964333+JCgH4164838Gh792C124B5@users.noreply.github.com> Date: Sun, 31 Oct 2021 17:46:43 -0400 Subject: [PATCH 5/7] Update: - Fixed any leftover merge conflict items missed from cherry-picks. - Fixed unit test elements from cherry-picks so they correspond to 2.6.x behaviour, instead of 2.5.x behaviour. - Removed searchValueStack elements from TextTag component and tests as it does not exist in 2.6.x anymore. --- .../org/apache/struts2/views/jsp/TextTag.java | 1 - .../struts2/views/jsp/PropertyTagTest.java | 14 --- .../apache/struts2/views/jsp/TextTagTest.java | 115 ------------------ .../apache/struts2/views/jsp/URLTagTest.java | 8 +- .../struts2/views/jsp/ui/ComboBoxTest.java | 2 + .../struts2/views/jsp/ui/DateTagTest.java | 12 +- .../struts2/views/jsp/ui/DebugTagTest.java | 3 + .../views/jsp/ui/DoubleSelectTest.java | 2 + .../struts2/views/jsp/ui/FormTagTest.java | 3 + .../struts2/views/jsp/ui/HeadTagTest.java | 2 + .../jsp/ui/InputTransferSelectTagTest.java | 1 + .../jsp/ui/OptionTransferSelectTagTest.java | 2 + .../struts2/views/jsp/ui/TooltipTest.java | 26 ++-- .../views/jsp/ui/UpDownSelectTagTest.java | 2 + 14 files changed, 42 insertions(+), 151 deletions(-) diff --git a/core/src/main/java/org/apache/struts2/views/jsp/TextTag.java b/core/src/main/java/org/apache/struts2/views/jsp/TextTag.java index d3b609e5b..812c81baa 100644 --- a/core/src/main/java/org/apache/struts2/views/jsp/TextTag.java +++ b/core/src/main/java/org/apache/struts2/views/jsp/TextTag.java @@ -91,7 +91,6 @@ public class TextTag extends ContextBeanTag { } super.clearTagStateForTagPoolingServers(); this.name = null; - this.searchValueStack = null; this.escapeHtml = false; this.escapeJavaScript = false; this.escapeXml = false; diff --git a/core/src/test/java/org/apache/struts2/views/jsp/PropertyTagTest.java b/core/src/test/java/org/apache/struts2/views/jsp/PropertyTagTest.java index b843e5685..f2e7f8457 100644 --- a/core/src/test/java/org/apache/struts2/views/jsp/PropertyTagTest.java +++ b/core/src/test/java/org/apache/struts2/views/jsp/PropertyTagTest.java @@ -435,8 +435,6 @@ public class PropertyTagTest extends StrutsInternalTestCase { public void testWithAltSyntax1_clearTagStateSet() throws Exception { // setups - initDispatcher(new HashMap() {{ put(StrutsConstants.STRUTS_TAG_ALTSYNTAX, "true");}}); - Foo foo = new Foo(); foo.setTitle("tm_jee"); stack.push(foo); @@ -510,8 +508,6 @@ public class PropertyTagTest extends StrutsInternalTestCase { public void testEscapeJavaScript_clearTagStateSet() throws Exception { // setups - initDispatcher(new HashMap() {{ put(StrutsConstants.STRUTS_TAG_ALTSYNTAX, "true");}}); - Foo foo = new Foo(); foo.setTitle("\t\b\n\f\r\"\'/\\"); stack.push(foo); @@ -585,8 +581,6 @@ public class PropertyTagTest extends StrutsInternalTestCase { public void testEscapeXml_clearTagStateSet() throws Exception { // setups - initDispatcher(new HashMap() {{ put(StrutsConstants.STRUTS_TAG_ALTSYNTAX, "true");}}); - Foo foo = new Foo(); foo.setTitle("<>'\"&"); stack.push(foo); @@ -660,8 +654,6 @@ public class PropertyTagTest extends StrutsInternalTestCase { public void testEscapeCsv_clearTagStateSet() throws Exception { // setups - initDispatcher(new HashMap() {{ put(StrutsConstants.STRUTS_TAG_ALTSYNTAX, "true");}}); - Foo foo = new Foo(); foo.setTitle("\"something,\",\""); stack.push(foo); @@ -733,8 +725,6 @@ public class PropertyTagTest extends StrutsInternalTestCase { public void testWithAltSyntax2_clearTagStateSet() throws Exception { // setups - initDispatcher(new HashMap() {{ put(StrutsConstants.STRUTS_TAG_ALTSYNTAX, "true");}}); - Foo foo = new Foo(); foo.setTitle("tm_jee"); stack.push(foo); @@ -804,8 +794,6 @@ public class PropertyTagTest extends StrutsInternalTestCase { public void testWithoutAltSyntax1_clearTagStateSet() throws Exception { // setups - initDispatcher(new HashMap() {{ put(StrutsConstants.STRUTS_TAG_ALTSYNTAX, "false");}}); - Foo foo = new Foo(); foo.setTitle("tm_jee"); stack.push(foo); @@ -874,8 +862,6 @@ public class PropertyTagTest extends StrutsInternalTestCase { public void testWithoutAltSyntax2_clearTagStateSet() throws Exception { // setups - initDispatcher(new HashMap() {{ put(StrutsConstants.STRUTS_TAG_ALTSYNTAX, "false");}}); - Foo foo = new Foo(); foo.setTitle("tm_jee"); stack.push(foo); diff --git a/core/src/test/java/org/apache/struts2/views/jsp/TextTagTest.java b/core/src/test/java/org/apache/struts2/views/jsp/TextTagTest.java index 1dfc98d4e..fa153e013 100644 --- a/core/src/test/java/org/apache/struts2/views/jsp/TextTagTest.java +++ b/core/src/test/java/org/apache/struts2/views/jsp/TextTagTest.java @@ -506,121 +506,6 @@ public class TextTagTest extends AbstractTagTest { strutsBodyTagsAreReflectionEqual(tag, freshTag)); } -<<<<<<< HEAD -======= - public void testTextTagCanSearchStackToFindValue() throws JspException { - String key = "result"; - - tag.setName(key); - tag.setSearchValueStack("true"); - final StringBuffer buffer = writer.getBuffer(); - buffer.delete(0, buffer.length()); - ValueStack newStack = container.getInstance(ValueStackFactory.class).createValueStack(); - newStack.getContext().put(ActionContext.CONTAINER, container); - TestAction testAction = new TestAction(); - container.inject(testAction); - testAction.setResult("bar"); - newStack.push(testAction); - request.setAttribute(ServletActionContext.STRUTS_VALUESTACK_KEY, newStack); - - tag.doStartTag(); - tag.doEndTag(); - assertEquals("bar", writer.toString()); - - // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). - TextTag freshTag = new TextTag(); - 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 testTextTagCanSearchStackToFindValue_clearTagStateSet() throws JspException { - String key = "result"; - - tag.setPerformClearTagStateForTagPoolingServers(true); // Explicitly request tag state clearing. - tag.setName(key); - tag.setSearchValueStack("true"); - final StringBuffer buffer = writer.getBuffer(); - buffer.delete(0, buffer.length()); - ValueStack newStack = container.getInstance(ValueStackFactory.class).createValueStack(); - newStack.getContext().put(ActionContext.CONTAINER, container); - TestAction testAction = new TestAction(); - container.inject(testAction); - testAction.setResult("bar"); - newStack.push(testAction); - request.setAttribute(ServletActionContext.STRUTS_VALUESTACK_KEY, newStack); - - tag.doStartTag(); - setComponentTagClearTagState(tag, true); // Ensure component tag state clearing is set true (to match tag). - tag.doEndTag(); - assertEquals("bar", writer.toString()); - - // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). - TextTag freshTag = new TextTag(); - freshTag.setPerformClearTagStateForTagPoolingServers(true); - 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)); - } - - public void testTextTagDoNotSearchStackByDefault() throws JspException { - String key = "result"; - - tag.setName(key); - final StringBuffer buffer = writer.getBuffer(); - buffer.delete(0, buffer.length()); - ValueStack newStack = container.getInstance(ValueStackFactory.class).createValueStack(); - newStack.getContext().put(ActionContext.CONTAINER, container); - TestAction testAction = new TestAction(); - container.inject(testAction); - testAction.setResult("bar"); - newStack.push(testAction); - request.setAttribute(ServletActionContext.STRUTS_VALUESTACK_KEY, newStack); - - tag.doStartTag(); - tag.doEndTag(); - assertEquals("result", writer.toString()); - - // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). - TextTag freshTag = new TextTag(); - 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 testTextTagDoNotSearchStackByDefault_clearTagStateSet() throws JspException { - String key = "result"; - - tag.setPerformClearTagStateForTagPoolingServers(true); // Explicitly request tag state clearing. - tag.setName(key); - final StringBuffer buffer = writer.getBuffer(); - buffer.delete(0, buffer.length()); - ValueStack newStack = container.getInstance(ValueStackFactory.class).createValueStack(); - newStack.getContext().put(ActionContext.CONTAINER, container); - TestAction testAction = new TestAction(); - container.inject(testAction); - testAction.setResult("bar"); - newStack.push(testAction); - request.setAttribute(ServletActionContext.STRUTS_VALUESTACK_KEY, newStack); - - tag.doStartTag(); - setComponentTagClearTagState(tag, true); // Ensure component tag state clearing is set true (to match tag). - tag.doEndTag(); - assertEquals("result", writer.toString()); - - // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). - TextTag freshTag = new TextTag(); - freshTag.setPerformClearTagStateForTagPoolingServers(true); - 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)); - } - ->>>>>>> da46cefa2 (Update:) public void testWithNoMessageAndBodyIsNotEmptyBodyIsReturned() throws Exception { final String key = "key.does.not.exist"; final String bodyText = "body text"; diff --git a/core/src/test/java/org/apache/struts2/views/jsp/URLTagTest.java b/core/src/test/java/org/apache/struts2/views/jsp/URLTagTest.java index e496f4d23..fdb382f39 100644 --- a/core/src/test/java/org/apache/struts2/views/jsp/URLTagTest.java +++ b/core/src/test/java/org/apache/struts2/views/jsp/URLTagTest.java @@ -1572,10 +1572,14 @@ public class URLTagTest extends AbstractUITagTest { context.put(ServletActionContext.HTTP_RESPONSE, response); context.put(ServletActionContext.SERVLET_CONTEXT, servletContext); - ActionContext.setContext(new ActionContext(context)); + ActionContext actionContext = ActionContext.of(context) + .withServletRequest(request) + .withServletResponse(response) + .withServletContext(servletContext) + .bind(); // Make sure we have an action invocation available - ActionContext.getContext().setActionInvocation(new DefaultActionInvocation(null, true)); + ActionContext.getContext().withActionInvocation(new DefaultActionInvocation(null, true)); DefaultActionProxyFactory apFactory = new DefaultActionProxyFactory(); apFactory.setContainer(container); ActionProxy ap = apFactory.createActionProxy("/", "hello", null, null); diff --git a/core/src/test/java/org/apache/struts2/views/jsp/ui/ComboBoxTest.java b/core/src/test/java/org/apache/struts2/views/jsp/ui/ComboBoxTest.java index afd786e08..e8d870315 100644 --- a/core/src/test/java/org/apache/struts2/views/jsp/ui/ComboBoxTest.java +++ b/core/src/test/java/org/apache/struts2/views/jsp/ui/ComboBoxTest.java @@ -106,6 +106,8 @@ public class ComboBoxTest extends AbstractUITagTest { tag.setId("cb"); tag.setList("collection"); + stack.getActionContext().getSession().put("nonce", "r4nd0m"); + tag.doStartTag(); setComponentTagClearTagState(tag, true); // Ensure component tag state clearing is set true (to match tag). tag.doEndTag(); 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 1f29d8239..408f5a912 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 @@ -129,9 +129,9 @@ public class DateTagTest extends AbstractTagTest { public void testCustomFormatWithTimezone_clearTagStateSet() throws Exception { String format = "yyyy/MM/dd hh:mm:ss"; - Date now = Calendar.getInstance(TimeZone.getTimeZone("UTC+1")).getTime(); + Date now = Calendar.getInstance(TimeZone.getTimeZone("GMT+1")).getTime(); SimpleDateFormat sdf = new SimpleDateFormat(format); - sdf.setTimeZone(TimeZone.getTimeZone("UTC+1")); + sdf.setTimeZone(TimeZone.getTimeZone("GMT+1")); String formatted = sdf.format(now); context.put("myDate", now); @@ -139,7 +139,7 @@ public class DateTagTest extends AbstractTagTest { tag.setName("myDate"); tag.setNice(false); tag.setFormat(format); - tag.setTimezone("UTC+1"); + tag.setTimezone("GMT+1"); tag.doStartTag(); setComponentTagClearTagState(tag, true); // Ensure component tag state clearing is set true (to match tag). tag.doEndTag(); @@ -181,12 +181,12 @@ public class DateTagTest extends AbstractTagTest { public void testCustomFormatWithTimezoneAsExpression_clearTagStateSet() throws Exception { String format = "yyyy/MM/dd hh:mm:ss"; - Date now = Calendar.getInstance(TimeZone.getTimeZone("UTC+2")).getTime(); + Date now = Calendar.getInstance(TimeZone.getTimeZone("GMT+2")).getTime(); SimpleDateFormat sdf = new SimpleDateFormat(format); - sdf.setTimeZone(TimeZone.getTimeZone("UTC+2")); + sdf.setTimeZone(TimeZone.getTimeZone("GMT+2")); String formatted = sdf.format(now); context.put("myDate", now); - context.put("myTimezone", "UTC+2"); + context.put("myTimezone", "GMT+2"); tag.setPerformClearTagStateForTagPoolingServers(true); // Explicitly request tag state clearing. tag.setName("myDate"); diff --git a/core/src/test/java/org/apache/struts2/views/jsp/ui/DebugTagTest.java b/core/src/test/java/org/apache/struts2/views/jsp/ui/DebugTagTest.java index c6b7dea77..7f4b54581 100644 --- a/core/src/test/java/org/apache/struts2/views/jsp/ui/DebugTagTest.java +++ b/core/src/test/java/org/apache/struts2/views/jsp/ui/DebugTagTest.java @@ -69,12 +69,15 @@ public class DebugTagTest extends AbstractUITagTest { public void testDevModeEnabled_clearTagStateSet() throws Exception { setDevMode(true); + stack.getActionContext().getSession().put("nonce", "r4nd0m"); tag.setPerformClearTagStateForTagPoolingServers(true); // Explicitly request tag state clearing. tag.doStartTag(); setComponentTagClearTagState(tag, true); // Ensure component tag state clearing is set true (to match tag). tag.doEndTag(); String result = writer.toString(); + + assertTrue("Nonce value not included", result.contains("nonce=\"r4nd0m\"")); assertTrue(StringUtils.isNotEmpty(result)); assertTrue("Property 'checkStackProperty' should be in Debug Tag output", StringUtils.contains(result, "checkStackProperty")); diff --git a/core/src/test/java/org/apache/struts2/views/jsp/ui/DoubleSelectTest.java b/core/src/test/java/org/apache/struts2/views/jsp/ui/DoubleSelectTest.java index a9c80f3bd..15d76cd6d 100644 --- a/core/src/test/java/org/apache/struts2/views/jsp/ui/DoubleSelectTest.java +++ b/core/src/test/java/org/apache/struts2/views/jsp/ui/DoubleSelectTest.java @@ -161,6 +161,8 @@ public class DoubleSelectTest extends AbstractUITagTest { tag.setDoubleCssClass("c2"); tag.setDoubleCssStyle("s2"); + stack.getActionContext().getSession().put("nonce", "r4nd0m"); + tag.doStartTag(); setComponentTagClearTagState(tag, true); // Ensure component tag state clearing is set true (to match tag). tag.doEndTag(); diff --git a/core/src/test/java/org/apache/struts2/views/jsp/ui/FormTagTest.java b/core/src/test/java/org/apache/struts2/views/jsp/ui/FormTagTest.java index cd3caa577..e9fba3ee6 100644 --- a/core/src/test/java/org/apache/struts2/views/jsp/ui/FormTagTest.java +++ b/core/src/test/java/org/apache/struts2/views/jsp/ui/FormTagTest.java @@ -78,6 +78,9 @@ public class FormTagTest extends AbstractUITagTest { tag.setEnctype("myEncType"); tag.setTitle("mytitle"); tag.setOnsubmit("submitMe()"); + + stack.getActionContext().getSession().put("nonce", "r4nd0m"); + tag.doStartTag(); setComponentTagClearTagState(tag, true); // Ensure component tag state clearing is set true (to match tag). tag.doEndTag(); diff --git a/core/src/test/java/org/apache/struts2/views/jsp/ui/HeadTagTest.java b/core/src/test/java/org/apache/struts2/views/jsp/ui/HeadTagTest.java index ce113672d..c9e4c7015 100644 --- a/core/src/test/java/org/apache/struts2/views/jsp/ui/HeadTagTest.java +++ b/core/src/test/java/org/apache/struts2/views/jsp/ui/HeadTagTest.java @@ -54,6 +54,8 @@ public class HeadTagTest extends AbstractUITagTest { tag.setPerformClearTagStateForTagPoolingServers(true); // Explicitly request tag state clearing. tag.setPageContext(pageContext); + stack.getActionContext().getSession().put("nonce", "r4nd0m"); + tag.doStartTag(); setComponentTagClearTagState(tag, true); // Ensure component tag state clearing is set true (to match tag). tag.doEndTag(); diff --git a/core/src/test/java/org/apache/struts2/views/jsp/ui/InputTransferSelectTagTest.java b/core/src/test/java/org/apache/struts2/views/jsp/ui/InputTransferSelectTagTest.java index ed3ae2483..d974baf36 100644 --- a/core/src/test/java/org/apache/struts2/views/jsp/ui/InputTransferSelectTagTest.java +++ b/core/src/test/java/org/apache/struts2/views/jsp/ui/InputTransferSelectTagTest.java @@ -72,6 +72,7 @@ public class InputTransferSelectTagTest extends AbstractUITagTest { tag.setName("collection"); tag.setList("collection"); + stack.getActionContext().getSession().put("nonce", "r4nd0m"); tag.doStartTag(); setComponentTagClearTagState(tag, true); // Ensure component tag state clearing is set true (to match tag). diff --git a/core/src/test/java/org/apache/struts2/views/jsp/ui/OptionTransferSelectTagTest.java b/core/src/test/java/org/apache/struts2/views/jsp/ui/OptionTransferSelectTagTest.java index c8892773c..671cdbf6e 100644 --- a/core/src/test/java/org/apache/struts2/views/jsp/ui/OptionTransferSelectTagTest.java +++ b/core/src/test/java/org/apache/struts2/views/jsp/ui/OptionTransferSelectTagTest.java @@ -158,6 +158,8 @@ public class OptionTransferSelectTagTest extends AbstractUITagTest { tag.setDoubleHeaderKey("Double Header Key"); tag.setDoubleHeaderValue("Double Header Value"); + stack.getActionContext().getSession().put("nonce", "r4nd0m"); + tag.doStartTag(); setComponentTagClearTagState(tag, true); // Ensure component tag state clearing is set true (to match tag). tag.doEndTag(); diff --git a/core/src/test/java/org/apache/struts2/views/jsp/ui/TooltipTest.java b/core/src/test/java/org/apache/struts2/views/jsp/ui/TooltipTest.java index 8ea723976..05b117562 100644 --- a/core/src/test/java/org/apache/struts2/views/jsp/ui/TooltipTest.java +++ b/core/src/test/java/org/apache/struts2/views/jsp/ui/TooltipTest.java @@ -102,7 +102,7 @@ public class TooltipTest extends AbstractUITagTest { tag.setTooltip("myTooltip"); tag.setTooltipConfig( "#{" + - "'tooltipIcon':'/struts/tooltip/myTooltip.gif', " + + "'tooltipIcon':'/static/tooltip/myTooltip.gif', " + "'tooltipDelay':'500', " + "'jsTooltipEnabled':'true' "+ "}" @@ -204,7 +204,7 @@ public class TooltipTest extends AbstractUITagTest { tag.setTooltip("myTooltip"); tag.setTooltipConfig( "#{" + - "'tooltipIcon':'/struts/tooltip/myTooltip.gif', " + + "'tooltipIcon':'/static/tooltip/myTooltip.gif', " + "'tooltipDelay':'500', " + "'jsTooltipEnabled':'false' "+ "}" @@ -303,7 +303,7 @@ public class TooltipTest extends AbstractUITagTest { //same parameters as the OGNL map configuration, output must be the same tag.setTooltip("myTooltip"); - tag.setTooltipIconPath("/struts/tooltip/myTooltip.gif"); + tag.setTooltipIconPath("/static/tooltip/myTooltip.gif"); tag.setTooltipDelay("500"); tag.setJavascriptTooltip("true"); @@ -391,7 +391,7 @@ public class TooltipTest extends AbstractUITagTest { formTag.setTooltipConfig( "#{" + - "'tooltipIcon':'/struts/tooltip/myTooltip.gif', " + + "'tooltipIcon':'/static/tooltip/myTooltip.gif', " + "'tooltipDelay':'500', " + "'jsTooltipEnabled':'true' "+ "}" @@ -487,7 +487,7 @@ public class TooltipTest extends AbstractUITagTest { // same parameters as the OGNL map configuration, output must be the same formTag.setTooltip("myTooltip"); - formTag.setTooltipIconPath("/struts/tooltip/myTooltip.gif"); + formTag.setTooltipIconPath("/static/tooltip/myTooltip.gif"); formTag.setTooltipDelay("500"); formTag.setJavascriptTooltip("true"); @@ -589,7 +589,7 @@ public class TooltipTest extends AbstractUITagTest { formTag.setTooltipConfig( "#{" + - "'tooltipIcon':'/struts/tooltip/myTooltip.gif', " + + "'tooltipIcon':'/static/tooltip/myTooltip.gif', " + "'tooltipDelay':'500', " + "'jsTooltipEnabled':'true' "+ "}" @@ -605,7 +605,7 @@ public class TooltipTest extends AbstractUITagTest { tag.setTooltip("myTooltip"); tag.setTooltipConfig( "#{" + - "'tooltipIcon':'/struts/tooltip/myTooltip2.gif', " + + "'tooltipIcon':'/static/tooltip/myTooltip2.gif', " + "'tooltipDelay':'5000' " + "}" ); @@ -696,7 +696,7 @@ public class TooltipTest extends AbstractUITagTest { // same parameters as the OGNL map configuration, output must be the same formTag.setTooltip("myTooltip"); - formTag.setTooltipIconPath("/struts/tooltip/myTooltip.gif"); + formTag.setTooltipIconPath("/static/tooltip/myTooltip.gif"); formTag.setTooltipDelay("500"); formTag.setJavascriptTooltip("true"); @@ -710,7 +710,7 @@ public class TooltipTest extends AbstractUITagTest { //same parameters as the OGNL map configuration, output must be the same tag.setTooltip("myTooltip"); - tag.setTooltipIconPath("/struts/tooltip/myTooltip2.gif"); + tag.setTooltipIconPath("/static/tooltip/myTooltip2.gif"); tag.setTooltipDelay("5000"); tag.setJavascriptTooltip("true"); @@ -816,7 +816,7 @@ public class TooltipTest extends AbstractUITagTest { formParamTag.setName("tooltipConfig"); formParamTag.setValue( "#{" + - "'tooltipIcon':'/struts/tooltip/myTooltip.gif', " + + "'tooltipIcon':'/static/tooltip/myTooltip.gif', " + "'tooltipDelay':'500', " + "'jsTooltipEnabled':'true' "+ "}" @@ -835,7 +835,7 @@ public class TooltipTest extends AbstractUITagTest { textFieldParamTag.setName("tooltipConfig"); textFieldParamTag.setValue( "#{" + - "'tooltipIcon':'/struts/tooltip/myTooltip2.gif', " + + "'tooltipIcon':'/static/tooltip/myTooltip2.gif', " + "'tooltipDelay':'5000' "+ "}" ); @@ -958,7 +958,7 @@ public class TooltipTest extends AbstractUITagTest { formParamTag.setName("tooltipConfig"); StrutsMockBodyContent bodyContent = new StrutsMockBodyContent(new MockJspWriter()); bodyContent.setString( - "tooltipIcon=/struts/tooltip/myTooltip.gif| " + + "tooltipIcon=/static/tooltip/myTooltip.gif| " + "tooltipDelay=500| " + "jsTooltipEnabled=true " ); @@ -978,7 +978,7 @@ public class TooltipTest extends AbstractUITagTest { textFieldParamTag.setName("tooltipConfig"); StrutsMockBodyContent bodyContent2 = new StrutsMockBodyContent(new MockJspWriter()); bodyContent2.setString( - "tooltipIcon=/struts/tooltip/myTooltip2.gif| " + + "tooltipIcon=/static/tooltip/myTooltip2.gif| " + "tooltipDelay=5000 " ); textFieldParamTag.setBodyContent(bodyContent2); diff --git a/core/src/test/java/org/apache/struts2/views/jsp/ui/UpDownSelectTagTest.java b/core/src/test/java/org/apache/struts2/views/jsp/ui/UpDownSelectTagTest.java index d39cef8d3..57942c192 100644 --- a/core/src/test/java/org/apache/struts2/views/jsp/ui/UpDownSelectTagTest.java +++ b/core/src/test/java/org/apache/struts2/views/jsp/ui/UpDownSelectTagTest.java @@ -119,6 +119,8 @@ public class UpDownSelectTagTest extends AbstractUITagTest { tag.setValue("mySelectedMapIds"); tag.setEmptyOption("false"); + stack.getActionContext().getSession().put("nonce", "r4nd0m"); + tag.doStartTag(); setComponentTagClearTagState(tag, true); // Ensure component tag state clearing is set true (to match tag). tag.doEndTag(); From ac6749617f4ce1d846bbc816e32f647d18fcc6fc Mon Sep 17 00:00:00 2001 From: JCgH4164838Gh792C124B5 <43964333+JCgH4164838Gh792C124B5@users.noreply.github.com> Date: Fri, 5 Nov 2021 23:32:11 -0400 Subject: [PATCH 6/7] Update: - Add overriden release() method to StrutsBodyTagSupport to ensure the Tag handler always releases state (using the clearTagStateForTagPoolingServers() method to do so). - Add basic unit test to confirm release() behaves as expected. --- .../views/jsp/StrutsBodyTagSupport.java | 25 +++++ .../struts2/views/jsp/PropertyTagTest.java | 103 ++++++++++++++++++ 2 files changed, 128 insertions(+) diff --git a/core/src/main/java/org/apache/struts2/views/jsp/StrutsBodyTagSupport.java b/core/src/main/java/org/apache/struts2/views/jsp/StrutsBodyTagSupport.java index 041d34ebc..2bccb3a25 100644 --- a/core/src/main/java/org/apache/struts2/views/jsp/StrutsBodyTagSupport.java +++ b/core/src/main/java/org/apache/struts2/views/jsp/StrutsBodyTagSupport.java @@ -82,6 +82,31 @@ public class StrutsBodyTagSupport extends BodyTagSupport { return super.doEndTag(); } + /** + * Release state for a Struts JSP Tag handler. + * + * According to the JSP API documentation, the page compiler guarantees that the release() method + * will be invoked on the Tag handler before releasing it to the GC (garbage collector). It does + * not specify when the release() call will be made, though, and timing likely depends + * on the implementation of the JSP/servlet engine being used. + */ + @Override + public void release() { + // Ensure release() performs the clearTagStateForTagPoolingServers tag state clearing processing with + // the clear state flag forced to true (if not already set to true), to ensure cleanup. + // The performClearTagStateForTagPoolingServers flag state is preserved for consistency, in case + // release() is called by framework code. + final boolean originalPerformClearTagState = getPerformClearTagStateForTagPoolingServers(); + if (originalPerformClearTagState == true) { + clearTagStateForTagPoolingServers(); + } else { + setPerformClearTagStateForTagPoolingServers(true); + clearTagStateForTagPoolingServers(); + setPerformClearTagStateForTagPoolingServers(originalPerformClearTagState); + } + super.release(); + } + /** * Request that the tag state be cleared during {@link StrutsBodyTagSupport#doEndTag()} processing, * which may help with certain edge cases with tag logic running on servers that implement JSP Tag Pooling. diff --git a/core/src/test/java/org/apache/struts2/views/jsp/PropertyTagTest.java b/core/src/test/java/org/apache/struts2/views/jsp/PropertyTagTest.java index f2e7f8457..621e7fb32 100644 --- a/core/src/test/java/org/apache/struts2/views/jsp/PropertyTagTest.java +++ b/core/src/test/java/org/apache/struts2/views/jsp/PropertyTagTest.java @@ -895,6 +895,109 @@ public class PropertyTagTest extends StrutsInternalTestCase { pageContext.verify(); } + public void testSimple_release() { + PropertyTag tag = new PropertyTag(); + + Foo foo = new Foo(); + foo.setTitle("test"); + + stack.push(foo); + + MockJspWriter jspWriter = new MockJspWriter(); + jspWriter.setExpectedData("test"); + + MockPageContext pageContext = new MockPageContext(); + pageContext.setJspWriter(jspWriter); + pageContext.setRequest(request); + + tag.setPageContext(pageContext); + tag.setValue("title"); + + try { + tag.doStartTag(); + } catch (JspException e) { + e.printStackTrace(); + fail(); + } + + request.verify(); + jspWriter.verify(); + pageContext.verify(); + + try { + tag.doEndTag(); + } catch (JspException e) { + e.printStackTrace(); + fail(); + } + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + PropertyTag freshTag = new PropertyTag(); + 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.", + objectsAreReflectionEqual(tag, freshTag)); + + // Test release at least once in unit tests (with clear tag state not set). + tag.release(); + assertTrue("Tag state after release() and explicit tag state clearing is inequal to new Tag with pageContext/parent set. " + + "May indicate that clearTagStateForTagPoolingServers() and release() calls are not working properly.", + objectsAreReflectionEqual(tag, freshTag)); + } + + public void testSimple_release_clearTagStateSet() { + PropertyTag tag = new PropertyTag(); + + Foo foo = new Foo(); + foo.setTitle("test"); + + stack.push(foo); + + MockJspWriter jspWriter = new MockJspWriter(); + jspWriter.setExpectedData("test"); + + MockPageContext pageContext = new MockPageContext(); + pageContext.setJspWriter(jspWriter); + pageContext.setRequest(request); + + tag.setPerformClearTagStateForTagPoolingServers(true); // Explicitly request tag state clearing. + tag.setPageContext(pageContext); + tag.setValue("title"); + + try { + tag.doStartTag(); + setComponentTagClearTagState(tag, true); // Ensure component tag state clearing is set true (to match tag). + } catch (JspException e) { + e.printStackTrace(); + fail(); + } + + request.verify(); + jspWriter.verify(); + pageContext.verify(); + + try { + tag.doEndTag(); + } catch (JspException e) { + e.printStackTrace(); + fail(); + } + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag(). + PropertyTag freshTag = new PropertyTag(); + freshTag.setPerformClearTagStateForTagPoolingServers(true); + 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.", + objectsAreReflectionEqual(tag, freshTag)); + + // Test release at least once in unit tests (with clear tag state set). + tag.release(); + assertTrue("Tag state after release() and explicit tag state clearing is inequal to new Tag with pageContext/parent set. " + + "May indicate that clearTagStateForTagPoolingServers() and release() calls are not working properly.", + objectsAreReflectionEqual(tag, freshTag)); + } + @Override protected void setUp() throws Exception { super.setUp(); From c4d3ef8687a30f715ca9494e130d1776c7d2427d Mon Sep 17 00:00:00 2001 From: JCgH4164838Gh792C124B5 <43964333+JCgH4164838Gh792C124B5@users.noreply.github.com> Date: Thu, 11 Nov 2021 19:28:43 -0500 Subject: [PATCH 7/7] Update: - Add some somewhat artificial unit tests to increase code coverage. --- .../struts2/components/ComponentTest.java | 51 ++++++++++++++++- .../struts2/views/jsp/ui/DateTagTest.java | 55 +++++++++++++++++++ 2 files changed, 105 insertions(+), 1 deletion(-) diff --git a/core/src/test/java/org/apache/struts2/components/ComponentTest.java b/core/src/test/java/org/apache/struts2/components/ComponentTest.java index 722f6be04..0bc098265 100644 --- a/core/src/test/java/org/apache/struts2/components/ComponentTest.java +++ b/core/src/test/java/org/apache/struts2/components/ComponentTest.java @@ -42,7 +42,8 @@ import org.apache.struts2.views.jsp.iterator.MergeIteratorTag; import org.apache.struts2.views.jsp.ui.TextFieldTag; import org.apache.struts2.views.jsp.ui.UpDownSelectTag; -import com.opensymphony.xwork2.ActionContext; +import java.util.HashMap; +import org.apache.struts2.StrutsException; /** * Test case for method findAncestor(Class) in Component and some commons @@ -542,4 +543,52 @@ public class ComponentTest extends AbstractTagTest { submit.setEscapeHtmlBody(true); assertTrue("Submit htmlEscapeBody not true after set true ?", submit.escapeHtmlBody()); } + + /** + * Attempt some code coverage tests for {@link Component} that can be achieved without + * too much difficulty. + * + * @throws Exception + */ + public void testComponent_coverageTest() throws Exception { + HashMap propertyMap = new HashMap<>(); + Exception exception = new Exception("Generic exception"); + Property property = new Property(stack); + ActionComponent actionComponent = new ActionComponent(stack, request, response); + + try { + actionComponent.setName("componentName"); + // Simulate component attribute with a hyphen in its name. + propertyMap.put("hyphen-keyname-for-coverage", "hyphen-keyname-for-coverage-value"); + propertyMap.put("someKeyName", "someKeyValue"); + actionComponent.copyParams(propertyMap); + actionComponent.addAllParameters(propertyMap); + try { + actionComponent.findString(null, "fieldName", "errorMessage"); + fail("null expr parameter should cause a StrutsException"); + } catch (StrutsException se) { + // expected + } + assertNull("completeExpression of a null expression returned non-null result ?", actionComponent.completeExpression(null)); + try { + actionComponent.findValue(null, "fieldName", "errorMessage"); + fail("null expr parameter should cause a StrutsException"); + } catch (StrutsException se) { + // expected + } + try { + actionComponent.findValue("", "fieldName", "errorMessage"); + fail("empty expr parameter should cause a StrutsException due to finding a null value"); + } catch (StrutsException se) { + // expected + } + assertNotNull("the toString() method with Exception parameter returned null result ?", actionComponent.toString(exception)); + assertFalse("Initial performClearTagStateForTagPoolingServers not false ?", actionComponent.getPerformClearTagStateForTagPoolingServers()); + actionComponent.setPerformClearTagStateForTagPoolingServers(true); + assertTrue("performClearTagStateForTagPoolingServers false after setting to true ?", actionComponent.getPerformClearTagStateForTagPoolingServers()); + } + finally { + property.getComponentStack().pop(); + } + } } 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 408f5a912..6f6e31ecc 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 @@ -33,6 +33,8 @@ 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}. @@ -905,6 +907,59 @@ public class DateTagTest extends AbstractTagTest { strutsBodyTagsAreReflectionEqual(tag, freshTag)); } + /** + * Artificial code coverage test for {@link DateTextFieldTag} within the DateTagTest + * 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 { + final String format = "yyyy/MM/dd hh:mm:ss"; + DateTextFieldTag dateTextFieldTag = createDateTextFieldTag(); + dateTextFieldTag.setFormat(format); + dateTextFieldTag.doStartTag(); + // Cannot call doEndTag(), as the missing datetextfield.ftl causes an exception. + dateTextFieldTag.populateParams(); + + Component bean = dateTextFieldTag.getBean(stack, request, response); + assertNotNull("DateTextField component instance is null ?", bean); + assertTrue("DateTextField component not a DateTextField ?", bean instanceof DateTextField); + + dateTextFieldTag.setPerformClearTagStateForTagPoolingServers(false); + dateTextFieldTag.clearTagStateForTagPoolingServers(); + dateTextFieldTag.setPerformClearTagStateForTagPoolingServers(true); + dateTextFieldTag.clearTagStateForTagPoolingServers(); + dateTextFieldTag.release(); + + // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after forced clearing of tag state. + DateTextFieldTag freshTag = new DateTextFieldTag(); + freshTag.setPerformClearTagStateForTagPoolingServers(true); + 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)); + } + + /** + * Utility method to create a new {@link DateTextFieldTag} instance for code coverage tests. + * + * 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. + * + * @return a basic {@link DateTextFieldTag} instance + * @throws Exception + */ + private DateTextFieldTag createDateTextFieldTag() throws Exception { + DateTextFieldTag tag = new DateTextFieldTag(); + tag.setPageContext(pageContext); + tag.setName("myDate"); + tag.setId("myDate"); + return tag; + } + @Override protected void setUp() throws Exception { super.setUp();