Skip to content

Commit

Permalink
chore: Update package version to 1.3.4
Browse files Browse the repository at this point in the history
  • Loading branch information
SoraKumo001 committed Aug 15, 2024
1 parent bee6bff commit baed4a0
Show file tree
Hide file tree
Showing 5 changed files with 79 additions and 71 deletions.
130 changes: 73 additions & 57 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,12 +1,11 @@
# storybook-addon-module-mock

Provides module mocking functionality like `jest.mock` on Storybook.
Provides module mocking functionality like `jest.mock` on Storybook@8.

Added 'storybook-addon-module-mock' to Storybook addons.
Only works if Webpack is used in the Builder.

If you use Vite for your Builder, use this package.

If you use Vite for your Builder, use this package.
https://www.npmjs.com/package/storybook-addon-vite-mock

## Screenshot
Expand Down Expand Up @@ -60,6 +59,11 @@ const config: StorybookConfig = {
options: {},
},
stories: ['../src/**/*.stories.@(tsx)'],
build: {
test: {
disabledAddons: ['@storybook/addon-docs', '@storybook/addon-essentials/docs'],
},
},
addons: [
'@storybook/addon-essentials',
'@storybook/addon-interactions',
Expand All @@ -71,11 +75,13 @@ const config: StorybookConfig = {
},
},
},
'storybook-addon-module-mock',
{
name: 'storybook-addon-module-mock',
options: {
exclude: ['**/node_modules/@mui/**'],
},
},
],
typescript: {
reactDocgen: 'react-docgen',
},
};

export default config;
Expand Down Expand Up @@ -114,32 +120,36 @@ export const MockTest: FC<Props> = ({}) => {
The `mockRestore()` is automatically performed after the Story display is finished.

```tsx
import { expect } from '@storybook/jest';
import { userEvent, waitFor, within } from '@storybook/testing-library';
import { createMock, getMock } from 'storybook-addon-module-mock';
import { ComponentMeta, ComponentStoryObj } from '@storybook/react';
import { Meta, StoryObj } from '@storybook/react';
import { expect, userEvent, waitFor, within } from '@storybook/test';
import React, { DependencyList } from 'react';
import { createMock, getMock, getOriginal } from 'storybook-addon-module-mock';
import { MockTest } from './MockTest';
import React from 'react';

const meta: ComponentMeta<typeof MockTest> = {
title: 'Components/MockTest',
const meta: Meta<typeof MockTest> = {
tags: ['autodocs'],
component: MockTest,
};
export default meta;

export const Primary: ComponentStoryObj<typeof MockTest> = {
export const Primary: StoryObj<typeof MockTest> = {
play: async ({ canvasElement }) => {
const canvas = within(canvasElement);
expect(canvas.getByText('Before')).toBeInTheDocument();
},
};

export const Mock: ComponentStoryObj<typeof MockTest> = {
export const Mock: StoryObj<typeof MockTest> = {
parameters: {
moduleMock: {
mock: () => {
const mock = createMock(React, 'useMemo');
mock.mockReturnValue('After');
mock.mockImplementation((fn: () => unknown, deps: DependencyList) => {
// Call the original useMemo
const value = getOriginal(mock)(fn, deps);
// Change the return value under certain conditions
return value === 'Before' ? 'After' : value;
});
return [mock];
},
},
Expand All @@ -152,19 +162,24 @@ export const Mock: ComponentStoryObj<typeof MockTest> = {
},
};

export const Action: ComponentStoryObj<typeof MockTest> = {
export const Action: StoryObj<typeof MockTest> = {
parameters: {
moduleMock: {
mock: () => {
const useMemo = React.useMemo;
const mock = createMock(React, 'useMemo');
mock.mockImplementation(useMemo);
return [mock];
},
},
},
play: async ({ canvasElement, parameters }) => {
const canvas = within(canvasElement);
const mock = getMock(parameters, React, 'useMemo');
mock.mockReturnValue('Action');
mock.mockImplementation((fn: () => unknown, deps: DependencyList) => {
const value = getOriginal(mock)(fn, deps);
return value === 'Before' ? 'Action' : value;
});
userEvent.click(await canvas.findByRole('button'));
await waitFor(() => {
expect(canvas.getByText('Action')).toBeInTheDocument();
Expand Down Expand Up @@ -210,27 +225,26 @@ export const LibHook: FC<Props> = ({}) => {
#### LibHook.stories.tsx

```tsx
import { expect } from '@storybook/jest';
import { userEvent, waitFor, within } from '@storybook/testing-library';
import { ComponentMeta, ComponentStoryObj } from '@storybook/react';
import { LibHook } from './LibHook';
import { Meta, StoryObj } from '@storybook/react';
import { expect, userEvent, waitFor, within } from '@storybook/test';
import { createMock, getMock } from 'storybook-addon-module-mock';
import { LibHook } from './LibHook';
import * as message from './message';

const meta: ComponentMeta<typeof LibHook> = {
title: 'Components/LibHook',
const meta: Meta<typeof LibHook> = {
tags: ['autodocs'],
component: LibHook,
};
export default meta;

export const Primary: ComponentStoryObj<typeof LibHook> = {
export const Primary: StoryObj<typeof LibHook> = {
play: async ({ canvasElement }) => {
const canvas = within(canvasElement);
expect(canvas.getByText('Before')).toBeInTheDocument();
},
};

export const Mock: ComponentStoryObj<typeof LibHook> = {
export const Mock: StoryObj<typeof LibHook> = {
parameters: {
moduleMock: {
mock: () => {
Expand All @@ -244,11 +258,12 @@ export const Mock: ComponentStoryObj<typeof LibHook> = {
const canvas = within(canvasElement);
expect(canvas.getByText('After')).toBeInTheDocument();
const mock = getMock(parameters, message, 'getMessage');
console.log(mock);
expect(mock).toBeCalled();
},
};

export const Action: ComponentStoryObj<typeof LibHook> = {
export const Action: StoryObj<typeof LibHook> = {
parameters: {
moduleMock: {
mock: () => {
Expand Down Expand Up @@ -298,14 +313,14 @@ export const MockTest: FC<Props> = ({}) => {
#### MockTest.stories.tsx

```tsx
import { expect } from '@storybook/jest';
import { Meta, StoryObj } from '@storybook/react';
import { userEvent, waitFor, within } from '@storybook/testing-library';
import React from 'react';
import { expect, userEvent, waitFor, within } from '@storybook/test';
import React, { DependencyList } from 'react';
import { createMock, getMock, getOriginal } from 'storybook-addon-module-mock';
import { MockTest } from './MockTest';

const meta: Meta<typeof MockTest> = {
tags: ['autodocs'],
component: MockTest,
};
export default meta;
Expand All @@ -322,7 +337,7 @@ export const Mock: StoryObj<typeof MockTest> = {
moduleMock: {
mock: () => {
const mock = createMock(React, 'useMemo');
mock.mockImplementation((fn: () => unknown, deps: unknown[]) => {
mock.mockImplementation((fn: () => unknown, deps: DependencyList) => {
// Call the original useMemo
const value = getOriginal(mock)(fn, deps);
// Change the return value under certain conditions
Expand Down Expand Up @@ -354,7 +369,7 @@ export const Action: StoryObj<typeof MockTest> = {
play: async ({ canvasElement, parameters }) => {
const canvas = within(canvasElement);
const mock = getMock(parameters, React, 'useMemo');
mock.mockImplementation((fn: () => unknown, deps: unknown[]) => {
mock.mockImplementation((fn: () => unknown, deps: DependencyList) => {
const value = getOriginal(mock)(fn, deps);
return value === 'Before' ? 'Action' : value;
});
Expand Down Expand Up @@ -391,40 +406,41 @@ export const ReRenderArgs: FC<Props> = ({ value }) => {
#### ReRenderArgs.stories.tsx

```tsx
import { expect } from '@storybook/jest';
import { Meta, StoryObj } from '@storybook/react';
import { waitFor, within } from '@storybook/testing-library';
import { render } from 'storybook-addon-module-mock';
import { ReRenderArgs } from './ReRenderArgs';
import { expect, waitFor, within } from '@storybook/test';
import { createMock, getMock, render } from 'storybook-addon-module-mock';
import * as message from './message';
import { ReRender } from './ReRender';

const meta: Meta<typeof ReRenderArgs> = {
component: ReRenderArgs,
args: { value: 'Test' },
const meta: Meta<typeof ReRender> = {
tags: ['autodocs'],
component: ReRender,
};
export default meta;

export const Primary: StoryObj<typeof ReRenderArgs> = {
args: {},
export const Primary: StoryObj<typeof ReRender> = {};

export const ReRenderTest: StoryObj<typeof ReRender> = {
parameters: {
moduleMock: {
mock: () => {
const mock = createMock(message, 'getMessage');
return [mock];
},
},
},
play: async ({ canvasElement, parameters }) => {
const canvas = within(canvasElement);
expect(canvas.getByText('Test')).toBeInTheDocument();

// Re-render with new props
render(parameters, { value: 'Test2' });
await waitFor(() => {
expect(canvas.getByText('Test2')).toBeInTheDocument();
});

// Re-render with new props
render(parameters, { value: 'Test3' });
const mock = getMock(parameters, message, 'getMessage');
mock.mockReturnValue('Test1');
render(parameters);
await waitFor(() => {
expect(canvas.getByText('Test3')).toBeInTheDocument();
expect(canvas.getByText('Test1')).toBeInTheDocument();
});

// Re-render with new props
render(parameters, { value: 'Test4' });
mock.mockReturnValue('Test2');
render(parameters);
await waitFor(() => {
expect(canvas.getByText('Test4')).toBeInTheDocument();
expect(canvas.getByText('Test2')).toBeInTheDocument();
});
},
};
Expand Down
Binary file modified document/image/image01.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified document/image/image02.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "storybook-addon-module-mock",
"version": "1.3.3",
"version": "1.3.4",
"main": "./dist/cjs/index.js",
"types": "./dist/cjs/index.d.ts",
"exports": {
Expand Down
18 changes: 5 additions & 13 deletions src/mocks/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,15 +24,14 @@ const hookFn = <T, Y extends unknown[]>(hook: (fn: Mock<Y, T>) => void) => {
export const createMock: {
<
T extends { [key in N]: (...args: any[]) => unknown },
N extends keyof T = 'default' extends keyof T ? keyof T : never
N extends keyof T = 'default' extends keyof T ? keyof T : never,
>(
module: T,
name?: N
): ModuleMock<T, N>;
<T extends { [key in 'default']: (...args: any[]) => unknown }>(module: T): ModuleMock<
T,
'default'
>;
<T extends { [key in 'default']: (...args: any[]) => unknown }>(
module: T
): ModuleMock<T, 'default'>;
} = <T extends { [key in N]: (...args: any[]) => unknown }, N extends keyof T>(
module: T,
name: N = 'default' as N
Expand All @@ -52,13 +51,6 @@ export const createMock: {
fn.mockRestore = () => {
module[name] = f;
};
} else if ('$$mock$$' in module) {
const mock = (module as unknown as { $$mock$$: (name: N, value: unknown) => unknown }).$$mock$$;
const f = mock(name, fn);
original = f;
fn.mockRestore = () => {
mock(name, f);
};
} else {
throw new Error('Failed to write mock');
}
Expand All @@ -71,7 +63,7 @@ export const createMock: {

export const getOriginal = <
T extends { [key in N]: (...args: any[]) => unknown },
N extends keyof T = 'default' extends keyof T ? keyof T : never
N extends keyof T = 'default' extends keyof T ? keyof T : never,
>(
mock: ModuleMock<T, N>
): T[N] extends never ? any : T[N] => {
Expand Down

0 comments on commit baed4a0

Please sign in to comment.