| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222 |
- //-------------------------------------------------------------------------------------------------------
- // Copyright (C) Microsoft. All rights reserved.
- // Licensed under the MIT license. See LICENSE.txt file in the project root for full license information.
- //-------------------------------------------------------------------------------------------------------
- /// <reference path="protolib.js" />
- if (this.WScript && this.WScript.LoadScriptFile) {
- WScript.LoadScriptFile("protolib.js");
- }
- // Test __proto__ (object literal) initializer in a new engine:
- // Run "enabled" function, disable__proto__, then run "disabled" (or by default "enabled" again).
- function test_init(enabled, /*optional*/disabled) {
- var eng = make_engine();
- eng.run(enabled);
- eng.disable__proto__();
- eng.run(disabled || enabled);
- }
- var tests = [
- {
- name: "init to an object",
- body: function () {
- test_init(
- function () { // enabled: [[prototype]]
- var p = { p: 123 };
- var o = { __proto__: p };
- assert.areEqual(p, Object.getPrototypeOf(o));
- assert.isTrue(!o.hasOwnProperty("__proto__"));
- assert.areEqual(123, o.p);
- assert.areEqual(p, Object.getPrototypeOf(o));
- });
- }
- },
- {
- name: "init to null",
- body: function () {
- test_init(
- function () { // enabled: [[prototype]]
- var o = { __proto__: null };
- assert.areEqual(null, Object.getPrototypeOf(o));
- assert.isFalse({}.hasOwnProperty.apply(o, ["__proto__"]));
- assert.areEqual(undefined, o.__proto__); // o's [[prototype]] is null, so doesn't have a __proto__ property
- });
- }
- },
- {
- name: "init to neither object nor null",
- body: function () {
- test_init(
- function () { // enabled: throw
- function test(value) {
- var o = { __proto__: value };
- assert.areEqual(Object.prototype, Object.getPrototypeOf(o));
- assert.isFalse(o.hasOwnProperty("__proto__"));
- }
- [undefined, 0, 123, Infinity, true, false, "string value"].forEach(function (value) {
- test(value);
- });
- });
- }
- },
- {
- name: "init to accessor",
- body: function () {
- test_init(
- function () { // same for enabled/disabled: local property
- var o = {
- get __proto__() { return "proto"; },
- set __proto__(value) { this.__proto__value = value; }
- };
- assert.areEqual(Object.prototype, Object.getPrototypeOf(o));
- assert.isTrue(o.hasOwnProperty("__proto__"));
- assert.areEqual("proto", o.__proto__);
- o.__proto__ = "a value";
- assert.areEqual("a value", o.__proto__value);
- });
- }
- },
- {
- name: "verify no incorrectly shared type",
- body: function () {
- function foo(p) {
- return {
- a: 100,
- __proto__: p,
- };
- }
- // If we incorrectly shared Type, we'll have wrong [[prototype]].
- var o1 = foo({ b: 1 });
- var o2 = foo({ b: 2 });
- var o3 = foo({ b: 3 });
- assert.areEqual(1, o1.b);
- assert.areEqual(2, o2.b);
- assert.areEqual(3, o3.b);
- }
- },
- {
- name: "verify not accidentally enables it for function parameters",
- body: function () {
- function foo(a, b, __proto__) {
- var o = arguments;
- assert.areEqual(Object.prototype, Object.getPrototypeOf(o));
- assert.areEqual(Object.prototype, o.__proto__);
- assert.isTrue(!o.hasOwnProperty("__proto__"));
- assert.areEqual(1, o[0]);
- assert.areEqual(3, o[2].a);
- assert.areEqual(4, __proto__.b);
- }
- foo(1, 2, { a: 3, b: 4, c: 5 });
- }
- },
- {
- name: "verify not accidentally enables it for JSON",
- body: function () {
- var o = JSON.parse('{ "a": 1, "b": 2, "__proto__": {"c": 3, "d": 4} }');
- assert.areEqual(Object.prototype, Object.getPrototypeOf(o));
- assert.isTrue(o.hasOwnProperty("__proto__"));
- assert.areEqual(3, o.__proto__.c);
- }
- },
- {
- name: "Verify not accidentally share code with global InitFld",
- body: function () {
- // Check if we accidentally changed global's [[prototype]] to a function when declaring a global
- // function with name __proto__ (see bottom of this file). If yes, we'd have "length" property.
- assert.areEqual(undefined, this.length);
- }
- },
- {
- name: "Run the same initializer with __proto__ enabled, run it again with __proto__ disabled",
- body: function () {
- var eng = make_engine();
- // inject global g_p and foo into eng
- eng.eval("var g_p = { p: 123 }");
- eng.eval("var foo = " + function() {
- return { a: 0, __proto__: g_p, b: 1 };
- });
- var test = function () { // enabled: [[prototype]]
- var o = foo();
- assert.areEqual(g_p, Object.getPrototypeOf(o));
- assert.areEqual("a,b", Object.keys(o).toString());
- assert.areEqual(123, o.p);
- };
- eng.run(test);
- eng.disable__proto__();
- eng.run(test);
- }
- },
- {
- name: "Enumeration order should be unaffected",
- body: function () {
- test_init(
- function () {
- var o = {
- a: 100,
- __proto__: new Number(200),
- b: 300,
- };
- assert.areEqual("a,b", Object.keys(o).toString());
- });
- test_init(
- function () { // enabled: [[prototype]]
- var o = {
- a: 100,
- __proto__: { c: "p0", d: "p1" },
- b: 300,
- };
- var names = [];
- for (var name in o) {
- names.push(name);
- }
- assert.areEqual("a,b", Object.keys(o).toString());
- assert.areEqual("a,b,c,d", names.toString());
- });
- }
- },
- {
- name: "Verify bytecode serialization",
- body: function () { // Test in current engine to use switch -ForceSerialized
- var o = {
- a: 100,
- __proto__: { c: "p0", d: "p1" },
- b: 300,
- };
- // Serialized bytecode should correctly mark if initializer has__proto__
- assert.areEqual("a,b", Object.keys(o).toString());
- }
- },
- ];
- testRunner.run(tests);
- // Used by: Verify not accidentally share code with global InitFld
- function __proto__() { }
|