Skip to content

Commit 1d8b5ea

Browse files
authored
Merge pull request #25888 from storybookjs/yann/rename-testing-utils-to-portable-stories
Maintenance: Rename testing-utils paths to portable-stories
2 parents ccb3e1a + a307dfa commit 1d8b5ea

15 files changed

+211
-331
lines changed

code/lib/preview-api/src/modules/store/csf/index.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -7,4 +7,4 @@ export * from './normalizeProjectAnnotations';
77
export * from './getValuesFromArgTypes';
88
export * from './composeConfigs';
99
export * from './stepRunners';
10-
export * from './testing-utils';
10+
export * from './portable-stories';
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,146 @@
1+
import { describe, expect, vi, it } from 'vitest';
2+
import { composeStory, composeStories } from './portable-stories';
3+
4+
// Most integration tests for this functionality are located under renderers/react
5+
describe('composeStory', () => {
6+
const meta = {
7+
title: 'Button',
8+
parameters: {
9+
firstAddon: true,
10+
},
11+
args: {
12+
label: 'Hello World',
13+
primary: true,
14+
},
15+
};
16+
17+
it('should return story with composed args and parameters', () => {
18+
const Story = () => {};
19+
Story.args = { primary: true };
20+
Story.parameters = {
21+
parameters: {
22+
secondAddon: true,
23+
},
24+
};
25+
26+
const composedStory = composeStory(Story, meta);
27+
expect(composedStory.args).toEqual({ ...Story.args, ...meta.args });
28+
expect(composedStory.parameters).toEqual(
29+
expect.objectContaining({ ...Story.parameters, ...meta.parameters })
30+
);
31+
});
32+
33+
it('should throw an error if Story is undefined', () => {
34+
expect(() => {
35+
// @ts-expect-error (invalid input)
36+
composeStory(undefined, meta);
37+
}).toThrow();
38+
});
39+
40+
describe('Id of the story', () => {
41+
it('is exposed correctly when composeStories is used', () => {
42+
const module = {
43+
default: {
44+
title: 'Example/Button',
45+
},
46+
CSF3Primary: () => {},
47+
};
48+
const Primary = composeStory(module.CSF3Primary, module.default, {});
49+
expect(Primary.id).toBe('example-button--csf-3-primary');
50+
});
51+
it('is exposed correctly when composeStory is used and exportsName is passed', () => {
52+
const module = {
53+
default: {
54+
title: 'Example/Button',
55+
},
56+
CSF3Primary: () => {},
57+
};
58+
const Primary = composeStory(module.CSF3Primary, module.default, {}, {}, 'overwritten');
59+
expect(Primary.id).toBe('example-button--overwritten');
60+
});
61+
it("is not unique when composeStory is used and exportsName isn't passed", () => {
62+
const Primary = composeStory({ render: () => {} }, {});
63+
expect(Primary.id).toContain('unknown');
64+
});
65+
});
66+
});
67+
68+
describe('composeStories', () => {
69+
const composeStoryFn = vi.fn((v) => v);
70+
const defaultAnnotations = { render: () => '' };
71+
it('should call composeStoryFn with stories', () => {
72+
const composeStorySpy = vi.fn((v) => v);
73+
const module = {
74+
default: {
75+
title: 'Button',
76+
},
77+
StoryOne: () => {},
78+
StoryTwo: () => {},
79+
};
80+
const globalConfig = {};
81+
composeStories(module, globalConfig, composeStorySpy);
82+
expect(composeStorySpy).toHaveBeenCalledWith(
83+
module.StoryOne,
84+
module.default,
85+
globalConfig,
86+
'StoryOne'
87+
);
88+
expect(composeStorySpy).toHaveBeenCalledWith(
89+
module.StoryTwo,
90+
module.default,
91+
globalConfig,
92+
'StoryTwo'
93+
);
94+
});
95+
96+
it('should not call composeStoryFn for non-story exports', () => {
97+
const composeStorySpy = vi.fn((v) => v);
98+
const module = {
99+
default: {
100+
title: 'Button',
101+
excludeStories: /Data/,
102+
},
103+
mockData: {},
104+
};
105+
composeStories(module, defaultAnnotations, composeStoryFn);
106+
expect(composeStorySpy).not.toHaveBeenCalled();
107+
});
108+
109+
describe('non-story exports', () => {
110+
it('should filter non-story exports with excludeStories', () => {
111+
const StoryModuleWithNonStoryExports = {
112+
default: {
113+
title: 'Some/Component',
114+
excludeStories: /.*Data/,
115+
},
116+
LegitimateStory: () => 'hello world',
117+
mockData: {},
118+
};
119+
120+
const result = composeStories(
121+
StoryModuleWithNonStoryExports,
122+
defaultAnnotations,
123+
composeStoryFn
124+
);
125+
expect(Object.keys(result)).not.toContain('mockData');
126+
});
127+
128+
it('should filter non-story exports with includeStories', () => {
129+
const StoryModuleWithNonStoryExports = {
130+
default: {
131+
title: 'Some/Component',
132+
includeStories: /.*Story/,
133+
},
134+
LegitimateStory: () => 'hello world',
135+
mockData: {},
136+
};
137+
138+
const result = composeStories(
139+
StoryModuleWithNonStoryExports,
140+
defaultAnnotations,
141+
composeStoryFn
142+
);
143+
expect(Object.keys(result)).not.toContain('mockData');
144+
});
145+
});
146+
});

code/lib/preview-api/src/modules/store/csf/testing-utils/index.ts code/lib/preview-api/src/modules/store/csf/portable-stories.ts

+6-6
Original file line numberDiff line numberDiff line change
@@ -15,12 +15,12 @@ import type {
1515
} from '@storybook/types';
1616

1717
import { HooksContext } from '../../../addons';
18-
import { composeConfigs } from '../composeConfigs';
19-
import { prepareContext, prepareStory } from '../prepareStory';
20-
import { normalizeStory } from '../normalizeStory';
21-
import { normalizeComponentAnnotations } from '../normalizeComponentAnnotations';
22-
import { getValuesFromArgTypes } from '../getValuesFromArgTypes';
23-
import { normalizeProjectAnnotations } from '../normalizeProjectAnnotations';
18+
import { composeConfigs } from './composeConfigs';
19+
import { prepareContext, prepareStory } from './prepareStory';
20+
import { normalizeStory } from './normalizeStory';
21+
import { normalizeComponentAnnotations } from './normalizeComponentAnnotations';
22+
import { getValuesFromArgTypes } from './getValuesFromArgTypes';
23+
import { normalizeProjectAnnotations } from './normalizeProjectAnnotations';
2424

2525
let GLOBAL_STORYBOOK_PROJECT_ANNOTATIONS = composeConfigs([]);
2626

code/lib/preview-api/src/modules/store/csf/testing-utils/index.test.ts

-79
This file was deleted.

code/renderers/react/src/__test__/internals.test.tsx

-117
This file was deleted.

0 commit comments

Comments
 (0)