mirror of
				https://github.com/tc39/test262.git
				synced 2025-10-30 03:03:51 +01:00 
			
		
		
		
	sourceRevisionAtLastExport: 33f2fb0e53d135f0ee17cfccd9d993eb2a6f47de targetRevisionAtLastExport: 31340cbd9add103f586d501b0c3354b7b182abc0
		
			
				
	
	
		
			227 lines
		
	
	
		
			7.0 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
			
		
		
	
	
			227 lines
		
	
	
		
			7.0 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
| // 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.
 | |
| 
 | |
| 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 (var f in funs) {
 | |
|   for (var 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; }
 | |
|   });
 | |
|   assertThrowsEquals(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]", Object.prototype.toString.call(obj));
 | |
| 
 | |
|   // With getter
 | |
|   obj = {};
 | |
|   Object.defineProperty(obj, Symbol.toStringTag, {
 | |
|     get: function() { return value; }
 | |
|   });
 | |
|   assertEquals("[object 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();
 | |
| 
 | |
| function testObjectToStringOnNonStringValue(obj) {
 | |
|   Object.defineProperty(obj, Symbol.toStringTag, { value: 1 });
 | |
|   assertEquals("[object Object]", ({}).toString.call(obj));
 | |
| }
 | |
| testObjectToStringOnNonStringValue({});
 | |
| 
 | |
| 
 | |
| // Proxies
 | |
| 
 | |
| function assertTag(tag, obj) {
 | |
|   assertEquals("[object " + tag + "]", Object.prototype.toString.call(obj));
 | |
| }
 | |
| 
 | |
| assertTag("Object", new Proxy({}, {}));
 | |
| assertTag("Array", new Proxy([], {}));
 | |
| assertTag("Function", new Proxy(() => 42, {}));
 | |
| assertTag("Foo", new Proxy(() => 42, {get() {return "Foo"}}));
 | |
| assertTag("Function", new Proxy(() => 42, {get() {return 666}}));
 | |
| 
 | |
| var revocable = Proxy.revocable([], {});
 | |
| revocable.revoke();
 | |
| assertThrows(() => Object.prototype.toString.call(revocable.proxy), TypeError);
 | |
| 
 | |
| var handler = {};
 | |
| revocable = Proxy.revocable([], handler);
 | |
| // The first get() call, i.e., toString() revokes the proxy
 | |
| handler.get = () => revocable.revoke();
 | |
| assertEquals("[object Array]", Object.prototype.toString.call(revocable.proxy));
 | |
| assertThrows(() => Object.prototype.toString.call(revocable.proxy), TypeError);
 | |
| 
 | |
| revocable = Proxy.revocable([], handler);
 | |
| handler.get = () => {revocable.revoke(); return "value";};
 | |
| assertEquals("[object value]", Object.prototype.toString.call(revocable.proxy));
 | |
| assertThrows(() => Object.prototype.toString.call(revocable.proxy), TypeError);
 | |
| 
 | |
| 
 | |
| revocable = Proxy.revocable(function() {}, handler);
 | |
| handler.get = () => revocable.revoke();
 | |
| assertEquals("[object Function]", Object.prototype.toString.call(revocable.proxy));
 | |
| assertThrows(() => Object.prototype.toString.call(revocable.proxy), TypeError);
 | |
| 
 | |
| function* gen() { yield 1; }
 | |
| 
 | |
| assertTag("GeneratorFunction", gen);
 | |
| Object.defineProperty(gen, Symbol.toStringTag, {writable: true});
 | |
| gen[Symbol.toStringTag] = "different string";
 | |
| assertTag("different string", gen);
 | |
| gen[Symbol.toStringTag] = 1;
 | |
| assertTag("Function", gen);
 | |
| 
 | |
| function overwriteToStringTagWithNonStringValue(tag, obj) {
 | |
|   assertTag(tag, obj);
 | |
| 
 | |
|   Object.defineProperty(obj, Symbol.toStringTag, {
 | |
|     configurable: true,
 | |
|     value: "different string"
 | |
|   });
 | |
|   assertTag("different string", obj);
 | |
| 
 | |
|   testObjectToStringOnNonStringValue(obj);
 | |
| }
 | |
| 
 | |
| overwriteToStringTagWithNonStringValue("global", global);
 | |
| overwriteToStringTagWithNonStringValue("Generator", gen());
 | |
| 
 | |
| var arrayBuffer = new ArrayBuffer();
 | |
| overwriteToStringTagWithNonStringValue("ArrayBuffer", arrayBuffer);
 | |
| overwriteToStringTagWithNonStringValue("DataView", new DataView(arrayBuffer));
 | |
| 
 | |
| overwriteToStringTagWithNonStringValue("Int8Array", new Int8Array());
 | |
| overwriteToStringTagWithNonStringValue("Uint8Array", new Uint8Array());
 | |
| overwriteToStringTagWithNonStringValue("Uint8ClampedArray",
 | |
|   new Uint8ClampedArray());
 | |
| overwriteToStringTagWithNonStringValue("Int16Array", new Int16Array());
 | |
| overwriteToStringTagWithNonStringValue("Uint16Array", new Uint16Array());
 | |
| overwriteToStringTagWithNonStringValue("Int32Array", new Int32Array());
 | |
| overwriteToStringTagWithNonStringValue("Uint32Array", new Uint32Array());
 | |
| overwriteToStringTagWithNonStringValue("Float32Array", new Float32Array());
 | |
| overwriteToStringTagWithNonStringValue("Float64Array", new Float64Array());
 | |
| 
 | |
| var set = new Set();
 | |
| var map = new Map();
 | |
| 
 | |
| overwriteToStringTagWithNonStringValue("Set", set);
 | |
| overwriteToStringTagWithNonStringValue("Map", map);
 | |
| 
 | |
| overwriteToStringTagWithNonStringValue("Set Iterator", set[Symbol.iterator]());
 | |
| overwriteToStringTagWithNonStringValue("Map Iterator", map[Symbol.iterator]());
 | |
| 
 | |
| overwriteToStringTagWithNonStringValue("WeakSet", new WeakSet());
 | |
| overwriteToStringTagWithNonStringValue("WeakMap", new WeakMap());
 | |
| 
 | |
| overwriteToStringTagWithNonStringValue("Promise", new Promise(function() {}));
 |