blob: bf2a61d22bea0c01447cd9d4e5b16c7f82ae40de [file] [log] [blame]
// 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);
}