433 lines
11 KiB
JavaScript
433 lines
11 KiB
JavaScript
// Copyright 2012 The Closure Library Authors. All Rights Reserved.
|
|
//
|
|
// Licensed under the Apache License, Version 2.0 (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.apache.org/licenses/LICENSE-2.0
|
|
//
|
|
// Unless required by applicable law or agreed to in writing, software
|
|
// distributed under the License is distributed on an "AS-IS" BASIS,
|
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
// See the License for the specific language governing permissions and
|
|
// limitations under the License.
|
|
|
|
goog.provide('goog.labs.structs.MapTest');
|
|
goog.setTestOnly('goog.labs.structs.MapTest');
|
|
|
|
goog.require('goog.labs.structs.Map');
|
|
goog.require('goog.testing.PropertyReplacer');
|
|
goog.require('goog.testing.jsunit');
|
|
|
|
var map;
|
|
var stubs;
|
|
|
|
function setUpPage() {
|
|
stubs = new goog.testing.PropertyReplacer();
|
|
}
|
|
|
|
function setUp() {
|
|
map = new goog.labs.structs.Map();
|
|
}
|
|
|
|
|
|
function testSet() {
|
|
var key = 'test';
|
|
var value = 'value';
|
|
map.set(key, value);
|
|
assertEquals(value, map.get(key));
|
|
}
|
|
|
|
|
|
function testSetsWithSameKey() {
|
|
var key = 'test';
|
|
var value = 'value';
|
|
var value2 = 'value2';
|
|
map.set(key, value);
|
|
map.set(key, value2);
|
|
assertEquals(value2, map.get(key));
|
|
}
|
|
|
|
|
|
function testSetWithUndefinedValue() {
|
|
var key = 'test';
|
|
map.set(key, undefined);
|
|
assertUndefined(map.get(key));
|
|
}
|
|
|
|
|
|
function testSetWithUnderUnderProtoUnderUnder() {
|
|
var key = '__proto__';
|
|
var value = 'value';
|
|
var value2 = 'value2';
|
|
|
|
map.set(key, value);
|
|
assertEquals(value, map.get(key));
|
|
|
|
map.set(key, value2);
|
|
assertEquals(value2, map.get(key));
|
|
}
|
|
|
|
|
|
function testSetWithBuiltInPropertyShadows() {
|
|
var key = 'toString';
|
|
var value = 'value';
|
|
var key2 = 'hasOwnProperty';
|
|
var value2 = 'value2';
|
|
|
|
map.set(key, value);
|
|
map.set(key2, value2);
|
|
assertEquals(value, map.get(key));
|
|
assertEquals(value2, map.get(key2));
|
|
|
|
map.set(key, value2);
|
|
map.set(key2, value);
|
|
assertEquals(value2, map.get(key));
|
|
assertEquals(value, map.get(key2));
|
|
}
|
|
|
|
|
|
function testGetBeforeSetOfUnderUnderProtoUnderUnder() {
|
|
assertUndefined(map.get('__proto__'));
|
|
}
|
|
|
|
|
|
function testContainsKey() {
|
|
assertFalse(map.containsKey('key'));
|
|
assertFalse(map.containsKey('__proto__'));
|
|
assertFalse(map.containsKey('toString'));
|
|
assertFalse(map.containsKey('hasOwnProperty'));
|
|
assertFalse(map.containsKey('key2'));
|
|
assertFalse(map.containsKey('key3'));
|
|
assertFalse(map.containsKey('key4'));
|
|
|
|
map.set('key', 'v');
|
|
map.set('__proto__', 'v');
|
|
map.set('toString', 'v');
|
|
map.set('hasOwnProperty', 'v');
|
|
map.set('key2', undefined);
|
|
map.set('key3', null);
|
|
map.set('key4', '');
|
|
|
|
assertTrue(map.containsKey('key'));
|
|
assertTrue(map.containsKey('__proto__'));
|
|
assertTrue(map.containsKey('toString'));
|
|
assertTrue(map.containsKey('hasOwnProperty'));
|
|
assertTrue(map.containsKey('key2'));
|
|
assertTrue(map.containsKey('key3'));
|
|
assertTrue(map.containsKey('key4'));
|
|
}
|
|
|
|
|
|
function testContainsValueWithShadowKeys() {
|
|
assertFalse(map.containsValue('v2'));
|
|
assertFalse(map.containsValue('v3'));
|
|
assertFalse(map.containsValue('v4'));
|
|
|
|
map.set('__proto__', 'v2');
|
|
map.set('toString', 'v3');
|
|
map.set('hasOwnProperty', 'v4');
|
|
|
|
assertTrue(map.containsValue('v2'));
|
|
assertTrue(map.containsValue('v3'));
|
|
assertTrue(map.containsValue('v4'));
|
|
|
|
assertFalse(map.containsValue(Object.prototype.toString));
|
|
assertFalse(map.containsValue(Object.prototype.hasOwnProperty));
|
|
}
|
|
|
|
|
|
function testContainsValueWithNullAndUndefined() {
|
|
assertFalse(map.containsValue(undefined));
|
|
assertFalse(map.containsValue(null));
|
|
|
|
map.set('key2', undefined);
|
|
map.set('key3', null);
|
|
|
|
assertTrue(map.containsValue(undefined));
|
|
assertTrue(map.containsValue(null));
|
|
}
|
|
|
|
|
|
function testContainsValueWithNumber() {
|
|
assertFalse(map.containsValue(-1));
|
|
assertFalse(map.containsValue(0));
|
|
assertFalse(map.containsValue(1));
|
|
map.set('key', -1);
|
|
map.set('key2', 0);
|
|
map.set('key3', 1);
|
|
assertTrue(map.containsValue(-1));
|
|
assertTrue(map.containsValue(0));
|
|
assertTrue(map.containsValue(1));
|
|
}
|
|
|
|
|
|
function testContainsValueWithNaN() {
|
|
assertFalse(map.containsValue(NaN));
|
|
map.set('key', NaN);
|
|
assertTrue(map.containsValue(NaN));
|
|
}
|
|
|
|
|
|
function testContainsValueWithNegativeZero() {
|
|
assertFalse(map.containsValue(-0));
|
|
map.set('key', -0);
|
|
assertTrue(map.containsValue(-0));
|
|
assertFalse(map.containsValue(0));
|
|
|
|
map.set('key', 0);
|
|
assertFalse(map.containsValue(-0));
|
|
assertTrue(map.containsValue(0));
|
|
}
|
|
|
|
|
|
function testContainsValueWithStrings() {
|
|
assertFalse(map.containsValue(''));
|
|
assertFalse(map.containsValue('v'));
|
|
map.set('key', '');
|
|
map.set('key2', 'v');
|
|
assertTrue(map.containsValue(''));
|
|
assertTrue(map.containsValue('v'));
|
|
}
|
|
|
|
function testRemove() {
|
|
map.set('key', 'v');
|
|
map.set('__proto__', 'v2');
|
|
map.set('toString', 'v3');
|
|
map.set('hasOwnProperty', 'v4');
|
|
map.set('key2', undefined);
|
|
map.set('key3', null);
|
|
map.set('key4', '');
|
|
|
|
assertFalse(map.remove('key do not exist'));
|
|
|
|
assertTrue(map.remove('key'));
|
|
assertFalse(map.containsKey('key'));
|
|
assertFalse(map.remove('key'));
|
|
|
|
assertTrue(map.remove('__proto__'));
|
|
assertFalse(map.containsKey('__proto__'));
|
|
assertFalse(map.remove('__proto__'));
|
|
|
|
assertTrue(map.remove('toString'));
|
|
assertFalse(map.containsKey('toString'));
|
|
assertFalse(map.remove('toString'));
|
|
|
|
assertTrue(map.remove('hasOwnProperty'));
|
|
assertFalse(map.containsKey('hasOwnProperty'));
|
|
assertFalse(map.remove('hasOwnProperty'));
|
|
|
|
assertTrue(map.remove('key2'));
|
|
assertFalse(map.containsKey('key2'));
|
|
assertFalse(map.remove('key2'));
|
|
|
|
assertTrue(map.remove('key3'));
|
|
assertFalse(map.containsKey('key3'));
|
|
assertFalse(map.remove('key3'));
|
|
|
|
assertTrue('', map.remove('key4'));
|
|
assertFalse(map.containsKey('key4'));
|
|
assertFalse(map.remove('key4'));
|
|
}
|
|
|
|
|
|
function testGetCountAndIsEmpty() {
|
|
assertEquals(0, map.getCount());
|
|
assertTrue(map.isEmpty());
|
|
|
|
map.set('key', 'v');
|
|
assertEquals(1, map.getCount());
|
|
map.set('__proto__', 'v2');
|
|
assertEquals(2, map.getCount());
|
|
map.set('toString', 'v3');
|
|
assertEquals(3, map.getCount());
|
|
map.set('hasOwnProperty', 'v4');
|
|
assertEquals(4, map.getCount());
|
|
|
|
map.set('key', 'a');
|
|
assertEquals(4, map.getCount());
|
|
map.set('__proto__', 'a2');
|
|
assertEquals(4, map.getCount());
|
|
map.set('toString', 'a3');
|
|
assertEquals(4, map.getCount());
|
|
map.set('hasOwnProperty', 'a4');
|
|
assertEquals(4, map.getCount());
|
|
|
|
map.remove('key');
|
|
assertEquals(3, map.getCount());
|
|
map.remove('__proto__');
|
|
assertEquals(2, map.getCount());
|
|
map.remove('toString');
|
|
assertEquals(1, map.getCount());
|
|
map.remove('hasOwnProperty');
|
|
assertEquals(0, map.getCount());
|
|
}
|
|
|
|
|
|
function testClear() {
|
|
map.set('key', 'v');
|
|
map.set('__proto__', 'v');
|
|
map.set('toString', 'v');
|
|
map.set('hasOwnProperty', 'v');
|
|
map.set('key2', undefined);
|
|
map.set('key3', null);
|
|
map.set('key4', '');
|
|
|
|
map.clear();
|
|
|
|
assertFalse(map.containsKey('key'));
|
|
assertFalse(map.containsKey('__proto__'));
|
|
assertFalse(map.containsKey('toString'));
|
|
assertFalse(map.containsKey('hasOwnProperty'));
|
|
assertFalse(map.containsKey('key2'));
|
|
assertFalse(map.containsKey('key3'));
|
|
assertFalse(map.containsKey('key4'));
|
|
}
|
|
|
|
|
|
function testGetEntries() {
|
|
map.set('key', 'v');
|
|
map.set('__proto__', 'v');
|
|
map.set('toString', 'v');
|
|
map.set('hasOwnProperty', 'v');
|
|
map.set('key2', undefined);
|
|
map.set('key3', null);
|
|
map.set('key4', '');
|
|
|
|
var entries = map.getEntries();
|
|
assertEquals(7, entries.length);
|
|
assertContainsEntry(['key', 'v'], entries);
|
|
assertContainsEntry(['__proto__', 'v'], entries);
|
|
assertContainsEntry(['toString', 'v'], entries);
|
|
assertContainsEntry(['hasOwnProperty', 'v'], entries);
|
|
assertContainsEntry(['key2', undefined], entries);
|
|
assertContainsEntry(['key3', null], entries);
|
|
assertContainsEntry(['key4', ''], entries);
|
|
}
|
|
|
|
|
|
function testGetKeys() {
|
|
map.set('key', 'v');
|
|
map.set('__proto__', 'v');
|
|
map.set('toString', 'v');
|
|
map.set('hasOwnProperty', 'v');
|
|
map.set('key2', undefined);
|
|
map.set('key3', null);
|
|
map.set('k4', '');
|
|
|
|
var values = map.getKeys();
|
|
assertSameElements(
|
|
['key', '__proto__', 'toString', 'hasOwnProperty', 'key2', 'key3', 'k4'],
|
|
values);
|
|
}
|
|
|
|
|
|
function testGetValues() {
|
|
map.set('key', 'v');
|
|
map.set('__proto__', 'v');
|
|
map.set('toString', 'v');
|
|
map.set('hasOwnProperty', 'v');
|
|
map.set('key2', undefined);
|
|
map.set('key3', null);
|
|
map.set('key4', '');
|
|
|
|
var values = map.getValues();
|
|
assertSameElements(['v', 'v', 'v', 'v', undefined, null, ''], values);
|
|
}
|
|
|
|
|
|
function testAddAllToEmptyMap() {
|
|
map.set('key', 'v');
|
|
map.set('key2', 'v2');
|
|
map.set('key3', 'v3');
|
|
map.set('key4', 'v4');
|
|
|
|
var map2 = new goog.labs.structs.Map();
|
|
map2.addAll(map);
|
|
|
|
assertEquals(4, map2.getCount());
|
|
assertEquals('v', map2.get('key'));
|
|
assertEquals('v2', map2.get('key2'));
|
|
assertEquals('v3', map2.get('key3'));
|
|
assertEquals('v4', map2.get('key4'));
|
|
}
|
|
|
|
|
|
function testAddAllToNonEmptyMap() {
|
|
map.set('key', 'v');
|
|
map.set('key2', 'v2');
|
|
map.set('key3', 'v3');
|
|
map.set('key4', 'v4');
|
|
|
|
var map2 = new goog.labs.structs.Map();
|
|
map2.set('key0', 'o');
|
|
map2.set('key', 'o');
|
|
map2.set('key2', 'o2');
|
|
map2.set('key3', 'o3');
|
|
map2.addAll(map);
|
|
|
|
assertEquals(5, map2.getCount());
|
|
assertEquals('o', map2.get('key0'));
|
|
assertEquals('v', map2.get('key'));
|
|
assertEquals('v2', map2.get('key2'));
|
|
assertEquals('v3', map2.get('key3'));
|
|
assertEquals('v4', map2.get('key4'));
|
|
}
|
|
|
|
|
|
function testClone() {
|
|
map.set('key', 'v');
|
|
map.set('key2', 'v2');
|
|
map.set('key3', 'v3');
|
|
map.set('key4', 'v4');
|
|
|
|
var map2 = map.clone();
|
|
|
|
assertEquals(4, map2.getCount());
|
|
assertEquals('v', map2.get('key'));
|
|
assertEquals('v2', map2.get('key2'));
|
|
assertEquals('v3', map2.get('key3'));
|
|
assertEquals('v4', map2.get('key4'));
|
|
}
|
|
|
|
|
|
function testMapWithModifiedObjectPrototype() {
|
|
stubs.set(Object.prototype, 'toString', function() {});
|
|
stubs.set(Object.prototype, 'foo', function() {});
|
|
stubs.set(Object.prototype, 'field', 100);
|
|
stubs.set(Object.prototype, 'fooKey', function() {});
|
|
|
|
map = new goog.labs.structs.Map();
|
|
map.set('key', 'v');
|
|
map.set('key2', 'v2');
|
|
map.set('fooKey', 'v3');
|
|
|
|
assertTrue(map.containsKey('key'));
|
|
assertTrue(map.containsKey('key2'));
|
|
assertTrue(map.containsKey('fooKey'));
|
|
assertFalse(map.containsKey('toString'));
|
|
assertFalse(map.containsKey('foo'));
|
|
assertFalse(map.containsKey('field'));
|
|
|
|
assertTrue(map.containsValue('v'));
|
|
assertTrue(map.containsValue('v2'));
|
|
assertTrue(map.containsValue('v3'));
|
|
assertFalse(map.containsValue(100));
|
|
|
|
var entries = map.getEntries();
|
|
assertEquals(3, entries.length);
|
|
assertContainsEntry(['key', 'v'], entries);
|
|
assertContainsEntry(['key2', 'v2'], entries);
|
|
assertContainsEntry(['fooKey', 'v3'], entries);
|
|
}
|
|
|
|
|
|
function assertContainsEntry(entry, entryList) {
|
|
for (var i = 0; i < entryList.length; ++i) {
|
|
if (entry[0] == entryList[i][0] && entry[1] === entryList[i][1]) {
|
|
return;
|
|
}
|
|
}
|
|
fail('Did not find entry: ' + entry + ' in: ' + entryList);
|
|
}
|