Skip to content

Commit

Permalink
Merge ca0c148 into e9ed2b6
Browse files Browse the repository at this point in the history
  • Loading branch information
joeyparis committed Jul 12, 2020
2 parents e9ed2b6 + ca0c148 commit d95c3c4
Show file tree
Hide file tree
Showing 10 changed files with 393 additions and 100 deletions.
25 changes: 20 additions & 5 deletions internals/generators/component/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
* Component Generator
*/

const properCase = require('change-case').pascalCase;
const componentExists = require('../utils/componentExists');

module.exports = {
Expand All @@ -13,6 +14,9 @@ module.exports = {
message: 'What should it be called?',
default: 'Button',
validate: value => {
if( (/\/\//).test(value) ) return "A parent directory cannot have two adjacent `/`"
if( (/^\/|.+\/$/).test(value) ) return "A parent directory cannot start or end with a `/`"

if (/.+/.test(value)) {
return componentExists(value)
? 'A component or container with this name already exists'
Expand Down Expand Up @@ -43,44 +47,55 @@ module.exports = {
],
actions: data => {
// Generate index.js and index.test.js
let filePath = data.name.split('/').map(properCase)
const shortName = filePath.pop()
filePath = filePath.join('/')
const fullPath = `${filePath}/${shortName}`

const actions = [
{
type: 'add',
path: '../../app/components/{{properCase name}}/index.js',
path: `../../app/components/${fullPath}/index.js`,
templateFile: './component/index.js.hbs',
abortOnFail: true,
data: {filePath, shortName},
},
{
type: 'add',
path: '../../app/components/{{properCase name}}/tests/index.test.js',
path: `../../app/components/${fullPath}/tests/index.test.js`,
templateFile: './component/test.js.hbs',
abortOnFail: true,
data: {filePath, shortName},
},
];

// If the user wants i18n messages
if (data.wantMessages) {
actions.push({
type: 'add',
path: '../../app/components/{{properCase name}}/messages.js',
path: `../../app/components/${fullPath}/messages.js`,
templateFile: './component/messages.js.hbs',
abortOnFail: true,
data: {filePath, shortName},
});
}

// If the user wants Loadable.js to load the component asynchronously
if (data.wantLoadable) {
actions.push({
type: 'add',
path: '../../app/components/{{properCase name}}/Loadable.js',
path: `../../app/components/${fullPath}/Loadable.js`,
templateFile: './component/loadable.js.hbs',
abortOnFail: true,
data: {filePath, shortName},
});
}

actions.push({
type: 'prettify',
path: '/components/',
path: `/components${filePath ? `/${filePath}/` : '/'}`,
name: shortName,
data: {filePath, shortName},
});

return actions;
Expand Down
10 changes: 5 additions & 5 deletions internals/generators/component/index.js.hbs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/**
*
* {{ properCase name }}
* {{ filePath }}/{{ properCase shortName }}
*
*/

Expand All @@ -17,7 +17,7 @@ import { FormattedMessage } from 'react-intl';
import messages from './messages';
{{/if}}

function {{ properCase name }}() {
function {{ properCase shortName }}() {
return (
<div>
{{#if wantMessages}}
Expand All @@ -27,10 +27,10 @@ function {{ properCase name }}() {
);
}

{{ properCase name }}.propTypes = {};
{{ properCase shortName }}.propTypes = {};

{{#if memo}}
export default memo({{ properCase name }});
export default memo({{ properCase shortName }});
{{else}}
export default {{ properCase name }};
export default {{ properCase shortName }};
{{/if}}
2 changes: 1 addition & 1 deletion internals/generators/component/loadable.js.hbs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/**
*
* Asynchronously loads the component for {{ properCase name }}
* Asynchronously loads the component for {{ filePath }}/{{ properCase shortName }}
*
*/

Expand Down
4 changes: 2 additions & 2 deletions internals/generators/component/messages.js.hbs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
/*
* {{ properCase name }} Messages
* {{ filePath }}/{{ properCase shortName }} Messages
*
* This contains all the text for the {{ properCase name }} component.
* This contains all the text for the {{ properCase shortName }} component.
*/

import { defineMessages } from 'react-intl';
Expand Down
14 changes: 7 additions & 7 deletions internals/generators/component/test.js.hbs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/**
*
* Tests for {{ properCase name }}
* Tests for {{ filePath }}/{{ properCase shortName }}
*
* @see https://github.com/react-boilerplate/react-boilerplate/tree/master/docs/testing
*
Expand All @@ -12,22 +12,22 @@ import { render } from '@testing-library/react';
import { IntlProvider } from 'react-intl';
{{/if}}

import {{ properCase name }} from '../index';
import {{ properCase shortName }} from '../index';
{{#if wantMessages}}
import { DEFAULT_LOCALE } from '../../../locales';
{{/if}}

describe('<{{ properCase name }} />', () => {
describe('<{{ properCase shortName }} />', () => {
it('Expect to not log errors in console', () => {
const spy = jest.spyOn(global.console, 'error');
{{#if wantMessages}}
render(
<IntlProvider locale={DEFAULT_LOCALE}>
<{{ properCase name }} />
<{{ properCase shortName }} />
</IntlProvider>,
);
{{else}}
render(<{{ properCase name }} />);
render(<{{ properCase shortName }} />);
{{/if}}
expect(spy).not.toHaveBeenCalled();
});
Expand All @@ -47,13 +47,13 @@ describe('<{{ properCase name }} />', () => {
container: { firstChild },
} = render(
<IntlProvider locale={DEFAULT_LOCALE}>
<{{ properCase name }} />
<{{ properCase shortName }} />
</IntlProvider>,
);
{{else}}
const {
container: { firstChild },
} = render(<{{ properCase name }} />);
} = render(<{{ properCase shortName }} />);
{{/if}}
expect(firstChild).toMatchSnapshot();
});
Expand Down
2 changes: 1 addition & 1 deletion internals/generators/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ module.exports = plop => {
__dirname,
'/../../app/',
config.path,
plop.getHelper('properCase')(answers.name),
plop.getHelper('properCase')(config.name || answers.name),
'**',
'**.js',
)}`;
Expand Down
23 changes: 14 additions & 9 deletions internals/generators/utils/componentExists.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,18 +4,23 @@
* Check whether the given component exist in either the components or containers directory
*/

const fs = require('fs');
const path = require('path');
const pageComponents = fs.readdirSync(
path.join(__dirname, '../../../app/components'),
);
const pageContainers = fs.readdirSync(
path.join(__dirname, '../../../app/containers'),
);
const components = pageComponents.concat(pageContainers);

const walkNestedComponents = require('./walkNestedComponents')

const pageComponents = walkNestedComponents(path.join(__dirname,'../../../app/components'))
const pageContainers = walkNestedComponents(path.join(__dirname,'../../../app/containers'))

const components = pageComponents.concat(pageContainers)

function componentExists(comp) {
return components.indexOf(comp) >= 0;
const containerPath = path.join(__dirname, `../../../app/containers/${comp}`)
const componentPath = path.join(__dirname, `../../../app/components/${comp}`)

return (
components.indexOf(containerPath) >= 0 ||
components.indexOf(componentPath) >= 0
);
}

module.exports = componentExists;
31 changes: 31 additions & 0 deletions internals/generators/utils/walkNestedComponents.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
/**
* walkNestedComponents
*
* List all components listed within a directory
*/

const fs = require('fs');

function walkNestedComponents(dir) {
let results = [];
const list = fs.readdirSync(dir);
list.forEach((file) => {
// Only include the directory as a component if `index.js` is defined
if(file === 'index.js')
{
results.push(dir)
}
else
{
const filePath = `${dir}/${file}`;
const stat = fs.statSync(filePath);
if (stat && stat.isDirectory()) {
/* Recurse into a subdirectory */
results = results.concat(walkNestedComponents(filePath));
}
}
});
return results;
}

module.exports = walkNestedComponents
Loading

0 comments on commit d95c3c4

Please sign in to comment.