2014-11-12 14:41:09 +01:00
|
|
|
|
|
|
|
function isConfigurable(obj, name) {
|
|
|
|
try {
|
|
|
|
delete obj[name];
|
|
|
|
} catch (e) {
|
|
|
|
if (!(e instanceof TypeError)) {
|
|
|
|
$ERROR("Expected TypeError, got " + e);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return !Object.prototype.hasOwnProperty.call(obj, name);
|
|
|
|
}
|
|
|
|
|
|
|
|
function isEnumerable(obj, name) {
|
2017-03-13 18:48:33 +01:00
|
|
|
var stringCheck;
|
|
|
|
|
|
|
|
if (typeof name === "string") {
|
|
|
|
for (var x in obj) {
|
|
|
|
if (x === name) {
|
|
|
|
stringCheck = true;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
// skip it if name is not string, works for Symbol names.
|
|
|
|
stringCheck = true;
|
|
|
|
}
|
|
|
|
|
|
|
|
return stringCheck &&
|
|
|
|
Object.prototype.hasOwnProperty.call(obj, name) &&
|
2016-03-14 18:01:59 +01:00
|
|
|
Object.prototype.propertyIsEnumerable.call(obj, name);
|
2014-11-12 14:41:09 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
function isEqualTo(obj, name, expectedValue) {
|
|
|
|
var actualValue = obj[name];
|
|
|
|
|
|
|
|
return assert._isSameValue(actualValue, expectedValue);
|
|
|
|
}
|
|
|
|
|
|
|
|
function isWritable(obj, name, verifyProp, value) {
|
|
|
|
var newValue = value || "unlikelyValue";
|
2015-03-05 00:38:37 +01:00
|
|
|
var hadValue = Object.prototype.hasOwnProperty.call(obj, name);
|
|
|
|
var oldValue = obj[name];
|
2015-04-21 20:19:45 +02:00
|
|
|
var writeSucceeded;
|
2014-11-12 14:41:09 +01:00
|
|
|
|
|
|
|
try {
|
|
|
|
obj[name] = newValue;
|
|
|
|
} catch (e) {
|
|
|
|
if (!(e instanceof TypeError)) {
|
|
|
|
$ERROR("Expected TypeError, got " + e);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-05-14 17:22:12 +02:00
|
|
|
writeSucceeded = isEqualTo(obj, verifyProp || name, newValue);
|
2015-03-05 00:38:37 +01:00
|
|
|
|
2015-04-21 20:19:45 +02:00
|
|
|
// Revert the change only if it was successful (in other cases, reverting
|
|
|
|
// is unnecessary and may trigger exceptions for certain property
|
|
|
|
// configurations)
|
|
|
|
if (writeSucceeded) {
|
|
|
|
if (hadValue) {
|
|
|
|
obj[name] = oldValue;
|
|
|
|
} else {
|
|
|
|
delete obj[name];
|
|
|
|
}
|
2014-11-12 14:41:09 +01:00
|
|
|
}
|
|
|
|
|
2015-04-21 20:19:45 +02:00
|
|
|
return writeSucceeded;
|
2014-11-12 14:41:09 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
function verifyEqualTo(obj, name, value) {
|
|
|
|
if (!isEqualTo(obj, name, value)) {
|
|
|
|
$ERROR("Expected obj[" + String(name) + "] to equal " + value +
|
|
|
|
", actually " + obj[name]);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
function verifyWritable(obj, name, verifyProp, value) {
|
2015-02-20 02:11:53 +01:00
|
|
|
if (!verifyProp) {
|
|
|
|
assert(Object.getOwnPropertyDescriptor(obj, name).writable,
|
|
|
|
"Expected obj[" + String(name) + "] to have writable:true.");
|
|
|
|
}
|
2014-11-12 14:41:09 +01:00
|
|
|
if (!isWritable(obj, name, verifyProp, value)) {
|
|
|
|
$ERROR("Expected obj[" + String(name) + "] to be writable, but was not.");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
function verifyNotWritable(obj, name, verifyProp, value) {
|
2015-02-20 02:11:53 +01:00
|
|
|
if (!verifyProp) {
|
|
|
|
assert(!Object.getOwnPropertyDescriptor(obj, name).writable,
|
|
|
|
"Expected obj[" + String(name) + "] to have writable:false.");
|
|
|
|
}
|
2014-11-12 14:41:09 +01:00
|
|
|
if (isWritable(obj, name, verifyProp)) {
|
|
|
|
$ERROR("Expected obj[" + String(name) + "] NOT to be writable, but was.");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
function verifyEnumerable(obj, name) {
|
2015-02-20 02:11:53 +01:00
|
|
|
assert(Object.getOwnPropertyDescriptor(obj, name).enumerable,
|
|
|
|
"Expected obj[" + String(name) + "] to have enumerable:true.");
|
2014-11-12 14:41:09 +01:00
|
|
|
if (!isEnumerable(obj, name)) {
|
|
|
|
$ERROR("Expected obj[" + String(name) + "] to be enumerable, but was not.");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
function verifyNotEnumerable(obj, name) {
|
2015-02-20 02:11:53 +01:00
|
|
|
assert(!Object.getOwnPropertyDescriptor(obj, name).enumerable,
|
|
|
|
"Expected obj[" + String(name) + "] to have enumerable:false.");
|
2014-11-12 14:41:09 +01:00
|
|
|
if (isEnumerable(obj, name)) {
|
|
|
|
$ERROR("Expected obj[" + String(name) + "] NOT to be enumerable, but was.");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
function verifyConfigurable(obj, name) {
|
2015-02-20 02:11:53 +01:00
|
|
|
assert(Object.getOwnPropertyDescriptor(obj, name).configurable,
|
|
|
|
"Expected obj[" + String(name) + "] to have configurable:true.");
|
2014-11-12 14:41:09 +01:00
|
|
|
if (!isConfigurable(obj, name)) {
|
|
|
|
$ERROR("Expected obj[" + String(name) + "] to be configurable, but was not.");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
function verifyNotConfigurable(obj, name) {
|
2015-02-20 02:11:53 +01:00
|
|
|
assert(!Object.getOwnPropertyDescriptor(obj, name).configurable,
|
|
|
|
"Expected obj[" + String(name) + "] to have configurable:false.");
|
2014-11-12 14:41:09 +01:00
|
|
|
if (isConfigurable(obj, name)) {
|
|
|
|
$ERROR("Expected obj[" + String(name) + "] NOT to be configurable, but was.");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|