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(storybook): dont generate stories for stories #10570

Merged
merged 1 commit into from
Jun 3, 2022
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.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
13 changes: 12 additions & 1 deletion packages/react-native/src/generators/stories/stories.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import {
containsComponentDeclaration,
projectRootPath,
} from '@nrwl/react/src/generators/stories/stories';
import { isTheFileAStory } from '@nrwl/storybook/src/utils/utilities';

export async function createAllStories(tree: Tree, projectName: string) {
const projects = getProjects(tree);
Expand All @@ -27,7 +28,17 @@ export async function createAllStories(tree: Tree, projectName: string) {
(path.endsWith('.js') && !path.endsWith('.spec.js')) ||
(path.endsWith('.jsx') && !path.endsWith('.spec.jsx'))
) {
componentPaths.push(path);
// Check if file is NOT a story (either ts/tsx or js/jsx)
if (!isTheFileAStory(tree, path)) {
// Since the file is not a story
// Let's see if the .stories.* file exists
const ext = path.slice(path.lastIndexOf('.'));
const storyPath = `${path.split(ext)[0]}.stories${ext}`;

if (!tree.exists(storyPath)) {
componentPaths.push(path);
}
}
}
});

Expand Down
9 changes: 7 additions & 2 deletions packages/react/src/generators/stories/stories-app.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,10 @@ describe('react:stories for applications', () => {

it('should not update existing stories', async () => {
// ARRANGE
appTree.write('apps/test-ui-app/src/app/nx-welcome.stories.tsx', '');
appTree.write(
'apps/test-ui-app/src/app/nx-welcome.stories.tsx',
`import { ComponentStory, ComponentMeta } from '@storybook/react'`
);

// ACT
await storiesGenerator(appTree, {
Expand All @@ -99,7 +102,9 @@ describe('react:stories for applications', () => {
// ASSERT
expect(
appTree.read('apps/test-ui-app/src/app/nx-welcome.stories.tsx', 'utf-8')
).toEqual('');
).toEqual(
`import { ComponentStory, ComponentMeta } from '@storybook/react'`
);
});
});

Expand Down
16 changes: 11 additions & 5 deletions packages/react/src/generators/stories/stories.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import {
visitNotIgnoredFiles,
} from '@nrwl/devkit';
import { join } from 'path';
import { isTheFileAStory } from '@nrwl/storybook/src/utils/utilities';

export interface StorybookStoriesSchema {
project: string;
Expand Down Expand Up @@ -82,11 +83,16 @@ export async function createAllStories(
(path.endsWith('.js') && !path.endsWith('.spec.js')) ||
(path.endsWith('.jsx') && !path.endsWith('.spec.jsx'))
) {
const ext = path.slice(path.lastIndexOf('.'));
const storyPath = `${path.split(ext)[0]}.stories${ext}`;
// only add component if a stories file doesnt already exist
if (!tree.exists(storyPath)) {
componentPaths.push(path);
// Check if file is NOT a story (either ts/tsx or js/jsx)
if (!isTheFileAStory(tree, path)) {
// Since the file is not a story
// Let's see if the .stories.* file exists
const ext = path.slice(path.lastIndexOf('.'));
const storyPath = `${path.split(ext)[0]}.stories${ext}`;

if (!tree.exists(storyPath)) {
componentPaths.push(path);
}
}
}
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import {
ChangeType,
} from '@nrwl/devkit';
import { findNodes } from '@nrwl/workspace/src/utilities/typescript/find-nodes';
import { getTsSourceFile } from '../../utils/utilities';
import ts = require('typescript');

let needsInstall = false;
Expand Down Expand Up @@ -134,22 +135,6 @@ function editRootMainJs(tree: Tree) {
}
}

function getTsSourceFile(host: Tree, path: string): ts.SourceFile {
const buffer = host.read(path);
if (!buffer) {
throw new Error(`Could not read TS file (${path}).`);
}
const content = buffer.toString();
const source = ts.createSourceFile(
path,
content,
ts.ScriptTarget.Latest,
true
);

return source;
}

export default async function (tree: Tree) {
editRootMainJs(tree);
installAddonEssentials(tree);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,14 +10,12 @@ import { findNodes } from '@nrwl/workspace/src/utils/ast-utils';
import * as ts from 'typescript';
import { SyntaxKind } from 'typescript';
import { nxVersion } from '../../../utils/versions';
import {
getTsSourceFile,
migrateStoriesTo62Generator,
} from './migrate-stories-to-6-2';
import { migrateStoriesTo62Generator } from './migrate-stories-to-6-2';
import {
overrideCollectionResolutionForTesting,
wrapAngularDevkitSchematic,
} from '@nrwl/devkit/ngcli-adapter';
import { getTsSourceFile } from '@nrwl/storybook/src/utils/utilities';

const componentSchematic = wrapAngularDevkitSchematic(
'@schematics/angular',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import {
Tree,
visitNotIgnoredFiles,
} from '@nrwl/devkit';
import { getTsSourceFile } from '@nrwl/storybook/src/utils/utilities';
import { fileExists } from '@nrwl/workspace/src/utilities/fileutils';
import { findNodes } from '@nrwl/workspace/src/utilities/typescript/find-nodes';
import { join, normalize } from 'path';
Expand Down Expand Up @@ -281,22 +282,6 @@ function findAllComponentsWithStoriesForSpecificProject(
return componentFileInfos;
}

export function getTsSourceFile(host: Tree, path: string): ts.SourceFile {
const buffer = host.read(path);
if (!buffer) {
throw new Error(`Could not read TS file (${path}).`);
}
const content = buffer.toString();
const source = ts.createSourceFile(
path,
content,
ts.ScriptTarget.Latest,
true
);

return source;
}

async function changeSyntaxOfStory(tree: Tree, storyFilePath: string) {
const file = getTsSourceFile(tree, storyFilePath);
const appFileContent = tree.read(storyFilePath, 'utf-8');
Expand Down
199 changes: 199 additions & 0 deletions packages/storybook/src/utils/utilities.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,199 @@
import { joinPathFragments, Tree, writeJson } from '@nrwl/devkit';
import {
overrideCollectionResolutionForTesting,
wrapAngularDevkitSchematic,
} from '@nrwl/devkit/ngcli-adapter';
import { createTreeWithEmptyWorkspace } from '@nrwl/devkit/testing';
import { isTheFileAStory } from './utilities';
import { nxVersion, storybookVersion } from './versions';

const componentSchematic = wrapAngularDevkitSchematic(
'@schematics/angular',
'component'
);
const runAngularLibrarySchematic = wrapAngularDevkitSchematic(
'@schematics/angular',
'library'
);
const runAngularStorybookSchematic = wrapAngularDevkitSchematic(
'@nrwl/angular',
'storybook-configuration'
);

describe('testing utilities', () => {
let appTree: Tree;

beforeEach(async () => {
overrideCollectionResolutionForTesting({
'@nrwl/storybook': joinPathFragments(
__dirname,
'../../../../generators.json'
),
});

appTree = createTreeWithEmptyWorkspace();

await runAngularLibrarySchematic(appTree, {
name: 'test-ui-lib',
});

await componentSchematic(appTree, {
name: 'button',
project: 'test-ui-lib',
});

writeJson(appTree, 'package.json', {
devDependencies: {
'@nrwl/storybook': nxVersion,
'@storybook/addon-knobs': storybookVersion,
'@storybook/angular': storybookVersion,
},
});
writeJson(appTree, 'test-ui-lib/tsconfig.json', {});

await runAngularStorybookSchematic(appTree, {
name: 'test-ui-lib',
configureCypress: true,
});

appTree.write(
`test-ui-lib/src/lib/button/button.component.stories.ts`,
`
import { Story, Meta } from '@storybook/react';
import { Button } from './button';

export default {
component: Button,
title: 'Button',
} as Meta;

const Template: Story = (args) => <Button {...args} />;

export const Primary = Template.bind({});
Primary.args = {};
`
);

appTree.write(
`test-ui-lib/src/lib/button/button.component.other.ts`,
`
import { Button } from './button';

// test test
`
);

appTree.write(
`test-ui-lib/src/lib/button/button.component.react-native.ts`,
`
import { storiesOf } from '@storybook/react-native';

// test test
`
);

appTree.write(
`test-ui-lib/src/lib/button/button.component.new-syntax.ts`,
`
import { ComponentStory } from '@storybook/react';

// test test
`
);

appTree.write(
`test-ui-lib/src/lib/button/button.component.stories.jsx`,
`
var test = 1;
// test test
`
);

appTree.write(
`test-ui-lib/src/lib/button/button.component.stories.js`,
`
var test = 1;
// test test
`
);
appTree.write(
`test-ui-lib/src/lib/button/button.component.js`,
`
var test = 1;
// test test
`
);
appTree.write(
`test-ui-lib/src/lib/button/button.component.jsx`,
`
var test = 1;
// test test
`
);
});

describe('typescript files', () => {
it('should verify it is story', () => {
const fileIsStory = isTheFileAStory(
appTree,
'test-ui-lib/src/lib/button/button.component.stories.ts'
);
expect(fileIsStory).toBeTruthy();
});

it('should verify it is story for ReactNative', () => {
const fileIsStory = isTheFileAStory(
appTree,
'test-ui-lib/src/lib/button/button.component.react-native.ts'
);
expect(fileIsStory).toBeTruthy();
});

it('should verify it is story for new Syntax', () => {
const fileIsStory = isTheFileAStory(
appTree,
'test-ui-lib/src/lib/button/button.component.new-syntax.ts'
);
expect(fileIsStory).toBeTruthy();
});

it('should verify it is not a story', () => {
const fileIsStory = isTheFileAStory(
appTree,
'test-ui-lib/src/lib/button/button.component.other.ts'
);
expect(fileIsStory).toBeFalsy();
});
});

describe('javascript files', () => {
it('should verify it is story if it ends in .stories.jsx', () => {
const fileIsStory = isTheFileAStory(
appTree,
'test-ui-lib/src/lib/button/button.component.stories.jsx'
);
expect(fileIsStory).toBeTruthy();
});
it('should verify it is story if it ends in .stories.js', () => {
const fileIsStory = isTheFileAStory(
appTree,
'test-ui-lib/src/lib/button/button.component.stories.js'
);
expect(fileIsStory).toBeTruthy();
});
it('should verify it is NOT a story if it does NOT end in .stories.jsx', () => {
const fileIsStory = isTheFileAStory(
appTree,
'test-ui-lib/src/lib/button/button.component.jsx'
);
expect(fileIsStory).toBeFalsy();
});
it('should verify it is NOT a story if it does NOT end in .stories.js', () => {
const fileIsStory = isTheFileAStory(
appTree,
'test-ui-lib/src/lib/button/button.component.js'
);
expect(fileIsStory).toBeFalsy();
});
});
});