Home | History | Annotate | Download | only in mjsunit
      1 // Copyright 2010 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 // Check that unshifting array of holes keeps the original array
     29 // as array of holes
     30 (function() {
     31   var array = new Array(10);
     32   assertEquals(13, array.unshift('1st', '2ns', '3rd'));
     33   assertTrue(0 in array);
     34   assertTrue(1 in array);
     35   assertTrue(2 in array);
     36   assertFalse(3 in array);
     37 })();
     38 
     39 
     40 // Check that unshift with no args has a side-effect of
     41 // filling the holes with elements from the prototype
     42 // (if present, of course)
     43 (function() {
     44   var len = 3;
     45   var array = new Array(len);
     46 
     47   var at0 = '@0';
     48   var at2 = '@2';
     49 
     50   Array.prototype[0] = at0;
     51   Array.prototype[2] = at2;
     52 
     53   // array owns nothing...
     54   assertFalse(array.hasOwnProperty(0));
     55   assertFalse(array.hasOwnProperty(1));
     56   assertFalse(array.hasOwnProperty(2));
     57 
     58   // ... but sees values from Array.prototype
     59   assertEquals(array[0], at0);
     60   assertEquals(array[1], undefined);
     61   assertEquals(array[2], at2);
     62 
     63   assertEquals(len, array.unshift());
     64 
     65   assertTrue(delete Array.prototype[0]);
     66   assertTrue(delete Array.prototype[2]);
     67 
     68   // unshift makes array own 0 and 2...
     69   assertTrue(array.hasOwnProperty(0));
     70   assertFalse(array.hasOwnProperty(1));
     71   assertTrue(array.hasOwnProperty(2));
     72 
     73   // ... so they are not affected be delete.
     74   assertEquals(array[0], at0);
     75   assertEquals(array[1], undefined);
     76   assertEquals(array[2], at2);
     77 })();
     78 
     79 
     80 // Now check the case with array of holes and some elements on prototype.
     81 (function() {
     82   var len = 9;
     83   var array = new Array(len);
     84   Array.prototype[3] = "@3";
     85   Array.prototype[7] = "@7";
     86 
     87   assertEquals(len, array.length);
     88   for (var i = 0; i < array.length; i++) {
     89     assertEquals(array[i], Array.prototype[i]);
     90   }
     91 
     92   assertEquals(len + 1, array.unshift('head'));
     93 
     94   assertEquals(len + 1, array.length);
     95   // Note that unshift copies values from prototype into the array.
     96   assertEquals(array[4], Array.prototype[3]);
     97   assertTrue(array.hasOwnProperty(4));
     98 
     99   assertEquals(array[8], Array.prototype[7]);
    100   assertTrue(array.hasOwnProperty(8));
    101 
    102   // ... but keeps the rest as holes:
    103   Array.prototype[5] = "@5";
    104   assertEquals(array[5], Array.prototype[5]);
    105   assertFalse(array.hasOwnProperty(5));
    106 
    107   assertEquals(array[3], Array.prototype[3]);
    108   assertFalse(array.hasOwnProperty(3));
    109 
    110   assertEquals(array[7], Array.prototype[7]);
    111   assertFalse(array.hasOwnProperty(7));
    112 
    113   assertTrue(delete Array.prototype[3]);
    114   assertTrue(delete Array.prototype[5]);
    115   assertTrue(delete Array.prototype[7]);
    116 })();
    117 
    118 // Check that unshift with no args has a side-effect of
    119 // filling the holes with elements from the prototype
    120 // (if present, of course)
    121 (function() {
    122   var len = 3;
    123   var array = new Array(len);
    124 
    125   var at0 = '@0';
    126   var at2 = '@2';
    127 
    128   var array_proto = [];
    129   array_proto[0] = at0;
    130   array_proto[2] = at2;
    131   array.__proto__ = array_proto;
    132 
    133   // array owns nothing...
    134   assertFalse(array.hasOwnProperty(0));
    135   assertFalse(array.hasOwnProperty(1));
    136   assertFalse(array.hasOwnProperty(2));
    137 
    138   // ... but sees values from array_proto.
    139   assertEquals(array[0], at0);
    140   assertEquals(array[1], undefined);
    141   assertEquals(array[2], at2);
    142 
    143   assertEquals(len, array.unshift());
    144 
    145   // unshift makes array own 0 and 2...
    146   assertTrue(array.hasOwnProperty(0));
    147   assertFalse(array.hasOwnProperty(1));
    148   assertTrue(array.hasOwnProperty(2));
    149 
    150   // ... so they are not affected be delete.
    151   assertEquals(array[0], at0);
    152   assertEquals(array[1], undefined);
    153   assertEquals(array[2], at2);
    154 })();
    155 
    156 
    157 // Now check the case with array of holes and some elements on prototype.
    158 (function() {
    159   var len = 9;
    160   var array = new Array(len);
    161   var array_proto = []
    162   array_proto[3] = "@3";
    163   array_proto[7] = "@7";
    164   array.__proto__ = array_proto;
    165 
    166   assertEquals(len, array.length);
    167   for (var i = 0; i < array.length; i++) {
    168     assertEquals(array[i], array_proto[i]);
    169   }
    170 
    171   assertEquals(len + 1, array.unshift('head'));
    172 
    173   assertEquals(len + 1, array.length);
    174   // Note that unshift copies values from prototype into the array.
    175   assertEquals(array[4], array_proto[3]);
    176   assertTrue(array.hasOwnProperty(4));
    177 
    178   assertEquals(array[8], array_proto[7]);
    179   assertTrue(array.hasOwnProperty(8));
    180 
    181   // ... but keeps the rest as holes:
    182   array_proto[5] = "@5";
    183   assertEquals(array[5], array_proto[5]);
    184   assertFalse(array.hasOwnProperty(5));
    185 
    186   assertEquals(array[3], array_proto[3]);
    187   assertFalse(array.hasOwnProperty(3));
    188 
    189   assertEquals(array[7], array_proto[7]);
    190   assertFalse(array.hasOwnProperty(7));
    191 })();
    192 
    193 // Check the behaviour when approaching maximal values for length.
    194 (function() {
    195   for (var i = 0; i < 7; i++) {
    196     try {
    197       new Array(Math.pow(2, 32) - 3).unshift(1, 2, 3, 4, 5);
    198       throw 'Should have thrown RangeError';
    199     } catch (e) {
    200       assertTrue(e instanceof RangeError);
    201     }
    202 
    203     // Check smi boundary
    204     var bigNum = (1 << 30) - 3;
    205     assertEquals(bigNum + 7, new Array(bigNum).unshift(1, 2, 3, 4, 5, 6, 7));
    206   }
    207 })();
    208 
    209 (function() {
    210   for (var i = 0; i < 7; i++) {
    211     var a = [6, 7, 8, 9];
    212     a.unshift(1, 2, 3, 4, 5);
    213     assertEquals([1, 2, 3, 4, 5, 6, 7, 8, 9], a);
    214   }
    215 })();
    216 
    217 // Check that non-enumerable elements are treated appropriately
    218 (function() {
    219   var array = [2, 3];
    220   Object.defineProperty(array, '1', {enumerable: false});
    221   array.unshift(1)
    222   assertEquals([1, 2, 3], array);
    223 
    224   array = [2];
    225   array.length = 2;
    226   array.__proto__[1] = 3;
    227   Object.defineProperty(array.__proto__, '1', {enumerable: false});
    228   array.unshift(1);
    229   assertEquals([1, 2, 3], array);
    230 })();
    231