blob: 379f7cfefac4795cd485ceac0523f7f841001836 [file] [log] [blame]
//-------------------------------------------------------------------------------------------------------
// Copyright (C) Microsoft. All rights reserved.
// Licensed under the MIT license. See LICENSE.txt file in the project root for full license information.
//-------------------------------------------------------------------------------------------------------
if (typeof (WScript) != "undefined") {
WScript.LoadScriptFile("..\\UnitTestFramework\\UnitTestFramework.js", "self");
}
var tests = {
test01: {
name: "Make sure that shared type handler is not shared between evolved instances",
body: function () {
var propName = "p01";
var x = helpers.getDummyObject(propName);
Object.preventExtensions(x);
var y = helpers.getDummyObject(propName);
assert.isFalse(Object.isExtensible(x), "Object.isExtensible(x)");
assert.isTrue (Object.isExtensible(y), "Object.isExtensible(y)");
}
},
test02: {
name: "Make sure that checks are done when preventExtensions=true for non-extensible object with same layout",
body: function () {
var propName = "p02_1";
var propName2 = "p02_2";
var f = function f(o) { var tepm = o[propName2]; o[propName2] = 10; };
var x = helpers.getDummyObject(propName);
f(x);
var y = helpers.getDummyObject(propName);
Object.preventExtensions(y);
f(y);
assert.areEqual(undefined, y[propName2], "y has preventExtensions=true -> can't add new property");
}
},
test03: {
name: "Make sure that after preventExtensions the type can evolve without corrupting the shared type",
body: function () {
var propName = "p03";
var x = helpers.getDummyObject(propName);
Object.preventExtensions(x);
delete x[propName];
var x = helpers.getDummyObject(propName); // new object with same layout as previous one.
x[propName] = 2;
Object.preventExtensions(x); // Earlier bug: this was associated a with evolved type.
var newValue = 3;
x[propName] = newValue; // Can modify writable property but not on evolved type.
assert.isFalse(Object.isExtensible(x));
assert.areEqual(newValue, x[propName]);
}
},
test04: {
name: "Make sure that after deleting property and then preventExtensions, inline cache is not used so that we can't add the property back",
body: function () {
var propName1 = "p04_1";
var propName2 = "p04_2";
var x = helpers.getDummyObject(propName1);
delete x[propName1];
x[propName2] = propName2;
Object.preventExtensions(x);
assert.throws(function() { Object.defineProperty(x, propName1, {value: 1}) }, TypeError);
}
},
test05: {
name: "Evolve s.d.t.h by redefining a property and make sure on shared instance there is no change",
body: function () {
var propName = "p05";
var x = helpers.getDummyObject(propName);
Object.seal(x);
Object.defineProperty(x, propName, {writable: false, value: 100}); // this should succeed
var y = helpers.getDummyObject(propName);
Object.seal(y); // Now y shares same s.d.t.h as x used to before defineProperty on x.
var newValue = 200;
Object.defineProperty(y, propName, {writable: false, value: newValue}); // this should succeed again (defineProperty on x should not corrupt shared t.h.)
assert.areEqual(newValue, y[propName]);
}
},
test06: {
name: "Make sure that preventExtensions/seal/freeze types are using different shared types",
body: function () {
var propName = "p06";
var values = [0, 1, 2, 3];
var x = helpers.getDummyObject(propName);
x[propName] = values[0];
Object.freeze(x);
x[propName] = values[1]; // this should not work
var y = helpers.getDummyObject(propName);
Object.seal(y);
y[propName] = values[2]; // this should work
var z = helpers.getDummyObject(propName);
Object.preventExtensions(z);
z[propName] = values[3]; // this should work
assert.areEqual([0, 2, 3], [x[propName], y[propName], z[propName]]);
}
},
test07: {
name: "Call preventExtensions, seal, freeze on the same instance",
body: function () {
var propName1 = "p07_01";
var propName2 = "p07_02";
var origVal = 0;
var x = helpers.getDummyObject(propName1);
var y = helpers.getDummyObject(propName1);
x[propName1] = origVal;
y[propName1] = origVal;
Object.preventExtensions(x);
Object.preventExtensions(y);
Object.seal(y);
Object.freeze(y);
var val = 100;
x[propName1] = val; // This should succeed
x[propName2] = val; // This should not succeed: can't add new property to non-extensible
assert.isFalse(Object.isExtensible(x));
assert.isFalse(Object.isSealed(x));
assert.areEqual(val, x[propName1], "x should still have read-write properties");
assert.areEqual(undefined, x[propName2]);
assert.isTrue(Object.isFrozen(y), "Object.isFrozen(y)");
y[propName1] = val;
y[propName2] = val;
assert.areEqual(origVal, y[propName1], "y is frozen");
assert.areEqual(undefined, y[propName2]);
}
},
test08: {
name: "Attmept to add a numeric property to non-extensible empty object",
body: function () {
var numericPropName = 0;
var x = helpers.getDummyObject();
Object.preventExtensions(x);
x[numericPropName] = 0;
assert.areEqual(undefined, x[numericPropName]);
}
},
test09: {
name: "Call preventExtensions on object with numeric item, then attempt to add a new numeric item",
body: function () {
var propName = "p09";
var numericPropName = 0;
var x = helpers.getDummyObject(propName);
x[numericPropName] = 0;
Object.preventExtensions(x);
x[numericPropName + 1] = 1; // Should fail.
Object.defineProperty(x, numericPropName, {value: 2}); // Another way to add a property, should fail as well.
assert.areEqual(undefined, x[numericPropName + 1]);
}
},
test10: {
name: "Inline cache and freeze: make sure that inline cache is not used for frozen type",
body: function () {
var newValue = 100;
var f = function f(o) {
var temp = o[propName]; // create inline cache for read.
o[propName] = newValue; // attempt to use inline cache, in particular, for read-only property.
}
var propName = "p10";
var x = helpers.getDummyObject(propName);
var y = helpers.getDummyObject(propName);
var z = helpers.getDummyObject(propName);
Object.freeze(y);
Object.freeze(z);
f(x);
f(y); f(y);
f(z);
assert.areEqual(newValue, x[propName], "x[propName]");
assert.areEqual(0, y[propName], "y[propName]");
assert.areEqual(0, z[propName], "z[propName]");
}
},
} // tests.
testRunner.run(tests);