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

fix(tools): removes global leaks to userLogs and adds additional noti… #18452

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
53 changes: 52 additions & 1 deletion tools/generators/migrate-converged-pkg/index.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import {
addProjectConfiguration,
readWorkspaceConfiguration,
updateJson,
logger,
} from '@nrwl/devkit';
import { serializeJson, stringUtils } from '@nrwl/workspace';

Expand All @@ -16,10 +17,21 @@ import generator from './index';
import { MigrateConvergedPkgGeneratorSchema } from './schema';

describe('migrate-converged-pkg generator', () => {
// eslint-disable-next-line @typescript-eslint/no-empty-function
const noop = () => {};
const originalConsoleLog = {
log: console.log,
warn: console.warn,
};
console.log = noop;
console.warn = noop;

let tree: Tree;
const options: MigrateConvergedPkgGeneratorSchema = { name: '@proj/react-dummy' };

beforeEach(() => {
jest.restoreAllMocks();

tree = createTreeWithEmptyWorkspace();
tree.write(
'jest.config.js',
Expand All @@ -40,6 +52,11 @@ describe('migrate-converged-pkg generator', () => {
});
});

afterAll(() => {
console.log = originalConsoleLog.log;
console.warn = originalConsoleLog.warn;
});

describe('general', () => {
it(`should throw error if name is empty`, async () => {
await expect(generator(tree, { name: '' })).rejects.toMatchInlineSnapshot(
Expand Down Expand Up @@ -342,17 +359,51 @@ describe('migrate-converged-pkg generator', () => {
};
}

it(`should work if there are no package stories in react-examples`, async () => {
const reactExamplesConfig = readProjectConfiguration(tree, '@proj/react-examples');
const workspaceConfig = readWorkspaceConfiguration(tree);

expect(
tree.exists(`${reactExamplesConfig.root}/src/${options.name.replace(`@${workspaceConfig.npmScope}/`, '')}`),
).toBe(false);

const loggerWarnSpy = jest.spyOn(logger, 'warn');
let sideEffectsCallback: () => void;

try {
sideEffectsCallback = await generator(tree, options);
sideEffectsCallback();
} catch (err) {
expect(err).toEqual(undefined);
}

expect(loggerWarnSpy).toHaveBeenCalledTimes(1);
expect(loggerWarnSpy).toHaveBeenCalledWith(
'No package stories found within react-examples. Skipping storybook stories migration...',
);
});

it(`should move stories from react-examples package to local package within sourceRoot`, async () => {
const { pathToStoriesWithinReactExamples, getMovedStoriesData } = setup();

const loggerWarnSpy = jest.spyOn(logger, 'warn');

expect(tree.exists(pathToStoriesWithinReactExamples)).toBeTruthy();

await generator(tree, options);
const sideEffectsCallback = await generator(tree, options);

const { movedStoriesPaths } = getMovedStoriesData();

expect(tree.exists(movedStoriesPaths.storyOne)).toBe(true);
expect(tree.exists(movedStoriesPaths.storyTwo)).toBe(true);

sideEffectsCallback();

expect(loggerWarnSpy).toHaveBeenCalledTimes(2);
expect(loggerWarnSpy.mock.calls[0][0]).toEqual('NOTE: Deleting packages/react-examples/src/react-dummy');
expect(loggerWarnSpy.mock.calls[1][0]).toEqual(
expect.stringContaining('- Please update your moved stories to follow standard storybook format'),
);
});

it(`should delete migrated package folder in react-examples`, async () => {
Expand Down
28 changes: 21 additions & 7 deletions tools/generators/migrate-converged-pkg/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,10 @@ import { MigrateConvergedPkgGeneratorSchema } from './schema';

interface NormalizedSchema extends ReturnType<typeof normalizeOptions> {}

type UserLog = Array<{ type: keyof typeof logger; message: string }>;

export default async function (tree: Tree, schema: MigrateConvergedPkgGeneratorSchema) {
const userLog: UserLog = [];
validateUserInput(tree, schema);

const options = normalizeOptions(tree, schema);
Expand All @@ -48,8 +51,8 @@ export default async function (tree: Tree, schema: MigrateConvergedPkgGeneratorS
setupStorybook(tree, options);

// 4. move stories to package
moveStorybookFromReactExamples(tree, options);
removeMigratedPackageFromReactExamples(tree, options);
moveStorybookFromReactExamples(tree, options, userLog);
removeMigratedPackageFromReactExamples(tree, options, userLog);

// 5. update package npm scripts
updateNpmScripts(tree, options);
Expand All @@ -62,8 +65,6 @@ export default async function (tree: Tree, schema: MigrateConvergedPkgGeneratorS
};
}

const userLog: Array<{ type: keyof typeof logger; message: string }> = [];

// ==== helpers ====

const templates = {
Expand Down Expand Up @@ -229,7 +230,7 @@ function setupStorybook(tree: Tree, options: NormalizedSchema) {
return tree;
}

function moveStorybookFromReactExamples(tree: Tree, options: NormalizedSchema) {
function moveStorybookFromReactExamples(tree: Tree, options: NormalizedSchema, userLog: UserLog) {
const reactExamplesConfig = getReactExamplesProjectConfig(tree, options);
const pathToStoriesWithinReactExamples = `${reactExamplesConfig.root}/src/${options.normalizedPkgName}`;

Expand All @@ -241,6 +242,15 @@ function moveStorybookFromReactExamples(tree: Tree, options: NormalizedSchema) {
}
});

if (storyPaths.length === 0) {
userLog.push({
type: 'warn',
message: 'No package stories found within react-examples. Skipping storybook stories migration...',
});

return tree;
}

storyPaths.forEach(originPath => {
const pathSegments = splitPathFragments(originPath);
const fileName = pathSegments[pathSegments.length - 1];
Expand Down Expand Up @@ -274,14 +284,18 @@ function getReactExamplesProjectConfig(tree: Tree, options: NormalizedSchema) {
return readProjectConfiguration(tree, `@${options.workspaceConfig.npmScope}/react-examples`);
}

function removeMigratedPackageFromReactExamples(tree: Tree, options: NormalizedSchema) {
function removeMigratedPackageFromReactExamples(tree: Tree, options: NormalizedSchema, userLog: UserLog) {
const reactExamplesConfig = getReactExamplesProjectConfig(tree, options);

const paths = {
packageStoriesWithinReactExamples: `${reactExamplesConfig.root}/src/${options.normalizedPkgName}`,
packageJson: `${reactExamplesConfig.root}/package.json`,
};

if (!tree.exists(paths.packageStoriesWithinReactExamples)) {
return tree;
}

tree.delete(paths.packageStoriesWithinReactExamples);

userLog.push(
Expand Down Expand Up @@ -342,7 +356,7 @@ function updatedBaseTsConfig(tree: Tree, options: NormalizedSchema) {
});
}

function printUserLogs(logs: typeof userLog) {
function printUserLogs(logs: UserLog) {
logger.log(`${'='.repeat(80)}\n`);

logs.forEach(log => logger[log.type](log.message));
Expand Down