blob: a1fa9c7665c46a393e6db7eabb3ac301e0b143a4 [file] [log] [blame]
// Copyright 2015 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// Array's toString should call the object's own join method, if one exists and
// is callable. Otherwise, just use the original Object.toString function.
// Flags: --allow-natives-syntax
var typedArrayConstructors = [
Uint8Array,
Int8Array,
Uint16Array,
Int16Array,
Uint32Array,
Int32Array,
Uint8ClampedArray,
Float32Array,
Float64Array
];
for (var constructor of typedArrayConstructors) {
var success = "[test success]";
var expectedThis;
function testJoin() {
assertEquals(0, arguments.length);
assertSame(expectedThis, this);
return success;
}
// On an Array object.
// Default case.
var a1 = new constructor([1, 2, 3]);
assertEquals("1,2,3", a1.toString());
assertEquals("1,2,3", a1.join());
assertEquals("1,2,3", a1.toLocaleString());
// Non-standard "join" function is called correctly.
var a2 = new constructor([1, 2, 3]);
a2.join = testJoin;
expectedThis = a2;
assertEquals(success, a2.toString());
assertEquals(success, a2.join());
assertEquals("1,2,3", a2.toLocaleString());
// Non-callable join function is ignored and Object.prototype.toString is
// used instead.
var a3 = new constructor([1, 2, 3]);
a3.join = "not callable";
assertEquals(0, a3.toString().search(/\[object .+Array\]/));
// Non-existing join function is treated same as non-callable.
var a4 = new constructor([1, 2, 3]);
a4.__proto__ = { toString: constructor.prototype.toString };
// No join on Array.
assertEquals(0, a3.toString().search(/\[object .+Array\]/));
// On a non-Array object, throws.
var o1 = {length: 3, 0: 1, 1: 2, 2: 3,
toString: constructor.prototype.toString,
join: constructor.prototype.join,
toLocaleString: constructor.prototype.toLocaleString};
assertThrows(function() { o1.join() }, TypeError);
assertThrows(function() { o1.toString() }, TypeError);
assertThrows(function() { o1.toLocaleString() }, TypeError);
// toString is OK if join not from here:
o1.join = Array.prototype.join;
assertEquals("1,2,3", o1.join());
assertEquals("1,2,3", o1.toString());
assertThrows(function() { o1.toLocaleString() }, TypeError);
// TODO(littledan): Use the same function for TypedArray as for
// Array, as the spec says (but Firefox doesn't do either).
// Currently, using the same method leads to a bootstrap failure.
// assertEquals(o1.toString, Array.prototype.toString);
// Redefining length does not change result
var a5 = new constructor([1, 2, 3])
Object.defineProperty(a5, 'length', { value: 2 });
assertEquals("1,2,3", a5.join());
assertEquals("1,2,3", a5.toString());
assertEquals("1,2,3", a5.toLocaleString());
assertEquals("1,2", Array.prototype.join.call(a5));
assertEquals("1,2,3", Array.prototype.toString.call(a5));
assertEquals("1,2", Array.prototype.toLocaleString.call(a5));
(function TestToLocaleStringCalls() {
let log = [];
let pushArgs = (label) => (...args) => log.push(label, args);
let NumberToLocaleString = Number.prototype.toLocaleString;
Number.prototype.toLocaleString = pushArgs("Number");
(new constructor([1, 2])).toLocaleString();
assertEquals(["Number", [], "Number", []], log);
Number.prototype.toLocaleString = NumberToLocaleString;
})();
// Detached Operation
var array = new constructor([1, 2, 3]);
%ArrayBufferNeuter(array.buffer);
assertThrows(() => array.join(), TypeError);
assertThrows(() => array.toLocalString(), TypeError);
assertThrows(() => array.toString(), TypeError);
}