blob: 4435545115128edaedd7d97ae81437784f705e4b [file] [log] [blame]
// ***************************************************************************************************************************
// * Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. See the NOTICE file *
// * distributed with this work for additional information regarding copyright ownership. The ASF licenses this file *
// * to you under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance *
// * with the License. You may obtain a copy of the License at *
// * *
// * http://www.apache.org/licenses/LICENSE-2.0 *
// * *
// * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an *
// * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the *
// * specific language governing permissions and limitations under the License. *
// ***************************************************************************************************************************
package org.apache.juneau.json;
import static org.apache.juneau.testutils.TestUtils.*;
import static org.junit.Assert.*;
import java.util.*;
import org.apache.juneau.*;
import org.apache.juneau.json.annotation.*;
import org.apache.juneau.serializer.*;
import org.junit.*;
@SuppressWarnings({"serial"})
public class JsonTest {
//====================================================================================================
// testBasic
//====================================================================================================
@Test
public void testBasic() throws Exception {
Map<String,Object> m = new LinkedHashMap<>();
List<Object> l = new LinkedList<>();
WriterSerializer s1 = JsonSerializer.create().ssq().trimNullProperties(false).build();
WriterSerializer s2 = JsonSerializer.create().simple().trimNullProperties(false).build();
String r;
// Null keys and values
m.clear();
m.put(null, null);
m.put("aaa", "bbb");
assertEquals("A1", "{null:null,aaa:'bbb'}", s1.serialize(m));
// Escapes.
// String = ["]
m.clear();
m.put("x", "[\"]");
assertEquals("{x:\"[\\\"]\"}", s2.serialize(m));
// String = [\"]
// JSON = {x:"\\\""}
m.clear();
m.put("x", "[\\\"]");
assertEquals("{x:\"[\\\\\\\"]\"}", s2.serialize(m));
// String = [\w[\w\-\.]{3,}\w]
// JSON = {x:"\\w[\\w\\-\\.]{3,}\\w"}
m.clear();
r = "\\w[\\w\\-\\.]{3,}\\w";
m.put("x", r);
assertEquals("{x:\"\\\\w[\\\\w\\\\-\\\\.]{3,}\\\\w\"}", s2.serialize(m));
assertEquals(r, new ObjectMap(s2.serialize(m)).getString("x"));
// String = [foo\bar]
// JSON = {x:"foo\\bar"}
m.clear();
m.put("x", "foo\\bar");
assertEquals("{x:\"foo\\\\bar\"}", s2.serialize(m));
m.clear();
m.put("null", null);
m.put("aaa", "bbb");
assertEquals("A2", "{'null':null,aaa:'bbb'}", s1.serialize(m));
m.clear();
m.put(null, "null");
m.put("aaa", "bbb");
assertEquals("A3", "{null:'null',aaa:'bbb'}", s1.serialize(m));
// Arrays
m.clear();
l.clear();
m.put("J", "f1");
m.put("B", "b");
m.put("C", "c");
l.add("1");
l.add("2");
l.add("3");
Object o = new Object[] { m, l };
Object o2 = new Object[] { o, "foo", "bar", new Integer(1), new Boolean(false), new Float(1.2), null };
assertEquals("K1", "[[{J:'f1',B:'b',C:'c'},['1','2','3']],'foo','bar',1,false,1.2,null]", s1.serialize(o2));
}
@Test
public void testReservedKeywordAttributes() throws Exception {
Map<String,Object> m = new LinkedHashMap<>();
// Keys with reserved names.
for (String attr : new String[]{"","true","false","null","try","123","1x","-123",".123"}) {
m.clear();
m.put(attr,1);
assertObjectEquals("{'"+attr+"':1}", m);
}
}
//====================================================================================================
// Validate various backslashes in strings.
//====================================================================================================
@Test
public void testBackslashesInStrings() throws Exception {
JsonSerializer s = JsonSerializer.create().simple().trimNullProperties(false).build();
String r, r2;
// [\\]
r = "\\";
r2 = s.serialize(r);
assertEquals(r2, "\"\\\\\"");
assertEquals(JsonParser.DEFAULT.parse(r2, Object.class), r);
// [\b\f\n\t]
r = "\b\f\n\t";
r2 = s.serialize(r);
assertEquals("\"\\b\\f\\n\\t\"", r2);
assertEquals(r, JsonParser.DEFAULT.parse(r2, Object.class));
// Special JSON case: Forward slashes can OPTIONALLY be escaped.
// [\/]
assertEquals(JsonParser.DEFAULT.parse("\"\\/\"", Object.class), "/");
// Unicode
r = "\u1234\u1ABC\u1abc";
r2 = s.serialize(r);
assertEquals("\"\u1234\u1ABC\u1abc\"", r2);
assertEquals("\u1234", JsonParser.DEFAULT.parse("\"\\u1234\"", Object.class));
}
//====================================================================================================
// Indentation
//====================================================================================================
@Test
public void testIndentation() throws Exception {
ObjectMap m = new ObjectMap("{J:{B:['c',{D:'e'},['f',{G:'h'},1,false]]},I:'j'}");
String e = ""
+ "{"
+ "\n J: {"
+ "\n B: ["
+ "\n 'c',"
+ "\n {"
+ "\n D: 'e'"
+ "\n },"
+ "\n ["
+ "\n 'f',"
+ "\n {"
+ "\n G: 'h'"
+ "\n },"
+ "\n 1,"
+ "\n false"
+ "\n ]"
+ "\n ]"
+ "\n },"
+ "\n I: 'j'"
+ "\n}";
assertEquals(e, SimpleJsonSerializer.DEFAULT_READABLE.serialize(m));
}
//====================================================================================================
// Escaping double quotes
//====================================================================================================
@Test
public void testEscapingDoubleQuotes() throws Exception {
JsonSerializer s = JsonSerializer.DEFAULT;
String r = s.serialize(new ObjectMap().append("f1", "x'x\"x"));
assertEquals("{\"f1\":\"x'x\\\"x\"}", r);
JsonParser p = JsonParser.DEFAULT;
assertEquals("x'x\"x", p.parse(r, ObjectMap.class).getString("f1"));
}
//====================================================================================================
// Escaping single quotes
//====================================================================================================
@Test
public void testEscapingSingleQuotes() throws Exception {
JsonSerializer s = SimpleJsonSerializer.DEFAULT;
String r = s.serialize(new ObjectMap().append("f1", "x'x\"x"));
assertEquals("{f1:'x\\'x\"x'}", r);
JsonParser p = JsonParser.DEFAULT;
assertEquals("x'x\"x", p.parse(r, ObjectMap.class).getString("f1"));
}
//====================================================================================================
// testWrapperAttrAnnotationOnBean
//====================================================================================================
@Test
public void testWrapperAttrAnnotationOnBean() throws Exception {
JsonSerializer s = SimpleJsonSerializer.DEFAULT;
JsonParser p = JsonParser.DEFAULT;
String r;
A t = A.create();
r = s.serialize(t);
assertEquals("{foo:{f1:1}}", r);
t = p.parse(r, A.class);
assertEquals(1, t.f1);
Map<String,A> m = new LinkedHashMap<>();
m.put("bar", A.create());
r = s.serialize(m);
assertEquals("{bar:{foo:{f1:1}}}", r);
m = p.parse(r, LinkedHashMap.class, String.class, A.class);
assertEquals(1, m.get("bar").f1);
}
@Json(wrapperAttr="foo")
public static class A {
public int f1;
static A create() {
A a = new A();
a.f1 = 1;
return a;
}
}
@Test
public void testWrapperAttrAnnotationOnBean_usingConfig() throws Exception {
JsonSerializer s = SimpleJsonSerializer.DEFAULT.builder().applyAnnotations(A2.class).build();
JsonParser p = JsonParser.DEFAULT.builder().applyAnnotations(A2.class).build();
String r;
A2 t = A2.create();
r = s.serialize(t);
assertEquals("{foo:{f1:1}}", r);
t = p.parse(r, A2.class);
assertEquals(1, t.f1);
Map<String,A2> m = new LinkedHashMap<>();
m.put("bar", A2.create());
r = s.serialize(m);
assertEquals("{bar:{foo:{f1:1}}}", r);
m = p.parse(r, LinkedHashMap.class, String.class, A2.class);
assertEquals(1, m.get("bar").f1);
}
@JsonConfig(annotateJson=@Json(on="A2",wrapperAttr="foo"))
public static class A2 {
public int f1;
static A2 create() {
A2 a = new A2();
a.f1 = 1;
return a;
}
}
//====================================================================================================
// testWrapperAttrAnnotationOnNonBean
//====================================================================================================
@Test
public void testWrapperAttrAnnotationOnNonBean() throws Exception {
JsonSerializer s = SimpleJsonSerializer.DEFAULT;
JsonParser p = JsonParser.DEFAULT;
String r;
B t = B.create();
r = s.serialize(t);
assertEquals("{foo:'1'}", r);
t = p.parse(r, B.class);
assertEquals(1, t.f1);
Map<String,B> m = new LinkedHashMap<>();
m.put("bar", B.create());
r = s.serialize(m);
assertEquals("{bar:{foo:'1'}}", r);
m = p.parse(r, LinkedHashMap.class, String.class, B.class);
assertEquals(1, m.get("bar").f1);
}
@Json(wrapperAttr="foo")
public static class B {
int f1;
static B create() {
B b = new B();
b.f1 = 1;
return b;
}
@Override /* Object */
public String toString() {
return String.valueOf(f1);
}
public static B valueOf(String s) {
B b = new B();
b.f1 = Integer.parseInt(s);
return b;
}
}
@Test
public void testWrapperAttrAnnotationOnNonBean_usingConfig() throws Exception {
JsonSerializer s = SimpleJsonSerializer.DEFAULT.builder().applyAnnotations(B2.class).build();
JsonParser p = JsonParser.DEFAULT.builder().applyAnnotations(B2.class).build();;
String r;
B2 t = B2.create();
r = s.serialize(t);
assertEquals("{foo:'1'}", r);
t = p.parse(r, B2.class);
assertEquals(1, t.f1);
Map<String,B2> m = new LinkedHashMap<>();
m.put("bar", B2.create());
r = s.serialize(m);
assertEquals("{bar:{foo:'1'}}", r);
m = p.parse(r, LinkedHashMap.class, String.class, B2.class);
assertEquals(1, m.get("bar").f1);
}
@JsonConfig(annotateJson=@Json(on="B2",wrapperAttr="foo"))
public static class B2 {
int f1;
static B2 create() {
B2 b = new B2();
b.f1 = 1;
return b;
}
@Override /* Object */
public String toString() {
return String.valueOf(f1);
}
public static B2 valueOf(String s) {
B2 b = new B2();
b.f1 = Integer.parseInt(s);
return b;
}
}
//====================================================================================================
// testSubclassedList
//====================================================================================================
@Test
public void testSubclassedList() throws Exception {
JsonSerializer s = JsonSerializer.DEFAULT;
Map<String,Object> o = new HashMap<>();
o.put("c", new C());
assertEquals("{\"c\":[]}", s.serialize(o));
}
public static class C extends LinkedList<String> {
}
//====================================================================================================
// testEscapeSolidus
//====================================================================================================
@Test
public void testEscapeSolidus() throws Exception {
JsonSerializer s = JsonSerializer.create().escapeSolidus(false).build();
String r = s.serialize("foo/bar");
assertEquals("\"foo/bar\"", r);
r = JsonParser.DEFAULT.parse(r, String.class);
assertEquals("foo/bar", r);
s = JsonSerializer.create().escapeSolidus(true).build();
r = s.serialize("foo/bar");
assertEquals("\"foo\\/bar\"", r);
r = JsonParser.DEFAULT.parse(r, String.class);
assertEquals("foo/bar", r);
s = JsonSerializer.create().escapeSolidus().build();
r = s.serialize("foo/bar");
assertEquals("\"foo\\/bar\"", r);
r = JsonParser.DEFAULT.parse(r, String.class);
assertEquals("foo/bar", r);
}
}