Skip to content

Commit

Permalink
Add Object.entries and Object.values polyfill
Browse files Browse the repository at this point in the history
Reviewed By: martinbigio

Differential Revision: D2876430

fb-gh-sync-id: 25c7680a71c9187beb937f6faf030a83c9c81fc5
  • Loading branch information
DmitrySoshnikov authored and facebook-github-bot-9 committed Jan 29, 2016
1 parent 203fdca commit 598df0b
Show file tree
Hide file tree
Showing 3 changed files with 177 additions and 0 deletions.
1 change: 1 addition & 0 deletions packager/react-packager/src/Resolver/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -157,6 +157,7 @@ class Resolver {
path.join(__dirname, 'polyfills/String.prototype.es6.js'),
path.join(__dirname, 'polyfills/Array.prototype.es6.js'),
path.join(__dirname, 'polyfills/Array.es6.js'),
path.join(__dirname, 'polyfills/Object.es7.js'),
path.join(__dirname, 'polyfills/babelHelpers.js'),
].concat(this._polyfillModuleNames);

Expand Down
56 changes: 56 additions & 0 deletions packager/react-packager/src/Resolver/polyfills/Object.es7.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
/**
* Copyright 2004-present Facebook. All Rights Reserved.
*
* @provides Object.es7
* @polyfill
*/

(function() {

const hasOwnProperty = Object.prototype.hasOwnProperty;

/**
* Returns an array of the given object's own enumerable entries.
* https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/entries
*
*/
if (typeof Object.entries !== 'function') {
Object.entries = function(object) {
// `null` and `undefined` values are not allowed.
if (object == null) {
throw new TypeError('Object.entries called on non-object');
}

let entries = [];
for (let key in object) {
if (hasOwnProperty.call(object, key)) {
entries.push([key, object[key]]);
}
}
return entries;
};
}

/**
* Returns an array of the given object's own enumerable entries.
* https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/values
*
*/
if (typeof Object.values !== 'function') {
Object.values = function(object) {
// `null` and `undefined` values are not allowed.
if (object == null) {
throw new TypeError('Object.values called on non-object');
}

let values = [];
for (let key in object) {
if (hasOwnProperty.call(object, key)) {
values.push(object[key]);
}
}
return values;
};
}

})();
Original file line number Diff line number Diff line change
@@ -0,0 +1,120 @@
/**
* Copyright 2004-present Facebook. All Rights Reserved.
*
* @emails oncall+jsinfra
*/

/* eslint-disable fb-www/object-create-only-one-param */

jest.autoMockOff();

describe('Object (ES7)', () => {
beforeEach(() => {
delete Object.entries;
delete Object.values;
jest.resetModuleRegistry();
require('../Object.es7');
});

describe('Object.entries', () => {
it('should have a length of 1', () => {
expect(Object.entries.length).toBe(1);
});

it('should check for type', () => {
expect(Object.entries.bind(null, null)).toThrow(TypeError(
'Object.entries called on non-object'
));
expect(Object.entries.bind(null, undefined)).toThrow(TypeError(
'Object.entries called on non-object'
));
expect(Object.entries.bind(null, [])).not.toThrow();
expect(Object.entries.bind(null, () => {})).not.toThrow();
expect(Object.entries.bind(null, {})).not.toThrow();
expect(Object.entries.bind(null, 'abc')).not.toThrow();
});

it('should return enumerable entries', () => {
let foo = Object.defineProperties({}, {
x: {value: 10, enumerable: true},
y: {value: 20},
});

expect(Object.entries(foo)).toEqual([['x', 10]]);

let bar = {x: 10, y: 20};
expect(Object.entries(bar)).toEqual([['x', 10], ['y', 20]]);
});

it('should work with proto-less objects', () => {
let foo = Object.create(null, {
x: {value: 10, enumerable: true},
y: {value: 20},
});

expect(Object.entries(foo)).toEqual([['x', 10]]);
});

it('should return only own entries', () => {
let foo = Object.create({z: 30}, {
x: {value: 10, enumerable: true},
y: {value: 20},
});

expect(Object.entries(foo)).toEqual([['x', 10]]);
});

it('should convert to object primitive string', () => {
expect(Object.entries('ab')).toEqual([['0', 'a'], ['1', 'b']]);
});
});

describe('Object.values', () => {
it('should have a length of 1', () => {
expect(Object.values.length).toBe(1);
});

it('should check for type', () => {
expect(Object.values.bind(null, null)).toThrow(TypeError(
'Object.values called on non-object'
));
expect(Object.values.bind(null, [])).not.toThrow();
expect(Object.values.bind(null, () => {})).not.toThrow();
expect(Object.values.bind(null, {})).not.toThrow();
});

it('should return enumerable values', () => {
let foo = Object.defineProperties({}, {
x: {value: 10, enumerable: true},
y: {value: 20},
});

expect(Object.values(foo)).toEqual([10]);

let bar = {x: 10, y: 20};
expect(Object.values(bar)).toEqual([10, 20]);
});

it('should work with proto-less objects', () => {
let foo = Object.create(null, {
x: {value: 10, enumerable: true},
y: {value: 20},
});

expect(Object.values(foo)).toEqual([10]);
});

it('should return only own values', () => {
let foo = Object.create({z: 30}, {
x: {value: 10, enumerable: true},
y: {value: 20},
});

expect(Object.values(foo)).toEqual([10]);
});

it('should convert to object primitive string', () => {
expect(Object.values('ab')).toEqual(['a', 'b']);
});
});
});

0 comments on commit 598df0b

Please sign in to comment.