Skip to content

Commit 892f771

Browse files
committed
Added new directory options for generated components (styles are now also generated in the components folder)
Added directory options fallbacks for version 3 and below Prepared for inclusion of css modules
1 parent ed4686e commit 892f771

File tree

11 files changed

+171
-91
lines changed

11 files changed

+171
-91
lines changed

generators/app/index.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,13 +54,15 @@ class AppGenerator extends Generators.Base {
5454
// Set needed global vars for yo
5555
this.appName = answers.appName;
5656
this.style = answers.style;
57+
this.cssmodules = answers.cssmodules;
5758
this.postcss = answers.postcss;
5859
this.generatedWithVersion = parseInt(packageInfo.version.split('.').shift(), 10);
5960

6061
// Set needed keys into config
6162
this.config.set('appName', this.appName);
6263
this.config.set('appPath', this.appPath);
6364
this.config.set('style', this.style);
65+
this.config.set('cssmodules', this.cssmodules);
6466
this.config.set('postcss', this.postcss);
6567
this.config.set('generatedWithVersion', this.generatedWithVersion);
6668
});

generators/app/prompts.js

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,12 @@ module.exports = [
1515
choices: utils.config.getChoices('style'),
1616
default: utils.config.getDefaultChoice('style')
1717
},
18+
{
19+
type: 'confirm',
20+
name: 'cssmodules',
21+
message: 'Enable css module support? See https://github.com/gajus/react-css-modules for further info',
22+
default: true
23+
},
1824
{
1925
type: 'confirm',
2026
name: 'postcss',

generators/component/index.js

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -16,34 +16,34 @@ class ComponentGenerator extends Generators.Base {
1616

1717
writing() {
1818

19-
let settings = utils.yeoman.getAllSettingsFromComponentName(this.name, this.config.get('style'));
20-
let componentType = this.options.stateless ? 'Stateless' : 'Base';
21-
2219
// Set the template base. If it cannot be guessed,
23-
// use files from the default directory. If it cannot be
24-
// guessed, assume we have something REALLY REALLY old here...
25-
let templateBase = this.config.get('generatedWithVersion');
26-
if(!templateBase) {
27-
templateBase = 3;
20+
// use files from the default directory. In this case,
21+
// assume we have something REALLY REALLY old here...
22+
let generatorVersion = this.config.get('generatedWithVersion');
23+
if(!generatorVersion) {
24+
generatorVersion = 3;
2825
}
2926

27+
const settings = utils.yeoman.getAllSettingsFromComponentName(this.name, this.config.get('style'), generatorVersion);
28+
const componentType = this.options.stateless ? 'Stateless' : 'Base';
29+
3030
// Create the style template
3131
this.fs.copyTpl(
32-
this.templatePath(`${templateBase}/styles/Component${settings.style.suffix}`),
32+
this.templatePath(`${generatorVersion}/styles/Component${settings.style.suffix}`),
3333
this.destinationPath(settings.style.path + settings.style.fileName),
3434
settings
3535
);
3636

3737
// Create the component
3838
this.fs.copyTpl(
39-
this.templatePath(`${templateBase}/components/${componentType}.js`),
39+
this.templatePath(`${generatorVersion}/components/${componentType}.js`),
4040
this.destinationPath(settings.component.path + settings.component.fileName),
4141
settings
4242
);
4343

4444
// Create the unit test
4545
this.fs.copyTpl(
46-
this.templatePath(`${templateBase}/tests/Base.js`),
46+
this.templatePath(`${generatorVersion}/tests/Base.js`),
4747
this.destinationPath(settings.test.path + settings.test.fileName),
4848
settings
4949
);

generators/component/templates/4/components/Base.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import styles from '<%= style.webpackPath %>';
44

55
@cssmodules(styles)
66
class <%= component.className %> extends React.Component {
7+
78
render() {
89
return (
910
<div className="<%= style.className %>" styleName="<%= style.className %>">

generators/component/templates/4/components/Stateless.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ import styles from '<%= style.webpackPath %>';
55
function <%= component.className %>() {
66

77
return (
8-
<div className="<%= style.className %>">
8+
<div className="<%= style.className %>" styleName="<%= style.className %>">
99
Please edit <%= component.path %><%= component.fileName %> to update this component!
1010
</div>
1111
);

generators/component/templates/4/tests/Base.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,12 +6,12 @@ describe('<<%= component.className %> />', () => {
66

77
let component;
88
beforeEach(() => {
9-
component = shallow(<%= component.className %>);
9+
component = shallow(<<%= component.className %> />);
1010
});
1111

1212
describe('when rendering the component', () => {
1313

14-
it('should have a className of "index"', () => {
14+
it('should have a className of "<%= style.className %>"', () => {
1515
expect(component.hasClass('<%= style.className %>')).to.equal(true);
1616
});
1717
});

package.json

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -40,9 +40,9 @@
4040
"scripts": {
4141
"test": "mocha",
4242
"test:watch": "mocha -w",
43-
"release:major": "npm version major && npm publish && git push --follow-tags",
44-
"release:minor": "npm version minor && npm publish && git push --follow-tags",
45-
"release:patch": "npm version patch && npm publish && git push --follow-tags"
43+
"release:major": "npm version major && npm publish && git push --follow-tags --tag beta",
44+
"release:minor": "npm version minor && npm publish && git push --follow-tags --tag beta",
45+
"release:patch": "npm version patch && npm publish && git push --follow-tags --tag beta"
4646
},
4747
"dependencies": {
4848
"escodegen": "^1.7.0",

test/generators/app/indexTest.js

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,8 +52,12 @@ describe('react-webpack:app', () => {
5252
expect(generator.config.get('style')).to.equal('css');
5353
});
5454

55+
it('should use "css modules" per default', () => {
56+
expect(generator.config.get('cssmodules')).to.be.true;
57+
});
58+
5559
it('should not enable "PostCSS" by default', () => {
56-
expect(generator.config.get('postcss')).to.equal(false);
60+
expect(generator.config.get('postcss')).to.be.false;
5761
});
5862
});
5963

test/generators/component/indexTest.js

Lines changed: 42 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -173,75 +173,72 @@ describe('react-webpack:component', () => {
173173
}
174174

175175
// Run all tests for all available style types.
176-
testComponentWithStyle(styleTypes.css);
177-
testComponentWithStyle(styleTypes.sass);
178-
testComponentWithStyle(styleTypes.scss);
179-
testComponentWithStyle(styleTypes.less);
180-
testComponentWithStyle(styleTypes.stylus);
181-
182-
// Test stateless components (should be enough when testing with defaults)
183-
testComponentWithStyle(styleTypes.css, { stateless: true });
176+
// Stateless components will also be tested!
177+
for(const style in styleTypes) {
178+
testComponentWithStyle(styleTypes[style]);
179+
testComponentWithStyle(styleTypes[style], { stateless: true });
180+
}
184181
});
185182

186183
describe('when using version 4 of the generator', () => {
187184

185+
/**
186+
* @var {yeoman.generator} generator
187+
* Global generator instance, set by createGeneratedComponent
188+
*/
189+
let generator;
190+
188191
// List of available style types. Please add a line that says
189192
// testComponentWithStyle(styleTypes.KEY); to the bottom of the file
190193
// to run all unit tests for this filetype.
191194
const styleTypes = {
192195
css: {
193196
type: 'css',
194-
fileName: 'src/styles/Mycomponent.css',
195-
expandedFileName: 'src/styles/my/littleSpecial/Test.css',
197+
fileName: 'src/components/mycomponent.cssmodule.css',
198+
expandedFileName: 'src/components/my/littleSpecial/test.cssmodule.css',
196199
assertions: {
197-
componentImport: 'import styles from \'styles//Mycomponent.css\';',
200+
componentImport: 'import styles from \'./mycomponent.cssmodule.css\';',
198201
styleContent: '.mycomponent-component'
199202
}
200203
},
201204
sass: {
202205
type: 'sass',
203-
fileName: 'src/styles/Mycomponent.sass',
204-
expandedFileName: 'src/styles/my/littleSpecial/Test.sass',
206+
fileName: 'src/components/Mycomponent.cssmodule.sass',
207+
expandedFileName: 'src/components/my/littleSpecial/test.cssmodule.sass',
205208
assertions: {
206-
componentImport: 'import styles from \'styles//Mycomponent.sass\';',
209+
componentImport: 'import styles from \'./mycomponent.cssmodule.sass\';',
207210
styleContent: '.mycomponent-component'
208211
}
209212
},
210213
scss: {
211214
type: 'scss',
212-
fileName: 'src/styles/Mycomponent.scss',
213-
expandedFileName: 'src/styles/my/littleSpecial/Test.scss',
215+
fileName: 'src/components/mycomponent.cssmodule.scss',
216+
expandedFileName: 'src/components/my/littleSpecial/test.cssmodule.scss',
214217
assertions: {
215-
componentImport: 'import styles from \'styles//Mycomponent.scss\';',
218+
componentImport: 'import styles from \'./mycomponent.cssmodule.scss\';',
216219
styleContent: '.mycomponent-component'
217220
}
218221
},
219222
less: {
220223
type: 'less',
221-
fileName: 'src/styles/Mycomponent.less',
222-
expandedFileName: 'src/styles/my/littleSpecial/Test.less',
224+
fileName: 'src/components/mycomponent.cssmodule.less',
225+
expandedFileName: 'src/components/my/littleSpecial/test.cssmodule.less',
223226
assertions: {
224-
componentImport: 'import styles from \'styles//Mycomponent.less\';',
227+
componentImport: 'import styles from \'./mycomponent.cssmodule.less\';',
225228
styleContent: '.mycomponent-component'
226229
}
227230
},
228231
stylus: {
229232
type: 'stylus',
230-
fileName: 'src/styles/Mycomponent.styl',
231-
expandedFileName: 'src/styles/my/littleSpecial/Test.styl',
233+
fileName: 'src/components/mycomponent.cssmodule.styl',
234+
expandedFileName: 'src/components/my/littleSpecial/test.cssmodule.styl',
232235
assertions: {
233-
componentImport: 'import styles from \'styles//Mycomponent.styl\';',
236+
componentImport: 'import styles from \'./mycomponent.cssmodule.styl\';',
234237
styleContent: '.mycomponent-component'
235238
}
236239
}
237240
};
238241

239-
/**
240-
* @var {yeoman.generator} generator
241-
* Global generator instance, set by createGeneratedComponent
242-
*/
243-
let generator;
244-
245242
/**
246243
* Return a newly generated component with given name and style
247244
* @param {String} name Name of the component
@@ -281,9 +278,9 @@ describe('react-webpack:component', () => {
281278
createGeneratedComponent('mycomponent', style.type, options, () => {
282279

283280
assert.file([
284-
'src/components/MycomponentComponent.js',
281+
'src/components/Mycomponent.js',
285282
style.fileName,
286-
'test/components/MycomponentComponentTest.js'
283+
'test/components/MycomponentTest.js'
287284
]);
288285
done();
289286
});
@@ -294,21 +291,21 @@ describe('react-webpack:component', () => {
294291

295292
it('should always import REACT', (done) => {
296293
createGeneratedComponent('mycomponent', style.type, options, () => {
297-
assert.fileContent('src/components/MycomponentComponent.js', 'import React from \'react\';');
294+
assert.fileContent('src/components/Mycomponent.js', 'import React from \'react\';');
298295
done();
299296
});
300297
});
301298

302299
it(`should require the created ${style.type} file`, (done) => {
303300
createGeneratedComponent('mycomponent', style.type, options, () => {
304-
assert.fileContent('src/components/MycomponentComponent.js', style.assertions.componentImport);
301+
assert.fileContent('src/components/Mycomponent.js', style.assertions.componentImport);
305302
done();
306303
});
307304
});
308305

309306
it('should have its displayName set per default', (done) => {
310307
createGeneratedComponent('mycomponent', style.type, options, () => {
311-
assert.fileContent('src/components/MycomponentComponent.js', 'displayName = \'MycomponentComponent\';');
308+
assert.fileContent('src/components/Mycomponent.js', 'Mycomponent.displayName = \'Mycomponent\';');
312309
done();
313310
});
314311
});
@@ -318,11 +315,11 @@ describe('react-webpack:component', () => {
318315

319316
let exportAssertion;
320317
if(generator.options.stateless) {
321-
exportAssertion = 'export default cssmodules(MycomponentComponent, styles);';
318+
exportAssertion = 'export default cssmodules(Mycomponent, styles);';
322319
} else {
323-
exportAssertion = 'export default MycomponentComponent';
320+
exportAssertion = 'export default Mycomponent';
324321
}
325-
assert.fileContent('src/components/MycomponentComponent.js', exportAssertion);
322+
assert.fileContent('src/components/Mycomponent.js', exportAssertion);
326323
done();
327324
});
328325
});
@@ -331,9 +328,9 @@ describe('react-webpack:component', () => {
331328
createGeneratedComponent('my/little !special/test', style.type, options, () => {
332329

333330
assert.file([
334-
'src/components/my/littleSpecial/TestComponent.js',
331+
'src/components/my/littleSpecial/Test.js',
335332
style.expandedFileName,
336-
'test/components/my/littleSpecial/TestComponentTest.js'
333+
'test/components/my/littleSpecial/TestTest.js'
337334
]);
338335
done();
339336
});
@@ -354,7 +351,7 @@ describe('react-webpack:component', () => {
354351

355352
it('should import the react component', (done) => {
356353
createGeneratedComponent('mycomponent', style.type, options, () => {
357-
assert.fileContent('test/components/MycomponentComponentTest.js', 'import MycomponentComponent from \'components//MycomponentComponent.js\';');
354+
assert.fileContent('test/components/MycomponentTest.js', 'import Mycomponent from \'components//Mycomponent.js\';');
358355
done();
359356
});
360357
});
@@ -363,14 +360,11 @@ describe('react-webpack:component', () => {
363360
}
364361

365362
// Run all tests for all available style types.
366-
testComponentWithStyle(styleTypes.css);
367-
testComponentWithStyle(styleTypes.sass);
368-
testComponentWithStyle(styleTypes.scss);
369-
testComponentWithStyle(styleTypes.less);
370-
testComponentWithStyle(styleTypes.stylus);
371-
372-
// Test stateless components (should be enough when testing with defaults)
373-
testComponentWithStyle(styleTypes.css, { stateless: true });
363+
// Stateless components will also be tested!
364+
for(const style in styleTypes) {
365+
testComponentWithStyle(styleTypes[style]);
366+
testComponentWithStyle(styleTypes[style], { stateless: true });
367+
}
374368
});
375369

376370
});

test/utils/yeomanTest.js

Lines changed: 35 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -67,9 +67,38 @@ describe('Utilities:Yeoman', () => {
6767

6868
describe('#getAllSettingsFromComponentName', () => {
6969

70-
it('should get all required information for component creation from the components name', () => {
70+
describe('when the generator version is set to 4', () => {
7171

72-
let expection = {
72+
const expection = {
73+
style: {
74+
webpackPath: './test.cssmodule.css',
75+
path: 'src/components/my/component/',
76+
fileName: 'test.cssmodule.css',
77+
className: 'test-component',
78+
suffix: '.css'
79+
},
80+
component: {
81+
webpackPath: 'components/my/component/Test.js',
82+
path: 'src/components/my/component/',
83+
fileName: 'Test.js',
84+
className: 'Test',
85+
displayName: 'MyComponentTest',
86+
suffix: '.js'
87+
},
88+
test: {
89+
path: 'test/components/my/component/',
90+
fileName: 'TestTest.js'
91+
}
92+
};
93+
94+
it('should get all required information for component creation from the components name', () => {
95+
expect(utils.getAllSettingsFromComponentName('my/component/test', 'css', 4)).to.deep.equal(expection);
96+
});
97+
});
98+
99+
describe('when the generator version is set to 3 (or not set at all)', () => {
100+
101+
const expection = {
73102
style: {
74103
webpackPath: 'styles/my/component/Test.css',
75104
path: 'src/styles/my/component/',
@@ -91,7 +120,10 @@ describe('Utilities:Yeoman', () => {
91120
}
92121
};
93122

94-
expect(utils.getAllSettingsFromComponentName('my/component/test')).to.deep.equal(expection);
123+
it('should get all required information for component creation from the components name', () => {
124+
expect(utils.getAllSettingsFromComponentName('my/component/test')).to.deep.equal(expection);
125+
expect(utils.getAllSettingsFromComponentName('my/component/test', 'css', 3)).to.deep.equal(expection);
126+
});
95127
});
96128
});
97129

0 commit comments

Comments
 (0)