From 9cf532828d11a00bf60e082cade9e12d2e573cd9 Mon Sep 17 00:00:00 2001 From: stleary Date: Sun, 7 Jun 2015 22:22:14 -0500 Subject: [PATCH] confirm current behavior --- EnumTest.java | 207 ++++++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 174 insertions(+), 33 deletions(-) diff --git a/EnumTest.java b/EnumTest.java index 6b2a4bc..14605b1 100644 --- a/EnumTest.java +++ b/EnumTest.java @@ -6,66 +6,117 @@ import org.json.*; import org.junit.*; /** - * Documents how enum is handled by JSON-Java. + * Enums are not explicitly supported in JSON-Java. But because enums act like + * classes, all required behavior is already be present in some form. + * These tests explore how enum serialization works with JSON-Java. */ public class EnumTest { - @Test - public void simpleEnum() { + public void jsonObjectFromEnum() { /** - * Nothing happens when a simple enum is parsed to JSONObject + * To serialize an enum by its getters, use the JSONObject Object constructor. + * The JSONObject ctor handles enum like any other bean. A JSONobject + * is created whose entries are the getter name/value pairs. */ + + // If there are no getters then the object is empty. MyEnum myEnum = MyEnum.VAL2; JSONObject jsonObject = new JSONObject(myEnum); - assertTrue("simple enum is not processed by JSONObject", jsonObject.length() == 0); - /** - * Nothing good happens when a simple enum is parsed to JSONArray - */ - try { - new JSONArray(myEnum); - } catch (JSONException e) { - assertTrue("JSONArray throws exception when passed enum", true); - } - } + assertTrue("simple enum has no getters", jsonObject.length() == 0); - @Test - public void enumWithField() { - /** - * enum with a getters is handled like a bean - */ + // enum with a getters should create a non-empty object String expectedStr = "{\"value\":\"val 2\", \"intVal\":2}"; - MyEnumField myEnum = MyEnumField.VAL2; - JSONObject jsonObject = new JSONObject(myEnum); + MyEnumField myEnumField = MyEnumField.VAL2; + jsonObject = new JSONObject(myEnumField); JSONObject expectedJsonObject = new JSONObject(expectedStr); Util.compareActualVsExpectedJsonObjects(jsonObject, expectedJsonObject); - } - @Test - public void enumInClass() { /** - * class which contains enum instances. - * The enum values in MyEnum are lost. - * The string values in MyEnumFild are extracted and wrapped. + * class which contains enum instances. Each enum should be stored + * in its own JSONObject */ - String expectedStr = "{\"myEnumField\":{\"intVal\":3,\"value\":\"val 3\"},\"myEnum\":{}}"; + expectedStr = "{\"myEnumField\":{\"intVal\":3,\"value\":\"val 3\"},\"myEnum\":{}}"; MyEnumClass myEnumClass = new MyEnumClass(); myEnumClass.setMyEnum(MyEnum.VAL1); myEnumClass.setMyEnumField(MyEnumField.VAL3); - JSONObject jsonObject = new JSONObject(myEnumClass); - JSONObject expectedJsonObject = new JSONObject(expectedStr); + jsonObject = new JSONObject(myEnumClass); + expectedJsonObject = new JSONObject(expectedStr); Util.compareActualVsExpectedJsonObjects(jsonObject, expectedJsonObject); } + @Test + public void jsonObjectFromEnumWithNames() { + /** + * To serialize an enum by its set of allowed values, use getNames() + * and the the JSONObject Object with names constructor. + */ + String [] names; + String expectedStr; + JSONObject jsonObject; + JSONObject finalJsonObject; + JSONObject expectedJsonObject; + + expectedStr = "{\"VAL1\":\"VAL1\",\"VAL2\":\"VAL2\",\"VAL3\":\"VAL3\"}"; + MyEnum myEnum = MyEnum.VAL1; + names = JSONObject.getNames(myEnum); + // The values will be MyEnmField fields, so need to convert back to string for comparison + jsonObject = new JSONObject(myEnum, names); + finalJsonObject = new JSONObject(jsonObject.toString()); + expectedJsonObject = new JSONObject(expectedStr); + Util.compareActualVsExpectedJsonObjects(finalJsonObject, expectedJsonObject); + + expectedStr = "{\"VAL1\":\"VAL1\",\"VAL2\":\"VAL2\",\"VAL3\":\"VAL3\"}"; + MyEnumField myEnumField = MyEnumField.VAL3; + names = JSONObject.getNames(myEnumField); + // The values will be MyEnmField fields, so need to convert back to string for comparison + jsonObject = new JSONObject(myEnumField, names); + finalJsonObject = new JSONObject(jsonObject.toString()); + expectedJsonObject = new JSONObject(expectedStr); + Util.compareActualVsExpectedJsonObjects(finalJsonObject, expectedJsonObject); + } + @Test + public void enumPut() { + /** + * To serialize by assigned value, use the put() methods. The value + * will be stored as a enum type. + */ + String expectedFinalStr = "{\"myEnum\":\"VAL2\", \"myEnumField\":\"VAL1\"}"; + JSONObject jsonObject = new JSONObject(); + MyEnum myEnum = MyEnum.VAL2; + jsonObject.put("myEnum", myEnum); + assertTrue("expecting myEnum value", MyEnum.VAL2.equals(jsonObject.get("myEnum"))); + assertTrue("expecting myEnum value", MyEnum.VAL2.equals(jsonObject.opt("myEnum"))); + MyEnumField myEnumField = MyEnumField.VAL1; + jsonObject.putOnce("myEnumField", myEnumField); + assertTrue("expecting myEnumField value", MyEnumField.VAL1.equals(jsonObject.get("myEnumField"))); + assertTrue("expecting myEnumField value", MyEnumField.VAL1.equals(jsonObject.opt("myEnumField"))); + JSONObject finalJsonObject = new JSONObject(jsonObject.toString()); + JSONObject expectedFinalJsonObject = new JSONObject(expectedFinalStr); + Util.compareActualVsExpectedJsonObjects(finalJsonObject, expectedFinalJsonObject); + + JSONArray jsonArray = new JSONArray(); + jsonArray.put(myEnum); + jsonArray.put(1, myEnumField); + assertTrue("expecting myEnum value", MyEnum.VAL2.equals(jsonArray.get(0))); + assertTrue("expecting myEnumField value", MyEnumField.VAL1.equals(jsonArray.opt(1))); + JSONArray expectedJsonArray = new JSONArray(); + expectedJsonArray.put(MyEnum.VAL2); + expectedJsonArray.put(MyEnumField.VAL1); + Util.compareActualVsExpectedJsonArrays(jsonArray, expectedJsonArray); + assertTrue("expecting myEnumField value", MyEnumField.VAL1.equals(jsonArray.remove(1))); + } + @Test public void enumValueToString() { + /** + * The default action of valueToString() is to call object.toString(). + * For enums, this means the assigned value will be returned as a string. + */ String expectedStr1 = "\"VAL1\""; String expectedStr2 = "\"VAL1\""; - String expectedStr3 = "\"org.json.junit.MyEnumClass@"; MyEnum myEnum = MyEnum.VAL1; MyEnumField myEnumField = MyEnumField.VAL1; MyEnumClass myEnumClass = new MyEnumClass(); - myEnumClass.setMyEnum(MyEnum.VAL1); - myEnumClass.setMyEnumField(MyEnumField.VAL1); String str1 = JSONObject.valueToString(myEnum); assertTrue("actual myEnum: "+str1+" expected: "+expectedStr1, @@ -73,8 +124,98 @@ public class EnumTest { String str2 = JSONObject.valueToString(myEnumField); assertTrue("actual myEnumField: "+str2+" expected: "+expectedStr2, str2.equals(expectedStr2)); + + /** + * However, an enum within another class will not be rendered + * unless that class overrides default toString() + */ + String expectedStr3 = "\"org.json.junit.MyEnumClass@"; + myEnumClass.setMyEnum(MyEnum.VAL1); + myEnumClass.setMyEnumField(MyEnumField.VAL1); String str3 = JSONObject.valueToString(myEnumClass); assertTrue("actual myEnumClass: "+str3+" expected: "+expectedStr3, str3.startsWith(expectedStr3)); } + + @Test + public void enumToString() { + /** + * In whatever form the enum was added to the JSONObject or JSONArray, + * json[Object|Array].toString should serialize it in a reasonable way. + */ + MyEnum myEnum = MyEnum.VAL2; + JSONObject jsonObject = new JSONObject(myEnum); + String expectedStr = "{}"; + assertTrue("myEnum toString() should be empty", expectedStr.equals(jsonObject.toString())); + + MyEnumField myEnumField = MyEnumField.VAL2; + jsonObject = new JSONObject(myEnumField); + expectedStr = "{\"value\":\"val 2\", \"intVal\":2}"; + JSONObject actualJsonObject = new JSONObject(jsonObject.toString()); + JSONObject expectedJsonObject = new JSONObject(expectedStr); + Util.compareActualVsExpectedJsonObjects(actualJsonObject, expectedJsonObject); + + expectedStr = "{\"myEnumField\":{\"intVal\":3,\"value\":\"val 3\"},\"myEnum\":{}}"; + MyEnumClass myEnumClass = new MyEnumClass(); + myEnumClass.setMyEnum(MyEnum.VAL1); + myEnumClass.setMyEnumField(MyEnumField.VAL3); + jsonObject = new JSONObject(myEnumClass); + actualJsonObject = new JSONObject(jsonObject.toString()); + expectedJsonObject = new JSONObject(expectedStr); + Util.compareActualVsExpectedJsonObjects(actualJsonObject, expectedJsonObject); + + expectedStr = "{\"VAL1\":\"VAL1\",\"VAL2\":\"VAL2\",\"VAL3\":\"VAL3\"}"; + String [] names = JSONObject.getNames(myEnum); + jsonObject = new JSONObject(myEnum, names); + actualJsonObject = new JSONObject(jsonObject.toString()); + expectedJsonObject = new JSONObject(expectedStr); + Util.compareActualVsExpectedJsonObjects(actualJsonObject, expectedJsonObject); + + expectedStr = "{\"VAL1\":\"VAL1\",\"VAL2\":\"VAL2\",\"VAL3\":\"VAL3\"}"; + names = JSONObject.getNames(myEnumField); + jsonObject = new JSONObject(myEnumField, names); + actualJsonObject = new JSONObject(jsonObject.toString()); + expectedJsonObject = new JSONObject(expectedStr); + Util.compareActualVsExpectedJsonObjects(actualJsonObject, expectedJsonObject); + + expectedStr = "{\"myEnum\":\"VAL2\", \"myEnumField\":\"VAL2\"}"; + jsonObject = new JSONObject(); + jsonObject.putOpt("myEnum", myEnum); + jsonObject.putOnce("myEnumField", myEnumField); + actualJsonObject = new JSONObject(jsonObject.toString()); + expectedJsonObject = new JSONObject(expectedStr); + Util.compareActualVsExpectedJsonObjects(actualJsonObject, expectedJsonObject); + + expectedStr = "[\"VAL2\", \"VAL2\"]"; + JSONArray jsonArray = new JSONArray(); + jsonArray.put(myEnum); + jsonArray.put(1, myEnumField); + JSONArray actualJsonArray = new JSONArray(jsonArray.toString()); + JSONArray expectedJsonArray = new JSONArray(expectedStr); + Util.compareActualVsExpectedJsonArrays(actualJsonArray, expectedJsonArray); + } + + public void wrap() { + /** + * Wrap should handle enums exactly the same way as the JSONObject(Object) + * constructor. + */ + MyEnum myEnum = MyEnum.VAL2; + JSONObject jsonObject = (JSONObject)JSONObject.wrap(myEnum); + assertTrue("simple enum has no getters", jsonObject.length() == 0); + + String expectedStr = "{\"value\":\"val 2\", \"intVal\":2}"; + MyEnumField myEnumField = MyEnumField.VAL2; + jsonObject = (JSONObject)JSONObject.wrap(myEnumField); + JSONObject expectedJsonObject = new JSONObject(expectedStr); + Util.compareActualVsExpectedJsonObjects(jsonObject, expectedJsonObject); + + expectedStr = "{\"myEnumField\":{\"intVal\":3,\"value\":\"val 3\"},\"myEnum\":{}}"; + MyEnumClass myEnumClass = new MyEnumClass(); + myEnumClass.setMyEnum(MyEnum.VAL1); + myEnumClass.setMyEnumField(MyEnumField.VAL3); + jsonObject = (JSONObject)JSONObject.wrap(myEnumClass); + expectedJsonObject = new JSONObject(expectedStr); + Util.compareActualVsExpectedJsonObjects(jsonObject, expectedJsonObject); + } }