Skip to content

Commit

Permalink
fix(storybook): dont generate stories for stories (#10570)
Browse files Browse the repository at this point in the history
ISSUES CLOSED: #10286
  • Loading branch information
mandarini committed Jun 3, 2022
1 parent 62b55d4 commit d48a709
Show file tree
Hide file tree
Showing 8 changed files with 294 additions and 44 deletions.
13 changes: 12 additions & 1 deletion packages/react-native/src/generators/stories/stories.ts
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
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
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
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
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
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
@@ -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();
});
});
});

0 comments on commit d48a709

Please sign in to comment.