Skip to content

Commit

Permalink
[New] add spyMethod
Browse files Browse the repository at this point in the history
  • Loading branch information
koba04 authored and ljharb committed Sep 28, 2017
1 parent eb55307 commit 9d6e304
Show file tree
Hide file tree
Showing 2 changed files with 90 additions and 0 deletions.
50 changes: 50 additions & 0 deletions packages/enzyme-test-suite/test/Utils-spec.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import {
nodeEqual,
nodeMatches,
displayNameOfNode,
spyMethod,
} from 'enzyme/build/Utils';
import {
flatten,
Expand Down Expand Up @@ -551,4 +552,53 @@ describe('Utils', () => {
expect(flat).to.deep.equal([1, 2, 3, 4, 5, 6, 7, 8, 9, 10]);
});
});

describe('spyMethod', () => {
it('should be able to spy last return value and restore it', () => {
class Counter {
constructor() {
this.count = 1;
}
incrementAndGet() {
this.count = this.count + 1;
return this.count;
}
}
const instance = new Counter();
const obj = {
count: 1,
incrementAndGet() {
this.count = this.count + 1;
return this.count;
},
};

// test an instance method and an object property function
const targets = [instance, obj];
targets.forEach((target) => {
const original = target.incrementAndGet;
const spy = spyMethod(target, 'incrementAndGet');
target.incrementAndGet();
target.incrementAndGet();
expect(spy.getLastReturnValue()).to.equal(3);
spy.restore();
expect(target.incrementAndGet).to.equal(original);
expect(target.incrementAndGet()).to.equal(4);
});
});

it('should be able to restore the property descriptor', () => {
const obj = {};
const descriptor = {
configurable: true,
enumerable: true,
writable: true,
value: () => {},
};
Object.defineProperty(obj, 'method', descriptor);
const spy = spyMethod(obj, 'method');
spy.restore();
expect(Object.getOwnPropertyDescriptor(obj, 'method')).to.deep.equal(descriptor);
});
});
});
40 changes: 40 additions & 0 deletions packages/enzyme/src/Utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import isEqual from 'lodash/isEqual';
import is from 'object-is';
import entries from 'object.entries';
import functionName from 'function.prototype.name';
import has from 'has';
import configuration from './configuration';
import validateAdapter from './validateAdapter';
import { childrenOfNode } from './RSTTraversal';
Expand Down Expand Up @@ -242,3 +243,42 @@ export function cloneElement(adapter, el, props) {
{ ...el.props, ...props },
);
}

export function spyMethod(instance, methodName) {
let lastReturnValue;
const originalMethod = instance[methodName];
const hasOwn = has(instance, methodName);
let descriptor;
if (hasOwn) {
descriptor = Object.getOwnPropertyDescriptor(instance, methodName);
}
Object.defineProperty(instance, methodName, {
configurable: true,
enumerable: !descriptor || !!descriptor.enumerable,
value(...args) {
const result = originalMethod.apply(this, args);
lastReturnValue = result;
return result;
},
});
return {
restore() {
if (hasOwn) {
if (descriptor) {
Object.defineProperty(instance, methodName, descriptor);
} else {
/* eslint-disable no-param-reassign */
instance[methodName] = originalMethod;
/* eslint-enable no-param-reassign */
}
} else {
/* eslint-disable no-param-reassign */
delete instance[methodName];
/* eslint-enable no-param-reassign */
}
},
getLastReturnValue() {
return lastReturnValue;
},
};
}

0 comments on commit 9d6e304

Please sign in to comment.