[gxml/serialization] Added SerializableHashMap and Test Suite



commit fc2852bf1adbd2a7a9261f9bfff7fe3fe6e71878
Author: Daniel Espinosa <esodan gmail com>
Date:   Mon Dec 2 08:16:42 2013 -0600

    Added SerializableHashMap and Test Suite

 gxml/Makefile.am                     |    1 +
 gxml/SerializableGeeHashMap.vala     |  146 +++++++++++++++++++++
 test/GXmlTest.vala                   |    1 +
 test/Makefile.am                     |    1 +
 test/SerializableGeeHashMapTest.vala |  238 ++++++++++++++++++++++++++++++++++
 5 files changed, 387 insertions(+), 0 deletions(-)
---
diff --git a/gxml/Makefile.am b/gxml/Makefile.am
index 1508209..ba77f74 100644
--- a/gxml/Makefile.am
+++ b/gxml/Makefile.am
@@ -66,6 +66,7 @@ libgxml_la_SOURCES = \
        SerializableJson.vala \
        Serialization.vala \
        SerializableGeeTreeMap.vala \
+       SerializableGeeHashMap.vala \
        SerializableMapKey.vala \
        SerializableGeeDualKeyMap.vala \
        SerializableMapDualKey.vala \
diff --git a/gxml/SerializableGeeHashMap.vala b/gxml/SerializableGeeHashMap.vala
new file mode 100644
index 0000000..b8544da
--- /dev/null
+++ b/gxml/SerializableGeeHashMap.vala
@@ -0,0 +1,146 @@
+/* -*- Mode: vala; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */
+/* SerializableGeeTreeModel.vala
+ *
+ * Copyright (C) 2013  Daniel Espinosa <esodan gmail com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
+ *
+ * Authors:
+ *      Daniel Espinosa <esodan gmail com>
+ */
+using GXml;
+
+public class GXml.SerializableHashMap<K,V> : Gee.HashMap<K,V>, Serializable
+{
+  protected ParamSpec[] properties { get; set; }
+  public GLib.HashTable<string,GLib.ParamSpec> ignored_serializable_properties { get; protected set; }
+  public string? serialized_xml_node_value { get; protected set; default=null; }
+  public GLib.HashTable<string,GXml.Node> unknown_serializable_property { get; protected set; }
+
+  public virtual bool property_use_nick () { return false; }
+
+  public virtual string node_name ()
+  {
+    return "";
+  }
+  public string default_node_name ()
+  {
+    return get_type().name().down();
+  }
+
+  public virtual GLib.ParamSpec? find_property_spec (string property_name)
+  {
+    return default_find_property_spec (property_name);
+  }
+
+  public virtual void init_properties ()
+  {
+    default_init_properties ();
+  }
+
+  public virtual GLib.ParamSpec[] list_serializable_properties ()
+  {
+    return default_list_serializable_properties ();
+  }
+
+  public virtual void get_property_value (GLib.ParamSpec spec, ref Value val)
+  {
+    default_get_property_value (spec, ref val);
+  }
+
+  public virtual void set_property_value (GLib.ParamSpec spec, GLib.Value val)
+  {
+    default_set_property_value (spec, val);
+  }
+
+  public virtual bool transform_from_string (string str, ref GLib.Value dest)
+  {
+    return false;
+  }
+
+  public virtual bool transform_to_string (GLib.Value val, ref string str)
+  {
+    return false;
+  }
+
+  public virtual GXml.Node? serialize (GXml.Node node)
+                              throws GLib.Error
+                              requires (node is Element)
+  {
+    return default_serialize (node);
+  }
+  public GXml.Node? default_serialize (GXml.Node node)
+                              throws GLib.Error
+                              requires (node is Element)
+  {
+    if (value_type.is_a (typeof (Serializable))) {
+      foreach (V v in values) {
+       ((GXml.Serializable) v).serialize (node);
+      }
+    }
+    return node;
+  }
+  public virtual GXml.Node? serialize_property (GXml.Element element,
+                                        GLib.ParamSpec prop)
+                                        throws GLib.Error
+  {
+    return default_serialize_property (element, prop);
+  }
+  public GXml.Node? default_serialize_property (GXml.Element element,
+                                        GLib.ParamSpec prop)
+                                        throws GLib.Error
+  {
+    return element;
+  }
+  public virtual GXml.Node? deserialize (GXml.Node node)
+                                    throws GLib.Error
+                                    requires (node_name () != null)
+  {
+    return default_deserialize (node);
+  }
+  public GXml.Node? default_deserialize (GXml.Node node)
+                    throws GLib.Error
+  {
+    if (!(value_type.is_a (typeof (GXml.Serializable)) &&
+        value_type.is_a (typeof (SerializableMapKey)))) {
+      throw new SerializableError.UNSUPPORTED_TYPE ("%s: Value type '%s' is unsupported", 
+                                                    this.get_type ().name (), value_type.name ());
+    }
+    if (node is Element) {
+      foreach (GXml.Node n in node.child_nodes) {
+        if (n is Element) {
+#if DEBUG
+          stdout.printf (@"Node $(node.node_name) for type '$(get_type ().name ())'\n");
+#endif
+          var obj = Object.new (value_type);
+          if (n.node_name == ((Serializable) obj).node_name ()) {
+            ((Serializable) obj).deserialize (n);
+            @set (((SerializableMapKey<K>) obj).get_map_key (), obj);
+          }
+        }
+      }
+    }
+    return node;
+  }
+  public virtual bool deserialize_property (GXml.Node property_node)
+                                            throws GLib.Error
+  {
+    return default_deserialize_property (property_node);
+  }
+  public bool default_deserialize_property (GXml.Node property_node)
+                                            throws GLib.Error
+  {
+    return true;
+  }
+}
diff --git a/test/GXmlTest.vala b/test/GXmlTest.vala
index 0db3afe..93c57d1 100644
--- a/test/GXmlTest.vala
+++ b/test/GXmlTest.vala
@@ -39,6 +39,7 @@ class GXmlTest {
                SerializableTest.add_tests ();
                SerializableObjectModelTest.add_tests ();
                SerializableGeeTreeMapTest.add_tests ();
+               SerializableGeeHashMapTest.add_tests ();
                SerializableGeeDualKeyMapTest.add_tests ();
                SerializableGeeArrayListTest.add_tests ();
                SerializableGeeCollectionsTest.add_tests ();
diff --git a/test/Makefile.am b/test/Makefile.am
index 35cc5f3..c6bbe6e 100644
--- a/test/Makefile.am
+++ b/test/Makefile.am
@@ -41,6 +41,7 @@ gxml_test_SOURCES = \
        SerializableGeeTreeMapTest.vala \
        SerializableGeeDualKeyMapTest.vala \
        SerializableGeeArrayListTest.vala \
+       SerializableGeeHashMapTest.vala \
        SerializableGeeCollectionsTest.vala \
        SerializableBasicTypesTest.vala \
        $(NULL)
diff --git a/test/SerializableGeeHashMapTest.vala b/test/SerializableGeeHashMapTest.vala
new file mode 100644
index 0000000..1631a17
--- /dev/null
+++ b/test/SerializableGeeHashMapTest.vala
@@ -0,0 +1,238 @@
+using GXml;
+using Gee;
+
+class SerializableGeeHashMapTest : GXmlTest
+{
+  class Space : SerializableObjectModel, SerializableMapKey<string>
+  {
+    public string get_map_key () { return name; }
+    public string name { get; set; }
+    public Space.named (string name) { this.name = name; }
+    public override string node_name () { return "space"; }
+    public override string to_string () { return name; }
+  }
+
+  class SpaceContainer : SerializableObjectModel
+  {
+    public string owner { get; set; }
+    public SpaceCollection storage { get; set; }
+    public override string node_name () { return "spacecontainer"; }
+    public override string to_string () { return owner; }
+    public override GXml.Node? deserialize (GXml.Node node)
+                                    throws GLib.Error
+    {
+      Element element;
+      if (node is Document)
+        element = ((Document) node).document_element;
+      else
+        element = (Element) node;
+      if (element.has_child_nodes ()) {
+        if (storage == null)
+          storage = new SpaceCollection ();
+        storage.deserialize (element);
+      }
+      return default_deserialize (node);
+    }
+    public class SpaceCollection : SerializableHashMap<string,Space> {}
+  }
+
+  public static void add_tests ()
+  {
+    Test.add_func ("/gxml/serializable/serializable_hash_map/api",
+    () => {
+      try {
+        var c = new SerializableHashMap<string,Space> ();
+        var o1 = new Space.named ("Big");
+        var o2 = new Space.named ("Small");
+        c.set (o1.name, o1);
+        c.set (o2.name, o2);
+        bool found1 = false;
+        bool found2 = false;
+        foreach (Space o in c.values) {
+          if (o.name == "Big") found1 = true;
+          if (o.name == "Small") found2 = true;
+        }
+        if (!found1) {
+          stdout.printf (@"Big is not found\n");
+          assert_not_reached ();
+        }
+        if (!found2) {
+          stdout.printf (@"Small is not found\n");
+          assert_not_reached ();
+        }
+        found1 = found2 = false;
+        foreach (string k in c.keys) {
+          if ((c  get (k)).name == "Big") found1 = true;
+          if ((c  get (k)).name == "Small") found2 = true;
+        }
+        if (!found1) {
+          stdout.printf (@"Big key value is not found\n");
+          assert_not_reached ();
+        }
+        if (!found2) {
+          stdout.printf (@"Small key value is not found\n");
+          assert_not_reached ();
+        }
+      }
+      catch (GLib.Error e) {
+        stdout.printf (@"ERROR: $(e.message)");
+      }
+    });
+    Test.add_func ("/gxml/serializable/serializable_hash_map/serialize",
+    () => {
+      try {
+        var c = new SerializableHashMap<string,Space> ();
+        var o1 = new Space.named ("Big");
+        var o2 = new Space.named ("Small");
+        c.set (o1.name, o1);
+        c.set (o2.name, o2);
+        var doc = new Document ();
+        var root = doc.create_element ("root");
+        doc.append_child (root);
+        c.serialize (root);
+        if (!root.has_child_nodes ()) {
+          stdout.printf (@"ERROR: root node have no childs $(doc)\n");
+          assert_not_reached ();
+        }
+        bool found1 = false;
+        bool found2 = false;
+        foreach (GXml.Node n in root.child_nodes) {
+          if (n is Element && n.node_name == "space") {
+            var name = ((Element) n).get_attribute_node ("name");
+            if (name != null) {
+              if (name.node_value == "Big") found1 = true;
+              if (name.node_value == "Small") found2 = true;
+            }
+          }
+        }
+        if (!found1) {
+          stdout.printf (@"ERROR: Big space node is not found\n$(doc)\n");
+          assert_not_reached ();
+        }
+        if (!found2) {
+          stdout.printf (@"ERROR: Small space node is not found\n$(doc)\n");
+          assert_not_reached ();
+        }
+      }
+      catch (GLib.Error e) {
+        stdout.printf (@"ERROR: $(e.message)");
+        assert_not_reached ();
+      }
+    });
+    Test.add_func ("/gxml/serializable/serializable_hash_map/deserialize",
+    () => {
+      try {
+        var doc = new Document.from_string ("""<?xml version="1.0"?>
+  <root><space name="Big"/><space name="Small"/></root>""");
+        var c = new SerializableHashMap<string,Space> ();
+        c.deserialize (doc.document_element);
+        if (c.size != 2) {
+          stdout.printf (@"ERROR: incorrect size must be 2 got: $(c.size)\n");
+          assert_not_reached ();
+        }
+        bool found1 = false;
+        bool found2 = false;
+        foreach (string k in c.keys) {
+          if ((c  get (k)).name == "Big") found1 = true;
+          if ((c  get (k)).name == "Small") found2 = true;
+        }
+        if (!found1) {
+          stdout.printf (@"ERROR: Big key value is not found\n");
+          assert_not_reached ();
+        }
+        if (!found2) {
+          stdout.printf (@"ERROR: Small key value is not found\n");
+          assert_not_reached ();
+        }
+      }
+      catch (GLib.Error e) {
+        stdout.printf (@"ERROR: $(e.message)");
+        assert_not_reached ();
+      }
+    });
+    Test.add_func ("/gxml/serializable/serializable_hash_map/container_class/deserialize",
+    () => {
+      try {
+        var doc = new Document.from_string ("""<?xml version="1.0"?>
+  <spacecontainer owner="Earth"><space name="Big"/><space name="Small"/></spacecontainer>""");
+        var c = new SpaceContainer ();
+        c.deserialize (doc);
+        if (c.owner != "Earth") {
+          stdout.printf (@"ERROR: owner must be 'Earth' got: $(c.owner)\n$(doc)\n");
+          assert_not_reached ();
+        }
+        if (c.storage.size != 2) {
+          stdout.printf (@"ERROR: Size must be 2 got: $(c.storage.size)\n$(doc)\n");
+          assert_not_reached ();
+        }
+        bool found1 = false;
+        bool found2 = false;
+        foreach (string k in c.storage.keys) {
+          if ((c storage  get (k)).name == "Big") found1 = true;
+          if ((c storage  get (k)).name == "Small") found2 = true;
+        }
+        if (!found1) {
+          stdout.printf (@"ERROR: Big key value is not found\n");
+          assert_not_reached ();
+        }
+        if (!found2) {
+          stdout.printf (@"ERROR: Small key value is not found\n");
+          assert_not_reached ();
+        }
+      }
+      catch (GLib.Error e) {
+        stdout.printf (@"ERROR: $(e.message)");
+        assert_not_reached ();
+      }
+    });
+    Test.add_func ("/gxml/serializable/serializable_hash_map/containder_class/serialize",
+    () => {
+      try {
+        var c = new SpaceContainer ();
+        var o1 = new Space.named ("Big");
+        var o2 = new Space.named ("Small");
+        c.storage = new SpaceContainer.SpaceCollection ();
+        c.storage.set (o1.name, o1);
+        c.storage.set (o2.name, o2);
+        var doc = new Document ();
+        c.serialize (doc);
+        if (doc.document_element == null) {
+          stdout.printf (@"ERROR: doc have no root node\n$(doc)\n");
+          assert_not_reached ();
+        }
+        if (doc.document_element.node_name != "spacecontainer") {
+          stdout.printf (@"ERROR: bad doc root node's name: $(doc.document_element.node_name)\n$(doc)\n");
+          assert_not_reached ();
+        }
+        var root = doc.document_element;
+        if (!root.has_child_nodes ()) {
+          stdout.printf (@"ERROR: root node have no childs $(doc)\n");
+          assert_not_reached ();
+        }
+        bool found1 = false;
+        bool found2 = false;
+        foreach (GXml.Node n in root.child_nodes) {
+          if (n is Element && n.node_name == "space") {
+            var name = ((Element) n).get_attribute_node ("name");
+            if (name != null) {
+              if (name.node_value == "Big") found1 = true;
+              if (name.node_value == "Small") found2 = true;
+            }
+          }
+        }
+        if (!found1) {
+          stdout.printf (@"ERROR: Big space node is not found\n$(doc)\n");
+          assert_not_reached ();
+        }
+        if (!found2) {
+          stdout.printf (@"ERROR: Small space node is not found\n$(doc)\n");
+          assert_not_reached ();
+        }
+      }
+      catch (GLib.Error e) {
+        stdout.printf (@"ERROR: $(e.message)");
+        assert_not_reached ();
+      }
+    });
+  }
+}


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]