gecko/toolkit/content/tests/unit/test_dict.js
2011-03-23 15:13:41 -04:00

227 lines
6.7 KiB
JavaScript

/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is mozilla.org code.
*
* The Initial Developer of the Original Code is
* the Mozilla Foundation.
* Portions created by the Initial Developer are Copyright (C) 2010
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Siddharth Agarwal <sid.bugzilla@gmail.com>
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
Components.utils.import("resource://gre/modules/Dict.jsm");
/**
* Test that a few basic get, set, has and del operations work.
*/
function test_get_set_has_del() {
let dict = new Dict({foo: "bar"});
dict.set("baz", 200);
do_check_eq(dict.get("foo"), "bar");
do_check_eq(dict.get("baz"), 200);
do_check_true(dict.has("foo"));
do_check_true(dict.has("baz"));
// Now delete the entries
do_check_true(dict.del("foo"));
do_check_true(dict.del("baz"));
do_check_false(dict.has("foo"));
do_check_false(dict.has("baz"));
// and make sure del returns false
do_check_false(dict.del("foo"));
do_check_false(dict.del("baz"));
}
/**
* Test that the second parameter of get (default value) works.
*/
function test_get_default() {
let dict = new Dict();
do_check_true(dict.get("foo") === undefined);
do_check_eq(dict.get("foo", "bar"), "bar");
}
/**
* Test that there are no collisions with builtins.
*/
function test_collisions_with_builtins() {
let dict = new Dict();
// First check that a new dictionary doesn't already have builtins.
do_check_false(dict.has("toString"));
do_check_false(dict.has("watch"));
do_check_false(dict.has("__proto__"));
// Add elements in an attempt to collide with builtins.
dict.set("toString", "toString");
dict.set("watch", "watch");
// This is a little evil. We set __proto__ to an object to try to make it look
// up the prototype chain.
dict.set("__proto__", {prototest: "prototest"});
// Now check that the entries exist.
do_check_true(dict.has("toString"));
do_check_true(dict.has("watch"));
do_check_true(dict.has("__proto__"));
// ...and that we aren't looking up the prototype chain.
do_check_false(dict.has("prototest"));
}
/**
* Test that the "count" property works as expected.
*/
function test_count() {
let dict = new Dict({foo: "bar"});
do_check_eq(dict.count, 1);
dict.set("baz", "quux");
do_check_eq(dict.count, 2);
// This shouldn't change the count
dict.set("baz", "quux2");
do_check_eq(dict.count, 2);
do_check_true(dict.del("baz"));
do_check_eq(dict.count, 1);
// This shouldn't change the count either
do_check_false(dict.del("not"));
do_check_eq(dict.count, 1);
do_check_true(dict.del("foo"));
do_check_eq(dict.count, 0);
}
/**
* Test that the copy function works as expected.
*/
function test_copy() {
let obj = {};
let dict1 = new Dict({foo: "bar", baz: obj});
let dict2 = dict1.copy();
do_check_eq(dict2.get("foo"), "bar");
do_check_eq(dict2.get("baz"), obj);
// Make sure the two update independent of each other.
dict1.del("foo");
do_check_false(dict1.has("foo"));
do_check_true(dict2.has("foo"));
dict2.set("test", 400);
do_check_true(dict2.has("test"));
do_check_false(dict1.has("test"));
// Check that the copy is shallow and not deep.
dict1.get("baz").prop = "proptest";
do_check_eq(dict2.get("baz").prop, "proptest");
}
// This is used by both test_listers and test_iterators.
function _check_lists(keys, values, items) {
do_check_eq(keys.length, 2);
do_check_true(keys.indexOf("x") != -1);
do_check_true(keys.indexOf("y") != -1);
do_check_eq(values.length, 2);
do_check_true(values.indexOf("a") != -1);
do_check_true(values.indexOf("b") != -1);
// This is a little more tricky -- we need to check that one of the two
// entries is ["x", "a"] and the other is ["y", "b"].
do_check_eq(items.length, 2);
do_check_eq(items[0].length, 2);
do_check_eq(items[1].length, 2);
let ix = (items[0][0] == "x") ? 0 : 1;
let iy = (ix == 0) ? 1 : 0;
do_check_eq(items[ix][0], "x");
do_check_eq(items[ix][1], "a");
do_check_eq(items[iy][0], "y");
do_check_eq(items[iy][1], "b");
}
/**
* Test the list functions.
*/
function test_listers() {
let dict = new Dict({"x": "a", "y": "b"});
let keys = dict.listkeys();
let values = dict.listvalues();
let items = dict.listitems();
_check_lists(keys, values, items);
}
/**
* Test the iterator functions.
*/
function test_iterators() {
let dict = new Dict({"x": "a", "y": "b"});
// Convert the generators to lists
let keys = [x for (x in dict.keys)];
let values = [x for (x in dict.values)];
let items = [x for (x in dict.items)];
_check_lists(keys, values, items);
}
/**
* Test that setting a property throws an exception in strict mode.
*/
function test_set_property_strict() {
"use strict";
var dict = new Dict();
var thrown = false;
try {
dict.foo = "bar";
}
catch (ex) {
thrown = true;
}
do_check_true(thrown);
}
/**
* Test that setting a property has no effect in non-strict mode.
*/
function test_set_property_non_strict() {
let dict = new Dict();
dict.foo = "bar";
do_check_false("foo" in dict);
let realget = dict.get;
dict.get = "baz";
do_check_eq(dict.get, realget);
}
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,
];
function run_test() {
for (let [, test] in Iterator(tests))
test();
}