Skip to content

Commit

Permalink
fix: Make instance referentially stable
Browse files Browse the repository at this point in the history
  • Loading branch information
NiGhTTraX committed Sep 8, 2021
1 parent de790f4 commit 4194526
Show file tree
Hide file tree
Showing 2 changed files with 22 additions and 1 deletion.
9 changes: 9 additions & 0 deletions src/instance/instance.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -87,4 +87,13 @@ describe('instance', () => {

expect({ ...instance(foo) }).toEqual({ foo: 1, bar: 2, [baz]: 3 });
});

it('should be referentially stable', () => {
const fn = mock<unknown>({ repository: SM.instance(repo) });

const i1 = instance(fn);
const i2 = instance(fn);

expect(i1 === i2).toBeTruthy();
});
});
14 changes: 13 additions & 1 deletion src/instance/instance.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,10 @@ import { getMockState } from '../mock/map';
import { Mock } from '../mock/mock';
import { createProxy } from '../proxy';

// Keep a cache of all mock instances so that we can return a stable reference
// if `instance` is used multiple times.
const cache = new Map<Mock<any>, any>();

/**
* Return the expectation's return value.
*
Expand Down Expand Up @@ -34,9 +38,13 @@ export const returnOrThrow = ({ isError, isPromise, value }: ReturnValue) => {
* Get a real instance from the mock that you can pass to your code under test.
*/
export const instance = <T>(mock: Mock<T>): T => {
if (cache.has(mock)) {
return cache.get(mock);
}

const { repository } = getMockState(mock);

return createProxy<T>({
const proxy = createProxy<T>({
property: (property) => returnOrThrow(repository.get(property)),
apply: (args: any[]) => {
const fn = repository.get(ApplyProp);
Expand All @@ -46,4 +54,8 @@ export const instance = <T>(mock: Mock<T>): T => {
},
ownKeys: () => repository.getAllProperties(),
});

cache.set(mock, proxy);

return proxy;
};

0 comments on commit 4194526

Please sign in to comment.