Skip to content

Commit 2b42bb4

Browse files
committed
Issue #35
- use the same char set when converting from characters to bytes and back again. - Remove usage of deprecated jsonFactory API in order to respect charset when printing to an OutputStream using the JsonJacksonFormat. - Added test class hierarchy to match production code hierarchy so tests do not need to be duplicated for each ProtobufFormatter.
1 parent 6a1b6f8 commit 2b42bb4

File tree

5 files changed

+72
-6
lines changed

5 files changed

+72
-6
lines changed

src/main/java/com/googlecode/protobuf/format/JsonJacksonFormat.java

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
3333
import java.io.IOException;
3434
import java.io.InputStream;
3535
import java.io.OutputStream;
36+
import java.io.OutputStreamWriter;
3637
import java.math.BigInteger;
3738
import java.nio.charset.Charset;
3839
import java.util.Iterator;
@@ -78,7 +79,7 @@ public class JsonJacksonFormat extends ProtobufFormatter {
7879
* original Protocol Buffer system)
7980
*/
8081
public void print(final Message message, OutputStream output, Charset cs) throws IOException {
81-
JsonGenerator generator = createGenerator(output);
82+
JsonGenerator generator = createGenerator(output, cs);
8283
print(message, generator);
8384
generator.close();
8485
}
@@ -144,9 +145,12 @@ public void merge(JsonParser parser,
144145
}
145146

146147

147-
148148
protected JsonGenerator createGenerator(OutputStream output) throws IOException {
149-
JsonGenerator generator = jsonFactory.createJsonGenerator(output, JsonEncoding.UTF8);
149+
return createGenerator(output, Charset.forName(JsonEncoding.UTF8.getJavaName()));
150+
}
151+
152+
private JsonGenerator createGenerator(OutputStream output, Charset cs) throws IOException {
153+
JsonGenerator generator = jsonFactory.createGenerator(new OutputStreamWriter(output, cs));
150154
generator.disable(JsonGenerator.Feature.AUTO_CLOSE_TARGET);
151155
return generator;
152156
}

src/main/java/com/googlecode/protobuf/format/ProtobufFormatter.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -88,7 +88,7 @@ public String printToString(final Message message) {
8888
ByteArrayOutputStream out = new ByteArrayOutputStream();
8989
print(message, out, defaultCharset);
9090
out.flush();
91-
return out.toString();
91+
return out.toString(defaultCharset.name());
9292
} catch (IOException e) {
9393
throw new RuntimeException("Writing to a StringBuilder threw an IOException (should never happen).",
9494
e);

src/test/java/com/googlecode/protobuf/format/JsonFormatTest.java

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@
2525
* @author scr on 10/13/15.
2626
*/
2727
@Test
28-
public class JsonFormatTest {
28+
public class JsonFormatTest extends ProtobufFormatterTest<JsonFormat> {
2929
private static final String RESOURCE_PATH = "/expectations/JsonFormatTest/";
3030
private static final FormatFactory FORMAT_FACTORY = new FormatFactory();
3131
private static final JsonFormat JSON_FORMATTER =
@@ -35,6 +35,11 @@ private static String getExpected(String name) throws IOException {
3535
return Files.readFile(JsonFormatTest.class.getResourceAsStream(RESOURCE_PATH + name)).trim();
3636
}
3737

38+
@Override
39+
protected JsonFormat getFormatterUnderTest() {
40+
return new JsonFormat();
41+
}
42+
3843
@DataProvider(name = "data")
3944
public static Object[][] data() throws IOException {
4045
return new Object[][]{

src/test/java/com/googlecode/protobuf/format/JsonJacksonFormatTest.java

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,9 +21,14 @@
2121
* @author scr on 10/13/15.
2222
*/
2323
@Test
24-
public class JsonJacksonFormatTest {
24+
public class JsonJacksonFormatTest extends ProtobufFormatterTest<JsonJacksonFormat> {
2525
private static final JsonFactory JSON_FACTORY = new JsonFactory();
2626

27+
@Override
28+
protected JsonJacksonFormat getFormatterUnderTest() {
29+
return new JsonJacksonFormat();
30+
}
31+
2732
@Test
2833
public void testPrettyPrint() throws Exception {
2934
StringWriter writer = new StringWriter();
Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
package com.googlecode.protobuf.format;
2+
3+
import org.testng.annotations.BeforeMethod;
4+
import org.testng.annotations.Test;
5+
import protobuf_unittest.UnittestProto;
6+
7+
import java.io.ByteArrayOutputStream;
8+
import java.io.IOException;
9+
import java.nio.charset.Charset;
10+
11+
import static org.hamcrest.CoreMatchers.containsString;
12+
import static org.hamcrest.MatcherAssert.assertThat;
13+
import static org.testng.Assert.assertNotEquals;
14+
15+
public abstract class ProtobufFormatterTest<T extends ProtobufFormatter> {
16+
private T protobufFormatter;
17+
private Charset platformDefaultCharset = Charset.defaultCharset();
18+
private Charset nonDefaultCharset = Charset.forName("UTF-16");
19+
private String testData = "A";
20+
private final String testDataAsJson = "\"" + testData + "\"";
21+
private UnittestProto.OneString testProto = UnittestProto.OneString.newBuilder().setData(testData).build();
22+
23+
protected abstract T getFormatterUnderTest();
24+
25+
@BeforeMethod
26+
public void setUp() throws Exception {
27+
protobufFormatter = getFormatterUnderTest();
28+
}
29+
30+
@Test
31+
public void validateTestSetUp() {
32+
//test is redundant unless default and non default charsets produce different results
33+
assertNotEquals(platformDefaultCharset, nonDefaultCharset);
34+
byte[] nonDefaultBytes = testData.getBytes(nonDefaultCharset);
35+
assertNotEquals(testData.getBytes(platformDefaultCharset), nonDefaultBytes);
36+
assertNotEquals(testData, new String(nonDefaultBytes, platformDefaultCharset));
37+
}
38+
39+
@Test
40+
public void canSerialiseToBytesUsingNonDefaultCharset() throws IOException {
41+
ByteArrayOutputStream output = new ByteArrayOutputStream();
42+
protobufFormatter.print(testProto, output, nonDefaultCharset);
43+
assertThat(output.toString(nonDefaultCharset.name()), containsString(testDataAsJson));
44+
}
45+
46+
@Test
47+
public void canSerialiseUsingNonDefaultCharSet() {
48+
protobufFormatter.setDefaultCharset(nonDefaultCharset);
49+
UnittestProto.OneString message = UnittestProto.OneString.newBuilder().setData(testData).build();
50+
assertThat(protobufFormatter.printToString(message), containsString(testDataAsJson));
51+
}
52+
}

0 commit comments

Comments
 (0)