JSONUtil { public static String toJSON( Object obj ) { return toJSON(obj, (JSONConfig)null); } private  JSONUtil(); static String toJSON( Object obj ); static String toJSON( Object obj, JSONConfig cfg ); static void toJSON( Object obj, Writer json ); static void toJSON( Object obj, JSONConfig cfg, Writer json ); static Set<String> getJavascriptReservedWords(); static boolean isReservedWord( String name ); static void checkValidJavascriptPropertyName( String propertyName, JSONConfig cfg ); static void checkValidJavascriptPropertyName( String propertyName ); static boolean isValidJavascriptPropertyName( String propertyName, JSONConfig cfg ); static boolean isValidJavascriptPropertyName( String propertyName );  }
@Test public void testReplaceUndefined() { JSONConfig cfg = new JSONConfig().setUseECMA6(false).setBadCharacterPolicy(JSONConfig.REPLACE); Random rand = new Random(); final String result = makeResult(StringProcessor.UNICODE_REPLACEMENT_CHARACTER); for ( int i = 0; i <= BAD_CHARS; i++ ){ assertThat(JSONUtil.toJSON(undefinedTestMap(getRandomUndefined(rand)), cfg), is(result)); } }
@Test public void testDiscardUndefined() { JSONConfig cfg = new JSONConfig().setUseECMA6(false).setBadCharacterPolicy(JSONConfig.DISCARD); Random rand = new Random(); final String result = makeResult(""); for ( int i = 0; i <= BAD_CHARS; i++ ){ assertThat(JSONUtil.toJSON(undefinedTestMap(getRandomUndefined(rand)), cfg), is(result)); } }
@Test public void testExceptionUndefined() { JSONConfig cfg = new JSONConfig().setUseECMA6(false).setBadCharacterPolicy(JSONConfig.EXCEPTION); Random rand = new Random(); for ( int i = 0; i <= BAD_CHARS; i++ ){ int cp = getRandomUndefined(rand); try{ JSONUtil.toJSON(undefinedTestMap(cp), cfg); fail("Expected a UndefinedCodePointException to be thrown."); }catch ( UndefinedCodePointException e ){ assertThat(e.getMessage(), containsString(String.format("Undefined code point U+%04X at position", cp))); } } }
@Test public void testEscapeUndefined() { JSONConfig cfg = new JSONConfig().setUseECMA6(false).setBadCharacterPolicy(JSONConfig.ESCAPE); Random rand = new Random(); for ( int i = 0; i <= BAD_CHARS; i++ ){ int cp = getRandomUndefined(rand); String escape; if ( cp < Character.MIN_SUPPLEMENTARY_CODE_POINT ){ escape = String.format("\\u%04X", cp); }else{ escape = String.format("\\u%04X\\u%04X", (int)Character.highSurrogate(cp), (int)Character.lowSurrogate(cp)); } assertThat(JSONUtil.toJSON(undefinedTestMap(cp), cfg), is(makeResult(escape))); } }
@Test public void testPassUndefined() { JSONConfig cfg = new JSONConfig().setUseECMA6(false).setBadCharacterPolicy(JSONConfig.PASS); StringBuilder buf = new StringBuilder(); Random rand = new Random(); for ( int i = 0; i <= BAD_CHARS; i++ ){ int cp = getRandomUndefined(rand); buf.setLength(0); buf.appendCodePoint(cp); assertThat(JSONUtil.toJSON(undefinedTestMap(cp), cfg), is(makeResult(buf))); } }
@Test public void testEscapePassThrough() throws ScriptException, NoSuchMethodException { Map<String,Object> jsonObj = new HashMap<>(); JSONConfig cfg = new JSONConfig().setUnEscapeWherePossible(false) .setPassThroughEscapes(true) .setUseECMA6(true); String[] strs = { "\\u1234", "a\\u{41}", "\\\"", "\\/", "\\b", "\\f", "\\n", "\\r", "\\t", "\\\\", "\\v" }; for ( String str : strs ){ jsonObj.clear(); jsonObj.put("x", str); String json = JSONUtil.toJSON(jsonObj, cfg); String result = "\\v".equals(str) ? "\\u{B}" : str; if ( result.indexOf('{') < 0 ){ validateJSON(json); } assertThat(json, is("{\"x\":\""+result+"\"}")); } String str = "a\\u{41}"; jsonObj.clear(); jsonObj.put("x", str); cfg.setUseECMA6(false); String json = JSONUtil.toJSON(jsonObj, cfg); validateJSON(json); assertThat(json, is("{\"x\":\"aA\"}")); }
@Test public void testUnEscape() throws ScriptException, NoSuchMethodException { Map<String,Object> jsonObj = new LinkedHashMap<>(); String[] strs = {"a\\u0041", "d\\u{41}", "e\\v", "f\\'"}; JSONConfig cfg = new JSONConfig().setUnEscapeWherePossible(true); for ( String str : strs ){ jsonObj.clear(); jsonObj.put("x", str+'Z'); String json = JSONUtil.toJSON(jsonObj, cfg); char firstChar = str.charAt(0); String result; switch ( firstChar ){ case 'e': result = firstChar + "\\u000B"; break; case 'f': result = firstChar + "'"; break; default: result = firstChar + "A"; break; } assertThat(json, is("{\"x\":\""+result+"Z\"}")); } cfg.setUnEscapeWherePossible(false) .setPassThroughEscapes(true); for ( int i = 0; i < 256; i++ ){ jsonObj.clear(); jsonObj.put("x", String.format("a\\%oZ", i)); jsonObj.put("y", String.format("a\\x%02XZ", i)); String result = StringProcessor.getEscape((char)i); if ( result == null ){ result = i < 0x20 ? String.format("\\u%04X", i) : String.format("%c", (char)i); } String json = JSONUtil.toJSON(jsonObj, cfg); validateJSON(json); assertThat(json, is("{\"x\":\"a"+result+"Z\",\"y\":\"a"+result+"Z\"}")); } }
@Test public void testParser() throws ParseException { Object obj = JSONParser.parseJSON("{\"foo\":\"b\\\\\\\"ar\",\"a\":5,\"b\":2.37e24,c:Infinity,\"d\":NaN,\"e\":[1,2,3,{\"a\":4}]}"); String json = JSONUtil.toJSON(obj); assertEquals("{\"foo\":\"b\\\\\\\"ar\",\"a\":5,\"b\":2.37E24,\"c\":\"Infinity\",\"d\":\"NaN\",\"e\":[1,2,3,{\"a\":4}]}", json); obj = JSONParser.parseJSON("'foo'"); assertEquals("foo", obj); obj = JSONParser.parseJSON("2.37e24"); assertEquals(2.37e24, obj); obj = JSONParser.parseJSON("Infinity"); assertTrue(Double.isInfinite((Double)obj)); obj = JSONParser.parseJSON("NaN"); assertTrue(Double.isNaN((Double)obj)); obj = JSONParser.parseJSON("false"); assertEquals(Boolean.FALSE, obj); obj = JSONParser.parseJSON("null"); assertEquals(null, obj); JSONConfig cfg = new JSONConfig().setUsePrimitiveArrays(true); obj = JSONParser.parseJSON("[1.1,2.2,-3.134598765,4.0]", cfg); double[] doubles = (double[])obj; assertEquals(new Double(1.1), new Double(doubles[0])); assertEquals(new Double(2.2), new Double(doubles[1])); assertEquals(new Double(-3.134598765), new Double(doubles[2])); assertEquals(new Double(4.0), new Double(doubles[3])); obj = JSONParser.parseJSON("[1.1,2.2,-3.134,4.0]", cfg); float[] floats = (float[])obj; assertEquals(new Float(1.1), new Float(floats[0])); assertEquals(new Float(2.2), new Float(floats[1])); assertEquals(new Float(-3.134), new Float(floats[2])); assertEquals(new Float(4.0), new Float(floats[3])); obj = JSONParser.parseJSON("[1,2,-3,4]", cfg); byte[] bytes = (byte[])obj; assertEquals(new Byte((byte)1), new Byte(bytes[0])); assertEquals(new Byte((byte)2), new Byte(bytes[1])); assertEquals(new Byte((byte)-3), new Byte(bytes[2])); assertEquals(new Byte((byte)4), new Byte(bytes[3])); cfg.setEncodeDatesAsStrings(true); DateFormat fmt = cfg.getDateGenFormat(); Date dt = (Date)JSONParser.parseJSON("new Date(\"2015-09-16T14:08:34.034Z\")", cfg); assertEquals("2015-09-16T14:08:34.034Z", fmt.format(dt)); dt = (Date)JSONParser.parseJSON("\"2015-09-16T14:08:34.034Z\"", cfg); assertEquals("2015-09-16T14:08:34.034Z", fmt.format(dt)); dt = (Date)JSONParser.parseJSON("\"2015-09-16T14:08:34.034+01\"", cfg); assertEquals("2015-09-16T14:08:34.034Z", fmt.format(dt)); dt = (Date)JSONParser.parseJSON("\"2015-09-16T14:08:34.034+01:30\"", cfg); assertEquals("2015-09-16T12:38:34.034Z", fmt.format(dt)); dt = (Date)JSONParser.parseJSON("\"2015-09-16T14:08:34\"", cfg); assertEquals("2015-09-16T14:08:34.034Z", fmt.format(dt)); dt = (Date)JSONParser.parseJSON("\"2015-09-16T14:08:34+01:30\"", cfg); assertEquals("2015-09-16T12:38:34.034Z", fmt.format(dt)); DateFormat nfmt = cfg.setDateGenFormat("EEE, d MMM yyyy HH:mm:ss Z"); nfmt.setTimeZone(TimeZone.getTimeZone("US/Eastern")); cfg.addDateParseFormat("yyyy.MM.dd G 'at' HH:mm:ss z"); dt = (Date)JSONParser.parseJSON("\"2001.07.04 AD at 12:08:56 EDT\"", cfg); assertEquals("Wed, 4 Jul 2001 12:08:56 -0400", nfmt.format(dt)); dt = (Date)JSONParser.parseJSON("\"2015-09-16T14:08:34+01:30\"", cfg); assertEquals("2015-09-16T12:38:34.034Z", fmt.format(dt)); try{ JSONParser.parseJSON("{\"foo\":\"b\\\\\\\"ar\",\"a\":5,\"b\":2.37e24,\"c\":&*^,\"d\":NaN,\"e\":[1,2,3,{\"a\":4}]}"); fail("Expected JSONParserException for bad data"); }catch ( JSONParserException e ){ } }
@Test public void testDate() throws ScriptException, NoSuchMethodException { JSONConfig cfg = new JSONConfig(); cfg.setEncodeDatesAsObjects(true); Map<String,Object> jsonObj = new LinkedHashMap<>(); Calendar cal = Calendar.getInstance(TimeZone.getTimeZone("UTC")); cal.set(2015, 8, 16, 14, 8, 34); cal.set(Calendar.MILLISECOND, 34); jsonObj.put("t", cal.getTime()); String json = JSONUtil.toJSON(jsonObj, cfg); assertThat(json, is("{\"t\":new Date(\"2015-09-16T14:08:34.034Z\")}")); Object result = evalJSON(json); if ( result instanceof ScriptObjectMirror ){ ScriptObjectMirror mirror = (ScriptObjectMirror)result; Object obj = mirror.get("t"); if ( obj instanceof ScriptObjectMirror ){ ScriptObjectMirror t = (ScriptObjectMirror)obj; if ( t.getClassName().equals("Date") ){ assertEquals(new Double(2015), t.callMember("getUTCFullYear")); assertEquals(new Double(8), t.callMember("getUTCMonth")); assertEquals(new Double(16), t.callMember("getUTCDate")); assertEquals(new Double(14), t.callMember("getUTCHours")); assertEquals(new Double(8), t.callMember("getUTCMinutes")); assertEquals(new Double(34), t.callMember("getUTCSeconds")); assertEquals(new Double(34), t.callMember("getUTCMilliseconds")); }else{ fail("Expected Date from t"); } }else{ fail("Expected ScriptObjectMirror from result"); } }else{ fail("Expected ScriptObjectMirror from evalJSON"); } cfg.setEncodeDatesAsStrings(true); json = JSONUtil.toJSON(jsonObj, cfg); validateJSON(json); assertThat(json, is("{\"t\":\"2015-09-16T14:08:34.034Z\"}")); }
@Test public void testValidStrings() throws ScriptException, NoSuchMethodException { int[] codePoints = new int[32768]; JSONConfig cfg = new JSONConfig(); JsonObject jsonObj = new JsonObject(1, cfg); int j = 0; for ( int i = 0; i <= Character.MAX_CODE_POINT; i++ ){ if ( isNormalCodePoint(i) ){ codePoints[j++] = i; if ( j == codePoints.length ){ jsonObj.clear(); jsonObj.add("x", new String(codePoints,0,j)); String json = jsonObj.toJSON(); validateJSON(json); j = 0; } } } if ( j > 0 ){ jsonObj.clear(); jsonObj.add("x", new String(codePoints,0,j)); String json = jsonObj.toJSON(); validateJSON(json); } jsonObj.clear(); jsonObj.add("x", "Some data\nSome other data."); String json = jsonObj.toJSON(); validateJSON(json); assertThat(json, is("{\"x\":\"Some data\\nSome other data.\"}")); }
@Test public void testBoolean() throws ScriptException, NoSuchMethodException { Map<String,Object> jsonObj = new LinkedHashMap<>(); jsonObj.put("t", true); jsonObj.put("f", false); String json = JSONUtil.toJSON(jsonObj); validateJSON(json); assertThat(json, is("{\"t\":true,\"f\":false}")); }
@Test public void testByte() throws ScriptException, NoSuchMethodException { Map<String,Object> jsonObj = new HashMap<>(); byte b = 27; jsonObj.put("x", b); String json = JSONUtil.toJSON(jsonObj); validateJSON(json); assertThat(json, is("{\"x\":27}")); }
@Test public void testChar() throws ScriptException, NoSuchMethodException { Map<String,Object> jsonObj = new HashMap<>(); char ch = '@'; jsonObj.put("x", ch); String json = JSONUtil.toJSON(jsonObj); validateJSON(json); assertThat(json, is("{\"x\":\"@\"}")); }
@Test public void testShort() throws ScriptException, NoSuchMethodException { Map<String,Object> jsonObj = new HashMap<>(); short s = 275; jsonObj.put("x", s); String json = JSONUtil.toJSON(jsonObj); validateJSON(json); assertThat(json, is("{\"x\":275}")); }
@Test public void testInt() throws ScriptException, NoSuchMethodException { Map<String,Object> jsonObj = new HashMap<>(); int i = 100000; jsonObj.put("x", i); String json = JSONUtil.toJSON(jsonObj); validateJSON(json); assertThat(json, is("{\"x\":100000}")); }
@Test public void testLong() throws ScriptException, NoSuchMethodException { Map<String,Object> jsonObj = new HashMap<>(); long l = 68719476735L; jsonObj.put("x", l); String json = JSONUtil.toJSON(jsonObj); validateJSON(json); assertThat(json, is("{\"x\":68719476735}")); l = 9007199254740993L; jsonObj.put("x", l); JSONConfig cfg = new JSONConfig(); cfg.setPreciseNumbers(false); json = JSONUtil.toJSON(jsonObj, cfg); assertThat(json, is("{\"x\":9007199254740993}")); cfg.setPreciseNumbers(true); json = JSONUtil.toJSON(jsonObj, cfg); assertThat(json, is("{\"x\":\"9007199254740993\"}")); }
@Test public void testFloat() throws ScriptException, NoSuchMethodException { Map<String,Object> jsonObj = new HashMap<>(); float f = 3.14f; jsonObj.put("x", f); String json = JSONUtil.toJSON(jsonObj); validateJSON(json); assertThat(json, is("{\"x\":3.14}")); }
@Test public void testDouble() throws ScriptException, NoSuchMethodException { Map<String,Object> jsonObj = new HashMap<>(); double d = 6.28; jsonObj.put("x", d); String json = JSONUtil.toJSON(jsonObj); validateJSON(json); assertThat(json, is("{\"x\":6.28}")); }
@Test public void testBigInteger() throws ScriptException, NoSuchMethodException { Map<String,Object> jsonObj = new HashMap<>(); BigInteger bi = new BigInteger("1234567890"); jsonObj.put("x", bi); String json = JSONUtil.toJSON(jsonObj); validateJSON(json); assertThat(json, is("{\"x\":1234567890}")); bi = new BigInteger("9007199254740993"); jsonObj.put("x", bi); JSONConfig cfg = new JSONConfig(); cfg.setPreciseNumbers(false); json = JSONUtil.toJSON(jsonObj, cfg); assertThat(json, is("{\"x\":9007199254740993}")); cfg.setPreciseNumbers(true); json = JSONUtil.toJSON(jsonObj, cfg); assertThat(json, is("{\"x\":\"9007199254740993\"}")); }
@Test public void testBigDecimal() throws ScriptException, NoSuchMethodException { Map<String,Object> jsonObj = new HashMap<>(); BigDecimal bd = new BigDecimal("12345.67890"); jsonObj.put("x", bd); String json = JSONUtil.toJSON(jsonObj); validateJSON(json); assertThat(json, is("{\"x\":12345.67890}")); bd = new BigDecimal("9007199254740993"); jsonObj.put("x", bd); JSONConfig cfg = new JSONConfig(); cfg.setPreciseNumbers(false); json = JSONUtil.toJSON(jsonObj, cfg); assertThat(json, is("{\"x\":9007199254740993}")); cfg.setPreciseNumbers(true); json = JSONUtil.toJSON(jsonObj, cfg); assertThat(json, is("{\"x\":\"9007199254740993\"}")); }
@Test public void testUnicodeEscapeInIdentifier() throws ScriptException, NoSuchMethodException { JsonObject jsonObj = new JsonObject(1); String[] ids = { "a\\u1234", "\\u1234x" }; for ( String id : ids ){ jsonObj.clear(); jsonObj.add(id, 0); String json = jsonObj.toJSON(); validateJSON(json); assertThat(json, is("{\""+id+"\":0}")); } }
@Test public void testNumberFormat() throws ScriptException, NoSuchMethodException { Map<String,Object> jsonObj = new HashMap<>(); float f = 1.23456f; jsonObj.put("x", f); NumberFormat fmt = NumberFormat.getInstance(); fmt.setMaximumFractionDigits(3); JSONConfig cfg = new JSONConfig().addNumberFormat(f, fmt); String json = JSONUtil.toJSON(jsonObj, cfg); validateJSON(json); assertThat(json, is("{\"x\":1.235}")); }
@Test public void testString() throws ScriptException, NoSuchMethodException { Map<String,Object> jsonObj = new HashMap<>(); String s = "bar"; jsonObj.put("x", s); String json = JSONUtil.toJSON(jsonObj); validateJSON(json); assertThat(json, is("{\"x\":\"bar\"}")); }
@Test public void testQuoteString() throws ScriptException, NoSuchMethodException { Map<String,Object> jsonObj = new HashMap<>(); String s = "ba\"r"; jsonObj.put("x", s); String json = JSONUtil.toJSON(jsonObj); validateJSON(json); assertThat(json, is("{\"x\":\"ba\\\"r\"}")); }
@Test public void testNonBmp() throws ScriptException, NoSuchMethodException { Map<String,Object> jsonObj = new HashMap<>(); StringBuilder buf = new StringBuilder(2); buf.appendCodePoint(0x1F4A9); jsonObj.put("x", buf); String json = JSONUtil.toJSON(jsonObj); validateJSON(json); assertThat(json, is("{\"x\":\"\uD83D\uDCA9\"}")); }
@Test public void testIterable() throws ScriptException, NoSuchMethodException { Map<String,Object> jsonObj = new HashMap<>(); jsonObj.put("x", Arrays.asList(1,2,3)); String json = JSONUtil.toJSON(jsonObj); validateJSON(json); assertThat(json, is("{\"x\":[1,2,3]}")); }
@Test public void testEnumeration() throws ScriptException, NoSuchMethodException { Map<String,Object> jsonObj = new HashMap<>(); Vector<Integer> list = new Vector<>(Arrays.asList(1,2,3)); jsonObj.put("x", list.elements()); String json = JSONUtil.toJSON(jsonObj); validateJSON(json); assertThat(json, is("{\"x\":[1,2,3]}")); }
@Test public void testLoop() throws ScriptException { Map<String,Object> jsonObj = new HashMap<>(4); jsonObj.put("a",1); jsonObj.put("b",2); jsonObj.put("c",3); jsonObj.put("x", jsonObj); JSONConfig cfg = new JSONConfig(); try{ JSONUtil.toJSON(jsonObj, cfg); fail("Expected a DataStructureLoopException to be thrown"); }catch ( DataStructureLoopException e ){ assertThat(e.getMessage(), containsString("java.util.HashMap includes itself which would cause infinite recursion.")); } }
@Test public void testComplex() throws ScriptException, NoSuchMethodException { Map<String,Object> jsonObj = new LinkedHashMap<>(); jsonObj.put("a",1); jsonObj.put("b","x"); String[] ia = {"1","2","3"}; List<String> il = Arrays.asList(ia); jsonObj.put("c",ia); jsonObj.put("d",il); Object[] objs = new Object[3]; objs[0] = null; objs[1] = (JSONAble)(jsonConfig, json) -> { JSONConfig cfg = jsonConfig == null ? new JSONConfig() : jsonConfig; Map<String,Object> stuff = new LinkedHashMap<>(); stuff.put("a", 0); stuff.put("b", 2); int[] ar = {1, 2, 3}; stuff.put("x", ar); stuff.put("t", null); JSONUtil.toJSON(stuff, cfg, json); }; objs[2] = il; jsonObj.put("e", objs); JSONConfig cfg = new JSONConfig(); String json = JSONUtil.toJSON(jsonObj, cfg); validateJSON(json); assertThat(json, is("{\"a\":1,\"b\":\"x\",\"c\":[\"1\",\"2\",\"3\"],\"d\":[\"1\",\"2\",\"3\"],\"e\":[null,{\"a\":0,\"b\":2,\"x\":[1,2,3],\"t\":null},[\"1\",\"2\",\"3\"]]}")); }
@Test public void testIndent() throws NoSuchMethodException, ScriptException { Map<String,Object> jsonObj = new LinkedHashMap<>(); jsonObj.put("a",1); jsonObj.put("b","x"); String[] ia = {"1","2","3"}; List<String> il = Arrays.asList(ia); jsonObj.put("c",ia); jsonObj.put("d",il); Object[] objs = new Object[3]; objs[0] = null; objs[1] = (JSONAble)(jsonConfig, json) -> { JSONConfig cfg = jsonConfig == null ? new JSONConfig() : jsonConfig; Map<String,Object> stuff = new LinkedHashMap<>(); Map<String,Object> more = new LinkedHashMap<>(); stuff.put("a", 0); stuff.put("b", 2); int[] ar = {1, 2, 3}; stuff.put("x", ar); more.put("z", 4); more.put("y", 2); more.put("t", null); stuff.put("w", more); JSONUtil.toJSON(stuff, cfg, json); }; objs[2] = il; jsonObj.put("e", objs); JSONConfig cfg = new JSONConfig().setIndentPadding(new IndentPadding("\t", String.format("%n"))); String json = JSONUtil.toJSON(jsonObj, cfg); validateJSON(json); @SuppressWarnings("unchecked") Map<String,Object> obj = (Map<String,Object>)JSONParser.parseJSON(json); assertThat((String)obj.get("b"), is("x")); @SuppressWarnings("unchecked") ArrayList<Object> innerObj = (ArrayList<Object>)obj.get("e"); @SuppressWarnings("unchecked") Map<Object,Object> jsonAble = (Map<Object,Object>)innerObj.get(1); assertThat(((Number)jsonAble.get("b")).intValue(), is(2)); }
@Test public void testDuplicateKeys() { JsonObject jsonObj = new JsonObject(2) .add(new DupStr(1), 0) .add(new DupStr(2), 1); try{ jsonObj.toJSON(); fail("Expected a DuplicatePropertyNameException to be thrown"); }catch ( DuplicatePropertyNameException e ){ assertThat(e.getMessage(), is("Property x occurs twice in the same object.")); } }
@Test public void testECMA6UnicodeEscapeInString() { JSONConfig cfg = new JSONConfig().setUseECMA6(true).setEscapeNonAscii(true) .setBadCharacterPolicy(JSONConfig.ESCAPE); StringBuilder buf = new StringBuilder(); Set<Character> singles = new HashSet<>(Arrays.asList('\b','\t','\n','\f','\r')); Random rand = new Random(); int bound = Character.MAX_CODE_POINT+1; int min = Character.MIN_SUPPLEMENTARY_CODE_POINT; for ( int i = 0; i < 4096; i++ ){ int cp; do{ cp = rand.nextInt(bound); }while ( cp > 0xF && cp < min ); buf.setLength(0); buf.appendCodePoint(cp); String result; if ( cp < 0xF && singles.contains((char)cp) ){ result = '"' + StringProcessor.getEscape((char)cp) + '"'; }else{ result = '"' + String.format("\\u{%X}", cp) + '"'; } String json = JSONUtil.toJSON(buf, cfg); assertThat(json, is(result)); } }
@Test public void testReflect() { JSONConfig cfg = new JSONConfig().setValidatePropertyNames(false) .setDetectDataStructureLoops(false) .setFastStrings(true) .setCacheReflectionData(false); JsonObject jsonObj = new JsonObject(1, cfg); jsonObj.add("f", new ReflectTestClass()); ReflectedObjectMapBuilder.clearReflectionCache(); String json = jsonObj.toJSON(); assertThat(json, is("{\"f\":{\"a\":1,\"k\":25.0}}")); cfg.clearReflectClasses(); cfg.addReflectClass(ReflectTestClass.class); cfg.setReflectionPrivacy(ReflectUtil.PRIVATE); json = jsonObj.toJSON(); assertThat(json, is("{\"f\":{\"a\":1,\"b\":\"something\",\"c\":[],\"d\":null,\"f\":true}}")); cfg.setReflectionPrivacy(ReflectUtil.PACKAGE); json = jsonObj.toJSON(); assertThat(json, is("{\"f\":{\"a\":1,\"b\":\"something\",\"c\":[],\"f\":true}}")); cfg.setReflectionPrivacy(ReflectUtil.PROTECTED); json = jsonObj.toJSON(); assertThat(json, is("{\"f\":{\"a\":1,\"b\":\"something\",\"f\":true}}")); cfg.setReflectionPrivacy(ReflectUtil.PUBLIC); json = jsonObj.toJSON(); assertThat(json, is("{\"f\":{\"a\":1,\"f\":true}}")); cfg = new JSONConfig(); jsonObj.setJSONConfig(cfg); json = jsonObj.toJSON(); assertThat(json, is("{\"f\":{\"a\":1,\"k\":25.0}}")); JSONConfigDefaults.getInstance().clearReflectClasses(); ReflectedObjectMapBuilder.clearReflectionCache(); cfg.setReflectUnknownObjects(false) .setReflectionPrivacy(ReflectUtil.PRIVATE) .addReflectClass(ReflectTestClass.class); int iterations = 100; ReflectTestClass r = new ReflectTestClass(); runMapTiming(iterations, r, cfg); runReflectionTiming(iterations, r, cfg, false); runReflectionTiming(iterations, r, cfg, true); runMapTiming(iterations, r, cfg); runReflectionTiming(iterations, r, cfg, false); runReflectionTiming(iterations, r, cfg, true); iterations = 1; cfg.clearReflectClasses() .addReflectClass(BigObject.class) .setFastStrings(false) .setEscapeNonAscii(true) .setUseECMA6(false); BigObject bigObj = new BigObject(); runReflectionTiming(iterations, bigObj, cfg, false); runReflectionTiming(iterations, bigObj, cfg, true); runReflectionTiming(iterations, bigObj, cfg, false); runReflectionTiming(iterations, bigObj, cfg, true); }
@Test public void testEscapeGenerator() { JSONConfig cfg = new JSONConfig().setUseECMA6(false).setEscapeNonAscii(true) .setBadCharacterPolicy(JSONConfig.ESCAPE); StringBuilder buf = new StringBuilder(); Set<Character> singles = new HashSet<>(Arrays.asList('\b','\t','\n','\f','\r')); Random rand = new Random(); int bound = Character.MAX_CODE_POINT+1; int min = Character.MIN_SUPPLEMENTARY_CODE_POINT; for ( int i = 0; i < 4096; i++ ){ int cp; do{ cp = rand.nextInt(bound); }while ( cp >= ' ' && cp < 128 ); buf.setLength(0); buf.appendCodePoint(cp); String result; if ( cp < min ){ if ( cp < 0xF && singles.contains((char)cp) ){ result = '"' + StringProcessor.getEscape((char)cp) + '"'; }else{ result = '"' + String.format("\\u%04X", cp) + '"'; } }else{ int high = Character.highSurrogate(cp); int low = Character.lowSurrogate(cp); result = '"' + String.format("\\u%04X\\u%04X", high, low) + '"'; } String json = JSONUtil.toJSON(buf, cfg); assertThat(json, is(result)); } }
@Test public void testReplaceSurrogates() { JSONConfig cfg = new JSONConfig().setUseECMA6(false).setBadCharacterPolicy(JSONConfig.REPLACE); Random rand = new Random(); final String result = makeResult(StringProcessor.UNICODE_REPLACEMENT_CHARACTER); for ( int i = 0; i <= BAD_CHARS; i++ ){ assertThat(JSONUtil.toJSON(surrogateTestMap(getRandomSurrogate(rand)), cfg), is(result)); } }
@Test public void testDiscardSurrogates() { JSONConfig cfg = new JSONConfig().setUseECMA6(false).setBadCharacterPolicy(JSONConfig.DISCARD); Random rand = new Random(); final String result = makeResult(""); for ( int i = 0; i <= BAD_CHARS; i++ ){ assertThat(JSONUtil.toJSON(surrogateTestMap(getRandomSurrogate(rand)), cfg), is(result)); } }
@Test public void testExceptionSurrogates() { JSONConfig cfg = new JSONConfig().setUseECMA6(false).setBadCharacterPolicy(JSONConfig.EXCEPTION); Random rand = new Random(); for ( int i = 0; i <= BAD_CHARS; i++ ){ char ch = getRandomSurrogate(rand); try{ JSONUtil.toJSON(surrogateTestMap(ch), cfg); fail("Expected a UnmatchedSurrogateException to be thrown."); }catch ( UnmatchedSurrogateException e ){ assertThat(e.getMessage(), containsString(String.format("Unmatched surrogate U+%04X at position", (int)ch))); } } }
@Test public void testEscapeBadSurrogates() { JSONConfig cfg = new JSONConfig().setUseECMA6(false).setBadCharacterPolicy(JSONConfig.ESCAPE); Random rand = new Random(); for ( int i = 0; i <= BAD_CHARS; i++ ){ char ch = getRandomSurrogate(rand); assertThat(JSONUtil.toJSON(surrogateTestMap(ch), cfg), is(makeResult(String.format("\\u%04X", (int)ch)))); } }
@Test public void testPassSurrogates() { JSONConfig cfg = new JSONConfig().setUseECMA6(false).setBadCharacterPolicy(JSONConfig.PASS); Random rand = new Random(); for ( int i = 0; i <= BAD_CHARS; i++ ){ char ch = getRandomSurrogate(rand); assertThat(JSONUtil.toJSON(surrogateTestMap(ch), cfg), is(makeResult(ch))); } }