[hyena] Add Serializer, and associated tests
- From: Gabriel Burt <gburt src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [hyena] Add Serializer, and associated tests
- Date: Wed, 26 May 2010 02:34:56 +0000 (UTC)
commit 3e59c95cc311e865a16d9a69d09597c42d39f43d
Author: Sandy Armstrong <sanfordarmstrong gmail com>
Date: Thu Feb 18 16:05:07 2010 -0800
Add Serializer, and associated tests
Signed-off-by: Gabriel Burt <gabriel burt gmail com>
src/Hyena/Hyena.Json/Serializer.cs | 146 +++++++++++++++++
src/Hyena/Hyena.Json/Tests/OldSerializerTests.cs | 101 ++++++++++++
src/Hyena/Hyena.Json/Tests/SerializerTests.cs | 188 +++++++++++++++-------
src/Hyena/Makefile.am | 1 +
4 files changed, 376 insertions(+), 60 deletions(-)
---
diff --git a/src/Hyena/Hyena.Json/Serializer.cs b/src/Hyena/Hyena.Json/Serializer.cs
new file mode 100644
index 0000000..24eb064
--- /dev/null
+++ b/src/Hyena/Hyena.Json/Serializer.cs
@@ -0,0 +1,146 @@
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+// Copyright (c) 2008 Novell, Inc. (http://www.novell.com)
+//
+// Authors:
+// Sandy Armstrong <sanfordarmstrong gmail com>
+//
+
+using System;
+using System.IO;
+using System.Text;
+
+namespace Hyena.Json
+{
+ public class Serializer
+ {
+ private const string serializedNull = "null";
+ private const string serializedTrue = "true";
+ private const string serializedFalse = "false";
+
+ private object input;
+
+ public Serializer () { }
+ public Serializer (object input) { SetInput (input); }
+
+ public void SetInput (object input)
+ {
+ this.input = input;
+ }
+
+ // TODO: Support serialize to stream?
+
+ public string Serialize ()
+ {
+ return Serialize (input);
+ }
+
+ private string SerializeBool (bool val)
+ {
+ return val ? serializedTrue : serializedFalse;
+ }
+
+ private string SerializeInt (int val)
+ {
+ return val.ToString ();
+ }
+
+ private string SerializeDouble (double val)
+ {
+ return val.ToString ();
+ }
+
+ // TODO: exponent stuff
+
+ private string SerializeString (string val)
+ {
+ // TODO: More work, escaping, etc
+ return "\"" +
+ val.Replace ("\\", "\\\\").
+ Replace ("\"", "\\\"").
+ Replace ("\b", "\\b").
+ Replace ("\f", "\\f").
+ Replace ("\n", "\\n").
+ Replace ("\r", "\\r").
+ Replace ("\t", "\\t") +
+ "\"";
+ }
+
+ private string SerializeArray (JsonArray array)
+ {
+ StringBuilder builder = new StringBuilder ("[");
+ for (int i = 0; i < array.Count; i++) {
+ builder.Append (Serialize (array [i]));
+ if (i != (array.Count -1))
+ builder.Append (",");
+ }
+ builder.Append ("]");
+ return builder.ToString ();
+ }
+
+ private string SerializeObject (JsonObject obj)
+ {
+ StringBuilder builder = new StringBuilder ("{");
+ foreach (var pair in obj) {
+ builder.Append (SerializeString (pair.Key));
+ builder.Append (":");
+ builder.Append (Serialize (pair.Value));
+ builder.Append (",");
+ }
+ // Get rid of trailing comma
+ if (obj.Count > 0)
+ builder.Remove (builder.Length - 1, 1);
+ builder.Append ("}");
+ return builder.ToString ();
+ }
+
+ private string Serialize (object unknownObj)
+ {
+ if (unknownObj == null)
+ return serializedNull;
+
+ bool? b = unknownObj as bool?;
+ if (b.HasValue)
+ return SerializeBool (b.Value);
+
+ int? i = unknownObj as int?;
+ if (i.HasValue)
+ return SerializeInt (i.Value);
+
+ double? d = unknownObj as double?;
+ if (d.HasValue)
+ return SerializeDouble (d.Value);
+
+ string s = unknownObj as string;
+ if (s != null)
+ return SerializeString (s);
+
+ JsonObject o = unknownObj as JsonObject;
+ if (o != null)
+ return SerializeObject (o);
+
+ JsonArray a = unknownObj as JsonArray;
+ if (a != null)
+ return SerializeArray (a);
+
+ throw new ArgumentException ("Cannot serialize anything but doubles, integers, strings, JsonObjects, and JsonArrays");
+ }
+ }
+}
diff --git a/src/Hyena/Hyena.Json/Tests/OldSerializerTests.cs b/src/Hyena/Hyena.Json/Tests/OldSerializerTests.cs
new file mode 100644
index 0000000..b427b5b
--- /dev/null
+++ b/src/Hyena/Hyena.Json/Tests/OldSerializerTests.cs
@@ -0,0 +1,101 @@
+//
+// SerializerTests.cs
+//
+// Author:
+// Gabriel Burt <gabriel burt gmail com>
+//
+// Copyright (c) 2010 Novell, Inc.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+
+#if ENABLE_TESTS
+
+using System;
+using System.Linq;
+using System.Reflection;
+using NUnit.Framework;
+
+using Hyena.Json;
+using System.Collections;
+
+namespace Hyena.Json.Tests
+{
+ [TestFixture]
+ public class SerializerTests : Hyena.Tests.TestBase
+ {
+ JsonObject obj;
+ const string obj_serialized = "{\n \"foo\" : bar\n \"baz\" : 12,2\n}\n";
+ const string array_serialized = "[\n foo\n {\n \"foo\" : bar\n \"baz\" : 12,2\n }\n]\n";
+
+ [TestFixtureSetUp]
+ public void Setup ()
+ {
+ obj = new JsonObject ();
+ obj["foo"] = "bar";
+ obj["baz"] = 12.2;
+ }
+
+ [Test]
+ public void Literal ()
+ {
+ Assert.AreEqual (obj_serialized, obj.ToString ());
+ }
+
+ [Test]
+ public void Array ()
+ {
+ var empty = new JsonArray ();
+ Assert.AreEqual ("[ ]\n", empty.ToString ());
+
+ empty.Add (new JsonArray ());
+ Assert.AreEqual ("[\n [ ]\n]\n", empty.ToString ());
+
+ empty.Add (new JsonObject ());
+ Assert.AreEqual ("[\n [ ]\n { }\n]\n", empty.ToString ());
+
+ var a = new JsonArray ();
+ a.Add ("foo");
+ a.Add (obj);
+ Assert.AreEqual (array_serialized, a.ToString ());
+ }
+
+ [Test]
+ public void ExtensionMethods ()
+ {
+ Assert.AreEqual (
+ "[\n 0\n 1\n 2\n 3\n]\n",
+ Enumerable.Range (0, 4).ToJsonString ()
+ );
+
+ Assert.AreEqual (
+ "{\n \"True\" : [\n 0\n 2\n ]\n \"False\" : [\n 1\n 3\n ]\n}\n",
+ Enumerable.Range (0, 4).GroupBy<int, bool> (i => i % 2 == 0).ToJsonString ()
+ );
+
+ /*var a = new ArrayList ();
+ a.Add (Enumerable.Range (0, 4).GroupBy<int, bool> (i => i % 2 == 0));
+ Assert.AreEqual (
+ "",
+ a.ToJsonString ()
+ );*/
+ }
+ }
+}
+
+#endif
diff --git a/src/Hyena/Hyena.Json/Tests/SerializerTests.cs b/src/Hyena/Hyena.Json/Tests/SerializerTests.cs
index b427b5b..12dee24 100644
--- a/src/Hyena/Hyena.Json/Tests/SerializerTests.cs
+++ b/src/Hyena/Hyena.Json/Tests/SerializerTests.cs
@@ -1,99 +1,167 @@
//
// SerializerTests.cs
//
-// Author:
-// Gabriel Burt <gabriel burt gmail com>
+// Authors:
+// Sandy Armstrong <sanfordarmstrong gmail com>
//
-// Copyright (c) 2010 Novell, Inc.
+// Copyright (c) 2009 Novell, Inc. (http://www.novell.com)
//
-// Permission is hereby granted, free of charge, to any person obtaining a copy
-// of this software and associated documentation files (the "Software"), to deal
-// in the Software without restriction, including without limitation the rights
-// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-// copies of the Software, and to permit persons to whom the Software is
-// furnished to do so, subject to the following conditions:
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
//
-// The above copyright notice and this permission notice shall be included in
-// all copies or substantial portions of the Software.
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-// THE SOFTWARE.
#if ENABLE_TESTS
using System;
-using System.Linq;
-using System.Reflection;
-using NUnit.Framework;
using Hyena.Json;
-using System.Collections;
+
+using NUnit.Framework;
namespace Hyena.Json.Tests
{
[TestFixture]
public class SerializerTests : Hyena.Tests.TestBase
{
- JsonObject obj;
- const string obj_serialized = "{\n \"foo\" : bar\n \"baz\" : 12,2\n}\n";
- const string array_serialized = "[\n foo\n {\n \"foo\" : bar\n \"baz\" : 12,2\n }\n]\n";
+ [Test]
+ public void SerializeBoolTest ()
+ {
+ Serializer ser = new Serializer (true);
+ Assert.AreEqual ("true", ser.Serialize ());
+ ser.SetInput (false);
+ Assert.AreEqual ("false", ser.Serialize ());
+ }
+
+ [Test]
+ public void SerializeIntTest ()
+ {
+ Serializer ser = new Serializer (12);
+ Assert.AreEqual ("12", ser.Serialize ());
+ ser.SetInput (-658);
+ Assert.AreEqual ("-658", ser.Serialize ());
+ ser.SetInput (0);
+ Assert.AreEqual ("0", ser.Serialize ());
+ }
+
+ [Test]
+ public void SerializeDoubleTest ()
+ {
+ Serializer ser = new Serializer (12.5);
+ Assert.AreEqual ("12.5", ser.Serialize ());
+ ser.SetInput (-658.1);
+ Assert.AreEqual ("-658.1", ser.Serialize ());
+ ser.SetInput (0.0);
+ Assert.AreEqual ("0", ser.Serialize ());
+ ser.SetInput (0.1);
+ Assert.AreEqual ("0.1", ser.Serialize ());
+ }
- [TestFixtureSetUp]
- public void Setup ()
+ [Test]
+ public void SerializeStringTest ()
{
- obj = new JsonObject ();
- obj["foo"] = "bar";
- obj["baz"] = 12.2;
+ VerifyString ("The cat\njumped \"over\" the rat! We escape with \\\"",
+ @"""The cat\njumped \""over\"" the rat! We escape with \\\""""");
}
[Test]
- public void Literal ()
+ public void EscapedCharactersTest ()
{
- Assert.AreEqual (obj_serialized, obj.ToString ());
+ VerifyString ("\\", @"""\\""");
+ VerifyString ("\b", @"""\b""");
+ VerifyString ("\f", @"""\f""");
+ VerifyString ("\n", @"""\n""");
+ VerifyString ("\r", @"""\r""");
+ VerifyString ("\t", @"""\t""");
+ VerifyString ("\u2022", "\"\u2022\"");
+ }
+
+ private void VerifyString (string original, string expectedSerialized)
+ {
+ Serializer ser = new Serializer (original);
+ string output = ser.Serialize ();
+ Assert.AreEqual (expectedSerialized, output, "Serialized Output");
+ Assert.AreEqual (original, new Deserializer (output).Deserialize (),
+ "Input should be identical after serialized then deserialized back to string");
}
[Test]
- public void Array ()
+ public void SerializeNullTest ()
{
- var empty = new JsonArray ();
- Assert.AreEqual ("[ ]\n", empty.ToString ());
+ Serializer ser = new Serializer (null);
+ Assert.AreEqual ("null", ser.Serialize ());
+ }
- empty.Add (new JsonArray ());
- Assert.AreEqual ("[\n [ ]\n]\n", empty.ToString ());
+ [Test]
+ public void SerializeArrayTest ()
+ {
+ JsonArray simpleArray = new JsonArray ();
+ simpleArray.Add (1);
+ simpleArray.Add ("text");
+ simpleArray.Add (0.1);
+ simpleArray.Add ("5");
+ simpleArray.Add (false);
+ simpleArray.Add (null);
- empty.Add (new JsonObject ());
- Assert.AreEqual ("[\n [ ]\n { }\n]\n", empty.ToString ());
+ Serializer ser = new Serializer (simpleArray);
+ Assert.AreEqual ("[1,\"text\",0.1,\"5\",false,null]",
+ ser.Serialize ());
- var a = new JsonArray ();
- a.Add ("foo");
- a.Add (obj);
- Assert.AreEqual (array_serialized, a.ToString ());
+ JsonArray emptyArray = new JsonArray ();
+ ser.SetInput (emptyArray);
+ Assert.AreEqual ("[]", ser.Serialize ());
}
+ // TODO: Test arrays/objects in each other, various levels deep
+
[Test]
- public void ExtensionMethods ()
+ public void SerializeObjectTest ()
+ {
+ JsonObject obj1 = new JsonObject ();
+ obj1 ["intfield"] = 1;
+ obj1 ["text field"] = "text";
+ obj1 ["double-field"] = 0.1;
+ obj1 ["Boolean, Field"] = true;
+ obj1 ["\"Null\"\nfield"] = null;
+
+ Serializer ser = new Serializer (obj1);
+ // Test object equality, since order not guaranteed
+ string output = ser.Serialize ();
+ JsonObject reconstitutedObj1 = (JsonObject) new Deserializer (output).Deserialize ();
+ AssertJsonObjectsEqual (obj1, reconstitutedObj1);
+
+ JsonObject obj2 = new JsonObject ();
+ obj2 ["double-field"] = 0.1;
+ obj2 ["\"Null\"\nfield"] = null;
+ ser.SetInput (obj2);
+ output = ser.Serialize ();
+ Assert.IsTrue ((output == "{\"double-field\":0.1,\"\\\"Null\\\"\\nfield\":null}") ||
+ (output == "{\"\\\"Null\\\"\\nfield\":null,\"double-field\":0.1}"),
+ "Serialized output format");
+ }
+
+ private void AssertJsonObjectsEqual (JsonObject expectedObj, JsonObject actualObj)
{
- Assert.AreEqual (
- "[\n 0\n 1\n 2\n 3\n]\n",
- Enumerable.Range (0, 4).ToJsonString ()
- );
-
- Assert.AreEqual (
- "{\n \"True\" : [\n 0\n 2\n ]\n \"False\" : [\n 1\n 3\n ]\n}\n",
- Enumerable.Range (0, 4).GroupBy<int, bool> (i => i % 2 == 0).ToJsonString ()
- );
-
- /*var a = new ArrayList ();
- a.Add (Enumerable.Range (0, 4).GroupBy<int, bool> (i => i % 2 == 0));
- Assert.AreEqual (
- "",
- a.ToJsonString ()
- );*/
+ Assert.AreEqual (expectedObj.Count, actualObj.Count, "Field count");
+ foreach (var expectedPair in expectedObj)
+ Assert.AreEqual (expectedPair.Value,
+ actualObj [expectedPair.Key],
+ expectedPair.Key + " field");
}
}
}
diff --git a/src/Hyena/Makefile.am b/src/Hyena/Makefile.am
index 7079d95..0247803 100644
--- a/src/Hyena/Makefile.am
+++ b/src/Hyena/Makefile.am
@@ -102,6 +102,7 @@ SOURCES = \
Hyena.Metrics/Sample.cs \
Hyena.Metrics/Tests/MetricsTests.cs \
Hyena.Json/Deserializer.cs \
+ Hyena.Json/Serializer.cs \
Hyena.Json/Tests/SerializerTests.cs \
Hyena.Json/IJsonCollection.cs \
Hyena.Json/Tests/DeserializerTests.cs \
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]