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) { for (var prop in obj) { if (Object.prototype.hasOwnProperty.call(obj, prop) && assert._isSameValue(prop, name)) { return true; } } return false; } function isEqualTo(obj, name, expectedValue) { var actualValue = obj[name]; return assert._isSameValue(actualValue, expectedValue); } function isWritable(obj, name, verifyProp, value) { var newValue = value || "unlikelyValue"; var hadValue = Object.prototype.hasOwnProperty.call(obj, name); var oldValue = obj[name]; var writeSucceeded; try { obj[name] = newValue; } catch (e) { if (!(e instanceof TypeError)) { $ERROR("Expected TypeError, got " + e); } } writeSucceeded = isEqualTo(obj, verifyProp || name, newValue); // 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]; } } return writeSucceeded; } 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) { if (!verifyProp) { assert(Object.getOwnPropertyDescriptor(obj, name).writable, "Expected obj[" + String(name) + "] to have writable:true."); } if (!isWritable(obj, name, verifyProp, value)) { $ERROR("Expected obj[" + String(name) + "] to be writable, but was not."); } } function verifyNotWritable(obj, name, verifyProp, value) { if (!verifyProp) { assert(!Object.getOwnPropertyDescriptor(obj, name).writable, "Expected obj[" + String(name) + "] to have writable:false."); } if (isWritable(obj, name, verifyProp)) { $ERROR("Expected obj[" + String(name) + "] NOT to be writable, but was."); } } function verifyEnumerable(obj, name) { assert(Object.getOwnPropertyDescriptor(obj, name).enumerable, "Expected obj[" + String(name) + "] to have enumerable:true."); if (!isEnumerable(obj, name)) { $ERROR("Expected obj[" + String(name) + "] to be enumerable, but was not."); } } function verifyNotEnumerable(obj, name) { assert(!Object.getOwnPropertyDescriptor(obj, name).enumerable, "Expected obj[" + String(name) + "] to have enumerable:false."); if (isEnumerable(obj, name)) { $ERROR("Expected obj[" + String(name) + "] NOT to be enumerable, but was."); } } function verifyConfigurable(obj, name) { assert(Object.getOwnPropertyDescriptor(obj, name).configurable, "Expected obj[" + String(name) + "] to have configurable:true."); if (!isConfigurable(obj, name)) { $ERROR("Expected obj[" + String(name) + "] to be configurable, but was not."); } } function verifyNotConfigurable(obj, name) { assert(!Object.getOwnPropertyDescriptor(obj, name).configurable, "Expected obj[" + String(name) + "] to have configurable:false."); if (isConfigurable(obj, name)) { $ERROR("Expected obj[" + String(name) + "] NOT to be configurable, but was."); } }