Skip to content

Commit

Permalink
Do not delete additional properties (#39)
Browse files Browse the repository at this point in the history
  • Loading branch information
ehmicky authored and sindresorhus committed Jun 13, 2019
1 parent 46b680b commit 1b1d2e5
Show file tree
Hide file tree
Showing 4 changed files with 4 additions and 45 deletions.
2 changes: 1 addition & 1 deletion index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ declare namespace mimicFn {
/**
Modifies the `to` function to mimic the `from` function. Returns the `to` function.
`name`, `displayName`, and any other properties of `from` are copied. The `length` property is not copied. Properties present in `to` but not in `from` are deleted. Prototype, class, and inherited properties are copied.
`name`, `displayName`, and any other properties of `from` are copied. The `length` property is not copied. Prototype, class, and inherited properties are copied.
@param to - Mimicking function.
@param from - Function to mimic.
Expand Down
21 changes: 0 additions & 21 deletions index.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
'use strict';

const {hasOwnProperty} = Object.prototype;

const copyProperty = (to, from, property, ignoreNonConfigurable) => {
// `Function#length` should reflect the parameters of `to` not `from` since we keep its body.
// `Function#prototype` is non-writable and non-configurable so can never be modified.
Expand Down Expand Up @@ -40,32 +38,13 @@ const changePrototype = (to, from) => {
Object.setPrototypeOf(to, fromPrototype);
};

// If `to` has properties that `from` does not have, remove them
const removeProperty = (to, from, property, ignoreNonConfigurable) => {
if (hasOwnProperty.call(from, property)) {
return;
}

const {configurable} = Object.getOwnPropertyDescriptor(to, property);

if (!configurable && ignoreNonConfigurable) {
return;
}

delete to[property];
};

const mimicFn = (to, from, {ignoreNonConfigurable = false} = {}) => {
for (const property of Reflect.ownKeys(from)) {
copyProperty(to, from, property, ignoreNonConfigurable);
}

changePrototype(to, from);

for (const property of Reflect.ownKeys(to)) {
removeProperty(to, from, property, ignoreNonConfigurable);
}

return to;
};

Expand Down
2 changes: 1 addition & 1 deletion readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ console.log(wrapper.unicorn);

Modifies the `to` function to mimic the `from` function. Returns the `to` function.

`name`, `displayName`, and any other properties of `from` are copied. The `length` property is not copied. Properties present in `to` but not in `from` are deleted. Prototype, class, and inherited properties are copied.
`name`, `displayName`, and any other properties of `from` are copied. The `length` property is not copied. Prototype, class, and inherited properties are copied.

#### to

Expand Down
24 changes: 2 additions & 22 deletions test.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
import test from 'ava';
import mimicFn from '.';

const {hasOwnProperty} = Object.prototype;

const foo = function (bar) {
return bar;
};
Expand Down Expand Up @@ -68,30 +66,12 @@ test('should copy inherited properties', t => {
t.is(wrapper.inheritedProp, foo.inheritedProp);
});

test('should delete extra configurable properties', t => {
test('should not delete extra configurable properties', t => {
const wrapper = function () {};
wrapper.extra = true;
mimicFn(wrapper, foo);

t.false(hasOwnProperty.call(wrapper, 'extra'));
});

test('should throw on extra non-configurable properties', t => {
const wrapper = function () {};
Object.defineProperty(wrapper, 'extra', {value: true, configurable: false, writable: true});

t.throws(() => {
mimicFn(wrapper, foo);
});
});

test('should not throw on extra non-configurable properties with ignoreNonConfigurable', t => {
const wrapper = function () {};
Object.defineProperty(wrapper, 'extra', {value: true, configurable: false, writable: true});

t.notThrows(() => {
mimicFn(wrapper, foo, {ignoreNonConfigurable: true});
});
t.true(wrapper.extra);
});

test('should not copy prototypes', t => {
Expand Down

0 comments on commit 1b1d2e5

Please sign in to comment.