michael@0: function strictArgs() { michael@0: return (function (a, b, c) {'use strict'; return arguments; })(1, 2); michael@0: } michael@0: michael@0: function normalArgs() { michael@0: return (function (a, b, c) { return arguments; })(1, 2); michael@0: } michael@0: michael@0: function checkProperty(options, prop, shouldThrow) { michael@0: var desc, orig; michael@0: var obj = options.strict ? strictArgs() : normalArgs(); michael@0: var objType = options.strict ? "strict arguments." : "normal arguments."; michael@0: michael@0: function check() { michael@0: orig = Object.getOwnPropertyDescriptor(obj, prop); michael@0: michael@0: var threw = false; michael@0: try { michael@0: obj[prop] = obj[prop]; michael@0: } michael@0: catch (e) { michael@0: threw = true; michael@0: } michael@0: assertEq(threw, shouldThrow, objType + prop + " threw"); michael@0: michael@0: if (orig === undefined) { michael@0: // The property wasn't defined, so we can skip it. michael@0: return; michael@0: } michael@0: michael@0: desc = Object.getOwnPropertyDescriptor(obj, prop); michael@0: if ("value" in orig) { michael@0: assertEq(desc.value, orig.value, objType + prop + " value"); michael@0: } else { michael@0: assertEq(desc.get, orig.get, objType + prop + " get"); michael@0: assertEq(desc.set, orig.set, objType + prop + " set"); michael@0: } michael@0: assertEq(desc.writable, orig.writable, objType + prop + " writable"); michael@0: assertEq(desc.enumerable, orig.enumerable, objType + prop + " enumerable"); michael@0: assertEq(desc.configurable, orig.configurable, objType + prop + " configurable"); michael@0: } michael@0: michael@0: check(); michael@0: michael@0: if (orig && orig.configurable) { michael@0: if(options.refresh) { obj = options.strict ? strictArgs() : normalArgs(); } michael@0: Object.defineProperty(obj, prop, {writable: false, enumerable: true}); michael@0: check(); michael@0: michael@0: if(options.refresh) { obj = options.strict ? strictArgs() : normalArgs(); } michael@0: Object.defineProperty(obj, prop, {writable: true, enumerable: false}); michael@0: check(); michael@0: michael@0: if(options.refresh) { obj = options.strict ? strictArgs() : normalArgs(); } michael@0: Object.defineProperty(obj, prop, {writable: false, configurable: false}); michael@0: check(); michael@0: } michael@0: } michael@0: michael@0: checkProperty({strict: true, refresh: true}, 'callee', true); michael@0: checkProperty({strict: true, refresh: false}, 'callee', true); michael@0: checkProperty({strict: false, refresh: true}, 'callee', false); michael@0: checkProperty({strict: false, refresh: false}, 'callee', false); michael@0: michael@0: checkProperty({strict: true, refresh: true}, 'length', false); michael@0: checkProperty({strict: true, refresh: false}, 'length', false); michael@0: checkProperty({strict: false, refresh: true}, 'length', false); michael@0: checkProperty({strict: false, refresh: false}, 'length', false); michael@0: michael@0: for (var i = 0; i <= 5; i++) { michael@0: checkProperty({strict: true, refresh: true}, "" + i, false); michael@0: checkProperty({strict: true, refresh: false}, "" + i, false); michael@0: checkProperty({strict: false, refresh: true}, "" + i, false); michael@0: checkProperty({strict: false, refresh: false}, "" + i, false); michael@0: }