/*
* Copyright 2010-2015 Amazon.com, Inc. or its affiliates. All Rights Reserved.
*
* Licensed 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://aws.amazon.com/apache2.0
*
* This file 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 com.amazonaws.util.json;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
import com.amazonaws.util.json.JsonUtils.JsonEngine;
import org.junit.Test;
import java.io.IOException;
import java.io.StringReader;
import java.io.StringWriter;
import java.nio.ByteBuffer;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
public class JsonUtilsTest {
private static final String JSON_STRING = "{\"string\":\"string\","
+ "\"long\":123,"
+ "\"double\":123.45,"
+ "\"null\":null,"
+ "\"true\":true,"
+ "\"false\":false,"
+ "\"encoding\":\"Chloë\","
+ "\"array\":[\"string\",123,123.45,null,true,false],"
+ "\"object\":{}"
+ "}";
@Test
public void testJsonToMap() {
Map<String, String> map = JsonUtils.jsonToMap(JSON_STRING);
assertEquals("string value", "string", map.get("string"));
assertEquals("long value", "123", map.get("long"));
assertEquals("double value", "123.45", map.get("double"));
assertEquals("null value", null, map.get("null"));
assertEquals("true value", "true", map.get("true"));
assertEquals("false value", "false", map.get("false"));
assertEquals("encoding", "Chloë", map.get("encoding"));
assertNull("array is ignored", map.get("array"));
assertNull("object is ignored", map.get("object"));
}
@Test
public void testMapToJson() {
Map<String, String> source = new HashMap<String, String>();
source.put("string", "string");
source.put("long", "123");
source.put("double", "123.45");
source.put("null", null);
source.put("true", "true");
source.put("false", "false");
source.put("encoding", "Chloë");
String json = JsonUtils.mapToString(source);
Map<String, String> map = JsonUtils.jsonToMap(json);
assertEquals("string value", "string", map.get("string"));
assertEquals("long value", "123", map.get("long"));
assertEquals("double value", "123.45", map.get("double"));
assertEquals("null value", null, map.get("null"));
assertEquals("true value", "true", map.get("true"));
assertEquals("false value", "false", map.get("false"));
assertEquals("encoding", "Chloë", map.get("encoding"));
}
@Test
public void testEmptyMapToJson() {
Map<String, String> source = new HashMap<String, String>();
assertEquals("empty map", "{}", JsonUtils.mapToString(source));
}
@Test
public void testNullJsonToMap() {
String nullStr = null;
Map<String, String> map = JsonUtils.jsonToMap(nullStr);
assertNotNull("map isn't null", map);
assertTrue("map is empty", map.isEmpty());
}
@Test
public void testEmptyJsonToMap() {
String json = "";
Map<String, String> map = JsonUtils.jsonToMap(json);
assertTrue("empty string", map.isEmpty());
}
@Test
public void testJsonReader() throws IOException {
AwsJsonReader reader = JsonUtils.getJsonReader(new StringReader(JSON_STRING));
reader.beginObject();
assertTrue("has properties", reader.hasNext());
while (reader.hasNext()) {
String name = reader.nextName();
if (name.equals("string")) {
assertTrue("VALUE_STRING", AwsJsonToken.VALUE_STRING == reader.peek());
assertEquals("string value", "string", reader.nextString());
} else if (name.equals("long")) {
assertTrue("VALUE_NUMBER", AwsJsonToken.VALUE_NUMBER == reader.peek());
assertEquals("long value", "123", reader.nextString());
} else if (name.equals("double")) {
assertTrue("VALUE_NUMBER", AwsJsonToken.VALUE_NUMBER == reader.peek());
assertEquals("double value", "123.45", reader.nextString());
} else if (name.equals("null")) {
assertTrue("VALUE_NULL", AwsJsonToken.VALUE_NULL == reader.peek());
assertNull("null value", reader.nextString());
} else if (name.equals("true")) {
assertTrue("VALUE_BOOLEAN", AwsJsonToken.VALUE_BOOLEAN == reader.peek());
assertEquals("true value", "true", reader.nextString());
} else if (name.equals("false")) {
assertTrue("VALUE_BOOLEAN", AwsJsonToken.VALUE_BOOLEAN == reader.peek());
assertEquals("false value", "false", reader.nextString());
} else if (name.equals("encoding")) {
assertTrue("VALUE_STRING", AwsJsonToken.VALUE_STRING == reader.peek());
assertEquals("encoding", "Chloë", reader.nextString());
} else if (name.equals("array")) {
assertTrue("BEGIN_ARRAY", AwsJsonToken.BEGIN_ARRAY == reader.peek());
reader.beginArray();
assertTrue("has next", reader.hasNext());
assertEquals("string value", "string", reader.nextString());
assertEquals("long value", "123", reader.nextString());
assertEquals("double value", "123.45", reader.nextString());
assertNull("null value", reader.nextString());
assertEquals("true value", "true", reader.nextString());
assertEquals("false value", "false", reader.nextString());
reader.endArray();
} else if (name.equals("object")) {
assertTrue("BEGIN_OBJECT", AwsJsonToken.BEGIN_OBJECT == reader.peek());
reader.beginObject();
assertFalse("empty object", reader.hasNext());
reader.endObject();
} else {
fail("should not reach here");
}
}
reader.endObject();
}
@Test
public void testJsonWriter() throws IOException {
StringWriter out = new StringWriter();
AwsJsonWriter writer = JsonUtils.getJsonWriter(out);
writer.beginObject()
.name("string").value("string")
.name("long").value(123)
.name("double").value(123.45)
.name("null").value()
.name("true").value(true)
.name("false").value(false)
.name("encoding").value("Chloë")
.name("array").beginArray()
.value("string").value(123).value(123.45).value().value(true).value(false)
.endArray()
.name("object").beginObject().endObject()
.endObject().close();
String json = out.toString();
assertEquals("same json", JSON_STRING, json);
}
@Test
public void testReadPerformance() throws IOException {
Map<String, String> map = new HashMap<String, String>();
for (int i = 0; i < 5000; i++) {
map.put("key" + i, "value" + i);
}
String json = JsonUtils.mapToString(map);
JsonUtils.setJsonEngine(JsonEngine.Jackson);
long start = System.nanoTime();
for (int i = 0; i < 1000; i++) {
JsonUtils.jsonToMap(json);
}
System.out.println("Serialize a 5000 properties map 1000 times");
System.out.println("Jackson read elapsed: "
+ (System.nanoTime() - start) / 1000000 + "ms");
JsonUtils.setJsonEngine(JsonEngine.Gson);
start = System.nanoTime();
for (int i = 0; i < 1000; i++) {
JsonUtils.jsonToMap(json);
}
System.out.println("Gson read elapsed: "
+ (System.nanoTime() - start) / 1000000 + "ms");
}
@Test
public void testWritePerformance() throws IOException {
Map<String, String> map = new HashMap<String, String>();
for (int i = 0; i < 5000; i++) {
map.put("key" + i, "value" + i);
}
System.out.println("Deserialize a JSON string with a 5000 properties map 1000 times");
JsonUtils.setJsonEngine(JsonEngine.Jackson);
long start = System.nanoTime();
for (int i = 0; i < 1000; i++) {
JsonUtils.mapToString(map);
}
System.out.println("Jackson write elapsed: "
+ (System.nanoTime() - start) / 1000000 + "ms");
JsonUtils.setJsonEngine(JsonEngine.Gson);
start = System.nanoTime();
for (int i = 0; i < 1000; i++) {
JsonUtils.mapToString(map);
}
System.out.println("Gson write elapsed: "
+ (System.nanoTime() - start) / 1000000 + "ms");
}
@Test
public void testDate() throws IOException {
Date d = new Date(1423875641895L);
String target = "1423875641.895";
JsonUtils.setJsonEngine(JsonEngine.Gson);
StringWriter out = new StringWriter();
// This is wrapped in an array so that Gson doesn't complain about
// invalid JSON encoding
JsonUtils.getJsonWriter(out)
.beginArray().value(d).endArray()
.close();
assertEquals("[" + target + "]", out.toString());
out.getBuffer().setLength(0); // clear string writer
JsonUtils.setJsonEngine(JsonEngine.Jackson);
JsonUtils.getJsonWriter(out)
.beginArray().value(d).endArray()
.close();
assertEquals("[" + target + "]", out.toString());
}
@Test
public void testByteBuffer() throws IOException {
ByteBuffer bb = generateByteBuffer(16);
// Note: the target string is back filled with the output of the above
// byte buffer
String target = "AAECAwQFBgcICQoLDA0ODw==";
JsonUtils.setJsonEngine(JsonEngine.Gson);
StringWriter out = new StringWriter();
JsonUtils.getJsonWriter(out)
.beginArray().value(bb).endArray()
.close();
assertEquals("[\"" + target + "\"]", out.toString());
out.getBuffer().setLength(0);
JsonUtils.setJsonEngine(JsonEngine.Jackson);
JsonUtils.getJsonWriter(out)
.beginArray().value(bb).endArray()
.close();
assertEquals("[\"" + target + "\"]", out.toString());
}
private ByteBuffer generateByteBuffer(int length) {
byte[] bytes = new byte[length];
for (int i = 0; i < length; i++) {
bytes[i] = (byte) (i % Byte.MAX_VALUE);
}
return ByteBuffer.wrap(bytes);
}
}