Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Don't merge, just testing something out #24387

Closed
wants to merge 33 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
33 commits
Select commit Hold shift + click to select a range
29f8596
Create @storybook/test package
kasperpeulen Aug 17, 2023
f0d68a1
Replace expect (from jest) with @vitest/expect
kasperpeulen Aug 25, 2023
97350aa
Fix build
kasperpeulen Aug 25, 2023
daeffb5
Move testing library to test package + some improvements
kasperpeulen Sep 19, 2023
1f02904
Add testing library assertion on expect
kasperpeulen Sep 19, 2023
b406b6d
Make sure synchronous methods are always promises, even in the first run
kasperpeulen Sep 20, 2023
76c109a
Revert mistake
kasperpeulen Sep 20, 2023
d034a44
Clear spies and instrument spies by event handler name
kasperpeulen Sep 20, 2023
e6b0f0a
Show deprecation message
kasperpeulen Sep 20, 2023
9d88027
Revert making get* method's promises and make sure we instrument `not`
kasperpeulen Sep 21, 2023
ea2c3c3
fix yarn lock
yannbf Sep 21, 2023
33cbcae
Fix eslint
kasperpeulen Sep 21, 2023
6d19861
Comment out deprecation for now
kasperpeulen Sep 22, 2023
0b76716
Fix types
kasperpeulen Sep 22, 2023
da91e3d
Make getters lazy and fix workspace
kasperpeulen Sep 22, 2023
17b3a33
Fix yarn.lock
kasperpeulen Sep 22, 2023
fae8299
Fix type fest range
kasperpeulen Sep 22, 2023
2085dd4
Patch vitest to make it compatible with the jest runner
kasperpeulen Sep 22, 2023
39ed28d
Add jest types to lock
kasperpeulen Sep 22, 2023
ddd8bf1
Better patch
kasperpeulen Sep 22, 2023
27ded25
Fix lock
kasperpeulen Sep 22, 2023
d44e0bd
Fix lazy getters
kasperpeulen Sep 23, 2023
8657c59
Fix gitignore
kasperpeulen Sep 23, 2023
db9bb66
Merge branch 'next' into kasper/test-package
kasperpeulen Oct 3, 2023
a5cdd31
Fix getter
kasperpeulen Oct 3, 2023
d62d5b2
Merge remote-tracking branch 'origin/next' into kasper/test-package
kasperpeulen Oct 3, 2023
de86f5d
Always externalize @vitest deps in tsup, as they are ESM-only. But st…
kasperpeulen Oct 4, 2023
6ee27f2
Always install extra deps
kasperpeulen Oct 3, 2023
47586d9
Fix getters that use `this`
kasperpeulen Oct 4, 2023
4ae6a77
Fix deps issue
kasperpeulen Oct 4, 2023
5497868
Merge remote-tracking branch 'origin/next' into kasper/bladiebla
kasperpeulen Oct 5, 2023
6de0d49
Fix lock files
kasperpeulen Oct 5, 2023
2b9981a
Fix check script
kasperpeulen Oct 5, 2023
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ test-results
!/**/.yarn/plugins
!/**/.yarn/sdks
!/**/.yarn/versions
!/**/.yarn/patches
/**/.pnp.*
!/node_modules

Expand Down
37 changes: 37 additions & 0 deletions code/.yarn/patches/@vitest-expect-npm-0.34.5-8031508efe.patch

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

7 changes: 6 additions & 1 deletion code/addons/actions/src/addArgs.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,12 @@
import type { ArgsEnhancer } from '@storybook/types';
import { addActionsFromArgTypes, inferActionsFromArgTypesRegex } from './addArgsHelpers';
import {
addActionsFromArgTypes,
attachActionsToFunctionMocks,
inferActionsFromArgTypesRegex,
} from './addArgsHelpers';

export const argsEnhancers: ArgsEnhancer[] = [
addActionsFromArgTypes,
inferActionsFromArgTypesRegex,
attachActionsToFunctionMocks,
];
33 changes: 32 additions & 1 deletion code/addons/actions/src/addArgsHelpers.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
/* eslint-disable no-underscore-dangle,no-param-reassign */
import type { Args, Renderer, ArgsEnhancer } from '@storybook/types';
import { action } from './runtime/action';

Expand Down Expand Up @@ -31,7 +32,7 @@ export const inferActionsFromArgTypesRegex: ArgsEnhancer<Renderer> = (context) =

return argTypesMatchingRegex.reduce((acc, [name, argType]) => {
if (isInInitialArgs(name, initialArgs)) {
acc[name] = action(name);
acc[name] = action(name, { implicit: true });
}
return acc;
}, {} as Args);
Expand Down Expand Up @@ -61,3 +62,33 @@ export const addActionsFromArgTypes: ArgsEnhancer<Renderer> = (context) => {
return acc;
}, {} as Args);
};

export const attachActionsToFunctionMocks: ArgsEnhancer<Renderer> = (context) => {
const {
initialArgs,
argTypes,
parameters: { actions },
} = context;
if (actions?.disable || !argTypes) {
return {};
}

const argTypesWithAction = Object.entries(initialArgs).filter(
([, value]) =>
typeof value === 'function' &&
'_isMockFunction' in value &&
value._isMockFunction &&
!value._actionAttached
);

return argTypesWithAction.reduce((acc, [key, value]) => {
const previous = value.getMockImplementation();
value.mockImplementation((...args: unknown[]) => {
action(key)(...args);
return previous?.(...args);
});
// this enhancer is being called multiple times
value._actionAttached = true;
return acc;
}, {} as Args);
};
1 change: 1 addition & 0 deletions code/addons/actions/src/models/ActionOptions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ interface Options {
depth: number; // backards compatibility, remove in 7.0
clearOnStoryChange: boolean;
limit: number;
implicit: boolean;
}

export type ActionOptions = Partial<Options> & Partial<TelejsonOptions>;
17 changes: 17 additions & 0 deletions code/addons/actions/src/runtime/action.ts
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,23 @@ export function action(name: string, options: ActionOptions = {}): HandlerFuncti
};

const handler = function actionHandler(...args: any[]) {
// TODO: Enable once codemods are finished
// if (options.implicit) {
// const preview =
// '__STORYBOOK_PREVIEW__' in global
// ? (global.__STORYBOOK_PREVIEW__ as PreviewWeb<Renderer>)
// : undefined;
// if (
// preview?.storyRenders.some(
// (render) => render.phase === 'playing' || render.phase === 'rendering'
// )
// ) {
// console.warn(
// 'Can not use implicit actions during rendering or playing of a story.'
// );
// }
// }

const channel = addons.getChannel();
const id = uuidv4();
const minDepth = 5; // anything less is really just storybook internals
Expand Down
24 changes: 22 additions & 2 deletions code/addons/interactions/src/preview.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
/* eslint-disable no-param-reassign,no-underscore-dangle */
/// <reference types="node" />

import { addons } from '@storybook/preview-api';
Expand All @@ -9,6 +10,7 @@ import type {
PlayFunction,
PlayFunctionContext,
StepLabel,
Args,
} from '@storybook/types';
import { instrument } from '@storybook/instrumenter';
import { ModuleMocker } from 'jest-mock';
Expand All @@ -33,7 +35,7 @@ const addSpies = (id: string, val: any, key?: string): any => {
try {
if (Object.prototype.toString.call(val) === '[object Object]') {
// We have to mutate the original object for this to survive HMR.
// eslint-disable-next-line no-restricted-syntax, no-param-reassign
// eslint-disable-next-line no-restricted-syntax
for (const [k, v] of Object.entries(val)) val[k] = addSpies(id, v, k);
return val;
}
Expand All @@ -56,7 +58,25 @@ const addSpies = (id: string, val: any, key?: string): any => {
const addActionsFromArgTypes: ArgsEnhancer<Renderer> = ({ id, initialArgs }) =>
addSpies(id, initialArgs);

export const argsEnhancers = [addActionsFromArgTypes];
const instrumentSpies: ArgsEnhancer = ({ initialArgs }) => {
const argTypesWithAction = Object.entries(initialArgs).filter(
([, value]) =>
typeof value === 'function' &&
'_isMockFunction' in value &&
value._isMockFunction &&
!value._instrumented
);

return argTypesWithAction.reduce((acc, [key, value]) => {
const instrumented = instrument({ [key]: () => value }, { retain: true })[key];
acc[key] = instrumented();
// this enhancer is being called multiple times
value._instrumented = true;
return acc;
}, {} as Args);
};

export const argsEnhancers = [addActionsFromArgTypes, instrumentSpies];

export const { step: runStep } = instrument(
{
Expand Down
1 change: 1 addition & 0 deletions code/jest.config.base.js
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ const modulesToTransform = [
'@angular',
'@lit',
'@mdx-js',
'@vitest',
'ccount',
'character-entities',
'decode-named-character-reference',
Expand Down
38 changes: 38 additions & 0 deletions code/lib/instrumenter/src/instrumenter.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,44 @@ describe('Instrumenter', () => {
expect(result.fn1.fn2.__originalFn__).toBe(fn1.fn2);
});

it('patches functions correctly that reference this', () => {
const object = {
name: 'name',
method() {
return this.name;
},
};

const instrumented = instrument(object);
expect(object.method()).toEqual(instrumented.method());

expect(instrumented.method).toEqual(expect.any(Function));
expect(instrumented.method.__originalFn__).toBe(object.method);
});

it('patches functions correctly that use proxies', () => {
const object = new Proxy(
{
name: 'name',
method() {
return this.name;
},
},
{
get(target, prop, receiver) {
if (prop === 'name') return `${target[prop]}!`;
return Reflect.get(target, prop, receiver);
},
}
);

const instrumented = instrument(object);
expect(object.method()).toEqual(instrumented.method());

expect(instrumented.method).toEqual(expect.any(Function));
expect(instrumented.method.__originalFn__).toBe(object.method);
});

it('patched functions call the original function when invoked', () => {
const { fn } = instrument({ fn: jest.fn() });
const obj = {};
Expand Down
Loading