Skip to content

Commit

Permalink
Support indented JSON formatting in csharp
Browse files Browse the repository at this point in the history
  • Loading branch information
boukeversteegh committed Jan 8, 2022
1 parent 0ac74b8 commit cfa4fa3
Show file tree
Hide file tree
Showing 2 changed files with 310 additions and 59 deletions.
188 changes: 182 additions & 6 deletions csharp/src/Google.Protobuf.Test/JsonFormatterTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,8 @@ namespace Google.Protobuf
/// </summary>
public class JsonFormatterTest
{
private static readonly JsonFormatter JsonFormatterPretty = new JsonFormatter(JsonFormatter.Settings.Default.WithIndentation());

[Test]
public void DefaultValues_WhenOmitted()
{
Expand Down Expand Up @@ -669,29 +671,203 @@ public void WriteValue_List()
AssertWriteValue(value, "[ 1, 2, 3 ]");
}

[Test]
public void WriteValuePretty_EmptyMessage()
{
var value = new TestEmptyMessage();

AssertWriteValue(value, "{}", JsonFormatterPretty);
}

[Test]
public void WriteValuePretty_NestedTestAllTypes()
{
var value = new NestedTestAllTypes
{
Payload = new TestAllTypes
{
SingleBool = true,
SingleInt32 = 100,
SingleString = "multiple fields",
RepeatedString = { "string1", "string2" },
},
Child = new NestedTestAllTypes
{
Payload = new TestAllTypes
{
SingleString = "single field",
},
},
RepeatedChild =
{
new NestedTestAllTypes { Payload = new TestAllTypes { SingleString = "child 1", RepeatedString = { "string" } } },
new NestedTestAllTypes { Payload = new TestAllTypes { SingleString = "child 2" } },
},
};

const string expectedJson = @"
{
'child': {
'payload': {
'singleString': 'single field'
}
},
'payload': {
'singleInt32': 100,
'singleBool': true,
'singleString': 'multiple fields',
'repeatedString': [
'string1',
'string2'
]
},
'repeatedChild': [
{
'payload': {
'singleString': 'child 1',
'repeatedString': [
'string'
]
}
},
{
'payload': {
'singleString': 'child 2'
}
}
]
}";
AssertWriteValue(value, expectedJson, JsonFormatterPretty);
}

[Test]
public void WriteValuePretty_WellKnownTypes()
{
var value = new TestWellKnownTypes
{
StructField = new Struct
{
Fields =
{
{ "string", Value.ForString("foo") },
{ "numbers", Value.ForList(Value.ForNumber(1), Value.ForNumber(2), Value.ForNumber(3)) },
{ "emptyList", Value.ForList() },
{ "emptyStruct", Value.ForStruct(new Struct()) },
},
},
};

const string expectedJson = @"
{
'structField': {
'string': 'foo',
'numbers': [
1,
2,
3
],
'emptyList': [],
'emptyStruct': {}
}
}";
AssertWriteValue(value, expectedJson, JsonFormatterPretty);
}

[Test]
public void WriteValuePretty_StructSingleField()
{
var value = new Struct { Fields = { { "structField1", Value.ForString("structFieldValue1") } } };

const string expectedJson = @"
{
'structField1': 'structFieldValue1'
}";
AssertWriteValue(value, expectedJson, JsonFormatterPretty);
}

[Test]
public void WriteValuePretty_StructMultipleFields()
{
var value = new Struct
{
Fields =
{
{ "structField1", Value.ForString("structFieldValue1") },
{ "structField2", Value.ForString("structFieldValue2") },
{ "structField3", Value.ForString("structFieldValue3") },
},
};

const string expectedJson = @"
{
'structField1': 'structFieldValue1',
'structField2': 'structFieldValue2',
'structField3': 'structFieldValue3'
}";
AssertWriteValue(value, expectedJson, JsonFormatterPretty);
}

[Test]
public void WriteValuePretty_Map()
{
var value = new TestMap
{
MapStringString =
{
{ "key1", "value1" },
{ "key2", "value2" },
},
};

const string expectedJson = @"
{
'mapStringString': {
'key1': 'value1',
'key2': 'value2'
}
}";

AssertWriteValue(value, expectedJson, JsonFormatterPretty);
}

[Test]
public void WriteValuePretty_List()
{
var value = new RepeatedField<int> { 1, 2, 3 };
AssertWriteValue(value, "[\n 1,\n 2,\n 3\n]", JsonFormatterPretty);
}

[Test]
public void WriteValuePretty_CustomIndentation()
{
var formatter = new JsonFormatter(JsonFormatter.Settings.Default.WithIndentation("\t"));
var value = new RepeatedField<int> { 1, 2, 3 };
AssertWriteValue(value, "[\n\t1,\n\t2,\n\t3\n]", formatter);
}

[Test]
public void Proto2_DefaultValuesWritten()
{
var value = new ProtobufTestMessages.Proto2.TestAllTypesProto2() { FieldName13 = 0 };
AssertWriteValue(value, "{ 'FieldName13': 0 }");
}

private static void AssertWriteValue(object value, string expectedJson)
private static void AssertWriteValue(object value, string expectedJson, JsonFormatter formatter = null)
{
var writer = new StringWriter();
JsonFormatter.Default.WriteValue(writer, value);
var writer = new StringWriter { NewLine = "\n" };
(formatter ?? JsonFormatter.Default).WriteValue(writer, value);
string actual = writer.ToString();
AssertJson(expectedJson, actual);
}

/// <summary>
/// Checks that the actual JSON is the same as the expected JSON - but after replacing
/// all apostrophes in the expected JSON with double quotes. This basically makes the tests easier
/// to read.
/// all apostrophes in the expected JSON with double quotes and trimming leading whitespace.
/// This basically makes the tests easier to read.
/// </summary>
private static void AssertJson(string expectedJsonWithApostrophes, string actualJson)
{
var expectedJson = expectedJsonWithApostrophes.Replace("'", "\"");
var expectedJson = expectedJsonWithApostrophes.Replace("'", "\"").TrimStart();
Assert.AreEqual(expectedJson, actualJson);
}
}
Expand Down
Loading

0 comments on commit cfa4fa3

Please sign in to comment.