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 slicing array of holes keeps it as array of holes
     29 (function() {
     30   var array = new Array(10);
     31   for (var i = 0; i < 7; i++) {
     32     var sliced = array.slice();
     33     assertEquals(array.length, sliced.length);
     34     assertFalse(0 in sliced);
     35   }
     36 })();
     37 
     38 
     39 // Check various forms of arguments omission.
     40 (function() {
     41   var array = new Array(7);
     42 
     43   for (var i = 0; i < 7; i++) {
     44     assertEquals(array, array.slice());
     45     assertEquals(array, array.slice(0));
     46     assertEquals(array, array.slice(undefined));
     47     assertEquals(array, array.slice("foobar"));
     48     assertEquals(array, array.slice(undefined, undefined));
     49   }
     50 })();
     51 
     52 
     53 // Check variants of negatives and positive indices.
     54 (function() {
     55   var array = new Array(7);
     56 
     57   for (var i = 0; i < 7; i++) {
     58     assertEquals(7, array.slice(-100).length);
     59     assertEquals(3, array.slice(-3).length);
     60     assertEquals(3, array.slice(4).length);
     61     assertEquals(1, array.slice(6).length);
     62     assertEquals(0, array.slice(7).length);
     63     assertEquals(0, array.slice(8).length);
     64     assertEquals(0, array.slice(100).length);
     65 
     66     assertEquals(0, array.slice(0, -100).length);
     67     assertEquals(4, array.slice(0, -3).length);
     68     assertEquals(4, array.slice(0, 4).length);
     69     assertEquals(6, array.slice(0, 6).length);
     70     assertEquals(7, array.slice(0, 7).length);
     71     assertEquals(7, array.slice(0, 8).length);
     72     assertEquals(7, array.slice(0, 100).length);
     73 
     74     // Some exotic cases.
     75 
     76     obj = { toString: function() { throw 'Exception'; } };
     77 
     78     // More than 2 arguments:
     79     assertEquals(7, array.slice(0, 7, obj, null, undefined).length);
     80 
     81     // Custom conversion:
     82     assertEquals(1, array.slice({valueOf: function() { return 1; }},
     83                                 {toString: function() { return 2; }}).length);
     84 
     85     // Throwing an exception in conversion:
     86     try {
     87       assertEquals(7, array.slice(0, obj).length);
     88       throw 'Should have thrown';
     89     } catch (e) {
     90       assertEquals('Exception', e);
     91     }
     92   }
     93 })();
     94 
     95 
     96 // Nasty: modify the array in ToInteger.
     97 (function() {
     98   var array = [];
     99   var expected = []
    100   bad_guy = { valueOf: function() { array.push(array.length); return -1; } };
    101 
    102   for (var i = 0; i < 13; i++) {
    103     var sliced = array.slice(bad_guy);
    104     expected.push(i);
    105     assertEquals(expected, array);
    106     // According to the spec (15.4.4.10), length is calculated before
    107     // performing ToInteger on arguments.
    108     if (i == 0) {
    109       assertEquals([], sliced);  // Length was 0, nothing to get.
    110     } else {
    111       // Actually out of array [0..i] we get [i - 1] as length is i.
    112       assertEquals([i - 1], sliced);
    113     }
    114   }
    115 })();
    116 
    117 
    118 // Now check the case with array of holes and some elements on prototype.
    119 (function() {
    120   var len = 9;
    121   var array = new Array(len);
    122 
    123   var at3 = "@3";
    124   var at7 = "@7";
    125 
    126   for (var i = 0; i < 7; i++) {
    127     Array.prototype[3] = at3;
    128     Array.prototype[7] = at7;
    129 
    130     assertEquals(len, array.length);
    131     for (var i = 0; i < array.length; i++) {
    132       assertEquals(array[i], Array.prototype[i]);
    133     }
    134 
    135     var sliced = array.slice();
    136 
    137     assertEquals(len, sliced.length);
    138 
    139     assertTrue(delete Array.prototype[3]);
    140     assertTrue(delete Array.prototype[7]);
    141 
    142     // Note that slice copies values from prototype into the array.
    143     assertEquals(array[3], undefined);
    144     assertFalse(array.hasOwnProperty(3));
    145     assertEquals(sliced[3], at3);
    146     assertTrue(sliced.hasOwnProperty(3));
    147 
    148     assertEquals(array[7], undefined);
    149     assertFalse(array.hasOwnProperty(7));
    150     assertEquals(sliced[7], at7);
    151     assertTrue(sliced.hasOwnProperty(7));
    152 
    153     // ... but keeps the rest as holes:
    154     Array.prototype[5] = "@5";
    155     assertEquals(array[5], Array.prototype[5]);
    156     assertFalse(array.hasOwnProperty(5));
    157     assertEquals(sliced[5], Array.prototype[5]);
    158     assertFalse(sliced.hasOwnProperty(5));
    159 
    160     assertTrue(delete Array.prototype[5]);
    161   }
    162 })();
    163