diff --git a/js/js.translator/testData/maps.js b/js/js.translator/testData/maps.js index 61e02737d8c..36e78202ff7 100644 --- a/js/js.translator/testData/maps.js +++ b/js/js.translator/testData/maps.js @@ -68,6 +68,8 @@ }; function hashObject(obj) { + if (obj == null) return ""; + var hashCode; if (typeof obj == "string") { return obj; @@ -97,23 +99,11 @@ } function equals_fixedValueNoEquals(fixedValue, variableValue) { - return (typeof variableValue.equals_za3rmp$ == FUNCTION) ? + return (variableValue != null && typeof variableValue.equals_za3rmp$ == FUNCTION) ? + // TODO: test this case variableValue.equals_za3rmp$(fixedValue) : (fixedValue === variableValue); } - function createKeyValCheck(kvStr) { - return function (kv) { - if (kv === null) { - throw new Error("null is not a valid " + kvStr); - } - else if (typeof kv == "undefined") { - throw new Error(kvStr + " must not be undefined"); - } - }; - } - - var checkKey = createKeyValCheck("key"), checkValue = createKeyValCheck("value"); - /** * @constructor * @param {string} hash @@ -167,7 +157,7 @@ Bucket.prototype = { getEqualityFunction: function (searchValue) { - return (typeof searchValue.equals_za3rmp$ == FUNCTION) ? equals_fixedValueHasEquals : equals_fixedValueNoEquals; + return (searchValue != null && typeof searchValue.equals_za3rmp$ == FUNCTION) ? equals_fixedValueHasEquals : equals_fixedValueNoEquals; }, getEntryForKey: createBucketSearcher(ENTRY), @@ -178,7 +168,7 @@ var result = this.getEntryAndIndexForKey(key); if (result) { arrayRemoveAt(this.entries, result[0]); - return result[1]; + return result; } return null; }, @@ -253,8 +243,6 @@ var equalityFunction = (typeof equalityFunctionParam == FUNCTION) ? equalityFunctionParam : null; this.put_wn2jw4$ = function (key, value) { - checkKey(key); - checkValue(value); var hash = hashingFunction(key), bucket, bucketEntry, oldValue = null; // Check if a bucket exists for the bucket key @@ -282,8 +270,6 @@ }; this.get_za3rmp$ = function (key) { - checkKey(key); - var hash = hashingFunction(key); // Check if a bucket exists for the bucket key @@ -300,7 +286,6 @@ }; this.containsKey_za3rmp$ = function (key) { - checkKey(key); var bucketKey = hashingFunction(key); // Check if a bucket exists for the bucket key @@ -310,7 +295,6 @@ }; this.containsValue_za3rmp$ = function (value) { - checkValue(value); var i = buckets.length; while (i--) { if (buckets[i].containsValue_za3rmp$(value)) { @@ -354,17 +338,17 @@ }; this.remove_za3rmp$ = function (key) { - checkKey(key); - - var hash = hashingFunction(key), bucketIndex, oldValue = null; + var hash = hashingFunction(key), bucketIndex, oldValue = null, result = null; // Check if a bucket exists for the bucket key var bucket = getBucketForHash(bucketsByHash, hash); if (bucket) { // Remove entry from this bucket for this key - oldValue = bucket.removeEntryForKey(key); - if (oldValue !== null) { + result = bucket.removeEntryForKey(key); + if (result !== null) { + oldValue = result[1]; + // Entry was removed, so check if bucket is empty if (!bucket.entries.length) { // Bucket is empty, so remove it from the bucket collections diff --git a/libraries/stdlib/test/js/MapJsTest.kt b/libraries/stdlib/test/js/MapJsTest.kt index 9e976453f7a..96d86e1e70d 100644 --- a/libraries/stdlib/test/js/MapJsTest.kt +++ b/libraries/stdlib/test/js/MapJsTest.kt @@ -23,6 +23,7 @@ class ComplexMapJsTest : MapJsTest() { override fun > Collection.toNormalizedList(): List = this.toSortedList() // hashMapOf returns ComlpexHashMap because it is Generic override fun emptyMutableMap(): MutableMap = hashMapOf() + override fun emptyMutableMapWithNullableKeyValue(): MutableMap = hashMapOf() } class PrimitiveMapJsTest : MapJsTest() { @@ -39,6 +40,7 @@ class PrimitiveMapJsTest : MapJsTest() { override fun > Collection.toNormalizedList(): List = this.toSortedList() override fun emptyMutableMap(): MutableMap = HashMap() + override fun emptyMutableMapWithNullableKeyValue(): MutableMap = HashMap() } class LinkedHashMapTest : MapJsTest() { @@ -55,6 +57,7 @@ class LinkedHashMapTest : MapJsTest() { override fun > Collection.toNormalizedList(): List = this.toList() override fun emptyMutableMap(): MutableMap = LinkedHashMap() + override fun emptyMutableMapWithNullableKeyValue(): MutableMap = LinkedHashMap() } abstract class MapJsTest { @@ -224,6 +227,31 @@ abstract class MapJsTest { assertTrue(map.isEmpty()) } + test fun nullAsKey() { + val map = emptyMutableMapWithNullableKeyValue() + + assertTrue(map.isEmpty()) + map.put(null, 23) + assertFalse(map.isEmpty()) + assertTrue(map.containsKey(null)) + assertEquals(23, map[null]) + assertEquals(23, map.remove(null)) + assertTrue(map.isEmpty()) + assertEquals(null, map[null]) + } + + test fun nullAsValue() { + val map = emptyMutableMapWithNullableKeyValue() + val KEY = "Key" + + assertTrue(map.isEmpty()) + map.put(KEY, null) + assertFalse(map.isEmpty()) + assertEquals(null, map[KEY]) + assertTrue(map.containsValue(null)) + assertEquals(null, map.remove(KEY)) + assertTrue(map.isEmpty()) + } /* TODO fix bug with .set() on Map... @@ -444,6 +472,8 @@ abstract class MapJsTest { abstract fun emptyMutableMap(): MutableMap + abstract fun emptyMutableMapWithNullableKeyValue(): MutableMap + fun createTestMap(): Map = createTestMutableMap() fun createTestMutableMap(): MutableMap { diff --git a/libraries/stdlib/test/js/SetJsTest.kt b/libraries/stdlib/test/js/SetJsTest.kt index 6cf3a28a4a3..f09e026e8d2 100644 --- a/libraries/stdlib/test/js/SetJsTest.kt +++ b/libraries/stdlib/test/js/SetJsTest.kt @@ -22,10 +22,13 @@ class ComplexSetJsTest : SetJsTest() { } // hashSetOf returns ComlpexHashSet because it is Generic - override fun createEmptyMutableSet(): MutableSet = hashSetOf() + override fun createEmptyMutableSet(): MutableSet = hashSetOf() + override fun createEmptyMutableSetWithNullableValues(): MutableSet = hashSetOf() } class PrimitiveSetJsTest : SetJsTest() { + override fun createEmptyMutableSet(): MutableSet = HashSet() + override fun createEmptyMutableSetWithNullableValues(): MutableSet = HashSet() test override fun constructors() { HashSet() HashSet(3) @@ -35,11 +38,11 @@ class PrimitiveSetJsTest : SetJsTest() { assertEquals(data, set) } - - override fun createEmptyMutableSet(): MutableSet = HashSet() } class LinkedHashSetTest : SetJsTest() { + override fun createEmptyMutableSet(): MutableSet = LinkedHashSet() + override fun createEmptyMutableSetWithNullableValues(): MutableSet = LinkedHashSet() test override fun constructors() { LinkedHashSet() LinkedHashSet(3) @@ -49,8 +52,6 @@ class LinkedHashSetTest : SetJsTest() { assertEquals(data, set) } - - override fun createEmptyMutableSet(): MutableSet = LinkedHashSet() } abstract class SetJsTest { @@ -187,8 +188,20 @@ abstract class SetJsTest { test abstract fun constructors() + Test fun nullAsValue() { + val set = createEmptyMutableSetWithNullableValues() + + assertTrue(set.isEmpty(), "Set should be empty") + set.add(null) + assertFalse(set.isEmpty(), "Set should not be empty") + assertTrue(set.contains(null), "Set should contains null") + assertTrue(set.remove(null), "Expected true when remove null") + assertTrue(set.isEmpty(), "Set should be empty") + } + //Helpers abstract fun createEmptyMutableSet(): MutableSet + abstract fun createEmptyMutableSetWithNullableValues(): MutableSet fun createTestMutableSet(): MutableSet { val set = createEmptyMutableSet()