findLast_findLastIndex.js (6205B)
1 /* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */ 2 /* This Source Code Form is subject to the terms of the Mozilla Public 3 * License, v. 2.0. If a copy of the MPL was not distributed with this 4 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 5 6 //----------------------------------------------------------------------------- 7 var BUGNUMBER = 1704385; 8 var summary = 'Array.prototype.findLast and Array.prototype.findLastIndex'; 9 10 print(BUGNUMBER + ": " + summary); 11 12 /************** 13 * BEGIN TEST * 14 **************/ 15 16 function isString(v, index, array) 17 { 18 assertEq(array[index], v); 19 return typeof v == 'string'; 20 } 21 22 function dumpError(e) 23 { 24 var s = e.name + ': ' + e.message + 25 ' File: ' + e.fileName + 26 ', Line: ' + e.lineNumber + 27 ', Stack: ' + e.stack; 28 return s; 29 } 30 31 var expect; 32 var actual; 33 var obj; 34 35 var strings = ['hello', 'Array', 'WORLD']; 36 var mixed = [0, '1', 2]; 37 var sparsestrings = new Array(); 38 sparsestrings[2] = 'sparse'; 39 var arraylike = {0:0, 1:'string', 2:2, length:3}; 40 // array for which JSObject::isIndexed() holds. 41 var indexedArray = []; 42 Object.defineProperty(indexedArray, 42, { get: function() { return 42; } }); 43 Object.defineProperty(indexedArray, 142, { get: function() { return 'string'; } }); 44 45 // findLast and findLastIndex have 1 required argument 46 47 expect = 1; 48 actual = Array.prototype.findLast.length; 49 reportCompare(expect, actual, 'Array.prototype.findLast.length == 1'); 50 actual = Array.prototype.findLastIndex.length; 51 reportCompare(expect, actual, 'Array.prototype.findLastIndex.length == 1'); 52 53 // throw TypeError if no predicate specified 54 expect = 'TypeError'; 55 try 56 { 57 strings.findLast(); 58 actual = 'no error'; 59 } 60 catch(e) 61 { 62 actual = e.name; 63 } 64 reportCompare(expect, actual, 'Array.findLast(undefined) throws TypeError'); 65 try 66 { 67 strings.findLastIndex(); 68 actual = 'no error'; 69 } 70 catch(e) 71 { 72 actual = e.name; 73 } 74 reportCompare(expect, actual, 'Array.findLastIndex(undefined) throws TypeError'); 75 76 // Length gets treated as integer, not uint32 77 obj = { length: -4294967295, 0: 42 }; 78 expected = undefined; 79 actual = Array.prototype.findLast.call(obj, () => true); 80 reportCompare(expected, actual, 'findLast correctly treats "length" as an integer'); 81 expected = -1 82 actual = Array.prototype.findLastIndex.call(obj, () => true); 83 reportCompare(expected, actual, 'findLastIndex correctly treats "length" as an integer'); 84 85 // test findLast and findLastIndex results 86 try 87 { 88 expect = 'WORLD'; 89 actual = strings.findLast(isString); 90 } 91 catch(e) 92 { 93 actual = dumpError(e); 94 } 95 reportCompare(expect, actual, 'strings: findLast finds last string element'); 96 97 try 98 { 99 expect = 2; 100 actual = strings.findLastIndex(isString); 101 } 102 catch(e) 103 { 104 actual = dumpError(e); 105 } 106 reportCompare(expect, actual, 'strings: findLastIndex finds last string element'); 107 108 try 109 { 110 expect = '1'; 111 actual = mixed.findLast(isString); 112 } 113 catch(e) 114 { 115 actual = dumpError(e); 116 } 117 reportCompare(expect, actual, 'mixed: findLast finds last string element'); 118 119 try 120 { 121 expect = 1; 122 actual = mixed.findLastIndex(isString); 123 } 124 catch(e) 125 { 126 actual = dumpError(e); 127 } 128 reportCompare(expect, actual, 'mixed: findLastIndex finds last string element'); 129 130 try 131 { 132 expect = 'sparse'; 133 actual = sparsestrings.findLast(isString); 134 } 135 catch(e) 136 { 137 actual = dumpError(e); 138 } 139 reportCompare(expect, actual, 'sparsestrings: findLast finds last string element'); 140 141 try 142 { 143 expect = 2; 144 actual = sparsestrings.findLastIndex(isString); 145 } 146 catch(e) 147 { 148 actual = dumpError(e); 149 } 150 reportCompare(expect, actual, 'sparsestrings: findLastIndex finds first string element'); 151 152 try 153 { 154 expect = 'string'; 155 actual = [].findLast.call(arraylike, isString); 156 } 157 catch(e) 158 { 159 actual = dumpError(e); 160 } 161 reportCompare(expect, actual, 'arraylike: findLast finds last string element'); 162 163 try 164 { 165 expect = 1; 166 actual = [].findLastIndex.call(arraylike, isString); 167 } 168 catch(e) 169 { 170 actual = dumpError(e); 171 } 172 reportCompare(expect, actual, 'arraylike: findLastIndex finds last string element'); 173 174 try 175 { 176 expect = 1; 177 actual = 0; 178 Array.prototype.findLast.call({get 0(){ actual++ }, length: 1}, ()=>true); 179 } 180 catch(e) 181 { 182 actual = dumpError(e); 183 } 184 reportCompare(expect, actual, 'arraylike with getter: getter only called once'); 185 186 try 187 { 188 expect = 'string'; 189 actual = [].findLast.call(indexedArray, isString); 190 } 191 catch(e) 192 { 193 actual = dumpError(e); 194 } 195 reportCompare(expect, actual, 'indexedArray: findLast finds last string element'); 196 197 try 198 { 199 expect = 142; 200 actual = [].findLastIndex.call(indexedArray, isString); 201 } 202 catch(e) 203 { 204 actual = dumpError(e); 205 } 206 reportCompare(expect, actual, 'indexedArray: findLastIndex finds last string element'); 207 208 // Bug 1058394 - Array#findLast and Array#findLastIndex no longer skip holes too. 209 var sparseArray = [1,,]; 210 var sparseArrayWithInheritedDataProperty = Object.setPrototypeOf([1,,,], { 211 __proto__: [].__proto__, 212 2 : 0 213 }); 214 var sparseArrayWithInheritedAccessorProperty = Object.setPrototypeOf([1,,,], { 215 __proto__: [].__proto__, 216 get 2(){ 217 throw "get 2"; 218 } 219 }); 220 221 try 222 { 223 expect = undefined; 224 actual = sparseArray.findLast(() => true); 225 } 226 catch(e) 227 { 228 actual = dumpError(e); 229 } 230 reportCompare(expect, actual, "Don't skip holes in Array#findLast."); 231 232 try 233 { 234 expect = 1; 235 actual = sparseArray.findLastIndex(() => true); 236 } 237 catch(e) 238 { 239 actual = dumpError(e); 240 } 241 reportCompare(expect, actual, "Don't skip holes in Array#findLastIndex."); 242 243 try 244 { 245 expect = 0; 246 actual = sparseArrayWithInheritedDataProperty.findLast(v => v === 0); 247 } 248 catch(e) 249 { 250 actual = dumpError(e); 251 } 252 reportCompare(expect, actual, "Array#findLast can find inherited data property."); 253 254 try 255 { 256 expect = 2; 257 actual = sparseArrayWithInheritedDataProperty.findLastIndex(v => v === 0); 258 } 259 catch(e) 260 { 261 actual = dumpError(e); 262 } 263 reportCompare(expect, actual, "Array#findLastIndex can find inherited data property."); 264 265 try 266 { 267 expect = "get 2"; 268 actual = sparseArrayWithInheritedAccessorProperty.findLast(() => true); 269 } 270 catch(e) 271 { 272 actual = e; 273 } 274 reportCompare(expect, actual, "Array#findLast can find inherited accessor property."); 275 276 try 277 { 278 expect = "get 2"; 279 actual = sparseArrayWithInheritedAccessorProperty.findLastIndex(() => true); 280 } 281 catch(e) 282 { 283 actual = e; 284 } 285 reportCompare(expect, actual, "Array#findLastIndex can find inherited accessor property.");