Add Verify Property harness (#979)

This commit is contained in:
Leo Balter 2017-04-15 12:56:29 -04:00 committed by GitHub
parent 1ba3a7c4a9
commit e43ce56105
12 changed files with 438 additions and 3 deletions

View File

@ -1,4 +1,74 @@
function verifyProperty(obj, name, desc, options) {
assert(
arguments.length > 2,
'verifyProperty should receive at least 3 arguments: obj, name, and descriptor'
);
var originalDesc = Object.getOwnPropertyDescriptor(obj, name);
var nameStr = String(name);
// Allows checking for undefined descriptor if it's explicitly given.
if (desc === undefined) {
assert.sameValue(
originalDesc,
undefined,
`obj['${nameStr}'] descriptor should be undefined`
);
// desc and originalDesc are both undefined, problem solved;
return true;
}
assert(
Object.prototype.hasOwnProperty.call(obj, name),
`obj should have an own property ${nameStr}`
);
assert.notSameValue(
desc,
null,
`The desc argument should be an object or undefined, null`
);
assert.sameValue(
typeof desc,
"object",
`The desc argument should be an object or undefined, ${String(desc)}`
);
var failures = [];
if (Object.prototype.hasOwnProperty.call(desc, 'enumerable')) {
if (desc.enumerable !== originalDesc.enumerable ||
desc.enumerable !== isEnumerable(obj, name)) {
failures.push(`descriptor should ${desc.enumerable ? '' : 'not '}be enumerable`);
}
}
if (Object.prototype.hasOwnProperty.call(desc, 'writable')) {
if (desc.writable !== originalDesc.writable ||
desc.writable !== isWritable(obj, name)) {
failures.push(`descriptor should ${desc.writable ? '' : 'not '}be writable`);
}
}
if (Object.prototype.hasOwnProperty.call(desc, 'configurable')) {
if (desc.configurable !== originalDesc.configurable ||
desc.configurable !== isConfigurable(obj, name)) {
failures.push(`descriptor should ${desc.configurable ? '' : 'not '}be configurable`);
}
}
assert.sameValue(failures.length, 0, failures.join('; '));
if (options && options.restore) {
Object.defineProperty(obj, name, originalDesc);
}
return true;
}
function isConfigurable(obj, name) {
try {
delete obj[name];
@ -11,7 +81,7 @@ function isConfigurable(obj, name) {
}
function isEnumerable(obj, name) {
var stringCheck;
var stringCheck = false;
if (typeof name === "string") {
for (var x in obj) {

View File

@ -3,8 +3,8 @@
/*---
description: >
Functions that throw values whose constructor does not match the specified
constructor do not satisfy the assertion.
Functions that throw values whose constructor does not match the specified
constructor do not satisfy the assertion.
---*/
var threw = false;

View File

@ -0,0 +1,25 @@
// Copyright (C) 2017 Leo Balter. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
description: >
verifyProperty should receive at least 3 arguments: obj, name, and descriptor
includes: [propertyHelper.js]
---*/
// monkeypatch the API
$ERROR = function $ERROR(message) {
throw new Test262Error(message);
};
assert.throws(Test262Error, () => {
verifyProperty();
}, "0 arguments");
assert.throws(Test262Error, () => {
verifyProperty(Object);
}, "1 argument");
assert.throws(Test262Error, () => {
verifyProperty(Object, 'foo');
}, "2 arguments");

View File

@ -0,0 +1,35 @@
// Copyright (C) 2017 Leo Balter. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
description: >
The desc argument should be an object or undefined
includes: [propertyHelper.js]
---*/
// monkeypatch the API
$ERROR = function $ERROR(message) {
throw new Test262Error(message);
};
var sample = { foo: 42 };
assert.throws(Test262Error, () => {
verifyProperty(sample, "foo", 'configurable');
}, "string");
assert.throws(Test262Error, () => {
verifyProperty(sample, 'foo', true);
}, "boolean");
assert.throws(Test262Error, () => {
verifyProperty(sample, 'foo', 42);
}, "number");
assert.throws(Test262Error, () => {
verifyProperty(sample, 'foo', null);
}, "null");
assert.throws(Test262Error, () => {
verifyProperty(sample, 'foo', Symbol(1));
}, "symbol");

View File

@ -0,0 +1,21 @@
// Copyright (C) 2017 Leo Balter. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
description: >
The first argument should have an own property
includes: [propertyHelper.js]
---*/
// monkeypatch the API
$ERROR = function $ERROR(message) {
throw new Test262Error(message);
};
assert.throws(Test262Error, () => {
verifyProperty(Object, 'JeanPaulSartre', {});
}, "inexisting property");
assert.throws(Test262Error, () => {
verifyProperty({}, 'hasOwnProperty', {});
}, "inexisting own property");

View File

@ -0,0 +1,42 @@
// Copyright (C) 2017 Leo Balter. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
description: >
verifyProperty allows restoring the original accessor descriptor
includes: [propertyHelper.js]
---*/
var obj;
var prop = Symbol(1);
var desc = { enumerable: true, configurable: true, get() { return 42; }, set() {} };
obj = {};
Object.defineProperty(obj, prop, desc);
verifyProperty(obj, prop, desc);
assert.sameValue(
Object.prototype.hasOwnProperty.call(obj, prop),
false
);
obj = {};
Object.defineProperty(obj, prop, desc);
verifyProperty(obj, prop, desc, { restore: true });
assert.sameValue(
Object.prototype.hasOwnProperty.call(obj, prop),
true
);
assert.sameValue(obj[prop], 42);
assert.sameValue(
Object.getOwnPropertyDescriptor(obj, prop).get,
desc.get
);
assert.sameValue(
Object.getOwnPropertyDescriptor(obj, prop).set,
desc.set
);

View File

@ -0,0 +1,42 @@
// Copyright (C) 2017 Leo Balter. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
description: >
verifyProperty allows restoring the original accessor descriptor
includes: [propertyHelper.js]
---*/
var obj;
var prop = "prop";
var desc = { enumerable: true, configurable: true, get() { return 42; }, set() {} };
obj = {};
Object.defineProperty(obj, prop, desc);
verifyProperty(obj, prop, desc);
assert.sameValue(
Object.prototype.hasOwnProperty.call(obj, prop),
false
);
obj = {};
Object.defineProperty(obj, prop, desc);
verifyProperty(obj, prop, desc, { restore: true });
assert.sameValue(
Object.prototype.hasOwnProperty.call(obj, prop),
true
);
assert.sameValue(obj[prop], 42);
assert.sameValue(
Object.getOwnPropertyDescriptor(obj, prop).get,
desc.get
);
assert.sameValue(
Object.getOwnPropertyDescriptor(obj, prop).set,
desc.set
);

View File

@ -0,0 +1,33 @@
// Copyright (C) 2017 Leo Balter. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
description: >
verifyProperty allows restoring the original descriptor
includes: [propertyHelper.js]
---*/
var obj;
var prop = Symbol(1);
var desc = { enumerable: true, configurable: true, writable: true, value: 42 };
obj = {};
Object.defineProperty(obj, prop, desc);
verifyProperty(obj, prop, desc);
assert.sameValue(
Object.prototype.hasOwnProperty.call(obj, prop),
false
);
obj = {};
Object.defineProperty(obj, prop, desc);
verifyProperty(obj, prop, desc, { restore: true });
assert.sameValue(
Object.prototype.hasOwnProperty.call(obj, prop),
true
);
assert.sameValue(obj[prop], 42);

View File

@ -0,0 +1,33 @@
// Copyright (C) 2017 Leo Balter. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
description: >
verifyProperty allows restoring the original descriptor
includes: [propertyHelper.js]
---*/
var obj;
var prop = 'prop';
var desc = { enumerable: true, configurable: true, writable: true, value: 42 };
obj = {};
Object.defineProperty(obj, prop, desc);
verifyProperty(obj, prop, desc);
assert.sameValue(
Object.prototype.hasOwnProperty.call(obj, prop),
false
);
obj = {};
Object.defineProperty(obj, prop, desc);
verifyProperty(obj, prop, desc, { restore: true });
assert.sameValue(
Object.prototype.hasOwnProperty.call(obj, prop),
true
);
assert.sameValue(obj[prop], 42);

View File

@ -0,0 +1,51 @@
// Copyright (C) 2017 Leo Balter. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
description: >
Verify property descriptor
includes: [propertyHelper.js]
---*/
var obj;
var prop = 'prop';
function reset(desc) {
obj = {};
Object.defineProperty(obj, prop, desc);
}
function checkDesc(desc) {
reset(desc);
assert(verifyProperty(obj, prop, desc));
reset(desc);
assert(verifyProperty(obj, prop, { enumerable: desc.enumerable }));
reset(desc);
assert(verifyProperty(obj, prop, { writable: desc.writable }));
reset(desc);
assert(verifyProperty(obj, prop, { configurable: desc.configurable }));
reset(desc);
assert(verifyProperty(obj, prop, { configurable: desc.configurable, enumerable: desc.enumerable }));
reset(desc);
assert(verifyProperty(obj, prop, { configurable: desc.configurable, writable: desc.writable }));
reset(desc);
assert(verifyProperty(obj, prop, { writable: desc.writable, enumerable: desc.enumerable }));
reset(desc);
assert(verifyProperty(obj, prop, { enumerable: desc.enumerable, configurable: desc.configurable }));
}
checkDesc({ enumerable: true, configurable: true, writable: true });
checkDesc({ enumerable: false, writable: false, configurable: false });
checkDesc({ enumerable: true, writable: false, configurable: false });
checkDesc({ enumerable: false, writable: true, configurable: false });
checkDesc({ enumerable: false, writable: false, configurable: true });
checkDesc({ enumerable: true, writable: false, configurable: true });
checkDesc({ enumerable: true, writable: true, configurable: false });
checkDesc({ enumerable: false, writable: true, configurable: true });

View File

@ -0,0 +1,51 @@
// Copyright (C) 2017 Leo Balter. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
description: >
Verify symbol named property descriptor
includes: [propertyHelper.js]
---*/
var obj;
var prop = Symbol(1);
function reset(desc) {
obj = {};
Object.defineProperty(obj, prop, desc);
}
function checkDesc(desc) {
reset(desc);
assert(verifyProperty(obj, prop, desc));
reset(desc);
assert(verifyProperty(obj, prop, { enumerable: desc.enumerable }));
reset(desc);
assert(verifyProperty(obj, prop, { writable: desc.writable }));
reset(desc);
assert(verifyProperty(obj, prop, { configurable: desc.configurable }));
reset(desc);
assert(verifyProperty(obj, prop, { configurable: desc.configurable, enumerable: desc.enumerable }));
reset(desc);
assert(verifyProperty(obj, prop, { configurable: desc.configurable, writable: desc.writable }));
reset(desc);
assert(verifyProperty(obj, prop, { writable: desc.writable, enumerable: desc.enumerable }));
reset(desc);
assert(verifyProperty(obj, prop, { enumerable: desc.enumerable, configurable: desc.configurable }));
}
checkDesc({ enumerable: true, configurable: true, writable: true });
checkDesc({ enumerable: false, writable: false, configurable: false });
checkDesc({ enumerable: true, writable: false, configurable: false });
checkDesc({ enumerable: false, writable: true, configurable: false });
checkDesc({ enumerable: false, writable: false, configurable: true });
checkDesc({ enumerable: true, writable: false, configurable: true });
checkDesc({ enumerable: true, writable: true, configurable: false });
checkDesc({ enumerable: false, writable: true, configurable: true });

View File

@ -0,0 +1,32 @@
// Copyright (C) 2017 Leo Balter. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
description: >
Verify an undefined descriptor
includes: [propertyHelper.js]
---*/
// monkeypatch the API
$ERROR = function $ERROR(message) {
throw new Test262Error(message);
};
var sample = {
bar: undefined,
get baz() {}
};
assert.sameValue(
verifyProperty(sample, "foo", undefined),
true,
"returns true if desc and property descriptor are both undefined"
);
assert.throws(Test262Error, () => {
verifyProperty(sample, 'bar', undefined);
}, "dataDescriptor value is undefined");
assert.throws(Test262Error, () => {
verifyProperty(sample, 'baz', undefined);
}, "accessor returns undefined");