Skip to content

Commit

Permalink
feat: generate tests by story
Browse files Browse the repository at this point in the history
  • Loading branch information
atanasster committed Apr 2, 2021
1 parent 3c0e9ad commit 5f799be
Show file tree
Hide file tree
Showing 13 changed files with 132 additions and 80 deletions.
4 changes: 3 additions & 1 deletion core/instrument/src/index.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import fs from 'fs';
import mdx from '@mdx-js/mdx';
import matter from 'gray-matter';
import { File } from '@babel/types';
Expand Down Expand Up @@ -123,10 +124,11 @@ export type ParseStoriesReturnType = { transformed: string } & Partial<
*/

export const parseStories = async (
source: string,
filePath: string,
fileSource?: string,
options?: InstrumentOptions,
): Promise<ParseStoriesReturnType> => {
const source = fileSource || fs.readFileSync(filePath, 'utf8');
const {
parser: parserOptions = {},
prettier: prettierOptions = {},
Expand Down
2 changes: 1 addition & 1 deletion core/instrument/test/loadTestFiles.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ export const fixtureToTest = (
const filePathName = path.join(folderName, fileName);
const content = fs.readFileSync(filePathName, 'utf8');
it(fileName, async () => {
const parsed = await parseStories(content, filePathName, options);
const parsed = await parseStories(filePathName, content, options);
await callback(parsed);
});
};
2 changes: 1 addition & 1 deletion core/loader/src/loader.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,8 @@ async function loader(this: WebpackLoaderContext): Promise<string> {
const options = deepmerge(configOptions, loaderOptions);

const { transformed, ...store } = await parseStories(
source,
filePath,
source,
options,
);
if (store?.doc) {
Expand Down
4 changes: 1 addition & 3 deletions plugins/cc-cli/src/cli/args.ts
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ export const jestCliArgs: ArgOptions = [
options: {
alias: 'w',
description: 'force overwrite test file',
default: true,
default: false,
type: 'boolean',
},
},
Expand All @@ -66,7 +66,6 @@ export const jestCliArgs: ArgOptions = [
alias: 't',
description: 'tests file name',
type: 'string',
default: 'stories.test.js',
},
},
{
Expand All @@ -75,7 +74,6 @@ export const jestCliArgs: ArgOptions = [
alias: 'n',
description: 'name of the test group (describe)',
type: 'string',
default: 'component-controls generated',
},
},
];
6 changes: 3 additions & 3 deletions plugins/cc-cli/src/cli/cli-store.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,18 +2,18 @@ import { CliOptions } from './types';
import { saveTemplate } from './save-template';
import { createStoreTemplate } from '../store-template';

export const cliStore = (options: CliOptions): void => {
export const cliStore = async (options: CliOptions): Promise<void> => {
const {
renderer,
format,
overwrite,
config,
test = 'stories.test.js',
bundle,
name,
name = 'component-controls generated',
output = 'tests',
} = options;
return saveTemplate(
return await saveTemplate(
{
renderer,
format,
Expand Down
84 changes: 63 additions & 21 deletions plugins/cc-cli/src/cli/cli-story.ts
Original file line number Diff line number Diff line change
@@ -1,32 +1,74 @@
import { StoryTemplateOptions } from '../types';
import path from 'path';
import { loadConfig, extractDocuments } from '@component-controls/config';
import { loadStore } from '@component-controls/store';
import { StoryTemplateOptions, TeplateFormats } from '../types';
import { CliOptions } from './types';
import { saveTemplate } from './save-template';
import { createStoriesTemplate } from '../stories-template';

export const cliStory = (options: CliOptions): void => {
const formatExtensions: { [key in TeplateFormats]: string } = {
cjs: '.js',
esm: '.js',
ts: '.ts',
};

export const formatExtension = (
fileName: string,
format: TeplateFormats,
): string => {
const basename = path.basename(fileName, path.extname(fileName));
const extension = formatExtensions[format];
return path.join(path.dirname(fileName), basename + extension);
};

export const cliStory = async (options: CliOptions): Promise<void> => {
const {
renderer,
format,
overwrite,
config,
test = 'stories.test.js',
config = '.config',
test,
bundle,
name,
output = 'tests',
output,
} = options;
const storyPath = '';
return saveTemplate<StoryTemplateOptions>(
{
renderer,
format,
overwrite,
config,
test,
bundle,
name,
output,
storyPath,
},
createStoriesTemplate,
);
let documents: string[] = [];

if (bundle) {
const store = loadStore(require(bundle));
documents = Object.keys(store.docs).map(key => store.docs[key].title);
} else {
const configPath = path.resolve(process.cwd(), config);
const configuration = loadConfig(configPath);
if (configuration) {
documents =
extractDocuments({ config: configuration.config, configPath }) || [];
}
}
for (const name of documents) {
const basename = path.basename(name);
const splitName = basename.split('.');
const componentName = splitName[0];
const fileFormat =
format || path.extname(name).startsWith('.ts') ? 'ts' : 'esm';
const testName =
test || formatExtension(`${componentName}.test.js`, fileFormat);
await saveTemplate<StoryTemplateOptions>(
{
renderer,
format,
overwrite,
config,
test: testName,
bundle,
name: options.name || componentName,
storyPath: name,
output: output
? output
: bundle
? path.dirname(bundle)
: path.dirname(name),
},
createStoriesTemplate,
);
}
};
4 changes: 2 additions & 2 deletions plugins/cc-cli/src/cli/cli.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ export const run = async (): Promise<void> => {
} = parsedArgs;
switch (parsedArgs.generate) {
case 'store':
return cliStore({
return await cliStore({
renderer,
format,
overwrite,
Expand All @@ -30,7 +30,7 @@ export const run = async (): Promise<void> => {
output,
} as CliOptions);
case 'story':
return cliStory({
return await cliStory({
renderer,
format,
overwrite,
Expand Down
6 changes: 3 additions & 3 deletions plugins/cc-cli/src/cli/save-template.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,10 @@ import fs from 'fs';
import { CliOptions } from './types';
import { TemplateFunction, TemplateOptions } from '../types';

export const saveTemplate = <P extends TemplateOptions>(
export const saveTemplate = async <P extends TemplateOptions>(
options: CliOptions<P>,
templateFn: TemplateFunction<P>,
): void => {
): Promise<void> => {
const { test, overwrite, output, ...rest } = options;

let testFolder = output as string;
Expand All @@ -27,7 +27,7 @@ export const saveTemplate = <P extends TemplateOptions>(
);
return;
}
const content = templateFn(({
const content = await templateFn(({
output: testFolder,
...rest,
} as unknown) as P);
Expand Down
2 changes: 1 addition & 1 deletion plugins/cc-cli/src/store-template.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import { createTemplate } from './template';
dot.templateSettings.strip = false;
(dot as any).log = false;

export const createStoreTemplate: TemplateFunction = (
export const createStoreTemplate: TemplateFunction = async (
options: TemplateOptions,
) => {
const {
Expand Down
25 changes: 17 additions & 8 deletions plugins/cc-cli/src/stories-template.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import fs from 'fs';
import path from 'path';
import dot from 'dot';
import { parseStories } from '@component-controls/instrument';

import { Document } from '@component-controls/core';
import { loadStore } from '@component-controls/store';
import { createTemplate } from './template';
Expand All @@ -9,11 +11,11 @@ import { StoryTemplateOptions, renderers, TemplateFunction } from './types';
dot.templateSettings.strip = false;
(dot as any).log = false;

export const createStoriesTemplate: TemplateFunction<StoryTemplateOptions> = (
export const createStoriesTemplate: TemplateFunction<StoryTemplateOptions> = async (
options: StoryTemplateOptions,
): string => {
): Promise<string> => {
const {
storyPath,
storyPath = '',
renderer = 'rtl',
format = 'cjs',
name,
Expand Down Expand Up @@ -44,11 +46,18 @@ export const createStoriesTemplate: TemplateFunction<StoryTemplateOptions> = (
});
}
} else {
const docExports = require(storyPath);
stories = Object.keys(docExports)
.filter(key => key !== 'default')
.map(key => ({ name: key }));
doc = docExports['default'];
const { doc: storeDoc, stories: storeStories } = await parseStories(
storyPath,
);
if (storeDoc) {
doc = storeDoc;
}
if (storeStories) {
stories = Object.keys(storeStories).map(key => ({
name: storeStories[key].name,
id: key,
}));
}
}
const store = bundle ? 'bundle' : 'imports';
const storeRender = fs.readFileSync(
Expand Down
4 changes: 2 additions & 2 deletions plugins/cc-cli/src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,9 @@ export type TemplateOptions = {
};

export interface StoryTemplateOptions extends TemplateOptions {
storyPath: string;
storyPath?: string;
}

export type TemplateFunction<P extends TemplateOptions = TemplateOptions> = (
options: P,
) => string;
) => Promise<string>;
33 changes: 17 additions & 16 deletions plugins/cc-cli/test/run-store-tests.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import { Config } from '@jest/types';
import { createStoreTemplate } from '../src/store-template';
import { TemplateOptions } from '../src/types';

export const runTests = (props: TemplateOptions): void => {
export const runTests = async (props: TemplateOptions): Promise<void> => {
const { renderer, format, config, bundle } = props;
const extension = format === 'ts' ? 'ts' : 'js';
const testName = `test_${renderer}_${format}${bundle ? '_bundle' : ''}`;
Expand All @@ -14,24 +14,25 @@ export const runTests = (props: TemplateOptions): void => {
__dirname,
`__snapshots__/${testName}.test.${extension}.snap`,
);
let renderedFile = '';
it(`${renderer} ${bundle ? 'bundle' : ''} ${format}`, async () => {
try {
let renderedFile = '';

renderedFile = createStoreTemplate({
format,
renderer,
bundle,
config,
output: __dirname,
});
renderedFile = await createStoreTemplate({
format,
renderer,
bundle,
config,
output: __dirname,
});

fs.writeFileSync(testFileName, renderedFile);
if (fs.existsSync(snapshotFileName)) {
fs.unlinkSync(snapshotFileName);
}

fs.writeFileSync(testFileName, renderedFile);
if (fs.existsSync(snapshotFileName)) {
fs.unlinkSync(snapshotFileName);
}
expect(renderedFile).toMatchSnapshot();

it(`${renderer} ${bundle ? 'bundle' : ''} ${format}`, async () => {
expect(renderedFile).toMatchSnapshot();
try {
await runCLI(
{
testRegex: testName,
Expand Down
36 changes: 18 additions & 18 deletions plugins/cc-cli/test/run-story-tests.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,9 @@ import { Config } from '@jest/types';
import { createStoriesTemplate } from '../src/stories-template';
import { StoryTemplateOptions } from '../src/types';

export const runTests = (
export const runTests = async (
props: Omit<StoryTemplateOptions, 'storyPath'>,
): void => {
): Promise<void> => {
const { renderer, format, config, bundle } = props;
const extension = format === 'ts' ? 'ts' : 'js';
const testName = `story_test_${renderer}_${format}${bundle ? '_bundle' : ''}`;
Expand All @@ -16,24 +16,24 @@ export const runTests = (
__dirname,
`__snapshots__/${testName}.test.${extension}.snap`,
);
let renderedFile = '';
renderedFile = createStoriesTemplate({
storyPath: path.resolve(__dirname, 'fixtures/VariantButton.docs.tsx'),
format,
name: bundle ? 'Components/Header' : undefined,
renderer,
bundle,
config,
output: __dirname,
});

fs.writeFileSync(testFileName, renderedFile);
if (fs.existsSync(snapshotFileName)) {
fs.unlinkSync(snapshotFileName);
}
it(`${renderer} ${bundle ? 'bundle' : ''} ${format}`, async () => {
expect(renderedFile).toMatchSnapshot();
let renderedFile = '';
renderedFile = await createStoriesTemplate({
storyPath: path.resolve(__dirname, 'fixtures/VariantButton.docs.tsx'),
format,
name: bundle ? 'Components/Header' : undefined,
renderer,
bundle,
config,
output: __dirname,
});

fs.writeFileSync(testFileName, renderedFile);
if (fs.existsSync(snapshotFileName)) {
fs.unlinkSync(snapshotFileName);
}
try {
expect(renderedFile).toMatchSnapshot();
await runCLI(
{
testRegex: testName,
Expand Down

0 comments on commit 5f799be

Please sign in to comment.