Skip to content

Commit

Permalink
fix(Object.assign): stop polyfilling Object assign (#2080)
Browse files Browse the repository at this point in the history
RxJS should not be responsible for polyfilling `Object.assign`.
This should also increase code coverage around the alternate method used for assign

BREAKING CHANGE: RxJS will no longer polyfill `Object.assign`. It does
not require `Object.assign` to function, however, your code may be
inadvertently relying on this polyfill.
  • Loading branch information
benlesh authored and jayphelps committed Nov 4, 2016
1 parent 9ec444e commit b5f8ab3
Show file tree
Hide file tree
Showing 2 changed files with 63 additions and 24 deletions.
49 changes: 49 additions & 0 deletions spec/util/assign-spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
import { expect } from 'chai';
import { assign, getAssign, assignImpl } from '../../dist/cjs/util/assign';

describe('assign', () => {
it('should exist', () => {
expect(assign).to.be.a('function');
});

if (Object.assign) {
it('should use Object.assign if available', () => {
expect(assign).to.equal(Object.assign);
});
}

it('should assign n objects to a target', () => {
const target = { what: 'what' };
const source1 = { wut: 'socks' };
const source2 = { and : 'sandals' };
const result = assign(target, source1, source2);

expect(result).to.equal(target);
expect(result).to.deep.equal({ what: 'what', wut: 'socks', and: 'sandals' });
});
});

describe('assignImpl', () => {
it('should assign n objects to a target', () => {
const target = { what: 'what' };
const source1 = { wut: 'socks' };
const source2 = { and : 'sandals' };
const result = assignImpl(target, source1, source2);

expect(result).to.equal(target);
expect(result).to.deep.equal({ what: 'what', wut: 'socks', and: 'sandals' });
});
});

describe('getAssign', () => {
it('should return assignImpl if Object.assign does not exist on root', () => {
const result = getAssign({ Object: {} });
expect(result).to.equal(assignImpl);
});

it('should return Object.assign if it exists', () => {
const FAKE = () => { /* lol */ };
const result = getAssign({ Object: { assign: FAKE } });
expect(result).to.equal(FAKE);
});
});
38 changes: 14 additions & 24 deletions src/util/assign.ts
Original file line number Diff line number Diff line change
@@ -1,30 +1,20 @@
import { root } from './root';

const Object = root.Object;

if (typeof (<any>Object).assign != 'function') {
(function () {
(<any>Object).assign = function assignPolyfill(target: Object, ...sources: Array<Object>): Object {
if (target === undefined || target === null) {
throw new TypeError('cannot convert undefined or null to object');
}

const output = Object(target);
const len = sources.length;
for (let index = 0; index < len; index++) {
let source = sources[index];
if (source !== undefined && source !== null) {
for (let key in source) {
if (source.hasOwnProperty(key)) {
output[key] = source[key];
}
}
}
export function assignImpl(target: Object, ...sources: Object[]) {
const len = sources.length;
for (let i = 0; i < len; i++) {
const source = sources[i];
for (let k in source) {
if (source.hasOwnProperty(k)) {
target[k] = source[k];
}
}
}
return target;
};

return output;
};
})();
export function getAssign(root: any) {
return root.Object.assign || assignImpl;
}

export const assign: (target: Object, ...sources: Array<Object>) => Object = Object.assign;
export const assign = getAssign(root);

0 comments on commit b5f8ab3

Please sign in to comment.