PageRenderTime 48ms CodeModel.GetById 18ms app.highlight 24ms RepoModel.GetById 1ms app.codeStats 1ms

/toolkit/content/tests/unit/test_dict.js

http://github.com/zpao/v8monkey
JavaScript | 304 lines | 181 code | 32 blank | 91 comment | 10 complexity | 39180419d9aebb768ebc432ed79af15a MD5 | raw file
  1/* ***** BEGIN LICENSE BLOCK *****
  2 * Version: MPL 1.1/GPL 2.0/LGPL 2.1
  3 *
  4 * The contents of this file are subject to the Mozilla Public License Version
  5 * 1.1 (the "License"); you may not use this file except in compliance with
  6 * the License. You may obtain a copy of the License at
  7 * http://www.mozilla.org/MPL/
  8 *
  9 * Software distributed under the License is distributed on an "AS IS" basis,
 10 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
 11 * for the specific language governing rights and limitations under the
 12 * License.
 13 *
 14 * The Original Code is mozilla.org code.
 15 *
 16 * The Initial Developer of the Original Code is
 17 * the Mozilla Foundation.
 18 * Portions created by the Initial Developer are Copyright (C) 2010
 19 * the Initial Developer. All Rights Reserved.
 20 *
 21 * Contributor(s):
 22 *   Siddharth Agarwal <sid.bugzilla@gmail.com>
 23 *
 24 * Alternatively, the contents of this file may be used under the terms of
 25 * either the GNU General Public License Version 2 or later (the "GPL"), or
 26 * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
 27 * in which case the provisions of the GPL or the LGPL are applicable instead
 28 * of those above. If you wish to allow use of your version of this file only
 29 * under the terms of either the GPL or the LGPL, and not to allow others to
 30 * use your version of this file under the terms of the MPL, indicate your
 31 * decision by deleting the provisions above and replace them with the notice
 32 * and other provisions required by the GPL or the LGPL. If you do not delete
 33 * the provisions above, a recipient may use your version of this file under
 34 * the terms of any one of the MPL, the GPL or the LGPL.
 35 *
 36 * ***** END LICENSE BLOCK ***** */
 37
 38Components.utils.import("resource://gre/modules/Dict.jsm");
 39
 40/**
 41 * Test that a few basic get, set, has and del operations work.
 42 */
 43function test_get_set_has_del() {
 44  let dict = new Dict({foo: "bar"});
 45  dict.set("baz", 200);
 46  do_check_eq(dict.get("foo"), "bar");
 47  do_check_eq(dict.get("baz"), 200);
 48  do_check_true(dict.has("foo"));
 49  do_check_true(dict.has("baz"));
 50  // Now delete the entries
 51  do_check_true(dict.del("foo"));
 52  do_check_true(dict.del("baz"));
 53  do_check_false(dict.has("foo"));
 54  do_check_false(dict.has("baz"));
 55  // and make sure del returns false
 56  do_check_false(dict.del("foo"));
 57  do_check_false(dict.del("baz"));
 58}
 59
 60/**
 61 * Test that the second parameter of get (default value) works.
 62 */
 63function test_get_default() {
 64  let dict = new Dict();
 65  do_check_true(dict.get("foo") === undefined);
 66  do_check_eq(dict.get("foo", "bar"), "bar");
 67}
 68
 69/**
 70 * Test that there are no collisions with builtins.
 71 */
 72function test_collisions_with_builtins() {
 73  let dict = new Dict();
 74  // First check that a new dictionary doesn't already have builtins.
 75  do_check_false(dict.has("toString"));
 76  do_check_false(dict.has("watch"));
 77  do_check_false(dict.has("__proto__"));
 78
 79  // Add elements in an attempt to collide with builtins.
 80  dict.set("toString", "toString");
 81  dict.set("watch", "watch");
 82  // This is a little evil. We set __proto__ to an object to try to make it look
 83  // up the prototype chain.
 84  dict.set("__proto__", {prototest: "prototest"});
 85
 86  // Now check that the entries exist.
 87  do_check_true(dict.has("toString"));
 88  do_check_true(dict.has("watch"));
 89  do_check_true(dict.has("__proto__"));
 90  // ...and that we aren't looking up the prototype chain.
 91  do_check_false(dict.has("prototest"));
 92}
 93
 94/**
 95 * Test that the "count" property works as expected.
 96 */
 97function test_count() {
 98  let dict = new Dict({foo: "bar"});
 99  do_check_eq(dict.count, 1);
100  dict.set("baz", "quux");
101  do_check_eq(dict.count, 2);
102  // This shouldn't change the count
103  dict.set("baz", "quux2");
104  do_check_eq(dict.count, 2);
105
106  do_check_true(dict.del("baz"));
107  do_check_eq(dict.count, 1);
108  // This shouldn't change the count either
109  do_check_false(dict.del("not"));
110  do_check_eq(dict.count, 1);
111  do_check_true(dict.del("foo"));
112  do_check_eq(dict.count, 0);
113}
114
115/**
116 * Test that the copy function works as expected.
117 */
118function test_copy() {
119  let obj = {};
120  let dict1 = new Dict({foo: "bar", baz: obj});
121  let dict2 = dict1.copy();
122  do_check_eq(dict2.get("foo"), "bar");
123  do_check_eq(dict2.get("baz"), obj);
124  // Make sure the two update independent of each other.
125  dict1.del("foo");
126  do_check_false(dict1.has("foo"));
127  do_check_true(dict2.has("foo"));
128  dict2.set("test", 400);
129  do_check_true(dict2.has("test"));
130  do_check_false(dict1.has("test"));
131
132  // Check that the copy is shallow and not deep.
133  dict1.get("baz").prop = "proptest";
134  do_check_eq(dict2.get("baz").prop, "proptest");
135}
136
137// This is used by both test_listers and test_iterators.
138function _check_lists(keys, values, items) {
139  do_check_eq(keys.length, 2);
140  do_check_true(keys.indexOf("x") != -1);
141  do_check_true(keys.indexOf("y") != -1);
142
143  do_check_eq(values.length, 2);
144  do_check_true(values.indexOf("a") != -1);
145  do_check_true(values.indexOf("b") != -1);
146
147  // This is a little more tricky -- we need to check that one of the two
148  // entries is ["x", "a"] and the other is ["y", "b"].
149  do_check_eq(items.length, 2);
150  do_check_eq(items[0].length, 2);
151  do_check_eq(items[1].length, 2);
152  let ix = (items[0][0] == "x") ? 0 : 1;
153  let iy = (ix == 0) ? 1 : 0;
154  do_check_eq(items[ix][0], "x");
155  do_check_eq(items[ix][1], "a");
156  do_check_eq(items[iy][0], "y");
157  do_check_eq(items[iy][1], "b");
158}
159
160/**
161 * Test the list functions.
162 */
163function test_listers() {
164  let dict = new Dict({"x": "a", "y": "b"});
165  let keys = dict.listkeys();
166  let values = dict.listvalues();
167  let items = dict.listitems();
168  _check_lists(keys, values, items);
169}
170
171/**
172 * Test the iterator functions.
173 */
174function test_iterators() {
175  let dict = new Dict({"x": "a", "y": "b"});
176  // Convert the generators to lists
177  let keys = [x for (x in dict.keys)];
178  let values = [x for (x in dict.values)];
179  let items = [x for (x in dict.items)];
180  _check_lists(keys, values, items);
181}
182
183/**
184 * Test that setting a property throws an exception in strict mode.
185 */
186function test_set_property_strict() {
187  "use strict";
188  var dict = new Dict();
189  var thrown = false;
190  try {
191    dict.foo = "bar";
192  }
193  catch (ex) {
194    thrown = true;
195  }
196  do_check_true(thrown);
197}
198
199/**
200 * Test that setting a property has no effect in non-strict mode.
201 */
202function test_set_property_non_strict() {
203  let dict = new Dict();
204  dict.foo = "bar";
205  do_check_false("foo" in dict);
206  let realget = dict.get;
207  dict.get = "baz";
208  do_check_eq(dict.get, realget);
209}
210
211/**
212 * Tests setting a property by a lazy getter.
213 */
214function test_set_property_lazy_getter() {
215  let thunkCalled = false;
216
217  let setThunk = function(dict) {
218    thunkCalled = false;
219    dict.setAsLazyGetter("foo", function() {
220      thunkCalled = true;
221      return "bar";
222    });
223  };
224
225  let (dict = new Dict()) {
226    setThunk(dict);
227
228    // Test that checking for the key existence does not invoke
229    // the getter function.
230    do_check_true(dict.has("foo"));
231    do_check_false(thunkCalled);
232    do_check_true(dict.isLazyGetter("foo"));
233
234    // Calling get the first time should invoke the getter function
235    // and unmark the key as a lazy getter.
236    do_check_eq(dict.get("foo"), "bar");
237    do_check_true(thunkCalled);
238    do_check_false(dict.isLazyGetter("foo"));
239
240    // Calling get again should not invoke the getter function
241    thunkCalled = false;
242    do_check_eq(dict.get("foo"), "bar");
243    do_check_false(thunkCalled);
244    do_check_false(dict.isLazyGetter("foo"));
245  }
246
247  // Test that listvalues works for lazy keys.
248  let (dict = new Dict()) {
249    setThunk(dict);
250    do_check_true(dict.isLazyGetter("foo"));
251
252    let (listvalues = dict.listvalues()) {
253      do_check_false(dict.isLazyGetter("foo"));
254      do_check_true(thunkCalled);
255      do_check_true(listvalues.length, 1);
256      do_check_eq(listvalues[0], "bar");
257    }
258
259    thunkCalled = false;
260
261    // Retrieving the list again shouldn't invoke our getter.
262    let (listvalues = dict.listvalues()) {
263      do_check_false(dict.isLazyGetter("foo"));
264      do_check_false(thunkCalled);
265      do_check_true(listvalues.length, 1);
266      do_check_eq(listvalues[0], "bar");
267    }
268  }
269
270  // Test that the values iterator also works as expected.
271  let (dict = new Dict()) {
272    setThunk(dict);
273    let values = dict.values;
274
275    // Our getter shouldn't be called before the iterator reaches it.
276    do_check_true(dict.isLazyGetter("foo"));
277    do_check_false(thunkCalled);
278    do_check_eq(values.next(), "bar");
279    do_check_true(thunkCalled);
280
281    thunkCalled = false;
282    do_check_false(dict.isLazyGetter("foo"));
283    do_check_eq(dict.get("foo"), "bar");
284    do_check_false(thunkCalled);
285  }
286}
287
288var tests = [
289  test_get_set_has_del,
290  test_get_default,
291  test_collisions_with_builtins,
292  test_count,
293  test_copy,
294  test_listers,
295  test_iterators,
296  test_set_property_strict,
297  test_set_property_non_strict,
298  test_set_property_lazy_getter
299];
300
301function run_test() {
302  for (let [, test] in Iterator(tests))
303    test();
304}