diff --git a/google-http-client-xml/src/test/java/com/google/api/client/xml/XmlEnumTest.java b/google-http-client-xml/src/test/java/com/google/api/client/xml/XmlEnumTest.java index 1e0d79182..b31a64c74 100644 --- a/google-http-client-xml/src/test/java/com/google/api/client/xml/XmlEnumTest.java +++ b/google-http-client-xml/src/test/java/com/google/api/client/xml/XmlEnumTest.java @@ -1,15 +1,23 @@ package com.google.api.client.xml; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; import java.io.ByteArrayOutputStream; import java.io.StringReader; import java.util.ArrayList; +import org.junit.Test; import org.xmlpull.v1.XmlPullParser; import org.xmlpull.v1.XmlSerializer; import com.google.api.client.util.Key; import com.google.api.client.util.Value; -import junit.framework.TestCase; -public class XmlEnumTest extends TestCase { +/** + * Tests {@link Xml}. + * + * @author Gerald Madlmayr + */ +public class XmlEnumTest { public enum AnyEnum { @Value ENUM_1, @@ -50,14 +58,21 @@ public static class ValueType { "" + "ENUM_2contentrep1rep2ENUM_1"; - private static final String XML_ENUM_ELEMENT_ONLY = "ENUM_2"; + private static final String XML_ENUM_ELEMENT_ONLY = + "ENUM_2"; - private static final String XML_ENUM_ATTRIBUTE_ONLY = ""; + private static final String XML_ENUM_ATTRIBUTE_ONLY = + ""; - private static final String XML_ENUM_INCORRECT = "ENUM_3"; + private static final String XML_ENUM_INCORRECT = + "ENUM_3"; + private static final String XML_ENUM_ELEMENT_ONLY_NESTED = + "ENUM_2something"; + @SuppressWarnings("cast") + @Test public void testParse_anyType() throws Exception { AnyType xml = new AnyType(); XmlPullParser parser = Xml.createParser(); @@ -82,10 +97,34 @@ public void testParse_anyType() throws Exception { assertEquals(XML, out.toString()); } - public void testParse_enumElementType() throws Exception { - XmlEnumTest.AnyTypeEnumElementOnly xml = new XmlEnumTest.AnyTypeEnumElementOnly(); + /** + * The purpose of this test is to parse an XML element to an objects's member variable + */ + @Test + public void testParseToEnumElementType() throws Exception { + assertEquals(XML_ENUM_ELEMENT_ONLY, testStandardXml(XML_ENUM_ELEMENT_ONLY)); + } + + + /** + * The purpose of this test is to parse an XML element to an objects's member variable, whereas + * there are additional nested elements in the tag. + */ + @Test + public void testParseToEnumElementTypeWithNestedElement() throws Exception { + assertEquals(XML_ENUM_ELEMENT_ONLY, testStandardXml(XML_ENUM_ELEMENT_ONLY_NESTED)); + } + + /** + * Private Method to handle standard parsing and mapping to {@link AnyTypeEnumElementOnly} + * @param xmlString XML String that needs to be mapped to {@link AnyTypeEnumElementOnly} + * @return Returns the serialized string of the XML Objects + * @throws Exception + */ + private String testStandardXml(final String xmlString) throws Exception { + AnyTypeEnumElementOnly xml = new AnyTypeEnumElementOnly(); XmlPullParser parser = Xml.createParser(); - parser.setInput(new StringReader(XML_ENUM_ELEMENT_ONLY)); + parser.setInput(new StringReader(xmlString)); XmlNamespaceDictionary namespaceDictionary = new XmlNamespaceDictionary(); Xml.parseElement(parser, xml, namespaceDictionary, null); assertTrue(xml.elementEnum instanceof XmlEnumTest.AnyEnum); @@ -95,9 +134,14 @@ public void testParse_enumElementType() throws Exception { ByteArrayOutputStream out = new ByteArrayOutputStream(); serializer.setOutput(out, "UTF-8"); namespaceDictionary.serialize(serializer, "any", xml); - assertEquals(XML_ENUM_ELEMENT_ONLY, out.toString()); + return out.toString(); + } + /** + * The purpose of this test is to parse an XML attribute to an objects's member variable + */ + @Test public void testParse_enumAttributeType() throws Exception { XmlEnumTest.AnyTypeEnumAttributeOnly xml = new XmlEnumTest.AnyTypeEnumAttributeOnly(); XmlPullParser parser = Xml.createParser(); @@ -114,6 +158,11 @@ public void testParse_enumAttributeType() throws Exception { assertEquals(XML_ENUM_ATTRIBUTE_ONLY, out.toString()); } + /** + * The purpose of this test is to parse an XML element to an objects's member variable, whereas + * the enumeration element does not exist. + */ + @Test public void testParse_enumElementTypeIncorrect() throws Exception { XmlEnumTest.AnyTypeEnumElementOnly xml = new XmlEnumTest.AnyTypeEnumElementOnly(); XmlPullParser parser = Xml.createParser(); @@ -126,7 +175,5 @@ public void testParse_enumElementTypeIncorrect() throws Exception { } catch (final IllegalArgumentException e){ assertEquals("given enum name ENUM_3 not part of enumeration", e.getMessage()); } - } - } diff --git a/google-http-client-xml/src/test/java/com/google/api/client/xml/XmlListTest.java b/google-http-client-xml/src/test/java/com/google/api/client/xml/XmlListTest.java new file mode 100644 index 000000000..f82dcbd0e --- /dev/null +++ b/google-http-client-xml/src/test/java/com/google/api/client/xml/XmlListTest.java @@ -0,0 +1,350 @@ +package com.google.api.client.xml; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertTrue; +import java.io.ByteArrayOutputStream; +import java.io.StringReader; +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; +import java.util.Map; +import org.junit.Ignore; +import org.junit.Test; +import org.xmlpull.v1.XmlPullParser; +import org.xmlpull.v1.XmlSerializer; +import com.google.api.client.util.ArrayMap; +import com.google.api.client.util.Key; + + +/** + * Tests {@link Xml}. + * + * @author Gerald Madlmayr + */ +public class XmlListTest { + + public static class ArrayWithClassType { + @Key + public XmlTest.AnyType[] rep; + } + + public static class CollectionWithClassType { + @Key + public Collection rep; + } + + + private static final String MULTI_TYPE_WITH_CLASS_TYPE = + "" + + "content1rep10rep11value1" + + "content2rep20rep21value2" + + "content3rep30rep31value3" + + ""; + + /** + * The purpose of this test is to map an XML with an array of Objects correctly. + */ + @Test + public void testParseArrayTypeWithClassType() throws Exception { + ArrayWithClassType xml = new ArrayWithClassType(); + XmlPullParser parser = Xml.createParser(); + parser.setInput(new StringReader(MULTI_TYPE_WITH_CLASS_TYPE)); + XmlNamespaceDictionary namespaceDictionary = new XmlNamespaceDictionary(); + Xml.parseElement(parser, xml, namespaceDictionary, null); + // check type + assertTrue(xml.rep instanceof XmlTest.AnyType[]); + XmlTest.AnyType[] rep = xml.rep; + assertNotNull(rep); + assertEquals(3, rep.length); + ArrayList> elem0 = (ArrayList>) rep[0].elem; + assertEquals(1, elem0.size()); + assertEquals("content1", elem0.get(0).get("text()")); + ArrayList> elem1 = (ArrayList>) rep[1].elem; + assertEquals(1, elem1.size()); + assertEquals("content2", elem1.get(0).get("text()")); + ArrayList> elem2 = (ArrayList>) rep[2].elem; + assertEquals(1, elem2.size()); + assertEquals("content3", elem2.get(0).get("text()")); + + // serialize + XmlSerializer serializer = Xml.createSerializer(); + ByteArrayOutputStream out = new ByteArrayOutputStream(); + serializer.setOutput(out, "UTF-8"); + namespaceDictionary.serialize(serializer, "any", xml); + assertEquals(MULTI_TYPE_WITH_CLASS_TYPE, out.toString()); + } + + @Test + public void testParseCollectionWithClassType() throws Exception { + CollectionWithClassType xml = new CollectionWithClassType(); + XmlPullParser parser = Xml.createParser(); + parser.setInput(new StringReader(MULTI_TYPE_WITH_CLASS_TYPE)); + XmlNamespaceDictionary namespaceDictionary = new XmlNamespaceDictionary(); + Xml.parseElement(parser, xml, namespaceDictionary, null); + // check type + assertTrue(xml.rep instanceof Collection); + Collection rep = xml.rep; + assertNotNull(rep); + assertEquals(3, rep.size()); + + + // serialize + XmlSerializer serializer = Xml.createSerializer(); + ByteArrayOutputStream out = new ByteArrayOutputStream(); + serializer.setOutput(out, "UTF-8"); + namespaceDictionary.serialize(serializer, "any", xml); + assertEquals(MULTI_TYPE_WITH_CLASS_TYPE, out.toString()); + } + + private static final String MULTIPLE_STRING_ELEMENT = + "" + + "rep1rep2"; + + public static class CollectionTypeString { + @Key + public Collection rep; + } + + public static class ArrayTypeString { + @Key + public String[] rep; + } + + + /** + * The Purpose of this test is to map a given list of elements (Strings) to a {@link Collection} + * of Strings. + */ + @Test + public void testParseCollectionTypeString() throws Exception { + CollectionTypeString xml = new CollectionTypeString(); + XmlPullParser parser = Xml.createParser(); + parser.setInput(new StringReader(MULTIPLE_STRING_ELEMENT)); + XmlNamespaceDictionary namespaceDictionary = new XmlNamespaceDictionary(); + Xml.parseElement(parser, xml, namespaceDictionary, null); + // check type + assertEquals(2, xml.rep.size()); + assertEquals("rep1", xml.rep.toArray(new String[]{})[0]); + assertEquals("rep2", xml.rep.toArray(new String[]{})[1]); + // serialize + XmlSerializer serializer = Xml.createSerializer(); + ByteArrayOutputStream out = new ByteArrayOutputStream(); + serializer.setOutput(out, "UTF-8"); + namespaceDictionary.serialize(serializer, "any", xml); + assertEquals(MULTIPLE_STRING_ELEMENT, out.toString()); + } + + /** + * The Purpose of this test is to map a given list of elements (Strings) to a String-Array. + */ + @Test + public void testParseArrayTypeString() throws Exception { + ArrayTypeString xml = new ArrayTypeString(); + XmlPullParser parser = Xml.createParser(); + parser.setInput(new StringReader(MULTIPLE_STRING_ELEMENT)); + XmlNamespaceDictionary namespaceDictionary = new XmlNamespaceDictionary(); + Xml.parseElement(parser, xml, namespaceDictionary, null); + // check type + assertEquals(2, xml.rep.length); + assertEquals("rep1", xml.rep[0]); + assertEquals("rep2", xml.rep[1]); + // serialize + XmlSerializer serializer = Xml.createSerializer(); + ByteArrayOutputStream out = new ByteArrayOutputStream(); + serializer.setOutput(out, "UTF-8"); + namespaceDictionary.serialize(serializer, "any", xml); + assertEquals(MULTIPLE_STRING_ELEMENT, out.toString()); + } + + private static final String MULTIPLE_STRING_ELEMENT_IN_COLLECTION = + "" + + "rep1rep2"; + + public static class AnyTypeWithCollectionString { + @Key + public CollectionTypeString coll; + } + + @Test + public void testParseAnyTypeWithACollectionString() throws Exception { + AnyTypeWithCollectionString xml = new AnyTypeWithCollectionString(); + XmlPullParser parser = Xml.createParser(); + parser.setInput(new StringReader(MULTIPLE_STRING_ELEMENT_IN_COLLECTION)); + XmlNamespaceDictionary namespaceDictionary = new XmlNamespaceDictionary(); + Xml.parseElement(parser, xml, namespaceDictionary, null); + // check type + assertNotNull(xml.coll); + // serialize + XmlSerializer serializer = Xml.createSerializer(); + ByteArrayOutputStream out = new ByteArrayOutputStream(); + serializer.setOutput(out, "UTF-8"); + namespaceDictionary.serialize(serializer, "any", xml); + assertEquals(MULTIPLE_STRING_ELEMENT_IN_COLLECTION, out.toString()); + } + + private static final String MULTIPLE_INTEGER_ELEMENT = + "" + + "12"; + + public static class CollectionTypeInteger { + @Key + public Collection rep; + } + + public static class ArrayTypeInteger { + @Key + public Integer[] rep; + } + + public static class ArrayTypeInt { + @Key + public int[] rep; + } + + /** + * The Purpose of this test is to map a given list of elements (Strings) to a {@link Collection} + * of Strings. + */ + @Test + public void testParseCollectionTypeInteger() throws Exception { + CollectionTypeInteger xml = new CollectionTypeInteger(); + XmlPullParser parser = Xml.createParser(); + parser.setInput(new StringReader(MULTIPLE_INTEGER_ELEMENT)); + XmlNamespaceDictionary namespaceDictionary = new XmlNamespaceDictionary(); + Xml.parseElement(parser, xml, namespaceDictionary, null); + // check type + assertEquals(2, xml.rep.size()); + assertEquals(1, xml.rep.toArray(new Integer[]{})[0].intValue()); + assertEquals(2, xml.rep.toArray(new Integer[]{})[1].intValue()); + // serialize + XmlSerializer serializer = Xml.createSerializer(); + ByteArrayOutputStream out = new ByteArrayOutputStream(); + serializer.setOutput(out, "UTF-8"); + namespaceDictionary.serialize(serializer, "any", xml); + assertEquals(MULTIPLE_INTEGER_ELEMENT, out.toString()); + } + + /** + * The Purpose of this test is to map a given list of elements (Strings) to a String-Array. + */ + @Test + public void testParseArrayTypeInteger() throws Exception { + ArrayTypeInteger xml = new ArrayTypeInteger(); + XmlPullParser parser = Xml.createParser(); + parser.setInput(new StringReader(MULTIPLE_INTEGER_ELEMENT)); + XmlNamespaceDictionary namespaceDictionary = new XmlNamespaceDictionary(); + Xml.parseElement(parser, xml, namespaceDictionary, null); + // check type + assertEquals(2, xml.rep.length); + assertEquals(1, xml.rep[0].intValue()); + assertEquals(2, xml.rep[1].intValue()); + // serialize + XmlSerializer serializer = Xml.createSerializer(); + ByteArrayOutputStream out = new ByteArrayOutputStream(); + serializer.setOutput(out, "UTF-8"); + namespaceDictionary.serialize(serializer, "any", xml); + assertEquals(MULTIPLE_INTEGER_ELEMENT, out.toString()); + } + + /** + * The Purpose of this test is to map a given list of elements (int) to a {@link List} + * of Strings. + */ + @Test + public void testParseArrayTypeInt() throws Exception { + ArrayTypeInt xml = new ArrayTypeInt(); + XmlPullParser parser = Xml.createParser(); + parser.setInput(new StringReader(MULTIPLE_INTEGER_ELEMENT)); + XmlNamespaceDictionary namespaceDictionary = new XmlNamespaceDictionary(); + Xml.parseElement(parser, xml, namespaceDictionary, null); + // check type + assertEquals(2, xml.rep.length); + assertEquals(1, xml.rep[0]); + assertEquals(2, xml.rep[1]); + // serialize + XmlSerializer serializer = Xml.createSerializer(); + ByteArrayOutputStream out = new ByteArrayOutputStream(); + serializer.setOutput(out, "UTF-8"); + namespaceDictionary.serialize(serializer, "any", xml); + assertEquals(MULTIPLE_INTEGER_ELEMENT, out.toString()); + } + + + private static final String MULTIPLE_ENUM_ELEMENT = + "" + + "ENUM_1ENUM_2"; + + public static class CollectionTypeEnum { + @Key + public Collection rep; + } + + public static class ArrayTypeEnum { + @Key + public XmlEnumTest.AnyEnum[] rep; + } + + public static class ListTypeEnum { + @Key + public List rep; + } + + + @Test + public void testParseCollectionTypeWithEnum() throws Exception { + CollectionTypeEnum xml = new CollectionTypeEnum(); + XmlPullParser parser = Xml.createParser(); + parser.setInput(new StringReader(MULTIPLE_ENUM_ELEMENT)); + XmlNamespaceDictionary namespaceDictionary = new XmlNamespaceDictionary(); + Xml.parseElement(parser, xml, namespaceDictionary, null); + // check type + assertEquals(2, xml.rep.size()); + assertEquals(XmlEnumTest.AnyEnum.ENUM_1, xml.rep.toArray(new XmlEnumTest.AnyEnum[]{})[0]); + assertEquals(XmlEnumTest.AnyEnum.ENUM_2, xml.rep.toArray(new XmlEnumTest.AnyEnum[]{})[1]); + // serialize + XmlSerializer serializer = Xml.createSerializer(); + ByteArrayOutputStream out = new ByteArrayOutputStream(); + serializer.setOutput(out, "UTF-8"); + namespaceDictionary.serialize(serializer, "any", xml); + assertEquals(MULTIPLE_ENUM_ELEMENT, out.toString()); + } + + @Test + public void testParseArrayTypeWithEnum() throws Exception { + ArrayTypeEnum xml = new ArrayTypeEnum(); + XmlPullParser parser = Xml.createParser(); + parser.setInput(new StringReader(MULTIPLE_ENUM_ELEMENT)); + XmlNamespaceDictionary namespaceDictionary = new XmlNamespaceDictionary(); + Xml.parseElement(parser, xml, namespaceDictionary, null); + // check type + assertEquals(2, xml.rep.length); + assertEquals(XmlEnumTest.AnyEnum.ENUM_1, xml.rep[0]); + assertEquals(XmlEnumTest.AnyEnum.ENUM_2, xml.rep[1]); + // serialize + XmlSerializer serializer = Xml.createSerializer(); + ByteArrayOutputStream out = new ByteArrayOutputStream(); + serializer.setOutput(out, "UTF-8"); + namespaceDictionary.serialize(serializer, "any", xml); + assertEquals(MULTIPLE_ENUM_ELEMENT, out.toString()); + } + + @Test + public void testParseListTypeWithEnum() throws Exception { + ListTypeEnum xml = new ListTypeEnum(); + XmlPullParser parser = Xml.createParser(); + parser.setInput(new StringReader(MULTIPLE_ENUM_ELEMENT)); + XmlNamespaceDictionary namespaceDictionary = new XmlNamespaceDictionary(); + Xml.parseElement(parser, xml, namespaceDictionary, null); + // check type + assertEquals(2, xml.rep.size()); + assertEquals(XmlEnumTest.AnyEnum.ENUM_1, xml.rep.get(0)); + assertEquals(XmlEnumTest.AnyEnum.ENUM_2, xml.rep.get(1)); + // serialize + XmlSerializer serializer = Xml.createSerializer(); + ByteArrayOutputStream out = new ByteArrayOutputStream(); + serializer.setOutput(out, "UTF-8"); + namespaceDictionary.serialize(serializer, "any", xml); + assertEquals(MULTIPLE_ENUM_ELEMENT, out.toString()); + } +} diff --git a/google-http-client/src/main/java/com/google/api/client/util/DataMap.java b/google-http-client/src/main/java/com/google/api/client/util/DataMap.java index cf234d15c..f855c6288 100644 --- a/google-http-client/src/main/java/com/google/api/client/util/DataMap.java +++ b/google-http-client/src/main/java/com/google/api/client/util/DataMap.java @@ -43,7 +43,8 @@ final class DataMap extends AbstractMap { DataMap(Object object, boolean ignoreCase) { this.object = object; classInfo = ClassInfo.of(object.getClass(), ignoreCase); - Preconditions.checkArgument(!classInfo.isEnum()); + // Removed due to issue #504 + // Preconditions.checkArgument(!classInfo.isEnum()); } @Override