123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403 |
- /* global window */
- var has = Object.prototype.hasOwnProperty;
- var supportsDescriptors = Object.defineProperty && (function () {
- try {
- var obj = {};
- Object.defineProperty(obj, 'x', { enumerable: false, value: obj });
- // eslint-disable-next-line no-unreachable-loop
- for (var _ in obj) { return false; } // jscs:ignore disallowUnusedVariables
- return obj.x === obj;
- } catch (e) { /* this is ES3 */
- return false;
- }
- }());
- var ifSupportsDescriptorsIt = supportsDescriptors ? it : xit;
- var ifWindowIt = typeof window === 'undefined' ? xit : it;
- var extensionsPreventible = typeof Object.preventExtensions === 'function' && (function () {
- var obj = {};
- Object.preventExtensions(obj);
- obj.a = 3;
- return obj.a !== 3;
- }());
- var ifExtensionsPreventibleIt = extensionsPreventible ? it : xit;
- var canSeal = typeof Object.seal === 'function' && (function () {
- var obj = { a: 3 };
- Object.seal(obj);
- delete obj.a;
- return obj.a === 3;
- }());
- var ifCanSealIt = canSeal ? it : xit;
- var canFreeze = typeof Object.freeze === 'function' && (function () {
- var obj = {};
- Object.freeze(obj);
- obj.a = 3;
- return obj.a !== 3;
- }());
- var ifCanFreezeIt = canFreeze ? it : xit;
- describe('Object', function () {
- 'use strict';
- describe('.keys()', function () {
- var obj = {
- str: 'boz',
- obj: { },
- arr: [],
- bool: true,
- num: 42,
- 'null': null,
- undefined: undefined
- };
- var loopedValues = [];
- for (var key in obj) {
- loopedValues.push(key);
- }
- var keys = Object.keys(obj);
- it('should have correct length', function () {
- expect(keys.length).toBe(7);
- });
- describe('arguments objects', function () {
- it('works with an arguments object', function () {
- (function () {
- expect(arguments.length).toBe(3);
- expect(Object.keys(arguments).length).toBe(arguments.length);
- expect(Object.keys(arguments)).toEqual(['0', '1', '2']);
- }(1, 2, 3));
- });
- it('works with a legacy arguments object', function () {
- var FakeArguments = function (args) {
- args.forEach(function (arg, i) {
- this[i] = arg;
- }.bind(this));
- };
- FakeArguments.prototype.length = 3;
- FakeArguments.prototype.callee = function () {};
- var fakeOldArguments = new FakeArguments(['a', 'b', 'c']);
- expect(Object.keys(fakeOldArguments)).toEqual(['0', '1', '2']);
- });
- });
- it('should return an Array', function () {
- expect(Array.isArray(keys)).toBe(true);
- });
- it('should return names which are own properties', function () {
- keys.forEach(function (name) {
- expect(has.call(obj, name)).toBe(true);
- });
- });
- it('should return names which are enumerable', function () {
- keys.forEach(function (name) {
- expect(loopedValues.indexOf(name)).toNotBe(-1);
- });
- });
- // ES6 Object.keys does not require this throw
- xit('should throw error for non object', function () {
- var e = {};
- expect(function () {
- try {
- Object.keys(42);
- } catch (err) {
- throw e;
- }
- }).toThrow(e);
- });
- describe('enumerating over non-enumerable properties', function () {
- it('has no enumerable keys on a Function', function () {
- var Foo = function () {};
- expect(Object.keys(Foo.prototype)).toEqual([]);
- });
- it('has no enumerable keys on a boolean', function () {
- expect(Object.keys(Boolean.prototype)).toEqual([]);
- });
- it('has no enumerable keys on an object', function () {
- expect(Object.keys(Object.prototype)).toEqual([]);
- });
- });
- it('works with boxed primitives', function () {
- expect(Object.keys(Object('hello'))).toEqual(['0', '1', '2', '3', '4']);
- });
- it('works with boxed primitives with extra properties', function () {
- var x = Object('x');
- x.y = 1;
- var actual = Object.keys(x);
- var expected = ['0', 'y'];
- actual.sort();
- expected.sort();
- expect(actual).toEqual(expected);
- });
- ifWindowIt('can serialize all objects on the `window`', function () {
- var windowItemKeys, exception;
- var excludedKeys = ['window', 'console', 'parent', 'self', 'frame', 'frames', 'frameElement', 'external', 'height', 'width', 'top', 'localStorage', 'applicationCache'];
- if (supportsDescriptors) {
- Object.defineProperty(window, 'thrower', {
- configurable: true,
- get: function () { throw new RangeError('thrower!'); }
- });
- }
- for (var k in window) {
- exception = void 0;
- windowItemKeys = exception;
- if (excludedKeys.indexOf(k) === -1 && has.call(window, k) && window[k] !== null && typeof window[k] === 'object') {
- try {
- windowItemKeys = Object.keys(window[k]);
- } catch (e) {
- exception = e;
- }
- expect(Array.isArray(windowItemKeys)).toBe(true);
- expect(exception).toBeUndefined();
- }
- }
- if (supportsDescriptors) {
- delete window.thrower;
- }
- });
- });
- describe('.isExtensible()', function () {
- var obj = { };
- it('should return true if object is extensible', function () {
- expect(Object.isExtensible(obj)).toBe(true);
- });
- ifExtensionsPreventibleIt('should return false if object is not extensible', function () {
- expect(Object.isExtensible(Object.preventExtensions(obj))).toBe(false);
- });
- ifCanSealIt('should return false if object is sealed', function () {
- expect(Object.isExtensible(Object.seal(obj))).toBe(false);
- });
- ifCanFreezeIt('should return false if object is frozen', function () {
- expect(Object.isExtensible(Object.freeze(obj))).toBe(false);
- });
- it('should throw error for non object', function () {
- try {
- // note: in ES6, this is expected to return false.
- expect(Object.isExtensible(42)).toBe(false);
- } catch (err) {
- expect(err).toEqual(jasmine.any(TypeError));
- }
- });
- });
- describe('.defineProperty()', function () {
- var obj;
- beforeEach(function () {
- obj = {};
- Object.defineProperty(obj, 'name', {
- value: 'Testing',
- configurable: true,
- enumerable: true,
- writable: true
- });
- });
- it('should return the initial value', function () {
- expect(has.call(obj, 'name')).toBeTruthy();
- expect(obj.name).toBe('Testing');
- });
- it('should be setable', function () {
- obj.name = 'Other';
- expect(obj.name).toBe('Other');
- });
- it('should return the parent initial value', function () {
- var child = Object.create(obj, {});
- expect(child.name).toBe('Testing');
- expect(has.call(child, 'name')).toBeFalsy();
- });
- it('should not override the parent value', function () {
- var child = Object.create(obj, {});
- Object.defineProperty(child, 'name', { value: 'Other' });
- expect(obj.name).toBe('Testing');
- expect(child.name).toBe('Other');
- });
- it('should throw error for non object', function () {
- expect(function () {
- Object.defineProperty(42, 'name', {});
- }).toThrow();
- });
- it('should not throw error for empty descriptor', function () {
- expect(function () {
- Object.defineProperty({}, 'name', {});
- }).not.toThrow();
- });
- ifSupportsDescriptorsIt('allows setting a nonwritable prototype', function () {
- var F = function () {};
- expect(F.prototype).toEqual(Object.getOwnPropertyDescriptor(F, 'prototype').value);
- expect((new F()).toString).toEqual(Object.prototype.toString);
- F.prototype = Number.prototype;
- expect(F.prototype).toEqual(Object.getOwnPropertyDescriptor(F, 'prototype').value);
- expect((new F()).toString).toEqual(Number.prototype.toString);
- var toStringSentinel = {};
- var sentinel = { toString: toStringSentinel };
- Object.defineProperty(F, 'prototype', { value: sentinel, writable: false });
- expect(F.prototype).toEqual(Object.getOwnPropertyDescriptor(F, 'prototype').value);
- expect((new F()).toString).toEqual(toStringSentinel);
- });
- ifSupportsDescriptorsIt('properly makes a prototype non-writable', function () {
- var O = { prototype: 1 };
- expect(O.prototype).toEqual(Object.getOwnPropertyDescriptor(O, 'prototype').value);
- expect(O.prototype).toEqual(1);
- expect(function () {
- Object.defineProperty(O, 'prototype', { writable: false, configurable: true });
- }).not.toThrow();
- var sentinel = {};
- expect(function () {
- Object.defineProperty(O, 'prototype', { value: sentinel });
- }).not.toThrow();
- expect(O.prototype).toEqual(Object.getOwnPropertyDescriptor(O, 'prototype').value);
- expect(O.prototype).toEqual(sentinel);
- });
- });
- describe('.getOwnPropertyDescriptor()', function () {
- it('should return undefined because the object does not own the property', function () {
- var descr = Object.getOwnPropertyDescriptor({}, 'name');
- expect(descr).toBeUndefined();
- });
- it('should return a data descriptor', function () {
- var descr = Object.getOwnPropertyDescriptor({ name: 'Testing' }, 'name');
- var expected = {
- value: 'Testing',
- enumerable: true,
- writable: true,
- configurable: true
- };
- expect(descr).toEqual(expected);
- });
- it('should return undefined because the object does not own the property', function () {
- var descr = Object.getOwnPropertyDescriptor(Object.create({ name: 'Testing' }, {}), 'name');
- expect(descr).toBeUndefined();
- });
- it('should return a data descriptor', function () {
- var expected = {
- value: 'Testing',
- configurable: true,
- enumerable: true,
- writable: true
- };
- var obj = Object.create({}, { name: expected });
- var descr = Object.getOwnPropertyDescriptor(obj, 'name');
- expect(descr).toEqual(expected);
- });
- it('should throw error for non object', function () {
- try {
- // note: in ES6, we expect this to return undefined.
- expect(Object.getOwnPropertyDescriptor(42, 'name')).toBeUndefined();
- } catch (err) {
- expect(err).toEqual(jasmine.any(TypeError));
- }
- });
- });
- describe('.getPrototypeOf()', function () {
- it('should return the [[Prototype]] of an object', function () {
- var Foo = function () {};
- var proto = Object.getPrototypeOf(new Foo());
- expect(proto).toBe(Foo.prototype);
- });
- it('should shamone to the `Object.prototype` if `object.constructor` is not a function', function () {
- var Foo = function () {};
- Foo.prototype.constructor = 1;
- var proto = Object.getPrototypeOf(new Foo()),
- fnToString = Function.prototype.toString;
- if (fnToString.call(Object.getPrototypeOf).indexOf('[native code]') < 0) {
- expect(proto).toBe(Object.prototype);
- } else {
- expect(proto).toBe(Foo.prototype);
- }
- });
- it('should throw error for non object', function () {
- try {
- expect(Object.getPrototypeOf(1)).toBe(Number.prototype); // ES6 behavior
- } catch (err) {
- expect(err).toEqual(jasmine.any(TypeError));
- }
- });
- it('should return null on Object.create(null)', function () {
- var obj = Object.create(null);
- expect(Object.getPrototypeOf(obj) === null).toBe(true);
- });
- });
- describe('.defineProperties()', function () {
- it('should define the constructor property', function () {
- var target = {};
- var newProperties = { constructor: { value: 'new constructor' } };
- Object.defineProperties(target, newProperties);
- expect(target.constructor).toBe('new constructor');
- });
- });
- describe('.create()', function () {
- it('should create objects with no properties when called as `Object.create(null)`', function () {
- var obj = Object.create(null);
- expect('hasOwnProperty' in obj).toBe(false);
- expect('toString' in obj).toBe(false);
- expect('constructor' in obj).toBe(false);
- var protoIsEnumerable = false;
- for (var k in obj) {
- if (k === '__proto__') {
- protoIsEnumerable = true;
- }
- }
- expect(protoIsEnumerable).toBe(false);
- expect(obj instanceof Object).toBe(false);
- });
- });
- });
|