blob: 30e10fcf190ac78ca1eb147990bea49d3babfc1a [file] [log] [blame]
description(
"Test some array functions on non-array objects."
);
function properties(object, extraName1, extraName2, extraName3)
{
var string = "";
// destructive, lists properties
var names = [];
var enumerables = {};
for (propertyName in object) {
names.push(propertyName);
enumerables[propertyName] = 1;
}
names.push("length");
names.push(extraName1);
names.push(extraName2);
names.push(extraName3);
names.sort();
var propertyStrings = [];
for (i = 0; i < names.length; ++i) {
var name = names[i];
if (name == names[i - 1])
continue;
if (!(name in object))
continue;
var propertyString = name + ":" + object[name];
var flags = [];
if (!object.hasOwnProperty(name))
flags.push("FromPrototype");
if (!enumerables[name])
flags.push("DontEnum");
if (name != "length") {
try {
object[name] = "ReadOnlyTestValue";
} catch (e) {
}
if (object[name] != "ReadOnlyTestValue")
flags.push("ReadOnly");
}
delete object[name];
if (object.hasOwnProperty(name))
flags.push("DontDelete");
flags.sort();
if (flags.length)
propertyString += "(" + flags.join(", ") + ")";
propertyStrings.push(propertyString);
}
return propertyStrings.join(", ");
}
var x;
var oneItemPrototype = { length:1, 0:'a' };
function OneItemConstructor()
{
}
OneItemConstructor.prototype = oneItemPrototype;
var twoItemPrototype = { length:2, 0:'b', 1:'a' };
function TwoItemConstructor()
{
}
TwoItemConstructor.prototype = twoItemPrototype;
shouldBe("properties(['b', 'a'])", "'0:b, 1:a, length:2(DontDelete, DontEnum)'");
shouldBe("properties({ length:2, 0:'b', 1:'a' })", "'0:b, 1:a, length:2'");
shouldBe("properties(new OneItemConstructor)", "'0:a(FromPrototype), length:1(FromPrototype)'");
shouldBe("properties(new TwoItemConstructor)", "'0:b(FromPrototype), 1:a(FromPrototype), length:2(FromPrototype)'");
shouldThrow("Array.prototype.toString.call({})");
shouldThrow("Array.prototype.toLocaleString.call({})");
shouldBe("Array.prototype.concat.call(x = { length:2, 0:'b', 1:'a' })", "[x]");
shouldBe("Array.prototype.join.call({})", "''");
shouldBe("Array.prototype.join.call(['b', 'a'])", "'b,a'");
shouldBe("Array.prototype.join.call({ length:2, 0:'b', 1:'a' })", "'b,a'");
shouldBe("Array.prototype.join.call(new TwoItemConstructor)", "'b,a'");
shouldBe("Array.prototype.pop.call({})", "undefined");
shouldBe("Array.prototype.pop.call({ length:2, 0:'b', 1:'a' })", "'a'");
shouldBe("Array.prototype.pop.call({ length:2, 0:'b', 1:'a' })", "'a'");
shouldBe("Array.prototype.pop.call(new TwoItemConstructor)", "'a'");
shouldBe("Array.prototype.pop.call(x = {}); properties(x)", "'length:0'");
shouldBe("Array.prototype.pop.call(x = ['b', 'a']); properties(x)", "'0:b, length:1(DontDelete, DontEnum)'");
shouldBe("Array.prototype.pop.call(x = { length:2, 0:'b', 1:'a' }); properties(x)", "'0:b, length:1'");
shouldBe("Array.prototype.pop.call(x = new TwoItemConstructor); properties(x)", "'0:b(FromPrototype), 1:a(FromPrototype), length:1'");
shouldBe("Array.prototype.push.call({})", "0");
shouldBe("Array.prototype.push.call(['b', 'a'])", "2");
shouldBe("Array.prototype.push.call({ length:2, 0:'b', 1:'a' })", "2");
shouldBe("Array.prototype.push.call(new TwoItemConstructor)", "2");
shouldBe("Array.prototype.push.call(x = {}); properties(x)", "'length:0'");
shouldBe("Array.prototype.push.call(x = ['b', 'a']); properties(x)", "'0:b, 1:a, length:2(DontDelete, DontEnum)'");
shouldBe("Array.prototype.push.call(x = { length:2, 0:'b', 1:'a' }); properties(x)", "'0:b, 1:a, length:2'");
shouldBe("Array.prototype.push.call(x = new TwoItemConstructor); properties(x)", "'0:b(FromPrototype), 1:a(FromPrototype), length:2'");
shouldBe("Array.prototype.push.call({}, 'c')", "1");
shouldBe("Array.prototype.push.call(['b', 'a'], 'c')", "3");
shouldBe("Array.prototype.push.call({ length:2, 0:'b', 1:'a' }, 'c')", "3");
shouldBe("Array.prototype.push.call(new TwoItemConstructor, 'c')", "3");
shouldBe("Array.prototype.push.call(x = {}, 'c'); properties(x)", "'0:c, length:1'");
shouldBe("Array.prototype.push.call(x = ['b', 'a'], 'c'); properties(x)", "'0:b, 1:a, 2:c, length:3(DontDelete, DontEnum)'");
shouldBe("Array.prototype.push.call(x = { length:2, 0:'b', 1:'a' }, 'c'); properties(x)", "'0:b, 1:a, 2:c, length:3'");
shouldBe("Array.prototype.push.call(x = new TwoItemConstructor, 'c'); properties(x)", "'0:b(FromPrototype), 1:a(FromPrototype), 2:c, length:3'");
shouldBe("properties(Array.prototype.reverse.call({}))", "''");
shouldBe("properties(Array.prototype.reverse.call(['b', 'a']))", "'0:a, 1:b, length:2(DontDelete, DontEnum)'");
shouldBe("properties(Array.prototype.reverse.call({ length:2, 0:'b', 1:'a' }))", "'0:a, 1:b, length:2'");
shouldBe("properties(Array.prototype.reverse.call(new OneItemConstructor))", "'0:a(FromPrototype), length:1(FromPrototype)'");
shouldBe("properties(Array.prototype.reverse.call(new TwoItemConstructor))", "'0:a, 1:b, length:2(FromPrototype)'");
shouldBe("Array.prototype.shift.call({})", "undefined");
shouldBe("Array.prototype.shift.call(['b', 'a'])", "'b'");
shouldBe("Array.prototype.shift.call({ length:2, 0:'b', 1:'a' })", "'b'");
shouldBe("Array.prototype.shift.call(new TwoItemConstructor)", "'b'");
shouldBe("Array.prototype.shift.call(x = {}); properties(x)", "'length:0'");
shouldBe("Array.prototype.shift.call(x = ['b', 'a']); properties(x)", "'0:a, length:1(DontDelete, DontEnum)'");
shouldBe("Array.prototype.shift.call(x = { length:2, 0:'b', 1:'a' }); properties(x)", "'0:a, length:1'");
shouldBe("Array.prototype.shift.call(x = new TwoItemConstructor); properties(x)", "'0:a, 1:a(FromPrototype), length:1'");
shouldBe("Array.prototype.slice.call({}, 0, 1)", "[]");
shouldBe("Array.prototype.slice.call(['b', 'a'], 0, 1)", "['b']");
shouldBe("Array.prototype.slice.call({ length:2, 0:'b', 1:'a' }, 0, 1)", "['b']");
shouldBe("Array.prototype.slice.call(new TwoItemConstructor, 0, 1)", "['b']");
shouldBe("properties(Array.prototype.sort.call({}))", "''");
shouldBe("properties(Array.prototype.sort.call(['b', 'a']))", "'0:a, 1:b, length:2(DontDelete, DontEnum)'");
shouldBe("properties(Array.prototype.sort.call({ length:2, 0:'b', 1:'a' }))", "'0:a, 1:b, length:2'");
shouldBe("properties(Array.prototype.sort.call(new OneItemConstructor))", "'0:a(FromPrototype), length:1(FromPrototype)'");
shouldBe("properties(Array.prototype.sort.call(new TwoItemConstructor))", "'0:a, 1:b, length:2(FromPrototype)'");
shouldBe("Array.prototype.splice.call({}, 0, 1)", "[]");
shouldBe("Array.prototype.splice.call(['b', 'a'], 0, 1)", "['b']");
shouldBe("Array.prototype.splice.call({ length:2, 0:'b', 1:'a' }, 0, 1)", "['b']");
shouldBe("Array.prototype.splice.call(new TwoItemConstructor, 0, 1)", "['b']");
shouldBe("Array.prototype.splice.call(x = {}, 0, 1); properties(x)", "'length:0'");
shouldBe("Array.prototype.splice.call(x = ['b', 'a'], 0, 1); properties(x)", "'0:a, length:1(DontDelete, DontEnum)'");
shouldBe("Array.prototype.splice.call(x = { length:2, 0:'b', 1:'a' }, 0, 1); properties(x)", "'0:a, length:1'");
shouldBe("Array.prototype.splice.call(x = new TwoItemConstructor, 0, 1); properties(x)", "'0:a, 1:a(FromPrototype), length:1'");
shouldBe("Array.prototype.unshift.call({})", "0");
shouldBe("Array.prototype.unshift.call(['b', 'a'])", "2");
shouldBe("Array.prototype.unshift.call({ length:2, 0:'b', 1:'a' })", "2");
shouldBe("Array.prototype.unshift.call(new TwoItemConstructor)", "2");
shouldBe("Array.prototype.unshift.call(x = {}); properties(x)", "'length:0'");
shouldBe("Array.prototype.unshift.call(x = ['b', 'a']); properties(x)", "'0:b, 1:a, length:2(DontDelete, DontEnum)'");
shouldBe("Array.prototype.unshift.call(x = { length:2, 0:'b', 1:'a' }); properties(x)", "'0:b, 1:a, length:2'");
shouldBe("Array.prototype.unshift.call(x = new TwoItemConstructor); properties(x)", "'0:b(FromPrototype), 1:a(FromPrototype), length:2'");
shouldBe("Array.prototype.unshift.call({}, 'c')", "1");
shouldBe("Array.prototype.unshift.call(['b', 'a'], 'c')", "3");
shouldBe("Array.prototype.unshift.call({ length:2, 0:'b', 1:'a' }, 'c')", "3");
shouldBe("Array.prototype.unshift.call(new TwoItemConstructor, 'c')", "3");
shouldBe("Array.prototype.unshift.call(x = {}, 'c'); properties(x)", "'0:c, length:1'");
shouldBe("Array.prototype.unshift.call(x = ['b', 'a'], 'c'); properties(x)", "'0:c, 1:b, 2:a, length:3(DontDelete, DontEnum)'");
shouldBe("Array.prototype.unshift.call(x = { length:2, 0:'b', 1:'a' }, 'c'); properties(x)", "'0:c, 1:b, 2:a, length:3'");
shouldBe("Array.prototype.unshift.call(x = new TwoItemConstructor, 'c'); properties(x)", "'0:c, 1:b, 2:a, length:3'");
// FIXME: Add tests for every, forEach, some, indexOf, lastIndexOf, filter, and map
var successfullyParsed = true;