Home | History | Annotate | Download | only in harmony
      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.find.length);
     31 
     32 var a = [21, 22, 23, 24];
     33 assertEquals(undefined, a.find(function() { return false; }));
     34 assertEquals(21, a.find(function() { return true; }));
     35 assertEquals(undefined, a.find(function(val) { return 121 === val; }));
     36 assertEquals(24, a.find(function(val) { return 24 === val; }));
     37 assertEquals(23, a.find(function(val) { return 23 === val; }), null);
     38 assertEquals(22, a.find(function(val) { return 22 === val; }), undefined);
     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.find(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 found = a.find(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(undefined, found);
     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   var found = a.find(function() {
    101     l++;
    102     return false;
    103   });
    104 
    105   assertEquals(a.length, l);
    106   assertEquals(undefined, found);
    107 })();
    108 
    109 
    110 //
    111 // Test Array.prototype.find 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   var found = Array.prototype.find.call(a, function(val, key, obj) {
    120     o = obj.toString();
    121     l = obj.length;
    122     v = val;
    123     k = key;
    124 
    125     return false;
    126   });
    127 
    128   assertEquals(a, o);
    129   assertEquals(a.length, l);
    130   assertEquals("d", v);
    131   assertEquals(3, k);
    132   assertEquals(undefined, found);
    133 
    134   found = Array.prototype.find.apply(a, [function(val, key, obj) {
    135     o = obj.toString();
    136     l = obj.length;
    137     v = val;
    138     k = key;
    139 
    140     return true;
    141   }]);
    142 
    143   assertEquals(a, o);
    144   assertEquals(a.length, l);
    145   assertEquals("a", v);
    146   assertEquals(0, k);
    147   assertEquals("a", found);
    148 })();
    149 
    150 
    151 //
    152 // Test Array.prototype.find works with exotic object
    153 //
    154 (function() {
    155   var l = -1;
    156   var o = -1;
    157   var v = -1;
    158   var k = -1;
    159   var a = {
    160     prop1: "val1",
    161     prop2: "val2",
    162     isValid: function() {
    163       return this.prop1 === "val1" && this.prop2 === "val2";
    164     }
    165   };
    166 
    167   Array.prototype.push.apply(a, [30, 31, 32]);
    168   var found = Array.prototype.find.call(a, function(val, key, obj) {
    169     o = obj;
    170     l = obj.length;
    171     v = val;
    172     k = key;
    173 
    174     return !obj.isValid();
    175   });
    176 
    177   assertArrayEquals(a, o);
    178   assertEquals(3, l);
    179   assertEquals(32, v);
    180   assertEquals(2, k);
    181   assertEquals(undefined, found);
    182 })();
    183 
    184 
    185 //
    186 // Test array modifications
    187 //
    188 (function() {
    189   var a = [1, 2, 3];
    190   var found = a.find(function(val) { a.push(val); return false; });
    191   assertArrayEquals([1, 2, 3, 1, 2, 3], a);
    192   assertEquals(6, a.length);
    193   assertEquals(undefined, found);
    194 
    195   a = [1, 2, 3];
    196   found = a.find(function(val, key) { a[key] = ++val; return false; });
    197   assertArrayEquals([2, 3, 4], a);
    198   assertEquals(3, a.length);
    199   assertEquals(undefined, found);
    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.find(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 found = [1, 2, 3].find(function(val, key) {
    224     return this.charAt(Number(key)) === String(val);
    225   }, "321");
    226   assertEquals(2, found);
    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   found = ["a", "b", "c"].find(function(val, key) {
    237     return this.elementAt(key) === val;
    238   }, thisArg);
    239   assertEquals("b", found);
    240 })();
    241 
    242 // Test exceptions
    243 assertThrows('Array.prototype.find.call(null, function() { })',
    244   TypeError);
    245 assertThrows('Array.prototype.find.call(undefined, function() { })',
    246   TypeError);
    247 assertThrows('Array.prototype.find.apply(null, function() { }, [])',
    248   TypeError);
    249 assertThrows('Array.prototype.find.apply(undefined, function() { }, [])',
    250   TypeError);
    251 
    252 assertThrows('[].find(null)', TypeError);
    253 assertThrows('[].find(undefined)', TypeError);
    254 assertThrows('[].find(0)', TypeError);
    255 assertThrows('[].find(true)', TypeError);
    256 assertThrows('[].find(false)', TypeError);
    257 assertThrows('[].find("")', TypeError);
    258 assertThrows('[].find({})', TypeError);
    259 assertThrows('[].find([])', TypeError);
    260 assertThrows('[].find(/\d+/)', TypeError);
    261 
    262 assertThrows('Array.prototype.find.call({}, null)', TypeError);
    263 assertThrows('Array.prototype.find.call({}, undefined)', TypeError);
    264 assertThrows('Array.prototype.find.call({}, 0)', TypeError);
    265 assertThrows('Array.prototype.find.call({}, true)', TypeError);
    266 assertThrows('Array.prototype.find.call({}, false)', TypeError);
    267 assertThrows('Array.prototype.find.call({}, "")', TypeError);
    268 assertThrows('Array.prototype.find.call({}, {})', TypeError);
    269 assertThrows('Array.prototype.find.call({}, [])', TypeError);
    270 assertThrows('Array.prototype.find.call({}, /\d+/)', TypeError);
    271 
    272 assertThrows('Array.prototype.find.apply({}, null, [])', TypeError);
    273 assertThrows('Array.prototype.find.apply({}, undefined, [])', TypeError);
    274 assertThrows('Array.prototype.find.apply({}, 0, [])', TypeError);
    275 assertThrows('Array.prototype.find.apply({}, true, [])', TypeError);
    276 assertThrows('Array.prototype.find.apply({}, false, [])', TypeError);
    277 assertThrows('Array.prototype.find.apply({}, "", [])', TypeError);
    278 assertThrows('Array.prototype.find.apply({}, {}, [])', TypeError);
    279 assertThrows('Array.prototype.find.apply({}, [], [])', TypeError);
    280 assertThrows('Array.prototype.find.apply({}, /\d+/, [])', TypeError);
    281