37bd114925
Updates Object.prototype.toString() to use algorithm described in harmony drafts. Currently, the behaviour is essentially the same as ES262's version, however this changes when internal structures such as Promise make use of symbolToStringTag (as they are supposed to, see v8:3241), and changes further once Symbol.toStringTag is exposed publicly. BUG=v8:3241, v8:3502 LOG=N R=dslomov@chromium.org Review URL: https://codereview.chromium.org/546803003 Patch from Caitlin Potter <caitpotter88@gmail.com>. git-svn-id: https://v8.googlecode.com/svn/branches/bleeding_edge@24783 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
134 lines
3.5 KiB
JavaScript
134 lines
3.5 KiB
JavaScript
// Copyright 2014 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.
|
|
|
|
// Flags: --harmony-tostring
|
|
|
|
var global = this;
|
|
|
|
var funs = {
|
|
Object: [ Object ],
|
|
Function: [ Function ],
|
|
Array: [ Array ],
|
|
String: [ String ],
|
|
Boolean: [ Boolean ],
|
|
Number: [ Number ],
|
|
Date: [ Date ],
|
|
RegExp: [ RegExp ],
|
|
Error: [ Error, TypeError, RangeError, SyntaxError, ReferenceError,
|
|
EvalError, URIError ]
|
|
}
|
|
for (f in funs) {
|
|
for (i in funs[f]) {
|
|
assertEquals("[object " + f + "]",
|
|
Object.prototype.toString.call(new funs[f][i]),
|
|
funs[f][i]);
|
|
assertEquals("[object Function]",
|
|
Object.prototype.toString.call(funs[f][i]),
|
|
funs[f][i]);
|
|
}
|
|
}
|
|
|
|
function testToStringTag(className) {
|
|
// Using builtin toStringTags
|
|
var obj = {};
|
|
obj[Symbol.toStringTag] = className;
|
|
assertEquals("[object ~" + className + "]",
|
|
Object.prototype.toString.call(obj));
|
|
|
|
// Getter throws
|
|
obj = {};
|
|
Object.defineProperty(obj, Symbol.toStringTag, {
|
|
get: function() { throw className; }
|
|
});
|
|
assertThrows(function() {
|
|
Object.prototype.toString.call(obj);
|
|
}, className);
|
|
|
|
// Getter does not throw
|
|
obj = {};
|
|
Object.defineProperty(obj, Symbol.toStringTag, {
|
|
get: function() { return className; }
|
|
});
|
|
assertEquals("[object ~" + className + "]",
|
|
Object.prototype.toString.call(obj));
|
|
|
|
// Custom, non-builtin toStringTags
|
|
obj = {};
|
|
obj[Symbol.toStringTag] = "X" + className;
|
|
assertEquals("[object X" + className + "]",
|
|
Object.prototype.toString.call(obj));
|
|
|
|
// With getter
|
|
obj = {};
|
|
Object.defineProperty(obj, Symbol.toStringTag, {
|
|
get: function() { return "X" + className; }
|
|
});
|
|
assertEquals("[object X" + className + "]",
|
|
Object.prototype.toString.call(obj));
|
|
|
|
// Undefined toStringTag should return [object className]
|
|
var obj = className === "Arguments" ?
|
|
(function() { return arguments; })() : new global[className];
|
|
obj[Symbol.toStringTag] = undefined;
|
|
assertEquals("[object " + className + "]",
|
|
Object.prototype.toString.call(obj));
|
|
|
|
// With getter
|
|
var obj = className === "Arguments" ?
|
|
(function() { return arguments; })() : new global[className];
|
|
Object.defineProperty(obj, Symbol.toStringTag, {
|
|
get: function() { return undefined; }
|
|
});
|
|
assertEquals("[object " + className + "]",
|
|
Object.prototype.toString.call(obj));
|
|
}
|
|
|
|
[
|
|
"Arguments",
|
|
"Array",
|
|
"Boolean",
|
|
"Date",
|
|
"Error",
|
|
"Function",
|
|
"Number",
|
|
"RegExp",
|
|
"String"
|
|
].forEach(testToStringTag);
|
|
|
|
function testToStringTagNonString(value) {
|
|
var obj = {};
|
|
obj[Symbol.toStringTag] = value;
|
|
assertEquals("[object ???]", Object.prototype.toString.call(obj));
|
|
|
|
// With getter
|
|
obj = {};
|
|
Object.defineProperty(obj, Symbol.toStringTag, {
|
|
get: function() { return value; }
|
|
});
|
|
assertEquals("[object ???]", Object.prototype.toString.call(obj));
|
|
}
|
|
|
|
[
|
|
null,
|
|
function() {},
|
|
[],
|
|
{},
|
|
/regexp/,
|
|
42,
|
|
Symbol("sym"),
|
|
new Date(),
|
|
(function() { return arguments; })(),
|
|
true,
|
|
new Error("oops"),
|
|
new String("str")
|
|
].forEach(testToStringTagNonString);
|
|
|
|
function testObjectToStringPropertyDesc() {
|
|
var desc = Object.getOwnPropertyDescriptor(Object.prototype, "toString");
|
|
assertTrue(desc.writable);
|
|
assertFalse(desc.enumerable);
|
|
assertTrue(desc.configurable);
|
|
}
|
|
testObjectToStringPropertyDesc();
|