1 | const path = require('path');
|
2 | const { writeRequires, getMain, getPreviewExists } = require('./loader');
|
3 |
|
4 | let pathMock;
|
5 | let fileContentMock;
|
6 |
|
7 | jest.mock('fs', () => ({
|
8 | ...jest.requireActual('fs'),
|
9 | writeFileSync: (filePath, fileContent, opts) => {
|
10 | pathMock = filePath;
|
11 | fileContentMock = fileContent;
|
12 | },
|
13 | }));
|
14 |
|
15 | jest.mock('prettier', () => ({
|
16 | format(s, opts) {
|
17 | return s;
|
18 | },
|
19 | }));
|
20 |
|
21 | describe('loader', () => {
|
22 | describe('getMain', () => {
|
23 | it('should return the main js default export as an object', () => {
|
24 | const main = getMain({ configPath: path.resolve(__dirname, 'mocks/all-config-files') });
|
25 | expect(main).toEqual({
|
26 | stories: ['./FakeStory.stories.tsx'],
|
27 | addons: [
|
28 | '@storybook/addon-ondevice-notes',
|
29 | '@storybook/addon-ondevice-controls',
|
30 | '@storybook/addon-ondevice-backgrounds',
|
31 | '@storybook/addon-ondevice-actions',
|
32 | ],
|
33 | });
|
34 | });
|
35 |
|
36 | it('should also work with relative paths', () => {
|
37 |
|
38 | const main = getMain({ configPath: './scripts/mocks/all-config-files' });
|
39 | expect(main).toEqual({
|
40 | stories: ['./FakeStory.stories.tsx'],
|
41 | addons: [
|
42 | '@storybook/addon-ondevice-notes',
|
43 | '@storybook/addon-ondevice-controls',
|
44 | '@storybook/addon-ondevice-backgrounds',
|
45 | '@storybook/addon-ondevice-actions',
|
46 | ],
|
47 | });
|
48 | });
|
49 | it('should work for any supported file extension', () => {
|
50 | const main = getMain({ configPath: './scripts/mocks/file-extensions' });
|
51 | expect(main).toEqual({
|
52 | stories: ['./FakeStory.stories.tsx'],
|
53 | addons: [
|
54 | '@storybook/addon-ondevice-notes',
|
55 | '@storybook/addon-ondevice-controls',
|
56 | '@storybook/addon-ondevice-backgrounds',
|
57 | '@storybook/addon-ondevice-actions',
|
58 | ],
|
59 | });
|
60 | });
|
61 | });
|
62 |
|
63 | describe('getPreviewExists', () => {
|
64 | const supportedExtensions = ['js', 'jsx', 'ts', 'tsx'];
|
65 | describe('when using a relative path', () => {
|
66 | it('should return true if the preview exists', () => {
|
67 | supportedExtensions.forEach((ext) => {
|
68 | expect(getPreviewExists({ configPath: `scripts/mocks/preview-files/${ext}` })).toBe(true);
|
69 | });
|
70 | });
|
71 |
|
72 | it('should return false if the preview does not exist', () => {
|
73 | expect(getPreviewExists({ configPath: './scripts/mocks/no-preview' })).toBe(false);
|
74 | });
|
75 |
|
76 | it('should return false if the preview does not match any of supportedExtensions values', () => {
|
77 | expect(getPreviewExists({ configPath: './scripts/mocks/wrong-extension-preview' })).toBe(
|
78 | false
|
79 | );
|
80 | });
|
81 | });
|
82 |
|
83 | describe('when using an absolute path', () => {
|
84 | it('should return true if the preview exists', () => {
|
85 | supportedExtensions.forEach((ext) => {
|
86 | expect(
|
87 | getPreviewExists({
|
88 | configPath: path.resolve(__dirname, `mocks/preview-files/${ext}`),
|
89 | })
|
90 | ).toBe(true);
|
91 | });
|
92 | });
|
93 |
|
94 | it('should return false if the preview does not exist', () => {
|
95 | expect(getPreviewExists({ configPath: path.resolve(__dirname, 'mocks/no-preview') })).toBe(
|
96 | false
|
97 | );
|
98 | });
|
99 |
|
100 | it('should return false if the preview does not match any of supportedExtensions values', () => {
|
101 | expect(
|
102 | getPreviewExists({ configPath: path.resolve(__dirname, 'mocks/wrong-extension-preview') })
|
103 | ).toBe(false);
|
104 | });
|
105 | });
|
106 | });
|
107 |
|
108 | describe('writeRequires', () => {
|
109 | describe('when there is a story glob', () => {
|
110 | it('writes the story imports', () => {
|
111 | writeRequires({ configPath: 'scripts/mocks/all-config-files' });
|
112 | expect(pathMock).toEqual(
|
113 | path.resolve(__dirname, 'mocks/all-config-files/storybook.requires.js')
|
114 | );
|
115 | expect(fileContentMock).toMatchSnapshot();
|
116 | });
|
117 | });
|
118 |
|
119 | describe('when there are different file extensions', () => {
|
120 | it('writes the story imports', () => {
|
121 | writeRequires({ configPath: 'scripts/mocks/file-extensions' });
|
122 | expect(pathMock).toEqual(
|
123 | path.resolve(__dirname, 'mocks/file-extensions/storybook.requires.js')
|
124 | );
|
125 | expect(fileContentMock).toMatchSnapshot();
|
126 | });
|
127 | });
|
128 |
|
129 | describe('when there is a story glob and exclude paths globs', () => {
|
130 | it('writes the story imports', () => {
|
131 | writeRequires({ configPath: 'scripts/mocks/exclude-config-files' });
|
132 | expect(pathMock).toEqual(
|
133 | path.resolve(__dirname, 'mocks/exclude-config-files/storybook.requires.js')
|
134 | );
|
135 |
|
136 | expect(fileContentMock).toContain('include-components/FakeStory.stories.tsx');
|
137 | expect(fileContentMock).not.toContain('exclude-components/FakeStory.stories.tsx');
|
138 |
|
139 | expect(fileContentMock).toMatchSnapshot();
|
140 | });
|
141 | });
|
142 |
|
143 | describe('when there is no story glob or addons', () => {
|
144 | it('throws an error', () => {
|
145 | expect(() => writeRequires({ configPath: 'scripts/mocks/blank-config' })).toThrow();
|
146 | });
|
147 | });
|
148 |
|
149 | describe('when there is no preview', () => {
|
150 | it('does not add preview related stuff', () => {
|
151 | writeRequires({ configPath: 'scripts/mocks/no-preview' });
|
152 | expect(pathMock).toEqual(path.resolve(__dirname, 'mocks/no-preview/storybook.requires.js'));
|
153 | expect(fileContentMock).toMatchSnapshot();
|
154 | });
|
155 | });
|
156 |
|
157 | describe('when the absolute option is true', () => {
|
158 | it('should write absolute paths to the requires file', () => {
|
159 | writeRequires({ configPath: 'scripts/mocks/all-config-files', absolute: true });
|
160 | expect(pathMock).toEqual(
|
161 | path.resolve(__dirname, 'mocks/all-config-files/storybook.requires.js')
|
162 | );
|
163 | expect(fileContentMock).toContain(
|
164 | path.resolve(__dirname, 'mocks/all-config-files/FakeStory.stories.tsx')
|
165 | );
|
166 | });
|
167 | });
|
168 |
|
169 | describe('when there is a configuration object', () => {
|
170 | it('writes the story imports', () => {
|
171 | writeRequires({ configPath: 'scripts/mocks/configuration-objects' });
|
172 | expect(pathMock).toEqual(
|
173 | path.resolve(__dirname, 'mocks/configuration-objects/storybook.requires.js')
|
174 | );
|
175 | expect(fileContentMock).toMatchSnapshot();
|
176 | });
|
177 | });
|
178 | });
|
179 | });
|