aboutsummaryrefslogtreecommitdiff
path: root/csharp/src/Google.Protobuf.Test
diff options
context:
space:
mode:
authorJon Skeet <jonskeet@google.com>2015-11-23 16:21:47 +0000
committerJon Skeet <jonskeet@google.com>2015-12-02 07:54:34 +0000
commit3de2fced6be1cc5e8f321c5aee2bb43176be962a (patch)
tree2942a336c3eb43c792520bbfd75006f2b2f4c6a6 /csharp/src/Google.Protobuf.Test
parent567579b50517e4f7efc459ab1d9d5ee2577af024 (diff)
downloadprotobuf-3de2fced6be1cc5e8f321c5aee2bb43176be962a.tar.gz
protobuf-3de2fced6be1cc5e8f321c5aee2bb43176be962a.tar.bz2
protobuf-3de2fced6be1cc5e8f321c5aee2bb43176be962a.zip
Handle JSON parsing for Any.
This required a rework of the tokenizer to allow for a "replaying" tokenizer, basically in case the @type value comes after the data itself. This rework is nice in some ways (all the pushback and object depth logic in one place) but is a little fragile in terms of token push-back when using the replay tokenizer. It'll be fine for the scenario we need it for, but we should be careful...
Diffstat (limited to 'csharp/src/Google.Protobuf.Test')
-rw-r--r--csharp/src/Google.Protobuf.Test/JsonParserTest.cs50
-rw-r--r--csharp/src/Google.Protobuf.Test/JsonTokenizerTest.cs14
2 files changed, 57 insertions, 7 deletions
diff --git a/csharp/src/Google.Protobuf.Test/JsonParserTest.cs b/csharp/src/Google.Protobuf.Test/JsonParserTest.cs
index b3664770..874489e4 100644
--- a/csharp/src/Google.Protobuf.Test/JsonParserTest.cs
+++ b/csharp/src/Google.Protobuf.Test/JsonParserTest.cs
@@ -30,6 +30,7 @@
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#endregion
+using Google.Protobuf.Reflection;
using Google.Protobuf.TestProtos;
using Google.Protobuf.WellKnownTypes;
using NUnit.Framework;
@@ -718,6 +719,55 @@ namespace Google.Protobuf
}
[Test]
+ public void Any_RegularMessage()
+ {
+ var registry = TypeRegistry.FromMessages(TestAllTypes.Descriptor);
+ var formatter = new JsonFormatter(new JsonFormatter.Settings(false, TypeRegistry.FromMessages(TestAllTypes.Descriptor)));
+ var message = new TestAllTypes { SingleInt32 = 10, SingleNestedMessage = new TestAllTypes.Types.NestedMessage { Bb = 20 } };
+ var original = Any.Pack(message);
+ var json = formatter.Format(original); // This is tested in JsonFormatterTest
+ var parser = new JsonParser(new JsonParser.Settings(10, registry));
+ Assert.AreEqual(original, parser.Parse<Any>(json));
+ string valueFirstJson = "{ \"singleInt32\": 10, \"singleNestedMessage\": { \"bb\": 20 }, \"@type\": \"type.googleapis.com/protobuf_unittest.TestAllTypes\" }";
+ Assert.AreEqual(original, parser.Parse<Any>(valueFirstJson));
+ }
+
+ [Test]
+ public void Any_UnknownType()
+ {
+ string json = "{ \"@type\": \"type.googleapis.com/bogus\" }";
+ Assert.Throws<InvalidOperationException>(() => Any.Parser.ParseJson(json));
+ }
+
+ [Test]
+ public void Any_WellKnownType()
+ {
+ var registry = TypeRegistry.FromMessages(Timestamp.Descriptor);
+ var formatter = new JsonFormatter(new JsonFormatter.Settings(false, registry));
+ var timestamp = new DateTime(1673, 6, 19, 12, 34, 56, DateTimeKind.Utc).ToTimestamp();
+ var original = Any.Pack(timestamp);
+ var json = formatter.Format(original); // This is tested in JsonFormatterTest
+ var parser = new JsonParser(new JsonParser.Settings(10, registry));
+ Assert.AreEqual(original, parser.Parse<Any>(json));
+ string valueFirstJson = "{ \"value\": \"1673-06-19T12:34:56Z\", \"@type\": \"type.googleapis.com/google.protobuf.Timestamp\" }";
+ Assert.AreEqual(original, parser.Parse<Any>(valueFirstJson));
+ }
+
+ [Test]
+ public void Any_Nested()
+ {
+ var registry = TypeRegistry.FromMessages(TestWellKnownTypes.Descriptor, TestAllTypes.Descriptor);
+ var formatter = new JsonFormatter(new JsonFormatter.Settings(false, registry));
+ var parser = new JsonParser(new JsonParser.Settings(10, registry));
+ var doubleNestedMessage = new TestAllTypes { SingleInt32 = 20 };
+ var nestedMessage = Any.Pack(doubleNestedMessage);
+ var message = new TestWellKnownTypes { AnyField = Any.Pack(nestedMessage) };
+ var json = formatter.Format(message);
+ // Use the descriptor-based parser just for a change.
+ Assert.AreEqual(message, parser.Parse(json, TestWellKnownTypes.Descriptor));
+ }
+
+ [Test]
public void DataAfterObject()
{
string json = "{} 10";
diff --git a/csharp/src/Google.Protobuf.Test/JsonTokenizerTest.cs b/csharp/src/Google.Protobuf.Test/JsonTokenizerTest.cs
index a38efeed..a0a62227 100644
--- a/csharp/src/Google.Protobuf.Test/JsonTokenizerTest.cs
+++ b/csharp/src/Google.Protobuf.Test/JsonTokenizerTest.cs
@@ -85,7 +85,7 @@ namespace Google.Protobuf
public void ObjectDepth()
{
string json = "{ \"foo\": { \"x\": 1, \"y\": [ 0 ] } }";
- var tokenizer = new JsonTokenizer(new StringReader(json));
+ var tokenizer = JsonTokenizer.FromTextReader(new StringReader(json));
// If we had more tests like this, I'd introduce a helper method... but for one test, it's not worth it.
Assert.AreEqual(0, tokenizer.ObjectDepth);
Assert.AreEqual(JsonToken.StartObject, tokenizer.Next());
@@ -118,7 +118,7 @@ namespace Google.Protobuf
public void ObjectDepth_WithPushBack()
{
string json = "{}";
- var tokenizer = new JsonTokenizer(new StringReader(json));
+ var tokenizer = JsonTokenizer.FromTextReader(new StringReader(json));
Assert.AreEqual(0, tokenizer.ObjectDepth);
var token = tokenizer.Next();
Assert.AreEqual(1, tokenizer.ObjectDepth);
@@ -275,7 +275,7 @@ namespace Google.Protobuf
// Note: we don't test that the earlier tokens are exactly as expected,
// partly because that's hard to parameterize.
var reader = new StringReader(json.Replace('\'', '"'));
- var tokenizer = new JsonTokenizer(reader);
+ var tokenizer = JsonTokenizer.FromTextReader(reader);
for (int i = 0; i < expectedValidTokens; i++)
{
Assert.IsNotNull(tokenizer.Next());
@@ -334,7 +334,7 @@ namespace Google.Protobuf
[Test]
public void NextAfterEndDocumentThrows()
{
- var tokenizer = new JsonTokenizer(new StringReader("null"));
+ var tokenizer = JsonTokenizer.FromTextReader(new StringReader("null"));
Assert.AreEqual(JsonToken.Null, tokenizer.Next());
Assert.AreEqual(JsonToken.EndDocument, tokenizer.Next());
Assert.Throws<InvalidOperationException>(() => tokenizer.Next());
@@ -343,7 +343,7 @@ namespace Google.Protobuf
[Test]
public void CanPushBackEndDocument()
{
- var tokenizer = new JsonTokenizer(new StringReader("null"));
+ var tokenizer = JsonTokenizer.FromTextReader(new StringReader("null"));
Assert.AreEqual(JsonToken.Null, tokenizer.Next());
Assert.AreEqual(JsonToken.EndDocument, tokenizer.Next());
tokenizer.PushBack(JsonToken.EndDocument);
@@ -373,7 +373,7 @@ namespace Google.Protobuf
private static void AssertTokensNoReplacement(string json, params JsonToken[] expectedTokens)
{
var reader = new StringReader(json);
- var tokenizer = new JsonTokenizer(reader);
+ var tokenizer = JsonTokenizer.FromTextReader(reader);
for (int i = 0; i < expectedTokens.Length; i++)
{
var actualToken = tokenizer.Next();
@@ -393,7 +393,7 @@ namespace Google.Protobuf
private static void AssertThrowsAfter(string json, params JsonToken[] expectedTokens)
{
var reader = new StringReader(json);
- var tokenizer = new JsonTokenizer(reader);
+ var tokenizer = JsonTokenizer.FromTextReader(reader);
for (int i = 0; i < expectedTokens.Length; i++)
{
var actualToken = tokenizer.Next();