blob: d7499e02dd2a774f0cf99282e804a66d6e28634c [file] [log] [blame]
// Copyright 2009 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.structs.StringSetTest');
goog.setTestOnly('goog.structs.StringSetTest');
goog.require('goog.array');
goog.require('goog.iter');
goog.require('goog.structs.StringSet');
goog.require('goog.testing.asserts');
goog.require('goog.testing.jsunit');
var TEST_VALUES = [
'', ' ', ' ', 'true', 'null', 'undefined', '0', 'new', 'constructor',
'prototype', '__proto__', 'set', 'hasOwnProperty', 'toString', 'valueOf'
];
var TEST_VALUES_WITH_DUPLICATES = [
'', '', ' ', ' ', 'true', true, 'null', null, 'undefined', undefined, '0', 0,
'new', 'constructor', 'prototype', '__proto__', 'set', 'hasOwnProperty',
'toString', 'valueOf'
];
function testConstructor() {
var empty = new goog.structs.StringSet;
assertSameElements('elements in empty set', [], empty.getValues());
var s = new goog.structs.StringSet(TEST_VALUES_WITH_DUPLICATES);
assertSameElements('duplicates are filtered out by their string value',
TEST_VALUES, s.getValues());
}
function testConstructorAssertsThatObjectPrototypeHasNoEnumerableKeys() {
assertNotThrows(goog.structs.StringSet);
Object.prototype.foo = 0;
try {
assertThrows(goog.structs.StringSet);
} finally {
delete Object.prototype.foo;
}
assertNotThrows(goog.structs.StringSet);
}
function testOverridingObjectPrototypeToStringIsSafe() {
var originalToString = Object.prototype.toString;
Object.prototype.toString = function() {
return 'object';
};
try {
assertEquals(0, new goog.structs.StringSet().getCount());
assertFalse(new goog.structs.StringSet().contains('toString'));
} finally {
Object.prototype.toString = originalToString;
}
}
function testAdd() {
var s = new goog.structs.StringSet;
goog.array.forEach(TEST_VALUES_WITH_DUPLICATES, s.add, s);
assertSameElements(TEST_VALUES, s.getValues());
}
function testAddArray() {
var s = new goog.structs.StringSet;
s.addArray(TEST_VALUES_WITH_DUPLICATES);
assertSameElements('added elements from array', TEST_VALUES, s.getValues());
}
function testAddSet() {
var s = new goog.structs.StringSet;
s.addSet(new goog.structs.StringSet([1, 2]));
assertSameElements('empty set + {1, 2}', ['1', '2'], s.getValues());
s.addSet(new goog.structs.StringSet([2, 3]));
assertSameElements('{1, 2} + {2, 3}', ['1', '2', '3'], s.getValues());
}
function testClear() {
var s = new goog.structs.StringSet([1, 2]);
s.clear();
assertSameElements('cleared set', [], s.getValues());
}
function testClone() {
var s = new goog.structs.StringSet([1, 2]);
var c = s.clone();
assertSameElements('elements in clone', ['1', '2'], c.getValues());
s.add(3);
assertSameElements('changing the original set does not affect the clone',
['1', '2'], c.getValues());
}
function testContains() {
var e = new goog.structs.StringSet;
goog.array.forEach(TEST_VALUES, function(element) {
assertFalse('empty set does not contain ' + element, e.contains(element));
});
var s = new goog.structs.StringSet(TEST_VALUES);
goog.array.forEach(TEST_VALUES_WITH_DUPLICATES, function(element) {
assertTrue('s contains ' + element, s.contains(element));
});
assertFalse('s does not contain 42', s.contains(42));
}
function testContainsArray() {
var s = new goog.structs.StringSet(TEST_VALUES);
assertTrue('set contains empty array', s.containsArray([]));
assertTrue('set contains all elements of itself with some duplication',
s.containsArray(TEST_VALUES_WITH_DUPLICATES));
assertFalse('set does not contain 42', s.containsArray([42]));
}
function testEquals() {
var s = new goog.structs.StringSet([1, 2]);
assertTrue('set equals to itself', s.equals(s));
assertTrue('set equals to its clone', s.equals(s.clone()));
assertFalse('set does not equal to its subset',
s.equals(new goog.structs.StringSet([1])));
assertFalse('set does not equal to its superset',
s.equals(new goog.structs.StringSet([1, 2, 3])));
}
function testForEach() {
var s = new goog.structs.StringSet(TEST_VALUES);
var values = [];
var context = {};
s.forEach(function(value, key, stringSet) {
assertEquals('context of forEach callback', context, this);
values.push(value);
assertUndefined('key argument of forEach callback', key);
assertEquals('set argument of forEach callback', s, stringSet);
}, context);
assertSameElements('values passed to forEach callback', TEST_VALUES, values);
}
function testGetCount() {
var empty = new goog.structs.StringSet;
assertEquals('count(empty set)', 0, empty.getCount());
var s = new goog.structs.StringSet(TEST_VALUES);
assertEquals('count(non-empty set)', TEST_VALUES.length, s.getCount());
}
function testGetDifference() {
var s1 = new goog.structs.StringSet([1, 2]);
var s2 = new goog.structs.StringSet([2, 3]);
assertSameElements('{1, 2} - {2, 3}', ['1'],
s1.getDifference(s2).getValues());
}
function testGetIntersection() {
var s1 = new goog.structs.StringSet([1, 2]);
var s2 = new goog.structs.StringSet([2, 3]);
assertSameElements('{1, 2} * {2, 3}', ['2'],
s1.getIntersection(s2).getValues());
}
function testGetSymmetricDifference() {
var s1 = new goog.structs.StringSet([1, 2]);
var s2 = new goog.structs.StringSet([2, 3]);
assertSameElements('{1, 2} sym.diff. {2, 3}', ['1', '3'],
s1.getSymmetricDifference(s2).getValues());
}
function testGetUnion() {
var s1 = new goog.structs.StringSet([1, 2]);
var s2 = new goog.structs.StringSet([2, 3]);
assertSameElements('{1, 2} + {2, 3}', ['1', '2', '3'],
s1.getUnion(s2).getValues());
}
function testIsDisjoint() {
var s = new goog.structs.StringSet;
var s12 = new goog.structs.StringSet([1, 2]);
var s23 = new goog.structs.StringSet([2, 3]);
var s34 = new goog.structs.StringSet([3, 4]);
assertTrue('{} and {1, 2} are disjoint', s.isDisjoint(s12));
assertTrue('{1, 2} and {3, 4} are disjoint', s12.isDisjoint(s34));
assertFalse('{1, 2} and {2, 3} are not disjoint', s12.isDisjoint(s23));
}
function testIsEmpty() {
assertTrue('empty set', new goog.structs.StringSet().isEmpty());
assertFalse('non-empty set', new goog.structs.StringSet(['']).isEmpty());
}
function testIsSubsetOf() {
var s1 = new goog.structs.StringSet([1]);
var s12 = new goog.structs.StringSet([1, 2]);
var s123 = new goog.structs.StringSet([1, 2, 3]);
var s23 = new goog.structs.StringSet([2, 3]);
assertTrue('{1, 2} is subset of {1, 2}', s12.isSubsetOf(s12));
assertTrue('{1, 2} is subset of {1, 2, 3}', s12.isSubsetOf(s123));
assertFalse('{1, 2} is not subset of {1}', s12.isSubsetOf(s1));
assertFalse('{1, 2} is not subset of {2, 3}', s12.isSubsetOf(s23));
}
function testIsSupersetOf() {
var s1 = new goog.structs.StringSet([1]);
var s12 = new goog.structs.StringSet([1, 2]);
var s123 = new goog.structs.StringSet([1, 2, 3]);
var s23 = new goog.structs.StringSet([2, 3]);
assertTrue('{1, 2} is superset of {1}', s12.isSupersetOf(s1));
assertTrue('{1, 2} is superset of {1, 2}', s12.isSupersetOf(s12));
assertFalse('{1, 2} is not superset of {1, 2, 3}', s12.isSupersetOf(s123));
assertFalse('{1, 2} is not superset of {2, 3}', s12.isSupersetOf(s23));
}
function testRemove() {
var n = new goog.structs.StringSet([1, 2]);
assertFalse('3 not removed from {1, 2}', n.remove(3));
assertSameElements('set == {1, 2}', ['1', '2'], n.getValues());
assertTrue('2 removed from {1, 2}', n.remove(2));
assertSameElements('set == {1}', ['1'], n.getValues());
assertTrue('"1" removed from {1}', n.remove('1'));
assertSameElements('set == {}', [], n.getValues());
var s = new goog.structs.StringSet(TEST_VALUES);
goog.array.forEach(TEST_VALUES, s.remove, s);
assertSameElements('all special values have been removed', [], s.getValues());
}
function testRemoveArray() {
var s = new goog.structs.StringSet(TEST_VALUES);
s.removeArray(TEST_VALUES.slice(0, TEST_VALUES.length - 2));
assertSameElements('removed elements from array',
TEST_VALUES.slice(TEST_VALUES.length - 2), s.getValues());
}
function testRemoveSet() {
var s1 = new goog.structs.StringSet([1, 2]);
var s2 = new goog.structs.StringSet([2, 3]);
s1.removeSet(s2);
assertSameElements('{1, 2} - {2, 3}', ['1'], s1.getValues());
}
function testIterator() {
var s = new goog.structs.StringSet(TEST_VALUES_WITH_DUPLICATES);
var values = [];
goog.iter.forEach(s, function(value) {
values.push(value);
});
assertSameElements('__iterator__ takes all elements once',
TEST_VALUES, values);
}