Protocol Buffers - Google's data interchange format (grpc依赖)
https://developers.google.com/protocol-buffers/
468 lines
19 KiB
468 lines
19 KiB
using System; |
|
using System.IO; |
|
using System.Text; |
|
using System.Xml; |
|
using Google.ProtocolBuffers.Serialization; |
|
using Google.ProtocolBuffers.TestProtos; |
|
using NUnit.Framework; |
|
|
|
namespace Google.ProtocolBuffers |
|
{ |
|
public class TestWriterFormatXml |
|
{ |
|
[Test] |
|
public void Example_FromXml() |
|
{ |
|
TestXmlMessage.Builder builder = TestXmlMessage.CreateBuilder(); |
|
|
|
XmlReader rdr = XmlReader.Create(new StringReader(@"<root><valid>true</valid></root>")); |
|
//3.5: builder.MergeFromXml(rdr); |
|
Extensions.MergeFromXml(builder, rdr); |
|
|
|
TestXmlMessage message = builder.Build(); |
|
Assert.AreEqual(true, message.Valid); |
|
} |
|
|
|
[Test] |
|
public void Example_ToXml() |
|
{ |
|
TestXmlMessage message = |
|
TestXmlMessage.CreateBuilder() |
|
.SetValid(true) |
|
.Build(); |
|
|
|
//3.5: string Xml = message.ToXml(); |
|
string Xml = Extensions.ToXml(message); |
|
|
|
Assert.AreEqual(@"<root><valid>true</valid></root>", Xml); |
|
} |
|
|
|
[Test] |
|
public void Example_WriteXmlUsingICodedOutputStream() |
|
{ |
|
TestXmlMessage message = |
|
TestXmlMessage.CreateBuilder() |
|
.SetValid(true) |
|
.Build(); |
|
|
|
using (TextWriter output = new StringWriter()) |
|
{ |
|
ICodedOutputStream writer = XmlFormatWriter.CreateInstance(output); |
|
writer.WriteMessageStart(); //manually begin the message, output is '{' |
|
|
|
ICodedOutputStream stream = writer; |
|
message.WriteTo(stream); //write the message normally |
|
|
|
writer.WriteMessageEnd(); //manually write the end message '}' |
|
Assert.AreEqual(@"<root><valid>true</valid></root>", output.ToString()); |
|
} |
|
} |
|
|
|
[Test] |
|
public void Example_ReadXmlUsingICodedInputStream() |
|
{ |
|
TestXmlMessage.Builder builder = TestXmlMessage.CreateBuilder(); |
|
ICodedInputStream reader = XmlFormatReader.CreateInstance(@"<root><valid>true</valid></root>"); |
|
|
|
reader.ReadMessageStart(); //manually read the begin the message '{' |
|
|
|
builder.MergeFrom(reader); //read the message normally |
|
|
|
reader.ReadMessageEnd(); //manually read the end message '}' |
|
} |
|
|
|
[Test] |
|
public void TestToXmlParseFromXml() |
|
{ |
|
TestAllTypes msg = new TestAllTypes.Builder().SetDefaultBool(true).Build(); |
|
string xml = Extensions.ToXml(msg); |
|
Assert.AreEqual("<root><default_bool>true</default_bool></root>", xml); |
|
TestAllTypes copy = Extensions.MergeFromXml(new TestAllTypes.Builder(), XmlReader.Create(new StringReader(xml))).Build(); |
|
Assert.IsTrue(copy.HasDefaultBool && copy.DefaultBool); |
|
Assert.AreEqual(msg, copy); |
|
} |
|
|
|
[Test] |
|
public void TestToXmlParseFromXmlWithRootName() |
|
{ |
|
TestAllTypes msg = new TestAllTypes.Builder().SetDefaultBool(true).Build(); |
|
string xml = Extensions.ToXml(msg, "message"); |
|
Assert.AreEqual("<message><default_bool>true</default_bool></message>", xml); |
|
TestAllTypes copy = Extensions.MergeFromXml(new TestAllTypes.Builder(), "message", XmlReader.Create(new StringReader(xml))).Build(); |
|
Assert.IsTrue(copy.HasDefaultBool && copy.DefaultBool); |
|
Assert.AreEqual(msg, copy); |
|
} |
|
|
|
[Test] |
|
public void TestEmptyMessage() |
|
{ |
|
TestXmlChild message = TestXmlChild.CreateBuilder() |
|
.Build(); |
|
|
|
StringWriter sw = new StringWriter(); |
|
XmlWriter xw = XmlWriter.Create(sw); |
|
|
|
//When we call message.WriteTo, we are responsible for the root element |
|
xw.WriteStartElement("root"); |
|
message.WriteTo(XmlFormatWriter.CreateInstance(xw)); |
|
xw.WriteEndElement(); |
|
xw.Flush(); |
|
|
|
string xml = sw.ToString(); |
|
XmlFormatReader rdr = XmlFormatReader.CreateInstance(xml); |
|
TestXmlChild copy = rdr.Merge(TestXmlChild.CreateBuilder()).Build(); |
|
Assert.AreEqual(message, copy); |
|
} |
|
[Test] |
|
public void TestRepeatedField() |
|
{ |
|
TestXmlChild message = TestXmlChild.CreateBuilder() |
|
.AddOptions(EnumOptions.ONE) |
|
.AddOptions(EnumOptions.TWO) |
|
.Build(); |
|
|
|
//Allow the writer to write the root element |
|
StringWriter sw = new StringWriter(); |
|
XmlFormatWriter.CreateInstance(sw).WriteMessage("root", message); |
|
|
|
string xml = sw.ToString(); |
|
XmlFormatReader rdr = XmlFormatReader.CreateInstance(xml); |
|
TestXmlChild copy = rdr.Merge(TestXmlChild.CreateBuilder()).Build(); |
|
Assert.AreEqual(message, copy); |
|
} |
|
|
|
[Test] |
|
public void TestNestedEmptyMessage() |
|
{ |
|
TestXmlMessage message = TestXmlMessage.CreateBuilder() |
|
.SetChild(TestXmlChild.CreateBuilder().Build()) |
|
.Build(); |
|
|
|
StringWriter sw = new StringWriter(); |
|
XmlFormatWriter.CreateInstance(sw).WriteMessage("root", message); |
|
|
|
string xml = sw.ToString(); |
|
XmlFormatReader rdr = XmlFormatReader.CreateInstance(xml); |
|
TestXmlMessage copy = rdr.Merge(TestXmlMessage.CreateBuilder()).Build(); |
|
Assert.AreEqual(message, copy); |
|
} |
|
|
|
[Test] |
|
public void TestNestedMessage() |
|
{ |
|
TestXmlMessage message = TestXmlMessage.CreateBuilder() |
|
.SetChild(TestXmlChild.CreateBuilder().AddOptions(EnumOptions.TWO).Build()) |
|
.Build(); |
|
|
|
StringWriter sw = new StringWriter(); |
|
XmlFormatWriter.CreateInstance(sw).WriteMessage("root", message); |
|
|
|
string xml = sw.ToString(); |
|
XmlFormatReader rdr = XmlFormatReader.CreateInstance(xml); |
|
TestXmlMessage copy = rdr.Merge(TestXmlMessage.CreateBuilder()).Build(); |
|
Assert.AreEqual(message, copy); |
|
} |
|
|
|
[Test] |
|
public void TestBooleanTypes() |
|
{ |
|
TestXmlMessage message = TestXmlMessage.CreateBuilder() |
|
.SetValid(true) |
|
.Build(); |
|
|
|
StringWriter sw = new StringWriter(); |
|
XmlFormatWriter.CreateInstance(sw).WriteMessage("root", message); |
|
|
|
string xml = sw.ToString(); |
|
XmlFormatReader rdr = XmlFormatReader.CreateInstance(xml); |
|
TestXmlMessage copy = rdr.Merge(TestXmlMessage.CreateBuilder()).Build(); |
|
Assert.AreEqual(message, copy); |
|
} |
|
|
|
[Test] |
|
public void TestFullMessage() |
|
{ |
|
TestXmlMessage message = TestXmlMessage.CreateBuilder() |
|
.SetValid(true) |
|
.SetText("text") |
|
.AddTextlines("a") |
|
.AddTextlines("b") |
|
.AddTextlines("c") |
|
.SetNumber(0x1010101010) |
|
.AddNumbers(1) |
|
.AddNumbers(2) |
|
.AddNumbers(3) |
|
.SetChild(TestXmlChild.CreateBuilder().AddOptions(EnumOptions.ONE).SetBinary(ByteString.CopyFrom(new byte[1]))) |
|
.AddChildren(TestXmlMessage.Types.Children.CreateBuilder().AddOptions(EnumOptions.TWO).SetBinary(ByteString.CopyFrom(new byte[2]))) |
|
.AddChildren(TestXmlMessage.Types.Children.CreateBuilder().AddOptions(EnumOptions.THREE).SetBinary(ByteString.CopyFrom(new byte[3]))) |
|
.Build(); |
|
|
|
StringWriter sw = new StringWriter(); |
|
XmlWriter xwtr = XmlWriter.Create(sw, new XmlWriterSettings {Indent = true, IndentChars = " "}); |
|
|
|
XmlFormatWriter.CreateInstance(xwtr).WriteMessage("root", message); |
|
|
|
string xml = sw.ToString(); |
|
|
|
XmlFormatReader rdr = XmlFormatReader.CreateInstance(xml); |
|
TestXmlMessage copy = rdr.Merge(TestXmlMessage.CreateBuilder()).Build(); |
|
Assert.AreEqual(message, copy); |
|
} |
|
|
|
[Test] |
|
public void TestFullMessageWithRichTypes() |
|
{ |
|
TestXmlMessage message = TestXmlMessage.CreateBuilder() |
|
.SetValid(true) |
|
.SetText("text") |
|
.AddTextlines("a") |
|
.AddTextlines("b") |
|
.AddTextlines("c") |
|
.SetNumber(0x1010101010) |
|
.AddNumbers(1) |
|
.AddNumbers(2) |
|
.AddNumbers(3) |
|
.SetChild(TestXmlChild.CreateBuilder().AddOptions(EnumOptions.ONE).SetBinary(ByteString.CopyFrom(new byte[1]))) |
|
.AddChildren(TestXmlMessage.Types.Children.CreateBuilder().AddOptions(EnumOptions.TWO).SetBinary(ByteString.CopyFrom(new byte[2]))) |
|
.AddChildren(TestXmlMessage.Types.Children.CreateBuilder().AddOptions(EnumOptions.THREE).SetBinary(ByteString.CopyFrom(new byte[3]))) |
|
.Build(); |
|
|
|
StringWriter sw = new StringWriter(); |
|
XmlWriter xwtr = XmlWriter.Create(sw, new XmlWriterSettings { Indent = true, IndentChars = " " }); |
|
|
|
XmlFormatWriter.CreateInstance(xwtr) |
|
.SetOptions(XmlWriterOptions.OutputNestedArrays | XmlWriterOptions.OutputEnumValues) |
|
.WriteMessage("root", message); |
|
|
|
string xml = sw.ToString(); |
|
|
|
XmlFormatReader rdr = XmlFormatReader.CreateInstance(xml); |
|
rdr.Options = XmlReaderOptions.ReadNestedArrays; |
|
TestXmlMessage copy = rdr.Merge(TestXmlMessage.CreateBuilder()).Build(); |
|
Assert.AreEqual(message, copy); |
|
} |
|
|
|
[Test] |
|
public void TestFullMessageWithUnknownFields() |
|
{ |
|
TestXmlMessage origial = TestXmlMessage.CreateBuilder() |
|
.SetValid(true) |
|
.SetText("text") |
|
.AddTextlines("a") |
|
.AddTextlines("b") |
|
.AddTextlines("c") |
|
.SetNumber(0x1010101010) |
|
.AddNumbers(1) |
|
.AddNumbers(2) |
|
.AddNumbers(3) |
|
.SetChild(TestXmlChild.CreateBuilder().AddOptions(EnumOptions.ONE).SetBinary(ByteString.CopyFrom(new byte[1]))) |
|
.AddChildren(TestXmlMessage.Types.Children.CreateBuilder().AddOptions(EnumOptions.TWO).SetBinary(ByteString.CopyFrom(new byte[2]))) |
|
.AddChildren(TestXmlMessage.Types.Children.CreateBuilder().AddOptions(EnumOptions.THREE).SetBinary(ByteString.CopyFrom(new byte[3]))) |
|
.Build(); |
|
TestXmlNoFields message = TestXmlNoFields.CreateBuilder().MergeFrom(origial.ToByteArray()).Build(); |
|
|
|
Assert.AreEqual(0, message.AllFields.Count); |
|
|
|
StringWriter sw = new StringWriter(); |
|
XmlFormatWriter.CreateInstance(sw) |
|
.SetOptions(XmlWriterOptions.OutputNestedArrays | XmlWriterOptions.OutputEnumValues) |
|
.WriteMessage("root", message); |
|
|
|
string xml = sw.ToString(); |
|
|
|
using (XmlReader x = XmlReader.Create(new StringReader(xml))) |
|
{ |
|
x.MoveToContent(); |
|
Assert.AreEqual(XmlNodeType.Element, x.NodeType); |
|
//should always be empty |
|
Assert.IsTrue(x.IsEmptyElement || |
|
(x.Read() && x.NodeType == XmlNodeType.EndElement) |
|
); |
|
} |
|
|
|
XmlFormatReader rdr = XmlFormatReader.CreateInstance(xml); |
|
rdr.Options = XmlReaderOptions.ReadNestedArrays; |
|
TestXmlMessage copy = rdr.Merge(TestXmlMessage.CreateBuilder()).Build(); |
|
Assert.AreEqual(TestXmlMessage.DefaultInstance, copy); |
|
} |
|
|
|
[Test] |
|
public void TestMessageWithXmlText() |
|
{ |
|
TestXmlMessage message = TestXmlMessage.CreateBuilder() |
|
.SetText("<text>").Build(); |
|
|
|
StringWriter sw = new StringWriter(); |
|
XmlFormatWriter.CreateInstance(sw).WriteMessage("root", message); |
|
|
|
string xml = sw.ToString(); |
|
|
|
XmlFormatReader rdr = XmlFormatReader.CreateInstance(xml); |
|
TestXmlMessage copy = rdr.Merge(TestXmlMessage.CreateBuilder()).Build(); |
|
Assert.AreEqual(message, copy); |
|
} |
|
|
|
[Test] |
|
public void TestXmlWithWhitespace() |
|
{ |
|
TestXmlMessage message = TestXmlMessage.CreateBuilder() |
|
.SetText(" \t <- leading space and trailing -> \r\n\t").Build(); |
|
|
|
StringWriter sw = new StringWriter(); |
|
XmlFormatWriter.CreateInstance(sw).WriteMessage("root", message); |
|
|
|
string xml = sw.ToString(); |
|
|
|
XmlFormatReader rdr = XmlFormatReader.CreateInstance(xml); |
|
TestXmlMessage copy = rdr.Merge(TestXmlMessage.CreateBuilder()).Build(); |
|
Assert.AreEqual(message, copy); |
|
} |
|
|
|
[Test] |
|
public void TestXmlWithExtensionText() |
|
{ |
|
TestXmlMessage message = TestXmlMessage.CreateBuilder() |
|
.SetExtension(UnittestExtrasXmltest.ExtensionText, " extension text value ! ") |
|
.Build(); |
|
|
|
StringWriter sw = new StringWriter(); |
|
XmlFormatWriter.CreateInstance(sw).WriteMessage("root", message); |
|
|
|
string xml = sw.ToString(); |
|
|
|
ExtensionRegistry registry = ExtensionRegistry.CreateInstance(); |
|
UnittestExtrasXmltest.RegisterAllExtensions(registry); |
|
|
|
XmlFormatReader rdr = XmlFormatReader.CreateInstance(xml); |
|
TestXmlMessage copy = rdr.Merge(TestXmlMessage.CreateBuilder(), registry).Build(); |
|
Assert.AreEqual(message, copy); |
|
} |
|
|
|
[Test] |
|
public void TestXmlWithExtensionMessage() |
|
{ |
|
TestXmlMessage message = TestXmlMessage.CreateBuilder() |
|
.SetExtension(UnittestExtrasXmltest.ExtensionMessage, |
|
new TestXmlExtension.Builder().SetNumber(42).Build()).Build(); |
|
|
|
StringWriter sw = new StringWriter(); |
|
XmlFormatWriter.CreateInstance(sw).WriteMessage("root", message); |
|
|
|
string xml = sw.ToString(); |
|
|
|
ExtensionRegistry registry = ExtensionRegistry.CreateInstance(); |
|
UnittestExtrasXmltest.RegisterAllExtensions(registry); |
|
|
|
XmlFormatReader rdr = XmlFormatReader.CreateInstance(xml); |
|
TestXmlMessage copy = rdr.Merge(TestXmlMessage.CreateBuilder(), registry).Build(); |
|
Assert.AreEqual(message, copy); |
|
} |
|
|
|
[Test] |
|
public void TestXmlWithExtensionArray() |
|
{ |
|
TestXmlMessage message = TestXmlMessage.CreateBuilder() |
|
.AddExtension(UnittestExtrasXmltest.ExtensionNumber, 100) |
|
.AddExtension(UnittestExtrasXmltest.ExtensionNumber, 101) |
|
.AddExtension(UnittestExtrasXmltest.ExtensionNumber, 102) |
|
.Build(); |
|
|
|
StringWriter sw = new StringWriter(); |
|
XmlFormatWriter.CreateInstance(sw).WriteMessage("root", message); |
|
|
|
string xml = sw.ToString(); |
|
|
|
ExtensionRegistry registry = ExtensionRegistry.CreateInstance(); |
|
UnittestExtrasXmltest.RegisterAllExtensions(registry); |
|
|
|
XmlFormatReader rdr = XmlFormatReader.CreateInstance(xml); |
|
TestXmlMessage copy = rdr.Merge(TestXmlMessage.CreateBuilder(), registry).Build(); |
|
Assert.AreEqual(message, copy); |
|
} |
|
|
|
[Test] |
|
public void TestXmlWithExtensionEnum() |
|
{ |
|
TestXmlMessage message = TestXmlMessage.CreateBuilder() |
|
.SetExtension(UnittestExtrasXmltest.ExtensionEnum, EnumOptions.ONE) |
|
.Build(); |
|
|
|
StringWriter sw = new StringWriter(); |
|
XmlFormatWriter.CreateInstance(sw).WriteMessage("root", message); |
|
|
|
string xml = sw.ToString(); |
|
|
|
ExtensionRegistry registry = ExtensionRegistry.CreateInstance(); |
|
UnittestExtrasXmltest.RegisterAllExtensions(registry); |
|
|
|
XmlFormatReader rdr = XmlFormatReader.CreateInstance(xml); |
|
TestXmlMessage copy = rdr.Merge(TestXmlMessage.CreateBuilder(), registry).Build(); |
|
Assert.AreEqual(message, copy); |
|
} |
|
|
|
[Test] |
|
public void TestXmlReadEmptyRoot() |
|
{ |
|
TestXmlMessage.Builder builder = TestXmlMessage.CreateBuilder(); |
|
ICodedInputStream reader = XmlFormatReader.CreateInstance(@"<root/>"); |
|
|
|
reader.ReadMessageStart(); //manually read the begin the message '{' |
|
|
|
builder.MergeFrom(reader); //write the message normally |
|
|
|
reader.ReadMessageEnd(); //manually read the end message '}' |
|
} |
|
|
|
[Test] |
|
public void TestXmlReadEmptyChild() |
|
{ |
|
TestXmlMessage.Builder builder = TestXmlMessage.CreateBuilder(); |
|
ICodedInputStream reader = XmlFormatReader.CreateInstance(@"<root><text /></root>"); |
|
|
|
reader.ReadMessageStart(); //manually read the begin the message '{' |
|
|
|
builder.MergeFrom(reader); //write the message normally |
|
Assert.IsTrue(builder.HasText); |
|
Assert.AreEqual(String.Empty, builder.Text); |
|
} |
|
|
|
[Test] |
|
public void TestXmlReadWriteWithoutRoot() |
|
{ |
|
TestXmlMessage.Builder builder = TestXmlMessage.CreateBuilder(); |
|
TestXmlMessage message = builder.SetText("abc").SetNumber(123).Build(); |
|
|
|
string xml; |
|
using (StringWriter sw = new StringWriter()) |
|
{ |
|
ICodedOutputStream output = XmlFormatWriter.CreateInstance( |
|
XmlWriter.Create(sw, new XmlWriterSettings() { ConformanceLevel = ConformanceLevel.Fragment })); |
|
|
|
message.WriteTo(output); |
|
output.Flush(); |
|
xml = sw.ToString(); |
|
} |
|
Assert.AreEqual("<text>abc</text><number>123</number>", xml); |
|
|
|
TestXmlMessage copy; |
|
using (XmlReader xr = XmlReader.Create(new StringReader(xml), new XmlReaderSettings() { ConformanceLevel = ConformanceLevel.Fragment })) |
|
{ |
|
ICodedInputStream input = XmlFormatReader.CreateInstance(xr); |
|
copy = TestXmlMessage.CreateBuilder().MergeFrom(input).Build(); |
|
} |
|
|
|
Assert.AreEqual(message, copy); |
|
} |
|
|
|
[Test] |
|
public void TestRecursiveLimit() |
|
{ |
|
StringBuilder sb = new StringBuilder(8192); |
|
for (int i = 0; i < 80; i++) |
|
{ |
|
sb.Append("<child>"); |
|
} |
|
Assert.Throws<RecursionLimitExceededException>(() => Extensions.MergeFromXml(new TestXmlRescursive.Builder(), "child", XmlReader.Create(new StringReader(sb.ToString()))).Build()); |
|
} |
|
} |
|
}
|
|
|