Skip to content

Commit

Permalink
[enzyme] [new] add spyProperty
Browse files Browse the repository at this point in the history
  • Loading branch information
ljharb committed Nov 23, 2020
1 parent 51b4c7e commit c68aff6
Show file tree
Hide file tree
Showing 2 changed files with 123 additions and 0 deletions.
70 changes: 70 additions & 0 deletions packages/enzyme-test-suite/test/Utils-spec.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import {
nodeMatches,
displayNameOfNode,
spyMethod,
spyProperty,
nodeHasType,
isCustomComponentElement,
makeOptions,
Expand Down Expand Up @@ -814,6 +815,75 @@ describe('Utils', () => {
});
});

describe('spyProperty', () => {
it('can spy "was assigned" status and restore it', () => {
let holder = 1;
const obj = {
count: 1,
get accessor() {
return holder;
},
set accessor(v) {
holder = v;
},
};

// test an instance method and an object property function
const targets = ['count', 'accessor'];
targets.forEach((target) => {
const originalValue = obj[target];

const spy = spyProperty(obj, target);

obj[target] += 1;

expect(spy.wasAssigned()).to.equal(true);

spy.restore();

expect(obj[target]).to.equal(originalValue);
});
});

it('restores the property descriptor', () => {
const obj = {};
const descriptor = {
configurable: true,
enumerable: true,
writable: true,
value: () => {},
};
const propertyName = 'foo';
Object.defineProperty(obj, propertyName, descriptor);
const spy = spyMethod(obj, propertyName);
spy.restore();
expect(Object.getOwnPropertyDescriptor(obj, propertyName)).to.deep.equal(descriptor);
});

it('accepts an optional `handlers` argument', () => {
const getSpy = sinon.stub().returns(1);
const setSpy = sinon.stub().returns(2);

const propertyName = 'foo';
const obj = {
[propertyName]: 1,
};

const spy = spyProperty(obj, propertyName, { get: getSpy, set: setSpy });

obj[propertyName] += 1;

spy.restore();

expect(getSpy.args).to.deep.equal([
[1],
]);
expect(setSpy.args).to.deep.equal([
[1, 2],
]);
});
});

describe('isCustomComponentElement()', () => {
const adapter = getAdapter();

Expand Down
53 changes: 53 additions & 0 deletions packages/enzyme/src/Utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -334,6 +334,59 @@ export function spyMethod(instance, methodName, getStub = () => {}) {
};
}

export function spyProperty(instance, propertyName, handlers = {}) {
const originalValue = instance[propertyName];
const hasOwn = has(instance, propertyName);
let descriptor;
if (hasOwn) {
descriptor = Object.getOwnPropertyDescriptor(instance, propertyName);
}
let wasAssigned = false;
let holder = originalValue;
const getV = handlers.get ? () => {
const value = descriptor && descriptor.get ? descriptor.get.call(instance) : holder;
return handlers.get.call(instance, value);
} : () => holder;
const set = handlers.set ? (newValue) => {
wasAssigned = true;
const handlerNewValue = handlers.set.call(instance, holder, newValue);
holder = handlerNewValue;
if (descriptor && descriptor.set) {
descriptor.set.call(instance, holder);
}
} : (v) => {
wasAssigned = true;
holder = v;
};
Object.defineProperty(instance, propertyName, {
configurable: true,
enumerable: !descriptor || !!descriptor.enumerable,
get: getV,
set,
});

return {
restore() {
if (hasOwn) {
if (descriptor) {
Object.defineProperty(instance, propertyName, descriptor);
} else {
/* eslint-disable no-param-reassign */
instance[propertyName] = holder;
/* eslint-enable no-param-reassign */
}
} else {
/* eslint-disable no-param-reassign */
delete instance[propertyName];
/* eslint-enable no-param-reassign */
}
},
wasAssigned() {
return wasAssigned;
},
};
}

export { default as shallowEqual } from 'enzyme-shallow-equal';

export function isEmptyValue(renderedValue) {
Expand Down

0 comments on commit c68aff6

Please sign in to comment.