Bug 727967 - Support conversion from/to JSON in Dict.jsm. r=gavin
authorAbhishek Potnis <abhishekp.bugzilla@gmail.com>
Wed, 10 Oct 2012 21:55:38 +0530
changeset 110887 c0977a9122d194de39414881c61e70ec12c06b8e
parent 110886 1c4ecfb93f84671095ad3e0acb9044a2c5d88389
child 110888 a79caf5f26b3b3f243e39b59942690d6d4a48b1b
push id23720
push userryanvm@gmail.com
push dateSat, 20 Oct 2012 22:55:06 +0000
treeherdermozilla-central@ddca56ec6bfc [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersgavin
bugs727967
milestone19.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 727967 - Support conversion from/to JSON in Dict.jsm. r=gavin
toolkit/content/Dict.jsm
toolkit/content/tests/unit/test_dict.js
--- a/toolkit/content/Dict.jsm
+++ b/toolkit/content/Dict.jsm
@@ -24,20 +24,23 @@ function unconvert(aProp) {
 /**
  * A dictionary of strings to arbitrary JS objects. This should be used whenever
  * the keys are potentially arbitrary, to avoid collisions with built-in
  * properties.
  *
  * @param aInitial An object containing the initial keys and values of this
  *                 dictionary. Only the "own" enumerable properties of the
  *                 object are considered.
+ *                 If |aInitial| is a string, it is assumed to be JSON and parsed into an object.
  */
 function Dict(aInitial) {
   if (aInitial === undefined)
     aInitial = {};
+  if (typeof aInitial == "string")
+    aInitial = JSON.parse(aInitial);
   var items = {}, count = 0;
   // That we don't look up the prototype chain is guaranteed by Iterator.
   for (var [key, val] in Iterator(aInitial)) {
     items[convert(key)] = val;
     count++;
   }
   this._state = {count: count, items: items};
   return Object.freeze(this);
@@ -220,16 +223,27 @@ Dict.prototype = Object.freeze({
   get items() {
     // If we don't capture this._state.items here then the this-binding will be
     // incorrect when the generator is executed
     var items = this._state.items;
     return ([unconvert(k), items[k]] for (k in items));
   },
 
   /**
-   * Returns a string representation of this dictionary.
+   * Returns a String representation of this dictionary.
    */
   toString: function Dict_toString() {
     return "{" +
       [(key + ": " + val) for ([key, val] in this.items)].join(", ") +
       "}";
   },
+
+  /**
+   * Returns a JSON representation of this dictionary.
+   */
+  toJSON: function Dict_toJSON() {
+    let obj = {};
+    for (let [key, item] of Iterator(this._state.items)) {
+      obj[unconvert(key)] = item;
+    }
+    return JSON.stringify(obj);
+  },
 });
--- a/toolkit/content/tests/unit/test_dict.js
+++ b/toolkit/content/tests/unit/test_dict.js
@@ -247,25 +247,58 @@ function test_set_property_lazy_getter()
 
     thunkCalled = false;
     do_check_false(dict.isLazyGetter("foo"));
     do_check_eq(dict.get("foo"), "bar");
     do_check_false(thunkCalled);
   }
 }
 
+// This is used by both test_construct_dict_from_json_string and test_serialize_dict_to_json_string
+function _sort_comp_arr(arr1,arr2){
+  arr1.sort();
+  arr2.sort();
+  do_check_eq(arr1.toString(),arr2.toString());
+}
+
+/**
+ * Tests constructing a dictionary from a JSON string.
+ */
+function test_construct_dict_from_json_string() {
+  let d1 = new Dict({a:1, b:2, c:"foobar"});
+  let d2 = new Dict(JSON.stringify(({a:1, b:2, c:"foobar"})));
+  _sort_comp_arr(d1.listkeys(),d2.listkeys());
+  do_check_eq(d1.get("a"), d2.get("a"));
+  do_check_eq(d1.get("b"), d2.get("b"));
+  do_check_eq(d1.get("c"), d2.get("c"));
+}
+
+/**
+ * Tests serializing a dictionary to a JSON string.
+ */
+function test_serialize_dict_to_json_string() {
+  let d1 = new Dict({a:1, b:2, c:"foobar"});
+  let d2 = new Dict(d1.toJSON());
+  _sort_comp_arr(d1.listkeys(),d2.listkeys());
+  do_check_eq(d1.get("a"), d2.get("a"));
+  do_check_eq(d1.get("b"), d2.get("b"));
+  do_check_eq(d1.get("c"), d2.get("c"));
+}
+
 var tests = [
   test_get_set_has_del,
   test_get_default,
   test_collisions_with_builtins,
   test_count,
   test_copy,
   test_listers,
   test_iterators,
   test_set_property_strict,
   test_set_property_non_strict,
-  test_set_property_lazy_getter
+  test_set_property_lazy_getter,
+  test_construct_dict_from_json_string,
+  test_serialize_dict_to_json_string
 ];
 
 function run_test() {
   for (let [, test] in Iterator(tests))
     test();
 }