1 // Copyright 2013 the V8 project authors. All rights reserved. 2 // Redistribution and use in source and binary forms, with or without 3 // modification, are permitted provided that the following conditions are 4 // met: 5 // 6 // * Redistributions of source code must retain the above copyright 7 // notice, this list of conditions and the following disclaimer. 8 // * Redistributions in binary form must reproduce the above 9 // copyright notice, this list of conditions and the following 10 // disclaimer in the documentation and/or other materials provided 11 // with the distribution. 12 // * Neither the name of Google Inc. nor the names of its 13 // contributors may be used to endorse or promote products derived 14 // from this software without specific prior written permission. 15 // 16 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 17 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 18 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 19 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 20 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 21 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 22 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 23 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 24 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 25 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 26 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 28 // Flags: --harmony-arrays 29 30 assertEquals(1, Array.prototype.findIndex.length); 31 32 var a = [21, 22, 23, 24]; 33 assertEquals(-1, a.findIndex(function() { return false; })); 34 assertEquals(-1, a.findIndex(function(val) { return 121 === val; })); 35 assertEquals(0, a.findIndex(function() { return true; })); 36 assertEquals(1, a.findIndex(function(val) { return 22 === val; }), undefined); 37 assertEquals(2, a.findIndex(function(val) { return 23 === val; }), null); 38 assertEquals(3, a.findIndex(function(val) { return 24 === val; })); 39 40 41 // 42 // Test predicate is not called when array is empty 43 // 44 (function() { 45 var a = []; 46 var l = -1; 47 var o = -1; 48 var v = -1; 49 var k = -1; 50 51 a.findIndex(function(val, key, obj) { 52 o = obj; 53 l = obj.length; 54 v = val; 55 k = key; 56 57 return false; 58 }); 59 60 assertEquals(-1, l); 61 assertEquals(-1, o); 62 assertEquals(-1, v); 63 assertEquals(-1, k); 64 })(); 65 66 67 // 68 // Test predicate is called with correct argumetns 69 // 70 (function() { 71 var a = ["b"]; 72 var l = -1; 73 var o = -1; 74 var v = -1; 75 var k = -1; 76 77 var index = a.findIndex(function(val, key, obj) { 78 o = obj; 79 l = obj.length; 80 v = val; 81 k = key; 82 83 return false; 84 }); 85 86 assertArrayEquals(a, o); 87 assertEquals(a.length, l); 88 assertEquals("b", v); 89 assertEquals(0, k); 90 assertEquals(-1, index); 91 })(); 92 93 94 // 95 // Test predicate is called array.length times 96 // 97 (function() { 98 var a = [1, 2, 3, 4, 5]; 99 var l = 0; 100 101 a.findIndex(function() { 102 l++; 103 return false; 104 }); 105 106 assertEquals(a.length, l); 107 })(); 108 109 110 // 111 // Test Array.prototype.findIndex works with String 112 // 113 (function() { 114 var a = "abcd"; 115 var l = -1; 116 var o = -1; 117 var v = -1; 118 var k = -1; 119 120 var index = Array.prototype.findIndex.call(a, function(val, key, obj) { 121 o = obj.toString(); 122 l = obj.length; 123 v = val; 124 k = key; 125 126 return false; 127 }); 128 129 assertEquals(a, o); 130 assertEquals(a.length, l); 131 assertEquals("d", v); 132 assertEquals(3, k); 133 assertEquals(-1, index); 134 135 index = Array.prototype.findIndex.apply(a, [function(val, key, obj) { 136 o = obj.toString(); 137 l = obj.length; 138 v = val; 139 k = key; 140 141 return true; 142 }]); 143 144 assertEquals(a, o); 145 assertEquals(a.length, l); 146 assertEquals("a", v); 147 assertEquals(0, k); 148 assertEquals(0, index); 149 })(); 150 151 152 // 153 // Test Array.prototype.findIndex works with exotic object 154 // 155 (function() { 156 var l = -1; 157 var o = -1; 158 var v = -1; 159 var k = -1; 160 var a = { 161 prop1: "val1", 162 prop2: "val2", 163 isValid: function() { 164 return this.prop1 === "val1" && this.prop2 === "val2"; 165 } 166 }; 167 168 Array.prototype.push.apply(a, [30, 31, 32]); 169 170 var index = Array.prototype.findIndex.call(a, function(val, key, obj) { 171 o = obj; 172 l = obj.length; 173 v = val; 174 k = key; 175 176 return !obj.isValid(); 177 }); 178 179 assertArrayEquals(a, o); 180 assertEquals(3, l); 181 assertEquals(32, v); 182 assertEquals(2, k); 183 assertEquals(-1, index); 184 })(); 185 186 187 // 188 // Test array modifications 189 // 190 (function() { 191 var a = [1, 2, 3]; 192 a.findIndex(function(val) { a.push(val); return false; }); 193 assertArrayEquals([1, 2, 3, 1, 2, 3], a); 194 assertEquals(6, a.length); 195 196 a = [1, 2, 3]; 197 a.findIndex(function(val, key) { a[key] = ++val; return false; }); 198 assertArrayEquals([2, 3, 4], a); 199 assertEquals(3, a.length); 200 })(); 201 202 203 // 204 // Test predicate is only called for existing elements 205 // 206 (function() { 207 var a = new Array(30); 208 a[11] = 21; 209 a[7] = 10; 210 a[29] = 31; 211 212 var count = 0; 213 a.findIndex(function() { count++; return false; }); 214 assertEquals(3, count); 215 })(); 216 217 218 // 219 // Test thisArg 220 // 221 (function() { 222 // Test String as a thisArg 223 var index = [1, 2, 3].findIndex(function(val, key) { 224 return this.charAt(Number(key)) === String(val); 225 }, "321"); 226 assertEquals(1, index); 227 228 // Test object as a thisArg 229 var thisArg = { 230 elementAt: function(key) { 231 return this[key]; 232 } 233 }; 234 Array.prototype.push.apply(thisArg, ["c", "b", "a"]); 235 236 index = ["a", "b", "c"].findIndex(function(val, key) { 237 return this.elementAt(key) === val; 238 }, thisArg); 239 assertEquals(1, index); 240 })(); 241 242 // Test exceptions 243 assertThrows('Array.prototype.findIndex.call(null, function() { })', 244 TypeError); 245 assertThrows('Array.prototype.findIndex.call(undefined, function() { })', 246 TypeError); 247 assertThrows('Array.prototype.findIndex.apply(null, function() { }, [])', 248 TypeError); 249 assertThrows('Array.prototype.findIndex.apply(undefined, function() { }, [])', 250 TypeError); 251 252 assertThrows('[].findIndex(null)', TypeError); 253 assertThrows('[].findIndex(undefined)', TypeError); 254 assertThrows('[].findIndex(0)', TypeError); 255 assertThrows('[].findIndex(true)', TypeError); 256 assertThrows('[].findIndex(false)', TypeError); 257 assertThrows('[].findIndex("")', TypeError); 258 assertThrows('[].findIndex({})', TypeError); 259 assertThrows('[].findIndex([])', TypeError); 260 assertThrows('[].findIndex(/\d+/)', TypeError); 261 262 assertThrows('Array.prototype.findIndex.call({}, null)', TypeError); 263 assertThrows('Array.prototype.findIndex.call({}, undefined)', TypeError); 264 assertThrows('Array.prototype.findIndex.call({}, 0)', TypeError); 265 assertThrows('Array.prototype.findIndex.call({}, true)', TypeError); 266 assertThrows('Array.prototype.findIndex.call({}, false)', TypeError); 267 assertThrows('Array.prototype.findIndex.call({}, "")', TypeError); 268 assertThrows('Array.prototype.findIndex.call({}, {})', TypeError); 269 assertThrows('Array.prototype.findIndex.call({}, [])', TypeError); 270 assertThrows('Array.prototype.findIndex.call({}, /\d+/)', TypeError); 271 272 assertThrows('Array.prototype.findIndex.apply({}, null, [])', TypeError); 273 assertThrows('Array.prototype.findIndex.apply({}, undefined, [])', TypeError); 274 assertThrows('Array.prototype.findIndex.apply({}, 0, [])', TypeError); 275 assertThrows('Array.prototype.findIndex.apply({}, true, [])', TypeError); 276 assertThrows('Array.prototype.findIndex.apply({}, false, [])', TypeError); 277 assertThrows('Array.prototype.findIndex.apply({}, "", [])', TypeError); 278 assertThrows('Array.prototype.findIndex.apply({}, {}, [])', TypeError); 279 assertThrows('Array.prototype.findIndex.apply({}, [], [])', TypeError); 280 assertThrows('Array.prototype.findIndex.apply({}, /\d+/, [])', TypeError); 281