add tests & fix some review comments

This commit is contained in:
Norbert de Langen 2024-02-07 13:15:14 +01:00
parent 923deb76b1
commit aeac06751f
4 changed files with 128 additions and 10 deletions

View File

@ -1,7 +1,7 @@
import { relative } from 'path';
import { createBlocker } from './types';
import { dedent } from 'ts-dedent';
import type { StorybookConfigRaw } from 'lib/types/src';
import type { StorybookConfigRaw } from '@storybook/types';
export const blocker = createBlocker({
id: 'storyStoreV7removal',
@ -17,18 +17,18 @@ export const blocker = createBlocker({
},
message(options, data) {
const mainConfigPath = relative(process.cwd(), options.mainConfigPath);
return `StoryStoreV7 feature most be removed from ${mainConfigPath}`;
return `StoryStoreV7 feature must be removed from ${mainConfigPath}`;
},
log() {
return dedent`
StoryStoreV7 feature most be removed from your Storybook configuration.
StoryStoreV7 feature must be removed from your Storybook configuration.
This feature was removed in Storybook 7.0.0.
Please see the migration guide for more information:
https://github.com/storybookjs/storybook/blob/next/MIGRATION.md#story-store-v7
In your Storybook configuration file you have this code:
module.exports = {
export default = {
features: {
storyStoreV7: false, <--- remove this line
},

View File

@ -0,0 +1,109 @@
import { expect, test, vi } from 'vitest';
import { autoblock } from './index';
import { JsPackageManagerFactory } from '@storybook/core-common';
import { createBlocker } from './types';
import { writeFile as writeFileRaw } from 'node:fs/promises';
import { logger } from '@storybook/node-logger';
vi.mock('node:fs/promises', () => ({
writeFile: vi.fn(),
}));
vi.mock('boxen', () => ({
default: vi.fn((x) => x),
}));
vi.mock('@storybook/node-logger', () => ({
logger: {
info: vi.fn(),
line: vi.fn(),
plain: vi.fn(),
},
}));
const writeFile = vi.mocked(writeFileRaw);
const blockers = {
alwaysPass: createBlocker({
id: 'alwaysPass',
check: async () => false,
message: () => 'Always pass',
log: () => 'Always pass',
}),
alwaysFail: createBlocker({
id: 'alwaysFail',
check: async () => ({ bad: true }),
message: () => 'Always fail',
log: () => '...',
}),
alwaysFail2: createBlocker({
id: 'alwaysFail2',
check: async () => ({ disaster: true }),
message: () => 'Always fail 2',
log: () => '...',
}),
} as const;
const baseOptions: Parameters<typeof autoblock>[0] = {
configDir: '.storybook',
mainConfig: {
stories: [],
},
mainConfigPath: '.storybook/main.ts',
packageJson: {
dependencies: {},
devDependencies: {},
},
packageManager: JsPackageManagerFactory.getPackageManager({ force: 'npm' }),
};
test('with empty list', async () => {
const result = await autoblock({ ...baseOptions }, []);
expect(result).toBe(null);
expect(logger.plain).not.toHaveBeenCalledWith(expect.stringContaining('No blockers found'));
});
test('all passing', async () => {
const result = await autoblock({ ...baseOptions }, [
Promise.resolve({ blocker: blockers.alwaysPass }),
Promise.resolve({ blocker: blockers.alwaysPass }),
]);
expect(result).toBe(null);
expect(logger.plain).toHaveBeenCalledWith(expect.stringContaining('No blockers found'));
});
test('1 fail', async () => {
const result = await autoblock({ ...baseOptions }, [
Promise.resolve({ blocker: blockers.alwaysPass }),
Promise.resolve({ blocker: blockers.alwaysFail }),
]);
expect(writeFile).toHaveBeenCalledWith(
expect.any(String),
expect.stringContaining('alwaysFail'),
expect.any(Object)
);
expect(result).toBe('alwaysFail');
expect(logger.plain).toHaveBeenCalledWith(expect.stringContaining('Oh no..'));
expect(writeFile.mock.calls[0][1]).toMatchInlineSnapshot(`
"(alwaysFail):
..."
`);
});
test('multiple fails', async () => {
const result = await autoblock({ ...baseOptions }, [
Promise.resolve({ blocker: blockers.alwaysPass }),
Promise.resolve({ blocker: blockers.alwaysFail }),
Promise.resolve({ blocker: blockers.alwaysFail2 }),
]);
expect(writeFile.mock.calls[0][1]).toMatchInlineSnapshot(`
"(alwaysFail):
...
----
(alwaysFail2):
..."
`);
expect(result).toBe('alwaysFail');
});

View File

@ -1,21 +1,30 @@
import type { AutoblockOptions } from './types';
import type { AutoblockOptions, Blocker } from './types';
import { logger } from '@storybook/node-logger';
import chalk from 'chalk';
import boxen from 'boxen';
import { writeFile } from 'fs/promises';
import { writeFile } from 'node:fs/promises';
const excludesFalse = <T>(x: T | false): x is T => x !== false;
const blockers = [
const blockers: () => BlockerModule<any>[] = () => [
// add/remove blockers here
import('./block-storystorev6'),
];
export const autoblock = async (options: AutoblockOptions) => {
type BlockerModule<T> = Promise<{ blocker: Blocker<T> }>;
export const autoblock = async (
options: AutoblockOptions,
list: BlockerModule<any>[] = blockers()
) => {
if (list.length === 0) {
return null;
}
logger.info('Checking for upgrade blockers...');
const out = await Promise.all(
blockers.map(async (i) => {
list.map(async (i) => {
const { blocker } = await i;
const result = await blocker.check(options);
if (result) {

View File

@ -300,7 +300,7 @@ export const doUpgrade = async ({
function missingStorybookVersionMessage(): string {
return dedent`
[Storybook automigrate] Unable to determine storybook version so the automigrations will be skipped.
[Storybook automigrate] Unable to determine Storybook version so that the automigrations will be skipped.
🤔 Are you running automigrate from your project directory? Please specify your Storybook config directory with the --config-dir flag.
`;
}