1 // Copyright 2014 the V8 project authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 // Based on Mozilla Array.of() tests at http://dxr.mozilla.org/mozilla-central/source/js/src/jit-test/tests/collections 6 7 // Flags: --harmony-arrays 8 9 10 11 // Array.of makes real arrays. 12 13 function check(a) { 14 assertEquals(Object.getPrototypeOf(a), Array.prototype); 15 assertEquals(Array.isArray(a), true); 16 a[9] = 9; 17 assertEquals(a.length, 10); 18 } 19 20 21 check(Array.of()); 22 check(Array.of(0)); 23 check(Array.of(0, 1, 2)); 24 var f = Array.of; 25 check(f()); 26 27 28 // Array.of basics 29 30 var a = Array.of(); 31 32 assertEquals(a.length, 0); 33 a = Array.of(undefined, null, 3.14, []); 34 assertEquals(a, [undefined, null, 3.14, []]); 35 a = []; 36 for (var i = 0; i < 1000; i++) 37 a[i] = i; 38 assertEquals(Array.of.apply(null, a), a); 39 40 41 // Array.of does not leave holes 42 43 assertEquals(Array.of(undefined), [undefined]); 44 assertEquals(Array.of(undefined, undefined), [undefined, undefined]); 45 assertEquals(Array.of.apply(null, [,,undefined]), [undefined, undefined, undefined]); 46 assertEquals(Array.of.apply(null, Array(4)), [undefined, undefined, undefined, undefined]); 47 48 49 // Array.of can be transplanted to other classes. 50 51 var hits = 0; 52 function Bag() { 53 hits++; 54 } 55 Bag.of = Array.of; 56 57 hits = 0; 58 var actual = Bag.of("zero", "one"); 59 assertEquals(hits, 1); 60 61 hits = 0; 62 var expected = new Bag; 63 expected[0] = "zero"; 64 expected[1] = "one"; 65 expected.length = 2; 66 assertEquals(areSame(actual, expected), true); 67 68 hits = 0; 69 actual = Array.of.call(Bag, "zero", "one"); 70 assertEquals(hits, 1); 71 assertEquals(areSame(actual, expected), true); 72 73 function areSame(object, array) { 74 var result = object.length == array.length; 75 for (var i = 0; i < object.length; i++) { 76 result = result && object[i] == array[i]; 77 } 78 return result; 79 } 80 81 82 // Array.of does not trigger prototype setters. 83 // (It defines elements rather than assigning to them.) 84 85 var status = "pass"; 86 Object.defineProperty(Array.prototype, "0", {set: function(v) {status = "FAIL 1"}}); 87 assertEquals(Array.of(1)[0], 1); 88 assertEquals(status, "pass"); 89 90 Object.defineProperty(Bag.prototype, "0", {set: function(v) {status = "FAIL 2"}}); 91 assertEquals(Bag.of(1)[0], 1); 92 assertEquals(status, "pass"); 93 94 95 // Array.of passes the number of arguments to the constructor it calls. 96 97 var hits = 0; 98 99 function Herd(n) { 100 assertEquals(arguments.length, 1); 101 assertEquals(n, 5); 102 hits++; 103 } 104 105 Herd.of = Array.of; 106 Herd.of("sheep", "cattle", "elephants", "whales", "seals"); 107 assertEquals(hits, 1); 108 109 110 // Array.of calls a "length" setter if one is present. 111 112 var hits = 0; 113 var lastObj = null, lastVal = undefined; 114 function setter(v) { 115 hits++; 116 lastObj = this; 117 lastVal = v; 118 } 119 120 // when the setter is on the new object 121 function Pack() { 122 Object.defineProperty(this, "length", {set: setter}); 123 } 124 Pack.of = Array.of; 125 var pack = Pack.of("wolves", "cards", "cigarettes", "lies"); 126 assertEquals(lastObj, pack); 127 assertEquals(lastVal, 4); 128 129 // when the setter is on the new object's prototype 130 function Bevy() {} 131 Object.defineProperty(Bevy.prototype, "length", {set: setter}); 132 Bevy.of = Array.of; 133 var bevy = Bevy.of("quail"); 134 assertEquals(lastObj, bevy); 135 assertEquals(lastVal, 1); 136 137 138 // Array.of does a strict assignment to the new object's .length. 139 // The assignment is strict even if the code we're calling from is not strict. 140 141 function Empty() {} 142 Empty.of = Array.of; 143 Object.defineProperty(Empty.prototype, "length", {get: function() { return 0; }}); 144 145 var nothing = new Empty; 146 nothing.length = 2; // no exception; this is not a strict mode assignment 147 148 assertThrows(function() { Empty.of(); }, TypeError); 149 150 151 // Check superficial features of Array.of. 152 153 var desc = Object.getOwnPropertyDescriptor(Array, "of"); 154 155 assertEquals(desc.configurable, true); 156 assertEquals(desc.enumerable, false); 157 assertEquals(desc.writable, true); 158 assertEquals(Array.of.length, 0); 159 assertThrows(function() { new Array.of() }, TypeError); // not a constructor 160 161 // When the this-value passed in is not a constructor, the result is an array. 162 [undefined, null, false, "cow"].forEach(function(val) { 163 assertEquals(Array.isArray(Array.of(val)), true); 164 }); 165