Skip to content

Commit

Permalink
Only mutate arg keys when writable
Browse files Browse the repository at this point in the history
  • Loading branch information
kasperpeulen committed Feb 20, 2024
1 parent 332c593 commit fcb5c34
Show file tree
Hide file tree
Showing 2 changed files with 39 additions and 3 deletions.
34 changes: 34 additions & 0 deletions code/addons/interactions/src/preview.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
import { expect, test } from 'vitest';
import { fn, isMockFunction } from '@storybook/test';
import { action } from '@storybook/addon-actions';

import { traverseArgs } from './preview';

test('traverseArgs', () => {
const args = {
deep: {
deeper: {
fnKey: fn(),
actionKey: action('name'),
},
},
arg2: Object.freeze({ frozen: true }),
};

expect(args.deep.deeper.fnKey.getMockName()).toEqual('spy');

const traversed = traverseArgs(args) as typeof args;
expect(traversed).toEqual({
deep: {
deeper: {
fnKey: args.deep.deeper.fnKey,
actionKey: args.deep.deeper.actionKey,
},
},
arg2: args.arg2,
});

expect(traversed.deep.deeper.fnKey.getMockName()).toEqual('fnKey');
const actionFn = traversed.deep.deeper.actionKey;
expect(isMockFunction(actionFn) && actionFn.getMockName()).toEqual('actionKey');
});
8 changes: 5 additions & 3 deletions code/addons/interactions/src/preview.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ export const { step: runStep } = instrument(
{ intercept: true }
);

const traverseArgs = (value: unknown, depth = 0, key?: string): any => {
export const traverseArgs = (value: unknown, depth = 0, key?: string): unknown => {
// Make sure to not get in infinite loops with self referencing args
if (depth > 5) return value;
if (value == null) return value;
Expand Down Expand Up @@ -45,9 +45,11 @@ const traverseArgs = (value: unknown, depth = 0, key?: string): any => {

if (typeof value === 'object' && value.constructor === Object) {
depth++;
// We have to mutate the original object for this to survive HMR.
for (const [k, v] of Object.entries(value)) {
(value as Record<string, unknown>)[k] = traverseArgs(v, depth, k);
if (Object.getOwnPropertyDescriptor(value, k).writable) {
// We have to mutate the original object for this to survive HMR.
(value as Record<string, unknown>)[k] = traverseArgs(v, depth, k);
}
}
return value;
}
Expand Down

0 comments on commit fcb5c34

Please sign in to comment.