1 /* global describe, it, xit, expect, beforeEach, jasmine, window */
3 var has = Object.prototype.hasOwnProperty;
4 var supportsDescriptors = Object.defineProperty && (function () {
7 Object.defineProperty(obj, 'x', { enumerable: false, value: obj });
8 for (var _ in obj) { return false; } // jscs:ignore disallowUnusedVariables
10 } catch (e) { /* this is ES3 */
14 var ifWindowIt = typeof window === 'undefined' ? xit : it;
15 var extensionsPreventible = typeof Object.preventExtensions === 'function' && (function () {
17 Object.preventExtensions(obj);
21 var ifExtensionsPreventibleIt = extensionsPreventible ? it : xit;
22 var canSeal = typeof Object.seal === 'function' && (function () {
28 var ifCanSealIt = canSeal ? it : xit;
29 var canFreeze = typeof Object.freeze === 'function' && (function () {
35 var ifCanFreezeIt = canFreeze ? it : xit;
37 describe('Object', function () {
40 describe('.keys()', function () {
51 var loopedValues = [];
52 for (var key in obj) {
53 loopedValues.push(key);
56 var keys = Object.keys(obj);
57 it('should have correct length', function () {
58 expect(keys.length).toBe(7);
61 describe('arguments objects', function () {
62 it('works with an arguments object', function () {
64 expect(arguments.length).toBe(3);
65 expect(Object.keys(arguments).length).toBe(arguments.length);
66 expect(Object.keys(arguments)).toEqual(['0', '1', '2']);
70 it('works with a legacy arguments object', function () {
71 var FakeArguments = function (args) {
72 args.forEach(function (arg, i) {
76 FakeArguments.prototype.length = 3;
77 FakeArguments.prototype.callee = function () {};
79 var fakeOldArguments = new FakeArguments(['a', 'b', 'c']);
80 expect(Object.keys(fakeOldArguments)).toEqual(['0', '1', '2']);
84 it('should return an Array', function () {
85 expect(Array.isArray(keys)).toBe(true);
88 it('should return names which are own properties', function () {
89 keys.forEach(function (name) {
90 expect(has.call(obj, name)).toBe(true);
94 it('should return names which are enumerable', function () {
95 keys.forEach(function (name) {
96 expect(loopedValues.indexOf(name)).toNotBe(-1);
100 // ES6 Object.keys does not require this throw
101 xit('should throw error for non object', function () {
112 describe('enumerating over non-enumerable properties', function () {
113 it('has no enumerable keys on a Function', function () {
114 var Foo = function () {};
115 expect(Object.keys(Foo.prototype)).toEqual([]);
118 it('has no enumerable keys on a boolean', function () {
119 expect(Object.keys(Boolean.prototype)).toEqual([]);
122 it('has no enumerable keys on an object', function () {
123 expect(Object.keys(Object.prototype)).toEqual([]);
127 it('works with boxed primitives', function () {
128 expect(Object.keys(Object('hello'))).toEqual(['0', '1', '2', '3', '4']);
131 it('works with boxed primitives with extra properties', function () {
134 var actual = Object.keys(x);
135 var expected = ['0', 'y'];
138 expect(actual).toEqual(expected);
141 ifWindowIt('can serialize all objects on the `window`', function () {
142 var windowItemKeys, exception;
143 var blacklistedKeys = ['window', 'console', 'parent', 'self', 'frame', 'frames', 'frameElement', 'external'];
144 if (supportsDescriptors) {
145 Object.defineProperty(window, 'thrower', {
147 get: function () { throw new RangeError('thrower!'); }
150 for (var k in window) {
151 windowItemKeys = exception = void 0;
152 if (blacklistedKeys.indexOf(k) === -1 && has.call(window, k) && window[k] !== null && typeof window[k] === 'object') {
154 windowItemKeys = Object.keys(window[k]);
158 expect(Array.isArray(windowItemKeys)).toBe(true);
159 expect(exception).toBeUndefined();
162 if (supportsDescriptors) {
163 delete window.thrower;
168 describe('.isExtensible()', function () {
171 it('should return true if object is extensible', function () {
172 expect(Object.isExtensible(obj)).toBe(true);
175 ifExtensionsPreventibleIt('should return false if object is not extensible', function () {
176 expect(Object.isExtensible(Object.preventExtensions(obj))).toBe(false);
179 ifCanSealIt('should return false if object is sealed', function () {
180 expect(Object.isExtensible(Object.seal(obj))).toBe(false);
183 ifCanFreezeIt('should return false if object is frozen', function () {
184 expect(Object.isExtensible(Object.freeze(obj))).toBe(false);
187 it('should throw error for non object', function () {
189 // note: in ES6, this is expected to return false.
190 expect(Object.isExtensible(42)).toBe(false);
192 expect(err).toEqual(jasmine.any(TypeError));
197 describe('.defineProperty()', function () {
200 beforeEach(function () {
203 Object.defineProperty(obj, 'name', {
211 it('should return the initial value', function () {
212 expect(has.call(obj, 'name')).toBeTruthy();
213 expect(obj.name).toBe('Testing');
216 it('should be setable', function () {
218 expect(obj.name).toBe('Other');
221 it('should return the parent initial value', function () {
222 var child = Object.create(obj, {});
224 expect(child.name).toBe('Testing');
225 expect(has.call(child, 'name')).toBeFalsy();
228 it('should not override the parent value', function () {
229 var child = Object.create(obj, {});
231 Object.defineProperty(child, 'name', {
235 expect(obj.name).toBe('Testing');
236 expect(child.name).toBe('Other');
239 it('should throw error for non object', function () {
241 Object.defineProperty(42, 'name', {});
245 it('should not throw error for empty descriptor', function () {
247 Object.defineProperty({}, 'name', {});
252 describe('.getOwnPropertyDescriptor()', function () {
253 it('should return undefined because the object does not own the property', function () {
254 var descr = Object.getOwnPropertyDescriptor({}, 'name');
256 expect(descr).toBeUndefined();
259 it('should return a data descriptor', function () {
260 var descr = Object.getOwnPropertyDescriptor({ name: 'Testing' }, 'name');
268 expect(descr).toEqual(expected);
271 it('should return undefined because the object does not own the property', function () {
272 var descr = Object.getOwnPropertyDescriptor(Object.create({ name: 'Testing' }, {}), 'name');
274 expect(descr).toBeUndefined();
277 it('should return a data descriptor', function () {
284 var obj = Object.create({}, { name: expected });
286 var descr = Object.getOwnPropertyDescriptor(obj, 'name');
288 expect(descr).toEqual(expected);
291 it('should throw error for non object', function () {
293 // note: in ES6, we expect this to return undefined.
294 expect(Object.getOwnPropertyDescriptor(42, 'name')).toBeUndefined();
296 expect(err).toEqual(jasmine.any(TypeError));
301 describe('.getPrototypeOf()', function () {
302 it('should return the [[Prototype]] of an object', function () {
303 var Foo = function () {};
305 var proto = Object.getPrototypeOf(new Foo());
307 expect(proto).toBe(Foo.prototype);
310 it('should shamone to the `Object.prototype` if `object.constructor` is not a function', function () {
311 var Foo = function () {};
312 Foo.prototype.constructor = 1;
314 var proto = Object.getPrototypeOf(new Foo()),
315 fnToString = Function.prototype.toString;
317 if (fnToString.call(Object.getPrototypeOf).indexOf('[native code]') < 0) {
318 expect(proto).toBe(Object.prototype);
320 expect(proto).toBe(Foo.prototype);
324 it('should throw error for non object', function () {
326 expect(Object.getPrototypeOf(1)).toBe(Number.prototype); // ES6 behavior
328 expect(err).toEqual(jasmine.any(TypeError));
332 it('should return null on Object.create(null)', function () {
333 var obj = Object.create(null);
335 expect(Object.getPrototypeOf(obj) === null).toBe(true);
339 describe('.defineProperties()', function () {
340 it('should define the constructor property', function () {
342 var newProperties = {
344 value: 'new constructor'
347 Object.defineProperties(target, newProperties);
348 expect(target.constructor).toBe('new constructor');
352 describe('.create()', function () {
353 it('should create objects with no properties when called as `Object.create(null)`', function () {
354 var obj = Object.create(null);
356 expect('hasOwnProperty' in obj).toBe(false);
357 expect('toString' in obj).toBe(false);
358 expect('constructor' in obj).toBe(false);
360 var protoIsEnumerable = false;
362 if (k === '__proto__') {
363 protoIsEnumerable = true;
366 expect(protoIsEnumerable).toBe(false);
368 expect(obj instanceof Object).toBe(false);