This is an automated email from the ASF dual-hosted git repository. lukaszlenart pushed a commit to branch fix/WW-5360-iterator in repository https://gitbox.apache.org/repos/asf/struts.git
commit 081c84bf6094d36cfb371ee5b32e1770d6c3b365 Author: Lukasz Lenart <lukaszlen...@apache.org> AuthorDate: Sun Jan 21 10:39:49 2024 +0100 WW-5360 Introduces additional countStr & indexStr to allow to ignore conversion --- .../apache/struts2/views/jsp/IteratorStatus.java | 20 ++- .../java/com/opensymphony/xwork2/test/User.java | 6 + .../test/java/org/apache/struts2/TestAction.java | 9 + .../struts2/components/IteratorComponentTest.java | 199 ++++++++++++++++++++- .../apache/struts2/views/jsp/IteratorTagTest.java | 86 ++++----- 5 files changed, 262 insertions(+), 58 deletions(-) diff --git a/core/src/main/java/org/apache/struts2/views/jsp/IteratorStatus.java b/core/src/main/java/org/apache/struts2/views/jsp/IteratorStatus.java index 13022f856..fedef363e 100644 --- a/core/src/main/java/org/apache/struts2/views/jsp/IteratorStatus.java +++ b/core/src/main/java/org/apache/struts2/views/jsp/IteratorStatus.java @@ -26,23 +26,29 @@ package org.apache.struts2.views.jsp; * <li>count: iterations so far, starts on 1. count is always index + 1</li> * <li>first: true if index == 0</li> * <li>even: true if (index + 1) % 2 == 0</li> - * <li>last: true if current iteration is the last iteration</li> + * <li>last: true if current iteration is the last iteration</li> * <li>odd: true if (index + 1) % 2 == 1</li> * </ul> * <p>Example</p> * <pre> * <s:iterator status="status" value='{0, 1}'> * Index: <s:property value="%{#status.index}" /> <br /> - * Count: <s:property value="%{#status.count}" /> <br /> + * Index Str: <s:property value="%{#status.indexStr}" /> <br /> + * Count: <s:property value="%{#status.count}" /> <br /> + * Count Str: <s:property value="%{#status.countStr}" /> <br /> * </s:iterator> * </pre> - * + * * <p>will print</p> * <pre> * Index: 0 + * Index Str: 0 * Count: 1 + * Count Str: 1 * Index: 1 + * Index Str: 1 * Count: 2 + * Count Str: 2 * </pre> */ public class IteratorStatus { @@ -56,6 +62,10 @@ public class IteratorStatus { return state.index + 1; } + public String getCountStr() { + return String.valueOf(state.index + 1); + } + public boolean isEven() { return ((state.index + 1) % 2) == 0; } @@ -68,6 +78,10 @@ public class IteratorStatus { return state.index; } + public String getIndexStr() { + return String.valueOf(state.index); + } + public boolean isLast() { return state.last; } diff --git a/core/src/test/java/com/opensymphony/xwork2/test/User.java b/core/src/test/java/com/opensymphony/xwork2/test/User.java index d377fe018..e6c5d2af4 100644 --- a/core/src/test/java/com/opensymphony/xwork2/test/User.java +++ b/core/src/test/java/com/opensymphony/xwork2/test/User.java @@ -37,6 +37,12 @@ public class User implements UserMarker { private String email2; private String name; + public User() { + } + + public User(String name) { + this.name = name; + } public void setCollection(Collection collection) { this.collection = collection; diff --git a/core/src/test/java/org/apache/struts2/TestAction.java b/core/src/test/java/org/apache/struts2/TestAction.java index 77f784a61..b9595de11 100644 --- a/core/src/test/java/org/apache/struts2/TestAction.java +++ b/core/src/test/java/org/apache/struts2/TestAction.java @@ -45,6 +45,7 @@ public class TestAction extends ActionSupport { private String result; private User user; private String[] array; + private Object[] objectArray; private String[][] list; private List list2; private List list3; @@ -135,6 +136,14 @@ public class TestAction extends ActionSupport { this.array = array; } + public Object[] getObjectArray() { + return objectArray; + } + + public void setObjectArray(Object[] arrayObject) { + this.objectArray = arrayObject; + } + public String[][] getList() { return list; } diff --git a/core/src/test/java/org/apache/struts2/components/IteratorComponentTest.java b/core/src/test/java/org/apache/struts2/components/IteratorComponentTest.java index d6cc5305d..78dd5536a 100644 --- a/core/src/test/java/org/apache/struts2/components/IteratorComponentTest.java +++ b/core/src/test/java/org/apache/struts2/components/IteratorComponentTest.java @@ -19,16 +19,20 @@ package org.apache.struts2.components; import com.opensymphony.xwork2.ActionContext; +import com.opensymphony.xwork2.test.User; import com.opensymphony.xwork2.util.ValueStack; import org.apache.struts2.StrutsInternalTestCase; +import org.apache.struts2.TestAction; import java.io.StringWriter; +import java.util.ArrayList; import java.util.Arrays; import java.util.List; +import java.util.Locale; public class IteratorComponentTest extends StrutsInternalTestCase { - public void testIterator() throws Exception { + public void testIterator() { // given final ValueStack stack = ActionContext.getContext().getValueStack(); stack.push(new FooAction()); @@ -62,7 +66,50 @@ public class IteratorComponentTest extends StrutsInternalTestCase { assertEquals("item1 item2 item3 item4 ", out.getBuffer().toString()); } - public void testIteratorWithBegin() throws Exception { + public void testSimpleIterator() { + // given + final ValueStack stack = ActionContext.getContext().getValueStack(); + stack.push(new FooAction()); + + StringWriter out = new StringWriter(); + + IteratorComponent ic = new IteratorComponent(stack); + ic.setBegin("1"); + ic.setEnd("8"); + ic.setStep("2"); + ic.setStatus("status"); + + Property prop = new Property(stack); + Property status = new Property(stack); + status.setValue("#status.index"); + + ic.getComponentStack().push(prop); + ic.getComponentStack().push(status); + ic.getComponentStack().push(prop); + ic.getComponentStack().push(status); + ic.getComponentStack().push(prop); + ic.getComponentStack().push(status); + ic.getComponentStack().push(prop); + ic.getComponentStack().push(status); + + String body = " "; + + // when + assertTrue(ic.start(out)); + + for (int i = 0; i < 4; i++) { + status.start(out); + status.end(out, body); + prop.start(out); + prop.end(out, body); + ic.end(out, null); + } + + // then + assertEquals("0 1 1 3 2 5 3 7 ", out.getBuffer().toString()); + } + + public void testIteratorWithBegin() { // given final ValueStack stack = ActionContext.getContext().getValueStack(); stack.push(new FooAction()); @@ -94,13 +141,13 @@ public class IteratorComponentTest extends StrutsInternalTestCase { assertEquals("item2 item3 item4 ", out.getBuffer().toString()); } - public void testIteratorWithNulls() throws Exception { + public void testIteratorWithNulls() { // given final ValueStack stack = ActionContext.getContext().getValueStack(); stack.push(new FooAction() { - private List items = Arrays.asList("1", "2", null, "4"); + private final List<String> items = Arrays.asList("1", "2", null, "4"); - public List getItems() { + public List<String> getItems() { return items; } }); @@ -132,15 +179,153 @@ public class IteratorComponentTest extends StrutsInternalTestCase { assertEquals("1, 2, , 4, ", out.getBuffer().toString()); } + public void testIteratorWithDifferentLocale() { + // given + ActionContext.getContext().withLocale(new Locale("fa_IR")); + final ValueStack stack = ActionContext.getContext().getValueStack(); + stack.push(new FooAction()); + + StringWriter out = new StringWriter(); + + IteratorComponent ic = new IteratorComponent(stack); + ic.setBegin("1"); + ic.setEnd("3"); + ic.setStatus("status"); + + Property prop = new Property(stack); + Property status = new Property(stack); + status.setValue("#status.count"); + + ic.getComponentStack().push(prop); + ic.getComponentStack().push(status); + ic.getComponentStack().push(prop); + ic.getComponentStack().push(status); + ic.getComponentStack().push(prop); + ic.getComponentStack().push(status); + + String body = ","; + + // when + assertTrue(ic.start(out)); + + for (int i = 0; i < 3; i++) { + status.start(out); + status.end(out, body); + + prop.start(out); + prop.end(out, body); + ic.end(out, null); + } + + // then + assertEquals("1,1,2,2,3,3,", out.getBuffer().toString()); + } + + public void testListOfBeansIterator() { + // given + final ValueStack stack = ActionContext.getContext().getValueStack(); + TestAction action = new TestAction(); + action.setList2(new ArrayList<User>() {{ + add(new User("Anton")); + add(new User("Tym")); + add(new User("Luk")); + }}); + stack.push(action); + + StringWriter out = new StringWriter(); + + IteratorComponent ic = new IteratorComponent(stack); + ic.setValue("list2"); + ic.setStatus("status"); + + Property prop = new Property(stack); + prop.setValue("name"); + Property status = new Property(stack); + status.setValue("#status.indexStr"); + + ic.getComponentStack().push(status); + ic.getComponentStack().push(prop); + ic.getComponentStack().push(status); + ic.getComponentStack().push(prop); + ic.getComponentStack().push(status); + ic.getComponentStack().push(prop); + + String body = ","; + + // when + assertTrue(ic.start(out)); + + for (int i = 0; i < 3; i++) { + status.start(out); + status.end(out, body); + + prop.start(out); + prop.end(out, body); + + ic.end(out, null); + } + + // then + assertEquals("0,Anton,1,Tym,2,Luk,", out.getBuffer().toString()); + } + + public void testArrayOfBeansIterator() { + // given + final ValueStack stack = ActionContext.getContext().getValueStack(); + TestAction action = new TestAction(); + action.setObjectArray(new ArrayList<User>() {{ + add(new User("Anton")); + add(new User("Tym")); + add(new User("Luk")); + }}.toArray()); + stack.push(action); + + StringWriter out = new StringWriter(); + + IteratorComponent ic = new IteratorComponent(stack); + ic.setValue("objectArray"); + ic.setStatus("status"); + + Property prop = new Property(stack); + prop.setValue("name"); + Property status = new Property(stack); + status.setValue("#status.countStr"); + + ic.getComponentStack().push(status); + ic.getComponentStack().push(prop); + ic.getComponentStack().push(status); + ic.getComponentStack().push(prop); + ic.getComponentStack().push(status); + ic.getComponentStack().push(prop); + + String body = " "; + + // when + assertTrue(ic.start(out)); + + for (int i = 0; i < 3; i++) { + status.start(out); + status.end(out, body); + + prop.start(out); + prop.end(out, body); + + ic.end(out, null); + } + + // then + assertEquals("1 Anton 2 Tym 3 Luk ", out.getBuffer().toString()); + } + static class FooAction { - private List items; + private final List<String> items; public FooAction() { items = Arrays.asList("item1", "item2", "item3", "item4"); } - public List getItems() { + public List<String> getItems() { return items; } } 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 df5022c0a..490b402a0 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 @@ -31,18 +31,12 @@ import java.util.HashMap; import java.util.List; import java.util.Map; - -/** - * Test Case for Iterator Tag - * - */ public class IteratorTagTest extends AbstractUITagTest { - IteratorTag tag; - + private IteratorTag tag; public void testIteratingWithIdSpecified() throws Exception { - List list = new ArrayList(); + List<String> list = new ArrayList<>(); list.add("one"); list.add("two"); list.add("three"); @@ -104,12 +98,12 @@ public class IteratorTagTest extends AbstractUITagTest { IteratorTag freshTag = new IteratorTag(); 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.", + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", strutsBodyTagsAreReflectionEqual(tag, freshTag)); } public void testIteratingWithIdSpecified_clearTagStateSet() throws Exception { - List list = new ArrayList(); + List<String> list = new ArrayList<>(); list.add("one"); list.add("two"); list.add("three"); @@ -174,12 +168,12 @@ public class IteratorTagTest extends AbstractUITagTest { freshTag.setPerformClearTagStateForTagPoolingServers(true); freshTag.setPageContext(pageContext); assertTrue("Tag state after doEndTag() and explicit tag state clearing is inequal to new Tag with pageContext/parent set. " + - "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", strutsBodyTagsAreReflectionEqual(tag, freshTag)); } public void testIteratingWithIdSpecifiedAndNullElementOnCollection() throws Exception { - List list = new ArrayList(); + List<String> list = new ArrayList<>(); list.add("one"); list.add(null); list.add("three"); @@ -224,12 +218,12 @@ public class IteratorTagTest extends AbstractUITagTest { IteratorTag freshTag = new IteratorTag(); 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.", + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", strutsBodyTagsAreReflectionEqual(tag, freshTag)); } public void testIteratingWithIdSpecifiedAndNullElementOnCollection_clearTagStateSet() throws Exception { - List list = new ArrayList(); + List<String> list = new ArrayList<>(); list.add("one"); list.add(null); list.add("three"); @@ -277,7 +271,7 @@ public class IteratorTagTest extends AbstractUITagTest { freshTag.setPerformClearTagStateForTagPoolingServers(true); freshTag.setPageContext(pageContext); assertTrue("Tag state after doEndTag() and explicit tag state clearing is inequal to new Tag with pageContext/parent set. " + - "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", strutsBodyTagsAreReflectionEqual(tag, freshTag)); } @@ -294,7 +288,7 @@ public class IteratorTagTest extends AbstractUITagTest { public void testCollectionIterator() { Foo foo = new Foo(); - ArrayList list = new ArrayList(); + List<String> list = new ArrayList<>(); list.add("test1"); list.add("test2"); list.add("test3"); @@ -314,7 +308,7 @@ public class IteratorTagTest extends AbstractUITagTest { public void testMapIterator() { Foo foo = new Foo(); - HashMap map = new HashMap(); + HashMap<String, String> map = new HashMap<>(); map.put("test1", "123"); map.put("test2", "456"); map.put("test3", "789"); @@ -382,13 +376,13 @@ public class IteratorTagTest extends AbstractUITagTest { IteratorTag freshTag = new IteratorTag(); 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.", + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", strutsBodyTagsAreReflectionEqual(tag, freshTag)); } public void testMapIterator_clearTagStateSet() { Foo foo = new Foo(); - HashMap map = new HashMap(); + HashMap<String, String> map = new HashMap<>(); map.put("test1", "123"); map.put("test2", "456"); map.put("test3", "789"); @@ -459,7 +453,7 @@ public class IteratorTagTest extends AbstractUITagTest { freshTag.setPerformClearTagStateForTagPoolingServers(true); freshTag.setPageContext(pageContext); assertTrue("Tag state after doEndTag() and explicit tag state clearing is inequal to new Tag with pageContext/parent set. " + - "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", strutsBodyTagsAreReflectionEqual(tag, freshTag)); } @@ -490,7 +484,9 @@ public class IteratorTagTest extends AbstractUITagTest { assertFalse(status.isLast()); assertTrue(status.isFirst()); assertEquals(0, status.getIndex()); + assertEquals("0", status.getIndexStr()); assertEquals(1, status.getCount()); + assertEquals("1", status.getCountStr()); assertTrue(status.isOdd()); assertFalse(status.isEven()); @@ -547,7 +543,7 @@ public class IteratorTagTest extends AbstractUITagTest { IteratorTag freshTag = new IteratorTag(); 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.", + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", strutsBodyTagsAreReflectionEqual(tag, freshTag)); } @@ -638,7 +634,7 @@ public class IteratorTagTest extends AbstractUITagTest { freshTag.setPerformClearTagStateForTagPoolingServers(true); freshTag.setPageContext(pageContext); assertTrue("Tag state after doEndTag() and explicit tag state clearing is inequal to new Tag with pageContext/parent set. " + - "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", strutsBodyTagsAreReflectionEqual(tag, freshTag)); } @@ -666,7 +662,7 @@ public class IteratorTagTest extends AbstractUITagTest { public void testEmptyCollection() { Foo foo = new Foo(); - foo.setList(new ArrayList()); + foo.setList(new ArrayList<>()); stack.push(foo); @@ -692,7 +688,7 @@ public class IteratorTagTest extends AbstractUITagTest { validateCounter(new Integer[]{0, 1, 2, 3, 4, 5}); } - public void testCounterWithStackValues() throws JspException { + public void testCounterWithStackValues() throws JspException { stack.getContext().put("begin", 0); stack.getContext().put("end", 5); tag.setBegin("%{#begin}"); @@ -702,7 +698,7 @@ public class IteratorTagTest extends AbstractUITagTest { public void testCounterWithList() throws JspException { Foo foo = new Foo(); - ArrayList list = new ArrayList(); + ArrayList<String> list = new ArrayList<>(); list.add("a"); list.add("b"); list.add("c"); @@ -720,7 +716,6 @@ public class IteratorTagTest extends AbstractUITagTest { public void testCounterWithArray() throws JspException { Foo foo = new Foo(); - ArrayList list = new ArrayList(); foo.setArray(new String[]{"a", "b", "c", "d"}); stack.push(foo); @@ -735,7 +730,7 @@ public class IteratorTagTest extends AbstractUITagTest { public void testCounterWithListNoEnd() throws JspException { Foo foo = new Foo(); - ArrayList list = new ArrayList(); + ArrayList<String> list = new ArrayList<>(); list.add("a"); list.add("b"); list.add("c"); @@ -752,7 +747,6 @@ public class IteratorTagTest extends AbstractUITagTest { public void testCounterWithArrayNoEnd() throws JspException { Foo foo = new Foo(); - ArrayList list = new ArrayList(); foo.setArray(new String[]{"a", "b", "c", "d"}); stack.push(foo); @@ -765,7 +759,7 @@ public class IteratorTagTest extends AbstractUITagTest { public void testCounterWithList2() throws JspException { Foo foo = new Foo(); - ArrayList list = new ArrayList(); + ArrayList<String> list = new ArrayList<>(); list.add("a"); list.add("b"); list.add("c"); @@ -783,7 +777,6 @@ public class IteratorTagTest extends AbstractUITagTest { public void testCounterWithArray2() throws JspException { Foo foo = new Foo(); - ArrayList list = new ArrayList(); foo.setArray(new String[]{"a", "b", "c", "d"}); stack.push(foo); @@ -797,7 +790,7 @@ public class IteratorTagTest extends AbstractUITagTest { public void testCounterWithListNoEnd2() throws JspException { Foo foo = new Foo(); - ArrayList list = new ArrayList(); + ArrayList<String> list = new ArrayList<>(); list.add("a"); list.add("b"); list.add("c"); @@ -812,9 +805,8 @@ public class IteratorTagTest extends AbstractUITagTest { validateCounter(new String[]{"c", "d"}); } - public void testCounterWithArrayNoEnd2() throws JspException { + public void testCounterWithArrayNoEnd2() throws JspException { Foo foo = new Foo(); - ArrayList list = new ArrayList(); foo.setArray(new String[]{"a", "b", "c", "d"}); stack.push(foo); @@ -838,9 +830,9 @@ public class IteratorTagTest extends AbstractUITagTest { validateCounter(new Integer[]{0, 2, 4}); } - public void testCounterWithListAndStep() throws JspException { + public void testCounterWithListAndStep() throws JspException { Foo foo = new Foo(); - ArrayList list = new ArrayList(); + ArrayList<String> list = new ArrayList<>(); list.add("a"); list.add("b"); list.add("c"); @@ -858,9 +850,8 @@ public class IteratorTagTest extends AbstractUITagTest { validateCounter(new String[]{"a", "c"}); } - public void testCounterWithArrayAndStep() throws JspException { + public void testCounterWithArrayAndStep() throws JspException { Foo foo = new Foo(); - ArrayList list = new ArrayList(); foo.setArray(new String[]{"a", "b", "c", "d"}); stack.push(foo); @@ -876,7 +867,7 @@ public class IteratorTagTest extends AbstractUITagTest { public void testCounterWithListAndStepNoEnd() throws JspException { Foo foo = new Foo(); - ArrayList list = new ArrayList(); + ArrayList<String> list = new ArrayList<>(); list.add("a"); list.add("b"); list.add("c"); @@ -895,7 +886,6 @@ public class IteratorTagTest extends AbstractUITagTest { public void testCounterWithArrayAndStepNoEnd() throws JspException { Foo foo = new Foo(); - ArrayList list = new ArrayList(); foo.setArray(new String[]{"a", "b", "c", "d"}); stack.push(foo); @@ -917,7 +907,7 @@ public class IteratorTagTest extends AbstractUITagTest { public void testCounterWithListAndNegativeStep() throws JspException { Foo foo = new Foo(); - ArrayList list = new ArrayList(); + ArrayList<String> list = new ArrayList<>(); list.add("a"); list.add("b"); list.add("c"); @@ -937,7 +927,7 @@ public class IteratorTagTest extends AbstractUITagTest { public void testCounterWithListAndNegativeStepNoEnd() throws JspException { Foo foo = new Foo(); - ArrayList list = new ArrayList(); + ArrayList<String> list = new ArrayList<>(); list.add("a"); list.add("b"); list.add("c"); @@ -954,9 +944,9 @@ public class IteratorTagTest extends AbstractUITagTest { validateCounter(new String[]{"d", "c", "b", "a"}); } - public void testCounterWithArrayAndNegativeStep() throws JspException { + public void testCounterWithArrayAndNegativeStep() throws JspException { Foo foo = new Foo(); - ArrayList list = new ArrayList(); + ArrayList<String> list = new ArrayList<>(); list.add("a"); list.add("b"); list.add("c"); @@ -976,7 +966,7 @@ public class IteratorTagTest extends AbstractUITagTest { public void testCounterWithArrayAndNegativeStepNoEnd() throws JspException { Foo foo = new Foo(); - ArrayList list = new ArrayList(); + ArrayList<String> list = new ArrayList<>(); list.add("a"); list.add("b"); list.add("c"); @@ -994,7 +984,7 @@ public class IteratorTagTest extends AbstractUITagTest { } protected void validateCounter(Object[] expectedValues) throws JspException { - List values = new ArrayList(); + ArrayList<Object> values = new ArrayList<>(); try { int result = tag.doStartTag(); assertEquals(TagSupport.EVAL_BODY_INCLUDE, result); @@ -1098,11 +1088,11 @@ public class IteratorTagTest extends AbstractUITagTest { IteratorTag freshTag = new IteratorTag(); 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.", + "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.", strutsBodyTagsAreReflectionEqual(tag, freshTag)); } - class Foo { + static class Foo { private Collection list; private Map map; private String[] array; @@ -1132,7 +1122,7 @@ public class IteratorTagTest extends AbstractUITagTest { } } - class TestMockBodyContent extends MockBodyContent { + static class TestMockBodyContent extends MockBodyContent { public String getString() { return ".-."; }