Skip to content

Commit

Permalink
Ensure that remaining Object static methods accept primitives.
Browse files Browse the repository at this point in the history
  • Loading branch information
ljharb committed Feb 24, 2015
1 parent 31fd2e7 commit 458c108
Show file tree
Hide file tree
Showing 2 changed files with 230 additions and 9 deletions.
143 changes: 143 additions & 0 deletions es6-shim.js
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,7 @@
var Symbol = globals.Symbol || {};
var symbolSpecies = Symbol.species || '@@species';
var Type = {
object: function (x) { return x !== null && typeof x === 'object'; },
string: function (x) { return _toString(x) === '[object String]'; },
regex: function (x) { return _toString(x) === '[object RegExp]'; },
symbol: function (x) {
Expand Down Expand Up @@ -1147,6 +1148,148 @@
Value.preserveToString(Object.getOwnPropertyNames, originalObjectGetOwnPropertyNames);
}
}
if (Object.getOwnPropertyDescriptor) {
var objectGOPDAcceptsPrimitives = (function () {
try {
Object.getOwnPropertyDescriptor('foo', 'bar');
return true;
} catch (e) {
return false;
}
}());
if (!objectGOPDAcceptsPrimitives) {
var originalObjectGetOwnPropertyDescriptor = Object.getOwnPropertyDescriptor;
defineProperty(Object, 'getOwnPropertyDescriptor', function getOwnPropertyDescriptor(value, property) {
return originalObjectGetOwnPropertyDescriptor(ES.ToObject(value), property);
}, true);
Value.preserveToString(Object.getOwnPropertyDescriptor, originalObjectGetOwnPropertyDescriptor);
}
}
if (Object.seal) {
var objectSealAcceptsPrimitives = (function () {
try {
Object.seal('foo');
return true;
} catch (e) {
return false;
}
}());
if (!objectSealAcceptsPrimitives) {
var originalObjectSeal = Object.seal;
defineProperty(Object, 'seal', function seal(value) {
if (!Type.object(value)) { return value; }
return originalObjectSeal(value);
}, true);
Value.preserveToString(Object.seal, originalObjectSeal);
}
}
if (Object.isSealed) {
var objectIsSealedAcceptsPrimitives = (function () {
try {
Object.isSealed('foo');
return true;
} catch (e) {
return false;
}
}());
if (!objectIsSealedAcceptsPrimitives) {
var originalObjectIsSealed = Object.isSealed;
defineProperty(Object, 'isSealed', function isSealed(value) {
if (!Type.object(value)) { return true; }
return originalObjectIsSealed(value);
}, true);
Value.preserveToString(Object.isSealed, originalObjectIsSealed);
}
}
if (Object.freeze) {
var objectFreezeAcceptsPrimitives = (function () {
try {
Object.freeze('foo');
return true;
} catch (e) {
return false;
}
}());
if (!objectFreezeAcceptsPrimitives) {
var originalObjectFreeze = Object.freeze;
defineProperty(Object, 'freeze', function freeze(value) {
if (!Type.object(value)) { return value; }
return originalObjectFreeze(value);
}, true);
Value.preserveToString(Object.freeze, originalObjectFreeze);
}
}
if (Object.isFrozen) {
var objectIsFrozenAcceptsPrimitives = (function () {
try {
Object.isFrozen('foo');
return true;
} catch (e) {
return false;
}
}());
if (!objectIsFrozenAcceptsPrimitives) {
var originalObjectIsFrozen = Object.isFrozen;
defineProperty(Object, 'isFrozen', function isFrozen(value) {
if (!Type.object(value)) { return true; }
return originalObjectIsFrozen(value);
}, true);
Value.preserveToString(Object.isFrozen, originalObjectIsFrozen);
}
}
if (Object.preventExtensions) {
var objectPreventExtensionsAcceptsPrimitives = (function () {
try {
Object.preventExtensions('foo');
return true;
} catch (e) {
return false;
}
}());
if (!objectPreventExtensionsAcceptsPrimitives) {
var originalObjectPreventExtensions = Object.preventExtensions;
defineProperty(Object, 'preventExtensions', function preventExtensions(value) {
if (!Type.object(value)) { return value; }
return originalObjectPreventExtensions(value);
}, true);
Value.preserveToString(Object.preventExtensions, originalObjectPreventExtensions);
}
}
if (Object.isExtensible) {
var objectIsExtensibleAcceptsPrimitives = (function () {
try {
Object.isExtensible('foo');
return true;
} catch (e) {
return false;
}
}());
if (!objectIsExtensibleAcceptsPrimitives) {
var originalObjectIsExtensible = Object.isExtensible;
defineProperty(Object, 'isExtensible', function isExtensible(value) {
if (!Type.object(value)) { return false; }
return originalObjectIsExtensible(value);
}, true);
Value.preserveToString(Object.isExtensible, originalObjectIsExtensible);
}
}
if (Object.getPrototypeOf) {
var objectGetProtoAcceptsPrimitives = (function () {
try {
Object.getPrototypeOf('foo');
return true;
} catch (e) {
return false;
}
}());
if (!objectGetProtoAcceptsPrimitives) {
var originalGetProto = Object.getPrototypeOf;
defineProperty(Object, 'getPrototypeOf', function getPrototypeOf(value) {
return originalGetProto(ES.ToObject(value));
}, true);
Value.preserveToString(Object.getPrototypeOf, originalGetProto);
}
}

if (!RegExp.prototype.flags && supportsDescriptors) {
var regExpFlagsGetter = function flags() {
Expand Down
96 changes: 87 additions & 9 deletions test/object.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,19 +6,97 @@ describe('Object', function (undefined) {
expect(exported.Object).to.equal(Object);
});

describe('Object.getOwnPropertyNames()', function () {
it('throws on null or undefined', function () {
expect(function () { Object.getOwnPropertyNames(); }).to['throw'](TypeError);
expect(function () { Object.getOwnPropertyNames(undefined); }).to['throw'](TypeError);
expect(function () { Object.getOwnPropertyNames(null); }).to['throw'](TypeError);
if (Object.getOwnPropertyNames) {
describe('Object.getOwnPropertyNames()', function () {
it('throws on null or undefined', function () {
expect(function () { Object.getOwnPropertyNames(); }).to['throw'](TypeError);
expect(function () { Object.getOwnPropertyNames(undefined); }).to['throw'](TypeError);
expect(function () { Object.getOwnPropertyNames(null); }).to['throw'](TypeError);
});

it('works on primitives', function () {
[true, false, NaN, 42, /a/g, 'foo'].forEach(function (item) {
expect(Object.getOwnPropertyNames(item)).to.eql(Object.getOwnPropertyNames(Object(item)));
});
});
});
}

it('works on primitives', function () {
[true, false, NaN, 42, /a/g, 'foo'].forEach(function (item) {
expect(Object.getOwnPropertyNames(item)).to.eql(Object.getOwnPropertyNames(Object(item)));
if (Object.getOwnPropertyDescriptor) {
describe('Object.getOwnPropertyDescriptor()', function () {
it('throws on null or undefined', function () {
expect(function () { Object.getOwnPropertyDescriptor(); }).to['throw'](TypeError);
expect(function () { Object.getOwnPropertyDescriptor(undefined); }).to['throw'](TypeError);
expect(function () { Object.getOwnPropertyDescriptor(null); }).to['throw'](TypeError);
});

it('works on primitives', function () {
[true, false, NaN, 42, /a/g, 'foo'].forEach(function (item) {
expect(Object.getOwnPropertyDescriptor(item, 'foo')).to.eql(Object.getOwnPropertyDescriptor(Object(item), 'foo'));
});
});
});
});
}

if (Object.seal) {
describe('Object.seal()', function () {
it('works on primitives', function () {
[null, undefined, true, false, NaN, 42, 'foo'].forEach(function (item) {
expect(Object.seal(item)).to.eql(item);
});
});
});
}

if (Object.isSealed) {
describe('Object.isSealed()', function () {
it('works on primitives', function () {
[null, undefined, true, false, NaN, 42, 'foo'].forEach(function (item) {
expect(Object.isSealed(item)).to.equal(true);
});
});
});
}

if (Object.freeze) {
describe('Object.freeze()', function () {
it('works on primitives', function () {
[null, undefined, true, false, NaN, 42, 'foo'].forEach(function (item) {
expect(Object.freeze(item)).to.eql(item);
});
});
});
}

if (Object.isFrozen) {
describe('Object.isFrozen()', function () {
it('works on primitives', function () {
[null, undefined, true, false, NaN, 42, 'foo'].forEach(function (item) {
expect(Object.isFrozen(item)).to.equal(true);
});
});
});
}

if (Object.preventExtensions) {
describe('Object.preventExtensions()', function () {
it('works on primitives', function () {
[null, undefined, true, false, NaN, 42, 'foo'].forEach(function (item) {
expect(Object.preventExtensions(item)).to.eql(item);
});
});
});
}

if (Object.isExtensible) {
describe('Object.isExtensible()', function () {
it('works on primitives', function () {
[null, undefined, true, false, NaN, 42, 'foo'].forEach(function (item) {
expect(Object.isExtensible(item)).to.equal(false);
});
});
});
}

describe('Object.keys()', function () {
it('works on strings', function () {
Expand Down

0 comments on commit 458c108

Please sign in to comment.