1 /*
   2  * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  * 
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.
   8  * 
   9  * This code is distributed in the hope that it will be useful, but WITHOUT
  10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  12  * version 2 for more details (a copy is included in the LICENSE file that
  13  * accompanied this code).
  14  * 
  15  * You should have received a copy of the GNU General Public License version
  16  * 2 along with this work; if not, write to the Free Software Foundation,
  17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  18  * 
  19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  20  * or visit www.oracle.com if you need additional information or have any
  21  * questions.
  22  */
  23 
  24 /**
  25  * JDK-8147558: Add support for ES6 collections
  26  *
  27  * @test
  28  * @run
  29  * @option --language=es6
  30  */
  31 
  32 function assertThrows(src, error) {
  33     try {
  34         eval(src);
  35         Assert.fail("No error, expected " + error);
  36     } catch (e) {
  37         if (!(e instanceof error)) {
  38             Assert.fail("Wrong error, expected " + error + " but got " + e);
  39         }
  40     }
  41 }
  42 
  43 // Map constructor and prototype
  44 
  45 var desc = Object.getOwnPropertyDescriptor(this, "Map");
  46 Assert.assertEquals(desc.writable, true);
  47 Assert.assertEquals(desc.configurable, true);
  48 Assert.assertEquals(desc.enumerable, false);
  49 
  50 Assert.assertTrue(Object.getPrototypeOf(new Map()) === Map.prototype);
  51 Assert.assertTrue(Object.getPrototypeOf(Map.prototype) === Object.prototype);
  52 Assert.assertTrue(new Map().size === 0);
  53 Assert.assertTrue(Object.getPrototypeOf(new Map([["a", 1], ["b", 2]])) === Map.prototype);
  54 Assert.assertTrue(new Map([["a", 1], ["b", 2]]).size === 2);
  55 Assert.assertTrue(Object.getPrototypeOf(new Map("")) === Map.prototype);
  56 Assert.assertTrue(new Map("").size === 0);
  57 Assert.assertTrue(Object.getPrototypeOf(new Map([])) === Map.prototype);
  58 Assert.assertTrue(new Map([]).size === 0);
  59 
  60 assertThrows("Map()", TypeError);
  61 assertThrows("new Map(3)", TypeError);
  62 assertThrows("new Map('abc')", TypeError);
  63 assertThrows("new Map({})", TypeError);
  64 assertThrows("new Map([1, 2, 3])", TypeError);
  65 
  66 assertThrows("Map.prototype.set.apply({}, ['', ''])", TypeError);
  67 assertThrows("Map.prototype.get.apply([], [''])", TypeError);
  68 assertThrows("Map.prototype.has.apply(3, [''])", TypeError);
  69 assertThrows("Map.prototype.clear.apply('', [])", TypeError);
  70 
  71 // Map methods
  72 
  73 var m = new Map([["a", 1], ["b", 2]]);
  74 Assert.assertTrue(m.size, 2);
  75 Assert.assertTrue(m.get("a") === 1);
  76 Assert.assertTrue(m.get("b") === 2);
  77 Assert.assertTrue(m.get("c") === undefined);
  78 Assert.assertTrue(m.has("a") === true);
  79 Assert.assertTrue(m.has("b") === true);
  80 Assert.assertTrue(m.has("c") === false);
  81 
  82 m.clear();
  83 Assert.assertTrue(m.size === 0);
  84 Assert.assertTrue(m.get("a") === undefined);
  85 Assert.assertTrue(m.get("b") === undefined);
  86 Assert.assertTrue(m.get("c") === undefined);
  87 Assert.assertTrue(m.has("a") === false);
  88 Assert.assertTrue(m.has("b") === false);
  89 Assert.assertTrue(m.has("c") === false);
  90 
  91 var a = "a", x = "x"; // for ConsString keys
  92 Assert.assertTrue(m.set("ab", false) === m);
  93 Assert.assertTrue(m.set(x + "y", m) === m);
  94 Assert.assertTrue(m.get(a + "b") === false);
  95 Assert.assertTrue(m.get("xy") === m);
  96 Assert.assertTrue(m.has(a + "b") === true);
  97 Assert.assertTrue(m.has("xy") === true);
  98 
  99 // Special keys
 100 
 101 m = new Map();
 102 Assert.assertTrue(m.set(NaN, NaN) === m);  // NaN should work as key
 103 Assert.assertTrue(m.size === 1);
 104 Assert.assertTrue(isNaN(m.get(NaN)));
 105 Assert.assertTrue(isNaN(m.keys().next().value));
 106 Assert.assertTrue(isNaN(m.values().next().value));
 107 Assert.assertTrue(m.has(NaN) === true);
 108 Assert.assertTrue(m.delete(NaN));
 109 Assert.assertTrue(m.size === 0);
 110 Assert.assertTrue(m.get(NaN) === undefined);
 111 Assert.assertTrue(m.keys().next().done);
 112 Assert.assertTrue(m.values().next().done);
 113 Assert.assertTrue(m.has(NaN) === false);
 114 
 115 m.clear();
 116 m.set(-0, -0); // -0 key should be converted to +0
 117 Assert.assertTrue(m.size === 1);
 118 Assert.assertTrue(m.get(-0) === 0);
 119 Assert.assertTrue(1 / m.keys().next().value === Infinity);
 120 Assert.assertTrue(1 / m.values().next().value === -Infinity);
 121 Assert.assertTrue(m.has(-0) === true);
 122 Assert.assertTrue(m.has(0) === true);
 123 Assert.assertTrue(m.delete(-0));
 124 Assert.assertTrue(m.size === 0);
 125 Assert.assertTrue(m.get(-0) === undefined);
 126 Assert.assertTrue(m.get(0) === undefined);
 127 Assert.assertTrue(m.has(-0) === false);
 128 Assert.assertTrue(m.has(0) === false);
 129 
 130 Assert.assertFalse(m.delete("foo"));
 131 Assert.assertFalse(m.delete(0));
 132 Assert.assertFalse(m.delete(NaN));
 133 
 134 // foreach
 135 
 136 m = new Map([[1, "one"], [2, "two"], [3, "three"]]);
 137 m.forEach(function(value, key, map) {
 138     Assert.assertTrue(this === m);
 139     Assert.assertTrue(map === m);
 140 }, m);
 141 
 142 function assertEqualArrays(a, b) {
 143     Assert.assertTrue(Array.isArray(a));
 144     Assert.assertTrue(Array.isArray(b));
 145     Assert.assertTrue(a.length === b.length);
 146     Assert.assertTrue(a.every(function(v, j) {
 147         return v === b[j];
 148     }));
 149 }
 150 
 151 let array = [];
 152 m = new Map([[1, "one"], [2, "two"], [3, "three"]]);
 153 m.forEach(function(value, key, map) {
 154     array.push(value);
 155 });
 156 assertEqualArrays(array, ["one", "two", "three"]);
 157 
 158 array = [];
 159 m = new Map([[1, "one"], [2, "two"], [3, "three"]]);
 160 m.forEach(function(value, key, map) {
 161     array.push(value);
 162     if (key == 3) {
 163         map.clear();
 164         map.set(4, "four");
 165     }
 166 });
 167 assertEqualArrays(array, ["one", "two", "three", "four"]);
 168 
 169 array = [];
 170 m = new Map([[1, "one"], [2, "two"], [3, "three"]]);
 171 m.forEach(function(value, key, map) {
 172     array.push(value);
 173     if (key == 1) {
 174         map.delete(1);
 175     }
 176     if (key == 2) {
 177         map.delete(3);
 178     }
 179 });
 180 assertEqualArrays(array, ["one", "two"]);
 181 
 182 array = [];
 183 m = new Map([[1, "one"], [2, "two"], [3, "three"]]);
 184 m.forEach(function(value, key, map) {
 185     array.push(value);
 186     if (array.length < 4) {
 187         map.delete(key);
 188         map.set(key, key + 3)
 189     }
 190 });
 191 assertEqualArrays(array, ["one", "two", "three", 4, 5, 6]);
 192 
 193 
 194 
 195