Skip to content

Commit 4194526

Browse files
committed
fix: Make instance referentially stable
1 parent de790f4 commit 4194526

2 files changed

Lines changed: 22 additions & 1 deletion

File tree

src/instance/instance.spec.ts

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -87,4 +87,13 @@ describe('instance', () => {
8787

8888
expect({ ...instance(foo) }).toEqual({ foo: 1, bar: 2, [baz]: 3 });
8989
});
90+
91+
it('should be referentially stable', () => {
92+
const fn = mock<unknown>({ repository: SM.instance(repo) });
93+
94+
const i1 = instance(fn);
95+
const i2 = instance(fn);
96+
97+
expect(i1 === i2).toBeTruthy();
98+
});
9099
});

src/instance/instance.ts

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,10 @@ import { getMockState } from '../mock/map';
33
import { Mock } from '../mock/mock';
44
import { createProxy } from '../proxy';
55

6+
// Keep a cache of all mock instances so that we can return a stable reference
7+
// if `instance` is used multiple times.
8+
const cache = new Map<Mock<any>, any>();
9+
610
/**
711
* Return the expectation's return value.
812
*
@@ -34,9 +38,13 @@ export const returnOrThrow = ({ isError, isPromise, value }: ReturnValue) => {
3438
* Get a real instance from the mock that you can pass to your code under test.
3539
*/
3640
export const instance = <T>(mock: Mock<T>): T => {
41+
if (cache.has(mock)) {
42+
return cache.get(mock);
43+
}
44+
3745
const { repository } = getMockState(mock);
3846

39-
return createProxy<T>({
47+
const proxy = createProxy<T>({
4048
property: (property) => returnOrThrow(repository.get(property)),
4149
apply: (args: any[]) => {
4250
const fn = repository.get(ApplyProp);
@@ -46,4 +54,8 @@ export const instance = <T>(mock: Mock<T>): T => {
4654
},
4755
ownKeys: () => repository.getAllProperties(),
4856
});
57+
58+
cache.set(mock, proxy);
59+
60+
return proxy;
4961
};

0 commit comments

Comments
 (0)