package protobuf.codec.json; import static org.junit.Assert.assertEquals; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.StringReader; import java.io.StringWriter; import java.util.ArrayList; import java.util.HashMap; import java.util.Map; import org.apache.commons.codec.binary.Base64; import org.codehaus.jackson.JsonFactory; import org.codehaus.jackson.JsonGenerator; import org.junit.Before; import org.junit.Test; import protobuf.codec.Codec; import protobuf.codec.Codec.Feature; import protobuf.codec.json.JsonCodec; import protobuf.codec.json.TypesProtoBuf; import protobuf.codec.json.TypesProtoBuf.Foo; import protobuf.codec.json.TypesProtoBuf.Lang; import protobuf.codec.json.TypesProtoBuf.RepeatedFields; import protobuf.codec.json.TypesProtoBuf.Types; import protobuf.codec.json.TypesProtoBuf.Version; import com.google.protobuf.ByteString; import com.google.protobuf.ExtensionRegistry; /** * Test cases for json codec * @author sijuv * */ //TODO Exten repeated objects public class JsonCodecTest { private Types types; private String typesJson; private String helloworld="HelloWorld"; private String helloworldInBase64=Base64.encodeBase64String(helloworld.getBytes()); @Test(expected=IllegalArgumentException.class) public void ensureSafelyInitialized() throws IOException{ RepeatedFields repFields=RepeatedFields.newBuilder() .addId(1) .addId(2) .addLangs(Lang.HASKELL) .addLangs(Lang.JAVA).buildPartial(); new JsonCodec().fromMessage(repFields, new StringWriter()); } @Before public void setupTypes() throws IOException { types=Types.newBuilder() .setIdbool(true) .setIddouble(Double.MAX_VALUE) .setIdfixed32(Integer.MIN_VALUE) .setIdfixed64(Long.MIN_VALUE) .setIdfloat(Float.MAX_VALUE) .setIdint32(1) .setIdint64(5000000000000000000l) .setIdsfixed32(-56) .setIdsfixed64(-561234561435l) .setIdsint32(-100) .setIdsint64(Long.MAX_VALUE) .setIdstring("Hello World") .setIduint32(100) .setIduint64(100l) .setLang(Lang.HASKELL) .setIdbyte(ByteString.copyFromUtf8(helloworld)) .build(); JsonFactory factory=new JsonFactory(); StringWriter writer=new StringWriter(); JsonGenerator generator=factory.createJsonGenerator(writer); generator.writeStartObject(); generator.writeStringField("idstring", types.getIdstring()); generator.writeNumberField("idint32", types.getIdint32()); generator.writeNumberField("iddouble", types.getIddouble()); generator.writeNumberField("idfloat", types.getIdfloat()); generator.writeNumberField("idint64", types.getIdint64()); generator.writeNumberField("iduint32", types.getIduint32()); generator.writeNumberField("iduint64", types.getIduint64()); generator.writeNumberField("idsint32", types.getIdsint32()); generator.writeNumberField("idsint64", types.getIdsint64()); generator.writeNumberField("idfixed32", types.getIdfixed32()); generator.writeNumberField("idfixed64", types.getIdfixed64()); generator.writeNumberField("idsfixed32", types.getIdsfixed32()); generator.writeNumberField("idsfixed64", types.getIdsfixed64()); generator.writeBooleanField("idbool", types.getIdbool()); generator.writeStringField("lang", Lang.HASKELL.name()); generator.writeStringField("idbyte", helloworldInBase64); generator.writeEndObject(); generator.close(); typesJson=writer.toString(); } @Test public void ensureTypes() throws IOException{ Codec codec=new JsonCodec(); codec.setFeature(Feature.CLOSE_STREAM, true); ByteArrayOutputStream bos=new ByteArrayOutputStream(); codec.fromMessage(types, bos); String jsonResponse=new String(bos.toByteArray()); assertEquals(typesJson, jsonResponse); assertEquals(types, codec.toMessage(Types.class, new StringReader(typesJson))); } @Test public void ensureRepeatedFields() throws IOException{ RepeatedFields repFields=RepeatedFields.newBuilder() .addId(1) .addId(2) .addLangs(Lang.HASKELL) .addLangs(Lang.JAVA) .addVersions(Version.newBuilder() .setName("release") .setVernum(1) .build()) .addVersions(Version.newBuilder() .setName("nightly") .setVernum(2) .build()) .addNames("funny") .addNames("bones") .setFieldId(5) .build(); StringWriter writer1=new StringWriter(); new JsonCodec().fromMessage(repFields, writer1); StringWriter writer=new StringWriter(); JsonGenerator generator=(new JsonFactory()).createJsonGenerator(writer); generator.writeStartObject(); generator.writeNumberField("fieldId", 5); generator.writeArrayFieldStart("id"); generator.writeNumber( 1); generator.writeNumber( 2); generator.writeEndArray(); generator.writeArrayFieldStart("names"); generator.writeString("funny"); generator.writeString("bones"); generator.writeEndArray(); generator.writeArrayFieldStart("versions"); generator.writeStartObject(); generator.writeStringField("name", "release"); generator.writeNumberField("vernum", 1); generator.writeEndObject(); generator.writeStartObject(); generator.writeStringField("name", "nightly"); generator.writeNumberField("vernum", 2); generator.writeEndObject(); generator.writeEndArray(); generator.writeArrayFieldStart("langs"); generator.writeString( Lang.HASKELL.name()); generator.writeString( Lang.JAVA.name()); generator.writeEndArray(); generator.writeEndObject(); generator.close(); assertEquals(writer1.toString(), writer.toString()); assertEquals(repFields, new JsonCodec().toMessage(RepeatedFields.class, new StringReader(writer1.toString()))); } @Test public void testForExtensionsWithRegistry() throws IOException{ Foo foo=Foo.newBuilder() .setId(1) .setName("Hello World") .setExtension(TypesProtoBuf.langs, new ArrayList<Lang>(){{ add(Lang.HASKELL); add(Lang.JAVA); }}) .setExtension(TypesProtoBuf.alias, "Hi There") .build(); StringWriter writer=new StringWriter(); JsonGenerator generator=new JsonFactory().createJsonGenerator(writer); generator.writeStartObject(); generator.writeNumberField("id", 1); generator.writeStringField("name", "Hello World"); generator.writeStringField(Codec.DEFAULT_EXTENSION_NAME_PREFIX+"-"+"alias", "Hi There"); generator.writeArrayFieldStart(Codec.DEFAULT_EXTENSION_NAME_PREFIX+"-"+"langs"); generator.writeString(Lang.HASKELL.name()); generator.writeString(Lang.JAVA.name()); generator.writeEndArray(); generator.writeEndObject(); generator.close(); StringWriter codecout=new StringWriter(); new JsonCodec().fromMessage(foo, codecout); assertEquals(codecout.toString(),writer.toString()); ExtensionRegistry reg=ExtensionRegistry.newInstance(); reg.add(TypesProtoBuf.alias); reg.add(TypesProtoBuf.langs); assertEquals(new JsonCodec().toMessage(Foo.class, new StringReader(codecout.toString()),reg),foo); } @Test public void testForExtensionsWithoutRegistry() throws IOException{ Foo foo=Foo.newBuilder() .setId(1) .setName("Hello World") .setExtension(TypesProtoBuf.langs, new ArrayList<Lang>(){{ add(Lang.HASKELL); add(Lang.JAVA); }}) .setExtension(TypesProtoBuf.alias, "Hi There") .build(); StringWriter writer=new StringWriter(); JsonGenerator generator=new JsonFactory().createJsonGenerator(writer); generator.writeStartObject(); generator.writeNumberField("id", 1); generator.writeStringField("name", "Hello World"); generator.writeStringField(Codec.DEFAULT_EXTENSION_NAME_PREFIX+"-"+"alias", "Hi There"); generator.writeArrayFieldStart(Codec.DEFAULT_EXTENSION_NAME_PREFIX+"-"+"langs"); generator.writeString(Lang.HASKELL.name()); generator.writeString(Lang.JAVA.name()); generator.writeEndArray(); generator.writeEndObject(); generator.close(); StringWriter codecout=new StringWriter(); new JsonCodec().fromMessage(foo, codecout); assertEquals(codecout.toString(),writer.toString()); Foo foo1=Foo.newBuilder() .setId(1) .setName("Hello World").build(); assertEquals(new JsonCodec().toMessage(Foo.class, new StringReader(codecout.toString())),foo1); } @Test public void testExtensionObjects()throws Exception{ Foo foo1=Foo.newBuilder() .setId(1) .setName("Hello World") .setExtension(TypesProtoBuf.langs, new ArrayList<Lang>(){{ add(Lang.HASKELL); add(Lang.JAVA); }}) .addExtension(TypesProtoBuf.version,Version.newBuilder() .setName("release") .setVernum(1) .build()) .addExtension(TypesProtoBuf.version,Version.newBuilder() .setName("nightly") .setVernum(2) .build()) .setExtension(TypesProtoBuf.version1,Version.newBuilder() .setName("snapshot") .setVernum(10) .build()) .setExtension(TypesProtoBuf.alias, "Hi There") .build(); StringWriter sw=new StringWriter(); Codec codec=new JsonCodec(); codec.fromMessage(foo1, sw); StringWriter writer=new StringWriter(); JsonGenerator generator=new JsonFactory().createJsonGenerator(writer); generator.writeStartObject(); generator.writeNumberField("id", 1); generator.writeStringField("name", "Hello World"); generator.writeStringField(Codec.DEFAULT_EXTENSION_NAME_PREFIX+"-"+"alias", "Hi There"); generator.writeArrayFieldStart(Codec.DEFAULT_EXTENSION_NAME_PREFIX+"-"+"langs"); generator.writeString(Lang.HASKELL.name()); generator.writeString(Lang.JAVA.name()); generator.writeEndArray(); generator.writeArrayFieldStart(Codec.DEFAULT_EXTENSION_NAME_PREFIX+"-"+"version"); generator.writeStartObject(); generator.writeStringField("name", "release"); generator.writeNumberField("vernum", 1); generator.writeEndObject(); generator.writeStartObject(); generator.writeStringField("name", "nightly"); generator.writeNumberField("vernum", 2); generator.writeEndObject(); generator.writeEndArray(); generator.writeFieldName(Codec.DEFAULT_EXTENSION_NAME_PREFIX+"-"+"version1"); generator.writeStartObject(); generator.writeStringField("name", "snapshot"); generator.writeNumberField("vernum", 10); generator.writeEndObject(); generator.writeEndObject(); generator.close(); assertEquals(writer.toString(), sw.toString()); //System.out.println(writer.toString()); Foo foo2= codec.toMessage(Foo.class, new StringReader(writer.toString())); Foo foonoextn=Foo.newBuilder().setId(1).setName("Hello World").build(); assertEquals(foo2,foonoextn); ExtensionRegistry reg=ExtensionRegistry.newInstance(); reg.add(TypesProtoBuf.alias); reg.add(TypesProtoBuf.langs); reg.add(TypesProtoBuf.version); reg.add(TypesProtoBuf.version1); foo2=codec.toMessage(Foo.class, new StringReader(writer.toString()),reg); assertEquals(foo1, foo2); } @Test public void testForFieldNameReplacements() throws Exception { Foo obj = Foo.newBuilder().setId(1).setName("FooName").build(); StringWriter writer = new StringWriter(); JsonGenerator generator = new JsonFactory().createJsonGenerator(writer); generator.writeStartObject(); generator.writeNumberField("_id", 1); generator.writeStringField("name_", "FooName"); generator.writeEndObject(); generator.close(); Codec codec = new JsonCodec(); Map<String, String> replaces = new HashMap<String, String>(); replaces.put("name", "name_"); replaces.put("id", "_id"); codec.setFeature(Codec.Feature.FIELD_NAME_WRITE_SUBSTITUTES, replaces); replaces = new HashMap<String, String>(); replaces.put("name_", "name"); replaces.put("_id", "id"); codec.setFeature(Codec.Feature.FIELD_NAME_READ_SUBSTITUTES, replaces); StringWriter out = new StringWriter(); codec.fromMessage(obj, out); assertEquals(writer.toString(), out.toString()); Foo msg = codec.toMessage(Foo.class, new StringReader(out.toString())); assertEquals(obj, msg); } }