diff --git a/src/fr/devinsy/xidyn/data/DisplayMode.java b/src/fr/devinsy/xidyn/data/DisplayMode.java
new file mode 100644
index 0000000..fe9218c
--- /dev/null
+++ b/src/fr/devinsy/xidyn/data/DisplayMode.java
@@ -0,0 +1,29 @@
+/*
+ * Copyright (C) 2006-2017,2020 Christian Pierre MOMON
+ *
+ * This file is part of Xidyn.
+ *
+ * Xidyn is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Xidyn is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with Xidyn. If not, see
+ */
+package fr.devinsy.xidyn.data;
+
+/**
+ * The Enum DisplayMode.
+ */
+public enum DisplayMode
+{
+ REPLACE,
+ APPEND,
+ IGNORE
+};
diff --git a/src/fr/devinsy/xidyn/data/SimpleTagData.java b/src/fr/devinsy/xidyn/data/SimpleTagData.java
index a0d553c..1afd821 100644
--- a/src/fr/devinsy/xidyn/data/SimpleTagData.java
+++ b/src/fr/devinsy/xidyn/data/SimpleTagData.java
@@ -20,6 +20,8 @@ package fr.devinsy.xidyn.data;
import java.io.Serializable;
+import fr.devinsy.strings.StringsUtils;
+
/**
* The Class SimpleTagData.
*
@@ -47,17 +49,10 @@ public class SimpleTagData implements Serializable, TagData
ALL_ROWS
}
- public enum MODE
- {
- REPLACE,
- APPEND,
- IGNORE
- };
-
- private IterationStrategy iterationStrategy;
+ IterationStrategy iterationStrategy;
private TagAttributes attributes;
private boolean excludeSection;
- private MODE displayMode = MODE.REPLACE;
+ private DisplayMode displayMode = DisplayMode.REPLACE;
private String content;
/**
@@ -65,11 +60,7 @@ public class SimpleTagData implements Serializable, TagData
*/
public SimpleTagData()
{
- this.attributes = null;
- this.excludeSection = false;
- this.displayMode = MODE.REPLACE;
- this.content = null;
- this.iterationStrategy = IterationStrategy.ALL_ROWS;
+ this(null);
}
/**
@@ -80,9 +71,9 @@ public class SimpleTagData implements Serializable, TagData
*/
public SimpleTagData(final String text)
{
- this.attributes = null;
+ this.attributes = new TagAttributes();
this.excludeSection = false;
- this.displayMode = MODE.REPLACE;
+ this.displayMode = DisplayMode.REPLACE;
this.content = text;
this.iterationStrategy = IterationStrategy.ALL_ROWS;
}
@@ -127,40 +118,20 @@ public class SimpleTagData implements Serializable, TagData
{
TagAttributes result;
- if (this.attributes == null)
- {
- this.attributes = new TagAttributes();
- }
-
result = this.attributes;
//
return result;
}
- /**
- * Display.
- *
- * @return the string
- */
- public String display()
- {
- String result;
-
- result = this.content;
-
- //
- return result;
- }
-
/**
* Display mode.
*
* @return the mode
*/
- public MODE displayMode()
+ public DisplayMode displayMode()
{
- MODE result;
+ DisplayMode result;
result = this.displayMode;
@@ -189,11 +160,76 @@ public class SimpleTagData implements Serializable, TagData
* the label
* @return the attribute
*/
- public String getAttribute(final String label)
+ public TagAttribute getAttribute(final String label)
+ {
+ TagAttribute result;
+
+ result = this.attributes.getAttribute(label);
+
+ //
+ return result;
+ }
+
+ /**
+ * Gets the attribute mode.
+ *
+ * @param label
+ * the label
+ * @return the attribute mode
+ */
+ public DisplayMode getAttributeMode(final String label)
+ {
+ DisplayMode result;
+
+ TagAttribute attribute = this.attributes.get(label);
+ if (attribute == null)
+ {
+ result = null;
+ }
+ else
+ {
+ result = attribute.getMode();
+ }
+
+ //
+ return result;
+ }
+
+ /**
+ * Gets the attribute value.
+ *
+ * @param label
+ * the label
+ * @return the attribute value
+ */
+ public String getAttributeValue(final String label)
{
String result;
- result = this.attributes.getAttribute(label);
+ TagAttribute attribute = this.attributes.get(label);
+ if (attribute == null)
+ {
+ result = null;
+ }
+ else
+ {
+ result = attribute.getValue();
+ }
+
+ //
+ return result;
+ }
+
+ /**
+ * Display.
+ *
+ * @return the string
+ */
+ public String getContent()
+ {
+ String result;
+
+ result = this.content;
//
return result;
@@ -224,7 +260,66 @@ public class SimpleTagData implements Serializable, TagData
*/
public void setAttribute(final String label, final String value)
{
- this.attributes.put(label, value);
+ if (this.attributes.containsKey(label))
+ {
+ this.attributes.get(label).setValue(value);
+ }
+ else
+ {
+ if (StringsUtils.containsAnyIgnoreCase(label, "style", "class"))
+ {
+ this.attributes.put(label, new TagAttribute(label, value, DisplayMode.APPEND));
+ }
+ else
+ {
+ this.attributes.put(label, new TagAttribute(label, value));
+ }
+ }
+ }
+
+ /**
+ * Sets the attribute.
+ *
+ * @param label
+ * the label
+ * @param value
+ * the value
+ * @param mode
+ * the mode
+ */
+ public void setAttribute(final String label, final String value, final DisplayMode mode)
+ {
+ if (this.attributes.containsKey(label))
+ {
+ TagAttribute attribute = this.attributes.get(label);
+ attribute.setValue(value);
+ attribute.setMode(mode);
+ }
+ else
+ {
+ this.attributes.put(label, new TagAttribute(label, value, mode));
+ }
+ }
+
+ /**
+ * Sets the attribute mode.
+ *
+ * @param label
+ * the label
+ * @param mode
+ * the mode
+ */
+ public void setAttributeMode(final String label, final DisplayMode mode)
+ {
+ if (this.attributes.containsKey(label))
+ {
+ this.attributes.get(label).setMode(mode);
+ }
+ else
+ {
+ TagAttribute tag = new TagAttribute(label, null, mode);
+ this.attributes.put(label, tag);
+ }
}
/**
@@ -244,7 +339,7 @@ public class SimpleTagData implements Serializable, TagData
* @param displayMode
* the new display mode
*/
- public void setDisplayMode(final MODE displayMode)
+ public void setDisplayMode(final DisplayMode displayMode)
{
this.displayMode = displayMode;
}
diff --git a/src/fr/devinsy/xidyn/data/TagAttribute.java b/src/fr/devinsy/xidyn/data/TagAttribute.java
new file mode 100644
index 0000000..24ba9e9
--- /dev/null
+++ b/src/fr/devinsy/xidyn/data/TagAttribute.java
@@ -0,0 +1,113 @@
+/*
+ * Copyright (C) 2020 Christian Pierre MOMON
+ *
+ * This file is part of Xidyn.
+ *
+ * Xidyn is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Xidyn is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with Xidyn. If not, see
+ */
+package fr.devinsy.xidyn.data;
+
+/**
+ * The Class TagAttribute.
+ */
+public class TagAttribute
+{
+ private DisplayMode mode;
+ private String label;
+ private String value;
+
+ /**
+ * Instantiates a new tag attribute.
+ *
+ * @param value
+ * the value
+ */
+ public TagAttribute(final String label, final String value)
+ {
+ this(label, value, DisplayMode.REPLACE);
+ }
+
+ /**
+ * Instantiates a new tag attribute.
+ *
+ * @param label
+ * the label
+ * @param value
+ * the value
+ * @param mode
+ * the mode
+ */
+ public TagAttribute(final String label, final String value, final DisplayMode mode)
+ {
+ this.mode = mode;
+ this.label = label;
+ this.value = value;
+ }
+
+ /**
+ * Append value.
+ *
+ * @param value
+ * the value
+ */
+ public void appendValue(final String value)
+ {
+ if (this.value == null)
+ {
+ this.value = value;
+ }
+ else
+ {
+ this.value = this.value + " " + value;
+ }
+ }
+
+ public String getLabel()
+ {
+ return this.label;
+ }
+
+ public DisplayMode getMode()
+ {
+ return this.mode;
+ }
+
+ public String getValue()
+ {
+ return this.value;
+ }
+
+ /**
+ * Sets the mode.
+ *
+ * @param mode
+ * the new mode
+ */
+ public void setMode(final DisplayMode mode)
+ {
+ if (mode == null)
+ {
+ throw new IllegalArgumentException("Null parameter.");
+ }
+ else
+ {
+ this.mode = mode;
+ }
+ }
+
+ public void setValue(final String value)
+ {
+ this.value = value;
+ }
+}
diff --git a/src/fr/devinsy/xidyn/data/TagAttributes.java b/src/fr/devinsy/xidyn/data/TagAttributes.java
index 0fcfdb9..d7e2c47 100644
--- a/src/fr/devinsy/xidyn/data/TagAttributes.java
+++ b/src/fr/devinsy/xidyn/data/TagAttributes.java
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2006-2017 Christian Pierre MOMON
+ * Copyright (C) 2006-2017,2020 Christian Pierre MOMON
*
* This file is part of Xidyn.
*
@@ -19,6 +19,7 @@
package fr.devinsy.xidyn.data;
import java.util.HashMap;
+import java.util.Iterator;
/**
* The Class TagAttributes.
@@ -26,8 +27,7 @@ import java.util.HashMap;
* Note: no more AttrValue as in Brill, because the exception of style is
* managed in the attribute merging on the "style" string detection.
*/
-
-public class TagAttributes extends HashMap
+public class TagAttributes extends HashMap implements Iterable
{
private static final long serialVersionUID = 2802739066295665336L;
@@ -62,11 +62,11 @@ public class TagAttributes extends HashMap
{
if (this.containsKey(label))
{
- this.put(label, this.get(label) + " " + value);
+ this.get(label).appendValue(value);
}
else
{
- this.put(label, value);
+ this.put(label, new TagAttribute(label, value));
}
}
@@ -77,9 +77,9 @@ public class TagAttributes extends HashMap
* the label
* @return the attribute
*/
- public String getAttribute(final String label)
+ public TagAttribute getAttribute(final String label)
{
- String result;
+ TagAttribute result;
if (this.containsKey(label))
{
@@ -95,15 +95,18 @@ public class TagAttributes extends HashMap
}
/**
- * Sets the attribute.
+ * Iterator.
*
- * @param label
- * the label
- * @param value
- * the value
+ * @return the iterator
*/
- public void setAttribute(final String label, final String value)
+ @Override
+ public Iterator iterator()
{
- this.put(label, value);
+ Iterator result;
+
+ result = this.values().iterator();
+
+ //
+ return result;
}
}
diff --git a/src/fr/devinsy/xidyn/data/TagDataManager.java b/src/fr/devinsy/xidyn/data/TagDataManager.java
index ed50eb4..9e27a10 100644
--- a/src/fr/devinsy/xidyn/data/TagDataManager.java
+++ b/src/fr/devinsy/xidyn/data/TagDataManager.java
@@ -428,7 +428,7 @@ public class TagDataManager
{
SimpleTagData tag = this.getIdData(id);
- tag.attributes().setAttribute("class", DomPresenterCore.NODISPLAY_CLASS);
+ tag.setAttribute("class", DomPresenterCore.NODISPLAY_CLASS);
}
/**
@@ -464,7 +464,7 @@ public class TagDataManager
{
SimpleTagData tag = this.getIdData(id, line);
- tag.attributes().setAttribute(label, value);
+ tag.setAttribute(label, value);
}
/**
@@ -504,7 +504,7 @@ public class TagDataManager
{
SimpleTagData tag = this.getIdData(id, line, column);
- tag.attributes().setAttribute(label, value);
+ tag.setAttribute(label, value);
}
/**
@@ -536,7 +536,7 @@ public class TagDataManager
{
SimpleTagData tag = this.getIdData(id);
- tag.attributes().setAttribute(label, value);
+ tag.setAttribute(label, value);
}
/**
diff --git a/src/fr/devinsy/xidyn/demo/XidynDemo.java b/src/fr/devinsy/xidyn/demo/XidynDemo.java
index bc60b16..a492a5c 100644
--- a/src/fr/devinsy/xidyn/demo/XidynDemo.java
+++ b/src/fr/devinsy/xidyn/demo/XidynDemo.java
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2006-2018 Christian Pierre MOMON
+ * Copyright (C) 2006-2018,2020 Christian Pierre MOMON
*
* This file is part of Xidyn.
*
@@ -73,7 +73,7 @@ class XidynDemo
}
catch (Exception exception)
{
- System.out.println(exception.getMessage());
+ System.out.println("Demo failed: " + exception.getMessage());
exception.printStackTrace();
}
}
@@ -107,7 +107,8 @@ class XidynDemo
}
catch (Exception exception)
{
- System.out.println(exception.getMessage());
+ System.out.println("Demo failed: " + exception.getMessage());
+ exception.printStackTrace();
}
}
@@ -148,7 +149,8 @@ class XidynDemo
}
catch (Exception exception)
{
- System.out.println(exception.getMessage());
+ System.out.println("Demo failed: " + exception.getMessage());
+ exception.printStackTrace();
}
}
@@ -190,7 +192,8 @@ class XidynDemo
}
catch (Exception exception)
{
- System.out.println(exception.getMessage());
+ System.out.println("Demo failed: " + exception.getMessage());
+ exception.printStackTrace();
}
}
diff --git a/src/fr/devinsy/xidyn/presenters/DomPresenterCore.java b/src/fr/devinsy/xidyn/presenters/DomPresenterCore.java
index 1614517..bdf1424 100644
--- a/src/fr/devinsy/xidyn/presenters/DomPresenterCore.java
+++ b/src/fr/devinsy/xidyn/presenters/DomPresenterCore.java
@@ -34,7 +34,9 @@ import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import fr.devinsy.xidyn.XidynException;
+import fr.devinsy.xidyn.data.DisplayMode;
import fr.devinsy.xidyn.data.SimpleTagData;
+import fr.devinsy.xidyn.data.TagAttribute;
import fr.devinsy.xidyn.data.TagAttributes;
import fr.devinsy.xidyn.data.TagData;
import fr.devinsy.xidyn.data.TagDataListById;
@@ -349,26 +351,26 @@ public class DomPresenterCore
// Put model attributes in the merged attributes list.
if (dataAttributes != null)
{
- Iterator> iterator = dataAttributes.entrySet().iterator();
-
- while (iterator.hasNext())
+ for (TagAttribute attribute : dataAttributes)
{
- Map.Entry attribute = iterator.next();
-
- if (mergedAttributes.containsKey(attribute.getKey()))
+ if (mergedAttributes.containsKey(attribute.getLabel()))
{
- if (attribute.getKey().equalsIgnoreCase("style"))
+ if (attribute.getMode() == DisplayMode.APPEND)
{
- mergedAttributes.put(attribute.getKey(), mergedAttributes.get(attribute.getKey()) + attribute.getValue());
+ mergedAttributes.put(attribute.getLabel(), mergedAttributes.get(attribute.getLabel()) + " " + attribute.getValue());
+ }
+ else if (attribute.getMode() == DisplayMode.REPLACE)
+ {
+ mergedAttributes.put(attribute.getLabel(), attribute.getValue());
}
else
{
- mergedAttributes.put(attribute.getKey(), attribute.getValue());
+ // Keep the already merged value.
}
}
else
{
- mergedAttributes.put(attribute.getKey(), attribute.getValue());
+ mergedAttributes.put(attribute.getLabel(), attribute.getValue());
}
}
}
@@ -619,7 +621,7 @@ public class DomPresenterCore
{
SimpleTagData data = (SimpleTagData) dataCore;
- String theClass = data.attributes().getAttribute("class");
+ String theClass = data.getAttributeValue("class");
if ((theClass == null) || (!theClass.equals(NODISPLAY_CLASS)))
{
@@ -630,7 +632,7 @@ public class DomPresenterCore
// Build attributes.
result.append(processAttributes(attrs, data.attributes(), suffix));
- if (((node.getChildNodes() == null) || (node.getChildNodes().getLength() == 0)) && ((data == null) || (data.display() == null)))
+ if (((node.getChildNodes() == null) || (node.getChildNodes().getLength() == 0)) && ((data == null) || (data.getContent() == null)))
{
// Close the tag.
result.append(" />");
@@ -639,16 +641,14 @@ public class DomPresenterCore
{
result.append('>');
- // CHANGED, cpm:
-
// Insert data.
- if ((data == null) || (data.display() == null))
+ if ((data == null) || (data.getContent() == null))
{
processChildren(result, node, datas, suffix);
}
else
{
- result.append(data.display());
+ result.append(data.getContent());
}
// Close the tag.
@@ -662,20 +662,20 @@ public class DomPresenterCore
{
TagDataListByIndex tags = (TagDataListByIndex) dataCore;
- int nbLines = tags.size();
- for (int nLine = 0; nLine < nbLines; nLine++)
+ int lineCount = tags.size();
+ for (int lineIndex = 0; lineIndex < lineCount; lineIndex++)
{
- if (tags.elementAt(nLine) instanceof SimpleTagData)
+ if (tags.elementAt(lineIndex) instanceof SimpleTagData)
{
- SimpleTagData data = (SimpleTagData) tags.elementAt(nLine);
+ SimpleTagData data = (SimpleTagData) tags.elementAt(lineIndex);
// Open the tag.
result.append("<");
result.append(node.getNodeName());
- result.append(processAttributes(attrs, data.attributes(), Integer.toString(nLine)));
+ result.append(processAttributes(attrs, data.attributes(), Integer.toString(lineIndex)));
- if (((node.getChildNodes() == null) || (node.getChildNodes().getLength() == 0)) && ((data == null) || (data.display() == null)))
+ if (((node.getChildNodes() == null) || (node.getChildNodes().getLength() == 0)) && ((data == null) || (data.getContent() == null)))
{
// Close the tag.
result.append(" />\n");
@@ -687,13 +687,13 @@ public class DomPresenterCore
// CHANGED, cpm
// Insert data.
- if ((data == null) || (data.display() == null))
+ if ((data == null) || (data.getContent() == null))
{
processChildren(result, node, datas, suffix);
}
else
{
- result.append(data.display());
+ result.append(data.getContent());
}
// Close the tag.
@@ -705,9 +705,9 @@ public class DomPresenterCore
else
{
// Manage a Hashmap.
- TagDataListById data = (TagDataListById) tags.elementAt(nLine);
+ TagDataListById data = (TagDataListById) tags.elementAt(lineIndex);
- processElementWithId(result, node, attrs, idAttr, data, Integer.toString(nLine));
+ processElementWithId(result, node, attrs, idAttr, data, Integer.toString(lineIndex));
result.append('\n');
}
}
diff --git a/test/fr/devinsy/xidyn/data/TagDataManagerTest.java b/test/fr/devinsy/xidyn/data/TagDataManagerTest.java
index 3ea9c3f..24e0738 100644
--- a/test/fr/devinsy/xidyn/data/TagDataManagerTest.java
+++ b/test/fr/devinsy/xidyn/data/TagDataManagerTest.java
@@ -67,4 +67,192 @@ public class TagDataManagerTest
Assertions.assertThat(target).isEqualTo(source);
}
+
+ /**
+ * Test 03.
+ *
+ * @throws Exception
+ * the exception
+ */
+ @Test
+ public void test03a() throws Exception
+ {
+ String source = "FOOO";
+
+ TagDataManager data = new TagDataManager();
+ data.setAttribute("foo", "class", "goodClass");
+
+ String target = PresenterUtils.dynamize(source, data).toString();
+
+ String goal = "FOOO";
+
+ Assertions.assertThat(target).isEqualTo(goal);
+ }
+
+ /**
+ * Test 04.
+ *
+ * @throws Exception
+ * the exception
+ */
+ @Test
+ public void test03b() throws Exception
+ {
+ String source = "FOOO";
+
+ TagDataManager data = new TagDataManager();
+ data.setAttribute("foo", "class", "goodClass");
+ data.getIdData("foo").setAttributeMode("class", DisplayMode.APPEND);
+ String target = PresenterUtils.dynamize(source, data).toString();
+
+ String goal = "FOOO";
+
+ Assertions.assertThat(target).isEqualTo(goal);
+ }
+
+ /**
+ * Test 05.
+ *
+ * @throws Exception
+ * the exception
+ */
+ @Test
+ public void test03c() throws Exception
+ {
+ String source = "FOOO";
+
+ TagDataManager data = new TagDataManager();
+ data.setAttribute("foo", "class", "goodClass");
+ data.getIdData("foo").setAttributeMode("class", DisplayMode.REPLACE);
+
+ String target = PresenterUtils.dynamize(source, data).toString();
+
+ String goal = "FOOO";
+
+ Assertions.assertThat(target).isEqualTo(goal);
+ }
+
+ /**
+ * Test 06.
+ *
+ * @throws Exception
+ * the exception
+ */
+ @Test
+ public void test06a() throws Exception
+ {
+ String source = "FOOO";
+
+ TagDataManager data = new TagDataManager();
+ data.setAttribute("foo", "style", "goodStyle;");
+
+ String target = PresenterUtils.dynamize(source, data).toString();
+
+ String goal = "FOOO";
+
+ Assertions.assertThat(target).isEqualTo(goal);
+ }
+
+ @Test
+ public void test06b() throws Exception
+ {
+ String source = "FOOO";
+
+ TagDataManager data = new TagDataManager();
+ data.setAttribute("foo", "style", "goodStyle;");
+ data.getIdData("foo").setAttributeMode("style", DisplayMode.APPEND);
+
+ String target = PresenterUtils.dynamize(source, data).toString();
+
+ String goal = "FOOO";
+
+ Assertions.assertThat(target).isEqualTo(goal);
+ }
+
+ /**
+ * Test 06 c.
+ *
+ * @throws Exception
+ * the exception
+ */
+ @Test
+ public void test06c() throws Exception
+ {
+ String source = "FOOO";
+
+ TagDataManager data = new TagDataManager();
+ data.setAttribute("foo", "style", "goodStyle;");
+ data.getIdData("foo").setAttributeMode("style", DisplayMode.REPLACE);
+
+ String target = PresenterUtils.dynamize(source, data).toString();
+
+ String goal = "FOOO";
+
+ Assertions.assertThat(target).isEqualTo(goal);
+ }
+
+ /**
+ * Test 9a.
+ *
+ * @throws Exception
+ * the exception
+ */
+ @Test
+ public void test09a() throws Exception
+ {
+ String source = "FOOO";
+
+ TagDataManager data = new TagDataManager();
+ data.setAttribute("foo", "name", "good;");
+
+ String target = PresenterUtils.dynamize(source, data).toString();
+
+ String goal = "FOOO";
+
+ Assertions.assertThat(target).isEqualTo(goal);
+ }
+
+ /**
+ * Test 9 b.
+ *
+ * @throws Exception
+ * the exception
+ */
+ @Test
+ public void test09b() throws Exception
+ {
+ String source = "FOOO";
+
+ TagDataManager data = new TagDataManager();
+ data.setAttribute("foo", "name", "good;");
+ data.getIdData("foo").setAttributeMode("name", DisplayMode.REPLACE);
+
+ String target = PresenterUtils.dynamize(source, data).toString();
+
+ String goal = "FOOO";
+
+ Assertions.assertThat(target).isEqualTo(goal);
+ }
+
+ /**
+ * Test 9 c.
+ *
+ * @throws Exception
+ * the exception
+ */
+ @Test
+ public void test09c() throws Exception
+ {
+ String source = "FOOO";
+
+ TagDataManager data = new TagDataManager();
+ data.setAttribute("foo", "name", "good;");
+ data.getIdData("foo").setAttributeMode("name", DisplayMode.APPEND);
+
+ String target = PresenterUtils.dynamize(source, data).toString();
+
+ String goal = "FOOO";
+
+ Assertions.assertThat(target).isEqualTo(goal);
+ }
}