From 1d4ce11089816527841736a7e8d65514c850ad21 Mon Sep 17 00:00:00 2001 From: Andrew Koroluk Date: Sat, 23 Apr 2016 16:04:53 -0400 Subject: [PATCH 01/81] feat(gen:app): run all client files through Babel & JS Beautifier --- app/generator.js | 70 ++++++++++++++++++++++++++++++++++++++++++++++++ package.json | 6 +++++ 2 files changed, 76 insertions(+) diff --git a/app/generator.js b/app/generator.js index c74d42b2f..838469608 100644 --- a/app/generator.js +++ b/app/generator.js @@ -7,6 +7,9 @@ import {Base} from 'yeoman-generator'; import {genBase} from '../generator-base'; import insight from '../insight-init'; import {exec} from 'child_process'; +import babelStream from 'gulp-babel'; +import beaufityStream from 'gulp-beautify'; +import filter from 'gulp-filter'; export default class Generator extends Base { constructor(...args) { @@ -119,6 +122,12 @@ export default class Generator extends Base { }[val]; } }, { + // TODO: enable once Babel setup supports Flow + // type: 'confirm', + // name: 'flow', + // message: 'Would you like to use Flow types with Babel?', + // when: answers => answers.transpiler === 'babel' + // }, { type: 'list', name: 'markup', message: 'What would you like to write markup with?', @@ -152,6 +161,9 @@ export default class Generator extends Base { this.filters[answers.transpiler] = true; insight.track('transpiler', answers.transpiler); + this.filters.flow = !!answers.flow; + insight.track('flow', !!answers.flow); + this.filters[answers.markup] = true; insight.track('markup', answers.markup); @@ -425,6 +437,64 @@ export default class Generator extends Base { get writing() { return { generateProject: function() { + /** + * var tap = require('gulp-tap'); + this.registerTransformStream([ + extensionFilter, + tap(function(file, t) { + var contents = file.contents.toString(); + contents = beautify_js(contents, config); + file.contents = new Buffer(contents); + }), + //prettifyJs(config), + extensionFilter.restore + ]); + */ + + let babelPlugins = [ + 'babel-plugin-syntax-flow', + 'babel-plugin-syntax-class-properties' + ]; + + // TODO: enable once Babel setup supports Flow + // if(this.filters.babel && !this.filters.flow) { + babelPlugins.push('babel-plugin-transform-flow-strip-types'); + // } + + const jsFilter = filter(['client/**/*.js'], {restore: true}); + this.registerTransformStream([ + jsFilter, + babelStream({ + plugins: babelPlugins.map(require.resolve), + /* Babel get's confused about these if you're using an `npm link`ed + generator-angular-fullstack, thus the `require.resolve` */ + // retainLines: true, + babelrc: false // don't grab the generator's `.babelrc` + }), + beaufityStream({ + "indent_size": 2, + "indent_char": " ", + "indent_level": 0, + "indent_with_tabs": false, + "preserve_newlines": true, + "max_preserve_newlines": 10, + "jslint_happy": false, + "space_after_anon_function": false, + "brace_style": "collapse", + "keep_array_indentation": false, + "keep_function_indentation": false, + "space_before_conditional": true, + "break_chained_methods": true, + "eval_code": false, + "unescape_strings": false, + "wrap_line_length": 100, + "wrap_attributes": "auto", + "wrap_attributes_indent_size": 4, + "end_with_newline": true + }), + jsFilter.restore + ]); + let self = this; this.sourceRoot(path.join(__dirname, './templates')); this.processDirectory('.', '.', function(dest) { diff --git a/package.json b/package.json index 693a406f4..e575595c9 100644 --- a/package.json +++ b/package.json @@ -35,12 +35,18 @@ }, "dependencies": { "babel-core": "^6.7.0", + "babel-plugin-syntax-class-properties": "^6.5.0", + "babel-plugin-syntax-flow": "^6.5.0", "babel-plugin-transform-class-properties": "^6.6.0", + "babel-plugin-transform-flow-strip-types": "^6.7.0", "babel-preset-es2015": "^6.6.0", "babel-register": "^6.6.5", "chalk": "^1.1.0", "generator-ng-component": "~0.2.1", "glob": "^7.0.3", + "gulp-babel": "^6.1.2", + "gulp-beautify": "^2.0.0", + "gulp-filter": "^4.0.0", "insight": "~0.8.1", "lodash": "^4.6.1", "underscore.string": "^3.1.1", From 9d4bcbd30091f635bfea160d60a9cd73afa1fba9 Mon Sep 17 00:00:00 2001 From: Andrew Koroluk Date: Sat, 23 Apr 2016 16:05:30 -0400 Subject: [PATCH 02/81] refactor(gen): move `.ts` transform to `util.js` --- app/generator.js | 8 +------- util.js | 10 ++++------ 2 files changed, 5 insertions(+), 13 deletions(-) diff --git a/app/generator.js b/app/generator.js index 838469608..ad6904f78 100644 --- a/app/generator.js +++ b/app/generator.js @@ -497,13 +497,7 @@ export default class Generator extends Base { let self = this; this.sourceRoot(path.join(__dirname, './templates')); - this.processDirectory('.', '.', function(dest) { - if(self.filters.ts && dest.indexOf('client') > -1 && dest.indexOf('.json') === -1) { - dest = dest.replace('.js', '.ts'); - } - - return dest; - }); + this.processDirectory('.', '.'); }, generateEndpoint: function() { var models; diff --git a/util.js b/util.js index 6b8c65e73..4ed6205c2 100644 --- a/util.js +++ b/util.js @@ -105,14 +105,10 @@ function templateIsUsable(self, filteredFile) { return true; } -function defaultIteratee(dest) { - return dest; -} - /** * */ -export function processDirectory(source, destination, iteratee = defaultIteratee) { +export function processDirectory(source, destination) { var self = this; var root = path.isAbsolute(source) ? source : path.join(self.sourceRoot(), source); var files = expandFiles('**', { dot: true, cwd: root }); @@ -132,7 +128,9 @@ export function processDirectory(source, destination, iteratee = defaultIteratee src = path.join(root, f); dest = path.join(destination, name); - dest = iteratee(dest); + if(self.filters.ts && dest.indexOf('client') > -1 && dest.indexOf('.json') === -1) { + dest = dest.replace('.js', '.ts'); + } if(path.basename(dest).indexOf('_') === 0) { stripped = path.basename(dest).replace(/^_/, ''); From 7ed25853b4a9ad4977cf4c9884bc2e29228f45a7 Mon Sep 17 00:00:00 2001 From: Andrew Koroluk Date: Sat, 23 Apr 2016 16:06:18 -0400 Subject: [PATCH 03/81] feat(client:auth): add first type definition (`callback: Function`) --- app/templates/client/components/auth(auth)/auth.service.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/templates/client/components/auth(auth)/auth.service.js b/app/templates/client/components/auth(auth)/auth.service.js index dbb13603a..3a75c5a9a 100644 --- a/app/templates/client/components/auth(auth)/auth.service.js +++ b/app/templates/client/components/auth(auth)/auth.service.js @@ -20,7 +20,7 @@ function AuthService($location, $http, $cookies, $q, appConfig, Util, User) { * @param {Function} callback - optional, function(error, user) * @return {Promise} */ - login({email, password}, callback) { + login({email, password}, callback: Function) { return $http.post('/auth/local', { email: email, password: password From b5475e4b10430557f4f8d030c05b78caccec67d1 Mon Sep 17 00:00:00 2001 From: Andrew Koroluk Date: Sat, 23 Apr 2016 19:39:59 -0400 Subject: [PATCH 04/81] chore(grunt): use grunt-sass instead of grunt-contrib-sass closes #1673 --- app/templates/_package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/templates/_package.json b/app/templates/_package.json index c158e50b4..b851e3914 100644 --- a/app/templates/_package.json +++ b/app/templates/_package.json @@ -131,7 +131,7 @@ "grunt-injector": "^0.6.0", "grunt-karma": "~0.12.0", "grunt-build-control": "^0.7.0",<% if(filters.sass) { %> - "grunt-contrib-sass": "^1.0.0",<% } %><% if(filters.stylus) { %> + "grunt-sass": "^1.1.0",<% } %><% if(filters.stylus) { %> "grunt-contrib-stylus": "^1.2.0",<% } %> "jit-grunt": "~0.10.0", "grunt-express-server": "^0.5.1", From 17052a5c678ecfce96bb1c6bafe38a2e1da3673b Mon Sep 17 00:00:00 2001 From: Andrew Koroluk Date: Sat, 23 Apr 2016 18:38:32 -0400 Subject: [PATCH 05/81] refactor(gen): set up whole generator to not need babel-register at runtime move all subgenerators to `src/`, all templates to `templates/`; use Gulp to build project; dist code is sent to `generators` --- .gitignore | 3 +- .npmignore | 4 ++ app/index.js | 9 ----- endpoint/index.js | 9 ----- gulpfile.babel.js | 35 ++++++++++++++++++ package.json | 9 +++-- {app => src/app}/USAGE | 0 app/generator.js => src/app/index.js | 6 ++- {controller => src/controller}/index.js | 0 {decorator => src/decorator}/index.js | 0 {directive => src/directive}/index.js | 0 .../generator.js => src/endpoint/index.js | 6 ++- {factory => src/factory}/index.js | 0 {filter => src/filter}/index.js | 0 generator-base.js => src/generator-base.js | 0 {heroku => src/heroku}/USAGE | 0 {heroku => src/heroku}/index.js | 0 {heroku => src/heroku}/templates/Procfile | 0 insight-init.js => src/insight-init.js | 2 +- {openshift => src/openshift}/USAGE | 0 {openshift => src/openshift}/index.js | 0 .../openshift}/templates/hot_deploy | 0 {provider => src/provider}/index.js | 0 {route => src/route}/index.js | 0 {service => src/service}/index.js | 0 util.js => src/util.js | 0 {app/templates => templates/app}/.bowerrc | 0 {app/templates => templates/app}/.buildignore | 0 .../templates => templates/app}/.editorconfig | 0 .../app}/.gitattributes | 0 {app/templates => templates/app}/.jscsrc | 0 {app/templates => templates/app}/.travis.yml | 0 .../app}/Gruntfile(grunt).js | 0 {app/templates => templates/app}/README.md | 0 {app/templates => templates/app}/_.babelrc | 0 {app/templates => templates/app}/_.gitignore | 0 {app/templates => templates/app}/_bower.json | 0 .../templates => templates/app}/_package.json | 0 .../app}/client/.htaccess | 0 .../app}/client/.jshintrc(babel) | 0 .../app}/client/app/account(auth)/account.js | 0 .../app/account(auth)/login/login(html).html | 0 .../app/account(auth)/login/login(jade).jade | 0 .../account(auth)/login/login.controller.js | 0 .../settings/settings(html).html | 0 .../settings/settings(jade).jade | 0 .../settings/settings.controller.js | 0 .../account(auth)/signup/signup(html).html | 0 .../account(auth)/signup/signup(jade).jade | 0 .../account(auth)/signup/signup.controller.js | 0 .../client/app/admin(auth)/admin(css).css | 0 .../client/app/admin(auth)/admin(html).html | 0 .../client/app/admin(auth)/admin(jade).jade | 0 .../client/app/admin(auth)/admin(less).less | 0 .../client/app/admin(auth)/admin(sass).scss | 0 .../client/app/admin(auth)/admin(stylus).styl | 0 .../app/admin(auth)/admin.controller.js | 0 .../client/app/admin(auth)/admin.module.js | 0 .../client/app/admin(auth)/admin.router.js | 0 .../app}/client/app/app(css).css | 0 .../app}/client/app/app(less).less | 0 .../app}/client/app/app(sass).scss | 0 .../app}/client/app/app(stylus).styl | 0 .../app}/client/app/app.js | 0 .../app}/client/app/main/main(css).css | 0 .../app}/client/app/main/main(html).html | 0 .../app}/client/app/main/main(jade).jade | 0 .../app}/client/app/main/main(less).less | 0 .../app}/client/app/main/main(sass).scss | 0 .../app}/client/app/main/main(stylus).styl | 0 .../app}/client/app/main/main.controller.js | 0 .../client/app/main/main.controller.spec.js | 0 .../app}/client/app/main/main.js | 0 .../app}/client/assets/images/!yeoman.png | Bin .../components/auth(auth)/auth.module.js | 0 .../components/auth(auth)/auth.service.js | 0 .../auth(auth)/interceptor.service.js | 0 .../components/auth(auth)/router.decorator.js | 0 .../components/auth(auth)/user.service.js | 0 .../client/components/footer/footer(css).css | 0 .../components/footer/footer(html).html | 0 .../components/footer/footer(jade).jade | 0 .../components/footer/footer(less).less | 0 .../components/footer/footer(sass).scss | 0 .../components/footer/footer(stylus).styl | 0 .../components/footer/footer.directive.js | 0 .../modal(uibootstrap)/modal(css).css | 0 .../modal(uibootstrap)/modal(html).html | 0 .../modal(uibootstrap)/modal(jade).jade | 0 .../modal(uibootstrap)/modal(less).less | 0 .../modal(uibootstrap)/modal(sass).scss | 0 .../modal(uibootstrap)/modal(stylus).styl | 0 .../modal(uibootstrap)/modal.service.js | 0 .../mongoose-error.directive.js | 0 .../components/navbar/navbar(html).html | 0 .../components/navbar/navbar(jade).jade | 0 .../components/navbar/navbar.controller.js | 0 .../components/navbar/navbar.directive.js | 0 .../oauth-buttons(css).css | 0 .../oauth-buttons(html).html | 0 .../oauth-buttons(jade).jade | 0 .../oauth-buttons(less).less | 0 .../oauth-buttons(sass).scss | 0 .../oauth-buttons(stylus).styl | 0 .../oauth-buttons.controller.js | 0 .../oauth-buttons.controller.spec.js | 0 .../oauth-buttons.directive.js | 0 .../oauth-buttons.directive.spec.js | 0 .../socket(socketio)/socket.mock.js | 0 .../socket(socketio)/socket.service.js | 0 .../ui-router(uirouter)/ui-router.mock.js | 0 .../client/components/util/util.module.js | 0 .../client/components/util/util.service.js | 0 .../app}/client/favicon.ico | Bin .../app}/client/index.html | 0 .../app}/client/robots.txt | 0 .../app}/client/tslint.json(ts) | 0 .../app}/e2e/account(auth)/login/login.po.js | 0 .../login/login.spec(jasmine).js | 0 .../account(auth)/login/login.spec(mocha).js | 0 .../logout/logout.spec(jasmine).js | 0 .../logout/logout.spec(mocha).js | 0 .../e2e/account(auth)/signup/signup.po.js | 0 .../signup/signup.spec(jasmine).js | 0 .../signup/signup.spec(mocha).js | 0 .../app}/e2e/components/navbar/navbar.po.js | 0 .../oauth-buttons(oauth)/oauth-buttons.po.js | 0 .../app}/e2e/main/main.po.js | 0 .../app}/e2e/main/main.spec(jasmine).js | 0 .../app}/e2e/main/main.spec(mocha).js | 0 .../app}/gulpfile.babel(gulp).js | 0 .../templates => templates/app}/karma.conf.js | 0 .../templates => templates/app}/mocha.conf.js | 0 .../app}/mocha.global(gulp).js | 0 .../app}/protractor.conf.js | 0 .../app}/server/.jshintrc | 0 .../app}/server/.jshintrc-spec | 0 .../app}/server/api/user(auth)/index.js | 0 .../app}/server/api/user(auth)/index.spec.js | 0 .../server/api/user(auth)/user.controller.js | 0 .../app}/server/api/user(auth)/user.events.js | 0 .../server/api/user(auth)/user.integration.js | 0 .../user(auth)/user.model(mongooseModels).js | 0 .../user(auth)/user.model(sequelizeModels).js | 0 .../user.model.spec(mongooseModels).js | 0 .../user.model.spec(sequelizeModels).js | 0 .../templates => templates/app}/server/app.js | 0 .../app}/server/auth(auth)/auth.service.js | 0 .../facebook(facebookAuth)/index.js | 0 .../facebook(facebookAuth)/passport.js | 0 .../auth(auth)/google(googleAuth)/index.js | 0 .../auth(auth)/google(googleAuth)/passport.js | 0 .../app}/server/auth(auth)/index.js | 0 .../app}/server/auth(auth)/local/index.js | 0 .../app}/server/auth(auth)/local/passport.js | 0 .../auth(auth)/twitter(twitterAuth)/index.js | 0 .../twitter(twitterAuth)/passport.js | 0 .../app}/server/components/errors/index.js | 0 .../app}/server/config/_local.env.js | 0 .../app}/server/config/_local.env.sample.js | 0 .../server/config/environment/development.js | 0 .../app}/server/config/environment/index.js | 0 .../server/config/environment/production.js | 0 .../app}/server/config/environment/shared.js | 0 .../app}/server/config/environment/test.js | 0 .../app}/server/config/express.js | 0 .../app}/server/config/seed(models).js | 0 .../app}/server/config/socketio(socketio).js | 0 .../app}/server/index.js | 0 .../app}/server/routes.js | 0 .../app}/server/sqldb(sequelize)/index.js | 0 .../app}/server/views/404(html).html | 0 .../app}/server/views/404(jade).jade | 0 .../app}/tsconfig.client(ts).json | 0 .../app}/tsconfig.client.test(ts).json | 0 {app/templates => templates/app}/tsd(ts).json | 0 .../app}/tsd_test(ts).json | 0 .../endpoint}/basename.controller.js | 0 .../endpoint}/basename.events(models).js | 0 .../endpoint}/basename.integration.js | 0 .../basename.model(mongooseModels).js | 0 .../basename.model(sequelizeModels).js | 0 .../endpoint}/basename.socket(socketio).js | 0 .../templates => templates/endpoint}/index.js | 0 .../endpoint}/index.spec.js | 0 185 files changed, 55 insertions(+), 28 deletions(-) delete mode 100644 app/index.js delete mode 100644 endpoint/index.js create mode 100644 gulpfile.babel.js rename {app => src/app}/USAGE (100%) rename app/generator.js => src/app/index.js (99%) rename {controller => src/controller}/index.js (100%) rename {decorator => src/decorator}/index.js (100%) rename {directive => src/directive}/index.js (100%) rename endpoint/generator.js => src/endpoint/index.js (96%) rename {factory => src/factory}/index.js (100%) rename {filter => src/filter}/index.js (100%) rename generator-base.js => src/generator-base.js (100%) rename {heroku => src/heroku}/USAGE (100%) rename {heroku => src/heroku}/index.js (100%) rename {heroku => src/heroku}/templates/Procfile (100%) rename insight-init.js => src/insight-init.js (92%) rename {openshift => src/openshift}/USAGE (100%) rename {openshift => src/openshift}/index.js (100%) rename {openshift => src/openshift}/templates/hot_deploy (100%) rename {provider => src/provider}/index.js (100%) rename {route => src/route}/index.js (100%) rename {service => src/service}/index.js (100%) rename util.js => src/util.js (100%) rename {app/templates => templates/app}/.bowerrc (100%) rename {app/templates => templates/app}/.buildignore (100%) rename {app/templates => templates/app}/.editorconfig (100%) rename {app/templates => templates/app}/.gitattributes (100%) rename {app/templates => templates/app}/.jscsrc (100%) rename {app/templates => templates/app}/.travis.yml (100%) rename {app/templates => templates/app}/Gruntfile(grunt).js (100%) rename {app/templates => templates/app}/README.md (100%) rename {app/templates => templates/app}/_.babelrc (100%) rename {app/templates => templates/app}/_.gitignore (100%) rename {app/templates => templates/app}/_bower.json (100%) rename {app/templates => templates/app}/_package.json (100%) rename {app/templates => templates/app}/client/.htaccess (100%) rename {app/templates => templates/app}/client/.jshintrc(babel) (100%) rename {app/templates => templates/app}/client/app/account(auth)/account.js (100%) rename {app/templates => templates/app}/client/app/account(auth)/login/login(html).html (100%) rename {app/templates => templates/app}/client/app/account(auth)/login/login(jade).jade (100%) rename {app/templates => templates/app}/client/app/account(auth)/login/login.controller.js (100%) rename {app/templates => templates/app}/client/app/account(auth)/settings/settings(html).html (100%) rename {app/templates => templates/app}/client/app/account(auth)/settings/settings(jade).jade (100%) rename {app/templates => templates/app}/client/app/account(auth)/settings/settings.controller.js (100%) rename {app/templates => templates/app}/client/app/account(auth)/signup/signup(html).html (100%) rename {app/templates => templates/app}/client/app/account(auth)/signup/signup(jade).jade (100%) rename {app/templates => templates/app}/client/app/account(auth)/signup/signup.controller.js (100%) rename {app/templates => templates/app}/client/app/admin(auth)/admin(css).css (100%) rename {app/templates => templates/app}/client/app/admin(auth)/admin(html).html (100%) rename {app/templates => templates/app}/client/app/admin(auth)/admin(jade).jade (100%) rename {app/templates => templates/app}/client/app/admin(auth)/admin(less).less (100%) rename {app/templates => templates/app}/client/app/admin(auth)/admin(sass).scss (100%) rename {app/templates => templates/app}/client/app/admin(auth)/admin(stylus).styl (100%) rename {app/templates => templates/app}/client/app/admin(auth)/admin.controller.js (100%) rename {app/templates => templates/app}/client/app/admin(auth)/admin.module.js (100%) rename {app/templates => templates/app}/client/app/admin(auth)/admin.router.js (100%) rename {app/templates => templates/app}/client/app/app(css).css (100%) rename {app/templates => templates/app}/client/app/app(less).less (100%) rename {app/templates => templates/app}/client/app/app(sass).scss (100%) rename {app/templates => templates/app}/client/app/app(stylus).styl (100%) rename {app/templates => templates/app}/client/app/app.js (100%) rename {app/templates => templates/app}/client/app/main/main(css).css (100%) rename {app/templates => templates/app}/client/app/main/main(html).html (100%) rename {app/templates => templates/app}/client/app/main/main(jade).jade (100%) rename {app/templates => templates/app}/client/app/main/main(less).less (100%) rename {app/templates => templates/app}/client/app/main/main(sass).scss (100%) rename {app/templates => templates/app}/client/app/main/main(stylus).styl (100%) rename {app/templates => templates/app}/client/app/main/main.controller.js (100%) rename {app/templates => templates/app}/client/app/main/main.controller.spec.js (100%) rename {app/templates => templates/app}/client/app/main/main.js (100%) rename {app/templates => templates/app}/client/assets/images/!yeoman.png (100%) rename {app/templates => templates/app}/client/components/auth(auth)/auth.module.js (100%) rename {app/templates => templates/app}/client/components/auth(auth)/auth.service.js (100%) rename {app/templates => templates/app}/client/components/auth(auth)/interceptor.service.js (100%) rename {app/templates => templates/app}/client/components/auth(auth)/router.decorator.js (100%) rename {app/templates => templates/app}/client/components/auth(auth)/user.service.js (100%) rename {app/templates => templates/app}/client/components/footer/footer(css).css (100%) rename {app/templates => templates/app}/client/components/footer/footer(html).html (100%) rename {app/templates => templates/app}/client/components/footer/footer(jade).jade (100%) rename {app/templates => templates/app}/client/components/footer/footer(less).less (100%) rename {app/templates => templates/app}/client/components/footer/footer(sass).scss (100%) rename {app/templates => templates/app}/client/components/footer/footer(stylus).styl (100%) rename {app/templates => templates/app}/client/components/footer/footer.directive.js (100%) rename {app/templates => templates/app}/client/components/modal(uibootstrap)/modal(css).css (100%) rename {app/templates => templates/app}/client/components/modal(uibootstrap)/modal(html).html (100%) rename {app/templates => templates/app}/client/components/modal(uibootstrap)/modal(jade).jade (100%) rename {app/templates => templates/app}/client/components/modal(uibootstrap)/modal(less).less (100%) rename {app/templates => templates/app}/client/components/modal(uibootstrap)/modal(sass).scss (100%) rename {app/templates => templates/app}/client/components/modal(uibootstrap)/modal(stylus).styl (100%) rename {app/templates => templates/app}/client/components/modal(uibootstrap)/modal.service.js (100%) rename {app/templates => templates/app}/client/components/mongoose-error(auth)/mongoose-error.directive.js (100%) rename {app/templates => templates/app}/client/components/navbar/navbar(html).html (100%) rename {app/templates => templates/app}/client/components/navbar/navbar(jade).jade (100%) rename {app/templates => templates/app}/client/components/navbar/navbar.controller.js (100%) rename {app/templates => templates/app}/client/components/navbar/navbar.directive.js (100%) rename {app/templates => templates/app}/client/components/oauth-buttons(oauth)/oauth-buttons(css).css (100%) rename {app/templates => templates/app}/client/components/oauth-buttons(oauth)/oauth-buttons(html).html (100%) rename {app/templates => templates/app}/client/components/oauth-buttons(oauth)/oauth-buttons(jade).jade (100%) rename {app/templates => templates/app}/client/components/oauth-buttons(oauth)/oauth-buttons(less).less (100%) rename {app/templates => templates/app}/client/components/oauth-buttons(oauth)/oauth-buttons(sass).scss (100%) rename {app/templates => templates/app}/client/components/oauth-buttons(oauth)/oauth-buttons(stylus).styl (100%) rename {app/templates => templates/app}/client/components/oauth-buttons(oauth)/oauth-buttons.controller.js (100%) rename {app/templates => templates/app}/client/components/oauth-buttons(oauth)/oauth-buttons.controller.spec.js (100%) rename {app/templates => templates/app}/client/components/oauth-buttons(oauth)/oauth-buttons.directive.js (100%) rename {app/templates => templates/app}/client/components/oauth-buttons(oauth)/oauth-buttons.directive.spec.js (100%) rename {app/templates => templates/app}/client/components/socket(socketio)/socket.mock.js (100%) rename {app/templates => templates/app}/client/components/socket(socketio)/socket.service.js (100%) rename {app/templates => templates/app}/client/components/ui-router(uirouter)/ui-router.mock.js (100%) rename {app/templates => templates/app}/client/components/util/util.module.js (100%) rename {app/templates => templates/app}/client/components/util/util.service.js (100%) rename {app/templates => templates/app}/client/favicon.ico (100%) rename {app/templates => templates/app}/client/index.html (100%) rename {app/templates => templates/app}/client/robots.txt (100%) rename {app/templates => templates/app}/client/tslint.json(ts) (100%) rename {app/templates => templates/app}/e2e/account(auth)/login/login.po.js (100%) rename {app/templates => templates/app}/e2e/account(auth)/login/login.spec(jasmine).js (100%) rename {app/templates => templates/app}/e2e/account(auth)/login/login.spec(mocha).js (100%) rename {app/templates => templates/app}/e2e/account(auth)/logout/logout.spec(jasmine).js (100%) rename {app/templates => templates/app}/e2e/account(auth)/logout/logout.spec(mocha).js (100%) rename {app/templates => templates/app}/e2e/account(auth)/signup/signup.po.js (100%) rename {app/templates => templates/app}/e2e/account(auth)/signup/signup.spec(jasmine).js (100%) rename {app/templates => templates/app}/e2e/account(auth)/signup/signup.spec(mocha).js (100%) rename {app/templates => templates/app}/e2e/components/navbar/navbar.po.js (100%) rename {app/templates => templates/app}/e2e/components/oauth-buttons(oauth)/oauth-buttons.po.js (100%) rename {app/templates => templates/app}/e2e/main/main.po.js (100%) rename {app/templates => templates/app}/e2e/main/main.spec(jasmine).js (100%) rename {app/templates => templates/app}/e2e/main/main.spec(mocha).js (100%) rename {app/templates => templates/app}/gulpfile.babel(gulp).js (100%) rename {app/templates => templates/app}/karma.conf.js (100%) rename {app/templates => templates/app}/mocha.conf.js (100%) rename {app/templates => templates/app}/mocha.global(gulp).js (100%) rename {app/templates => templates/app}/protractor.conf.js (100%) rename {app/templates => templates/app}/server/.jshintrc (100%) rename {app/templates => templates/app}/server/.jshintrc-spec (100%) rename {app/templates => templates/app}/server/api/user(auth)/index.js (100%) rename {app/templates => templates/app}/server/api/user(auth)/index.spec.js (100%) rename {app/templates => templates/app}/server/api/user(auth)/user.controller.js (100%) rename {app/templates => templates/app}/server/api/user(auth)/user.events.js (100%) rename {app/templates => templates/app}/server/api/user(auth)/user.integration.js (100%) rename {app/templates => templates/app}/server/api/user(auth)/user.model(mongooseModels).js (100%) rename {app/templates => templates/app}/server/api/user(auth)/user.model(sequelizeModels).js (100%) rename {app/templates => templates/app}/server/api/user(auth)/user.model.spec(mongooseModels).js (100%) rename {app/templates => templates/app}/server/api/user(auth)/user.model.spec(sequelizeModels).js (100%) rename {app/templates => templates/app}/server/app.js (100%) rename {app/templates => templates/app}/server/auth(auth)/auth.service.js (100%) rename {app/templates => templates/app}/server/auth(auth)/facebook(facebookAuth)/index.js (100%) rename {app/templates => templates/app}/server/auth(auth)/facebook(facebookAuth)/passport.js (100%) rename {app/templates => templates/app}/server/auth(auth)/google(googleAuth)/index.js (100%) rename {app/templates => templates/app}/server/auth(auth)/google(googleAuth)/passport.js (100%) rename {app/templates => templates/app}/server/auth(auth)/index.js (100%) rename {app/templates => templates/app}/server/auth(auth)/local/index.js (100%) rename {app/templates => templates/app}/server/auth(auth)/local/passport.js (100%) rename {app/templates => templates/app}/server/auth(auth)/twitter(twitterAuth)/index.js (100%) rename {app/templates => templates/app}/server/auth(auth)/twitter(twitterAuth)/passport.js (100%) rename {app/templates => templates/app}/server/components/errors/index.js (100%) rename {app/templates => templates/app}/server/config/_local.env.js (100%) rename {app/templates => templates/app}/server/config/_local.env.sample.js (100%) rename {app/templates => templates/app}/server/config/environment/development.js (100%) rename {app/templates => templates/app}/server/config/environment/index.js (100%) rename {app/templates => templates/app}/server/config/environment/production.js (100%) rename {app/templates => templates/app}/server/config/environment/shared.js (100%) rename {app/templates => templates/app}/server/config/environment/test.js (100%) rename {app/templates => templates/app}/server/config/express.js (100%) rename {app/templates => templates/app}/server/config/seed(models).js (100%) rename {app/templates => templates/app}/server/config/socketio(socketio).js (100%) rename {app/templates => templates/app}/server/index.js (100%) rename {app/templates => templates/app}/server/routes.js (100%) rename {app/templates => templates/app}/server/sqldb(sequelize)/index.js (100%) rename {app/templates => templates/app}/server/views/404(html).html (100%) rename {app/templates => templates/app}/server/views/404(jade).jade (100%) rename {app/templates => templates/app}/tsconfig.client(ts).json (100%) rename {app/templates => templates/app}/tsconfig.client.test(ts).json (100%) rename {app/templates => templates/app}/tsd(ts).json (100%) rename {app/templates => templates/app}/tsd_test(ts).json (100%) rename {endpoint/templates => templates/endpoint}/basename.controller.js (100%) rename {endpoint/templates => templates/endpoint}/basename.events(models).js (100%) rename {endpoint/templates => templates/endpoint}/basename.integration.js (100%) rename {endpoint/templates => templates/endpoint}/basename.model(mongooseModels).js (100%) rename {endpoint/templates => templates/endpoint}/basename.model(sequelizeModels).js (100%) rename {endpoint/templates => templates/endpoint}/basename.socket(socketio).js (100%) rename {endpoint/templates => templates/endpoint}/index.js (100%) rename {endpoint/templates => templates/endpoint}/index.spec.js (100%) diff --git a/.gitignore b/.gitignore index 78a6835b7..f9b1763a8 100644 --- a/.gitignore +++ b/.gitignore @@ -6,4 +6,5 @@ demo .DS_Store release.txt test/fixtures/bower.json -test/fixtures/package.json \ No newline at end of file +test/fixtures/package.json +generators \ No newline at end of file diff --git a/.npmignore b/.npmignore index c823223d9..58e92379e 100644 --- a/.npmignore +++ b/.npmignore @@ -1,3 +1,7 @@ angular-fullstack-deps test .idea +src +scripts +ISSUE_TEMPLATE.md +PULL_REQUEST_TEMPLATE.md diff --git a/app/index.js b/app/index.js deleted file mode 100644 index e4df68f08..000000000 --- a/app/index.js +++ /dev/null @@ -1,9 +0,0 @@ -'use strict'; - -// Register the Babel require hook -require('babel-register')({ - only: /generator-angular-fullstack\/(?!node_modules)/ -}); - -// Export the generator -module.exports = require('./generator').default; diff --git a/endpoint/index.js b/endpoint/index.js deleted file mode 100644 index e4df68f08..000000000 --- a/endpoint/index.js +++ /dev/null @@ -1,9 +0,0 @@ -'use strict'; - -// Register the Babel require hook -require('babel-register')({ - only: /generator-angular-fullstack\/(?!node_modules)/ -}); - -// Export the generator -module.exports = require('./generator').default; diff --git a/gulpfile.babel.js b/gulpfile.babel.js new file mode 100644 index 000000000..a8c2ecfe1 --- /dev/null +++ b/gulpfile.babel.js @@ -0,0 +1,35 @@ +'use strict'; +// import _ from 'lodash'; +// import fs from 'fs'; +import gulp from 'gulp'; +import babel from 'gulp-babel'; +import del from 'del'; +import runSequence from 'run-sequence'; + +gulp.task('clean', () => { + return del(['generators/**/*']); +}); + +gulp.task('babel', () => { + return gulp.src(['src/**/*.js']) + .pipe(babel()) + .pipe(gulp.dest('generators')); +}); + +gulp.task('watch', () => { + return gulp.watch('src/**/*.js', ['babel']); +}); + +gulp.task('copy', () => { + return gulp.src(['src/**/*', '!src/**/*.js']) + .pipe(gulp.dest('generators')); +}); + +gulp.task('build', cb => { + return runSequence( + 'clean', + 'babel', + 'copy', + cb + ); +}); diff --git a/package.json b/package.json index e575595c9..0db5e59e0 100644 --- a/package.json +++ b/package.json @@ -34,13 +34,9 @@ "test": "grunt test" }, "dependencies": { - "babel-core": "^6.7.0", "babel-plugin-syntax-class-properties": "^6.5.0", "babel-plugin-syntax-flow": "^6.5.0", - "babel-plugin-transform-class-properties": "^6.6.0", "babel-plugin-transform-flow-strip-types": "^6.7.0", - "babel-preset-es2015": "^6.6.0", - "babel-register": "^6.6.5", "chalk": "^1.1.0", "generator-ng-component": "~0.2.1", "glob": "^7.0.3", @@ -55,6 +51,10 @@ }, "devDependencies": { "chai": "^3.2.0", + "babel-register": "^6.6.5", + "babel-preset-es2015": "^6.6.0", + "babel-plugin-transform-class-properties": "^6.6.0", + "del": "^2.2.0", "grunt": "^1.0.1", "grunt-build-control": "^0.7.0", "grunt-contrib-clean": "^1.0.0", @@ -68,6 +68,7 @@ "mocha": "^2.2.5", "q": "^1.0.1", "recursive-readdir": "^2.0.0", + "run-sequence": "^1.1.5", "shelljs": "^0.6.0", "yeoman-assert": "^2.0.0", "yeoman-test": "^1.1.0" diff --git a/app/USAGE b/src/app/USAGE similarity index 100% rename from app/USAGE rename to src/app/USAGE diff --git a/app/generator.js b/src/app/index.js similarity index 99% rename from app/generator.js rename to src/app/index.js index ad6904f78..1bfaa9e16 100644 --- a/app/generator.js +++ b/src/app/index.js @@ -11,7 +11,7 @@ import babelStream from 'gulp-babel'; import beaufityStream from 'gulp-beautify'; import filter from 'gulp-filter'; -export default class Generator extends Base { +export class Generator extends Base { constructor(...args) { super(...args); @@ -496,7 +496,7 @@ export default class Generator extends Base { ]); let self = this; - this.sourceRoot(path.join(__dirname, './templates')); + this.sourceRoot(path.join(__dirname, '../../templates/app')); this.processDirectory('.', '.'); }, generateEndpoint: function() { @@ -531,3 +531,5 @@ export default class Generator extends Base { return {}; } } + +module.exports = Generator; diff --git a/controller/index.js b/src/controller/index.js similarity index 100% rename from controller/index.js rename to src/controller/index.js diff --git a/decorator/index.js b/src/decorator/index.js similarity index 100% rename from decorator/index.js rename to src/decorator/index.js diff --git a/directive/index.js b/src/directive/index.js similarity index 100% rename from directive/index.js rename to src/directive/index.js diff --git a/endpoint/generator.js b/src/endpoint/index.js similarity index 96% rename from endpoint/generator.js rename to src/endpoint/index.js index a7c968093..9ea93f7e8 100644 --- a/endpoint/generator.js +++ b/src/endpoint/index.js @@ -4,7 +4,7 @@ import path from 'path'; import {NamedBase} from 'yeoman-generator'; import {genNamedBase} from '../generator-base'; -export default class Generator extends NamedBase { +export class Generator extends NamedBase { constructor(...args) { super(...args); @@ -99,7 +99,7 @@ export default class Generator extends NamedBase { } writing() { - this.sourceRoot(path.join(__dirname, './templates')); + this.sourceRoot(path.join(__dirname, '../../templates/endpoint')); this.processDirectory('.', this.routeDest); } @@ -145,3 +145,5 @@ export default class Generator extends NamedBase { } } } + +module.exports = Generator; diff --git a/factory/index.js b/src/factory/index.js similarity index 100% rename from factory/index.js rename to src/factory/index.js diff --git a/filter/index.js b/src/filter/index.js similarity index 100% rename from filter/index.js rename to src/filter/index.js diff --git a/generator-base.js b/src/generator-base.js similarity index 100% rename from generator-base.js rename to src/generator-base.js diff --git a/heroku/USAGE b/src/heroku/USAGE similarity index 100% rename from heroku/USAGE rename to src/heroku/USAGE diff --git a/heroku/index.js b/src/heroku/index.js similarity index 100% rename from heroku/index.js rename to src/heroku/index.js diff --git a/heroku/templates/Procfile b/src/heroku/templates/Procfile similarity index 100% rename from heroku/templates/Procfile rename to src/heroku/templates/Procfile diff --git a/insight-init.js b/src/insight-init.js similarity index 92% rename from insight-init.js rename to src/insight-init.js index b9fede03b..66984352d 100644 --- a/insight-init.js +++ b/src/insight-init.js @@ -1,6 +1,6 @@ 'use strict'; var Insight = require('insight'); -var pkg = require('./package.json'); +var pkg = require('../package.json'); var insight = new Insight({ // Google Analytics tracking code diff --git a/openshift/USAGE b/src/openshift/USAGE similarity index 100% rename from openshift/USAGE rename to src/openshift/USAGE diff --git a/openshift/index.js b/src/openshift/index.js similarity index 100% rename from openshift/index.js rename to src/openshift/index.js diff --git a/openshift/templates/hot_deploy b/src/openshift/templates/hot_deploy similarity index 100% rename from openshift/templates/hot_deploy rename to src/openshift/templates/hot_deploy diff --git a/provider/index.js b/src/provider/index.js similarity index 100% rename from provider/index.js rename to src/provider/index.js diff --git a/route/index.js b/src/route/index.js similarity index 100% rename from route/index.js rename to src/route/index.js diff --git a/service/index.js b/src/service/index.js similarity index 100% rename from service/index.js rename to src/service/index.js diff --git a/util.js b/src/util.js similarity index 100% rename from util.js rename to src/util.js diff --git a/app/templates/.bowerrc b/templates/app/.bowerrc similarity index 100% rename from app/templates/.bowerrc rename to templates/app/.bowerrc diff --git a/app/templates/.buildignore b/templates/app/.buildignore similarity index 100% rename from app/templates/.buildignore rename to templates/app/.buildignore diff --git a/app/templates/.editorconfig b/templates/app/.editorconfig similarity index 100% rename from app/templates/.editorconfig rename to templates/app/.editorconfig diff --git a/app/templates/.gitattributes b/templates/app/.gitattributes similarity index 100% rename from app/templates/.gitattributes rename to templates/app/.gitattributes diff --git a/app/templates/.jscsrc b/templates/app/.jscsrc similarity index 100% rename from app/templates/.jscsrc rename to templates/app/.jscsrc diff --git a/app/templates/.travis.yml b/templates/app/.travis.yml similarity index 100% rename from app/templates/.travis.yml rename to templates/app/.travis.yml diff --git a/app/templates/Gruntfile(grunt).js b/templates/app/Gruntfile(grunt).js similarity index 100% rename from app/templates/Gruntfile(grunt).js rename to templates/app/Gruntfile(grunt).js diff --git a/app/templates/README.md b/templates/app/README.md similarity index 100% rename from app/templates/README.md rename to templates/app/README.md diff --git a/app/templates/_.babelrc b/templates/app/_.babelrc similarity index 100% rename from app/templates/_.babelrc rename to templates/app/_.babelrc diff --git a/app/templates/_.gitignore b/templates/app/_.gitignore similarity index 100% rename from app/templates/_.gitignore rename to templates/app/_.gitignore diff --git a/app/templates/_bower.json b/templates/app/_bower.json similarity index 100% rename from app/templates/_bower.json rename to templates/app/_bower.json diff --git a/app/templates/_package.json b/templates/app/_package.json similarity index 100% rename from app/templates/_package.json rename to templates/app/_package.json diff --git a/app/templates/client/.htaccess b/templates/app/client/.htaccess similarity index 100% rename from app/templates/client/.htaccess rename to templates/app/client/.htaccess diff --git a/app/templates/client/.jshintrc(babel) b/templates/app/client/.jshintrc(babel) similarity index 100% rename from app/templates/client/.jshintrc(babel) rename to templates/app/client/.jshintrc(babel) diff --git a/app/templates/client/app/account(auth)/account.js b/templates/app/client/app/account(auth)/account.js similarity index 100% rename from app/templates/client/app/account(auth)/account.js rename to templates/app/client/app/account(auth)/account.js diff --git a/app/templates/client/app/account(auth)/login/login(html).html b/templates/app/client/app/account(auth)/login/login(html).html similarity index 100% rename from app/templates/client/app/account(auth)/login/login(html).html rename to templates/app/client/app/account(auth)/login/login(html).html diff --git a/app/templates/client/app/account(auth)/login/login(jade).jade b/templates/app/client/app/account(auth)/login/login(jade).jade similarity index 100% rename from app/templates/client/app/account(auth)/login/login(jade).jade rename to templates/app/client/app/account(auth)/login/login(jade).jade diff --git a/app/templates/client/app/account(auth)/login/login.controller.js b/templates/app/client/app/account(auth)/login/login.controller.js similarity index 100% rename from app/templates/client/app/account(auth)/login/login.controller.js rename to templates/app/client/app/account(auth)/login/login.controller.js diff --git a/app/templates/client/app/account(auth)/settings/settings(html).html b/templates/app/client/app/account(auth)/settings/settings(html).html similarity index 100% rename from app/templates/client/app/account(auth)/settings/settings(html).html rename to templates/app/client/app/account(auth)/settings/settings(html).html diff --git a/app/templates/client/app/account(auth)/settings/settings(jade).jade b/templates/app/client/app/account(auth)/settings/settings(jade).jade similarity index 100% rename from app/templates/client/app/account(auth)/settings/settings(jade).jade rename to templates/app/client/app/account(auth)/settings/settings(jade).jade diff --git a/app/templates/client/app/account(auth)/settings/settings.controller.js b/templates/app/client/app/account(auth)/settings/settings.controller.js similarity index 100% rename from app/templates/client/app/account(auth)/settings/settings.controller.js rename to templates/app/client/app/account(auth)/settings/settings.controller.js diff --git a/app/templates/client/app/account(auth)/signup/signup(html).html b/templates/app/client/app/account(auth)/signup/signup(html).html similarity index 100% rename from app/templates/client/app/account(auth)/signup/signup(html).html rename to templates/app/client/app/account(auth)/signup/signup(html).html diff --git a/app/templates/client/app/account(auth)/signup/signup(jade).jade b/templates/app/client/app/account(auth)/signup/signup(jade).jade similarity index 100% rename from app/templates/client/app/account(auth)/signup/signup(jade).jade rename to templates/app/client/app/account(auth)/signup/signup(jade).jade diff --git a/app/templates/client/app/account(auth)/signup/signup.controller.js b/templates/app/client/app/account(auth)/signup/signup.controller.js similarity index 100% rename from app/templates/client/app/account(auth)/signup/signup.controller.js rename to templates/app/client/app/account(auth)/signup/signup.controller.js diff --git a/app/templates/client/app/admin(auth)/admin(css).css b/templates/app/client/app/admin(auth)/admin(css).css similarity index 100% rename from app/templates/client/app/admin(auth)/admin(css).css rename to templates/app/client/app/admin(auth)/admin(css).css diff --git a/app/templates/client/app/admin(auth)/admin(html).html b/templates/app/client/app/admin(auth)/admin(html).html similarity index 100% rename from app/templates/client/app/admin(auth)/admin(html).html rename to templates/app/client/app/admin(auth)/admin(html).html diff --git a/app/templates/client/app/admin(auth)/admin(jade).jade b/templates/app/client/app/admin(auth)/admin(jade).jade similarity index 100% rename from app/templates/client/app/admin(auth)/admin(jade).jade rename to templates/app/client/app/admin(auth)/admin(jade).jade diff --git a/app/templates/client/app/admin(auth)/admin(less).less b/templates/app/client/app/admin(auth)/admin(less).less similarity index 100% rename from app/templates/client/app/admin(auth)/admin(less).less rename to templates/app/client/app/admin(auth)/admin(less).less diff --git a/app/templates/client/app/admin(auth)/admin(sass).scss b/templates/app/client/app/admin(auth)/admin(sass).scss similarity index 100% rename from app/templates/client/app/admin(auth)/admin(sass).scss rename to templates/app/client/app/admin(auth)/admin(sass).scss diff --git a/app/templates/client/app/admin(auth)/admin(stylus).styl b/templates/app/client/app/admin(auth)/admin(stylus).styl similarity index 100% rename from app/templates/client/app/admin(auth)/admin(stylus).styl rename to templates/app/client/app/admin(auth)/admin(stylus).styl diff --git a/app/templates/client/app/admin(auth)/admin.controller.js b/templates/app/client/app/admin(auth)/admin.controller.js similarity index 100% rename from app/templates/client/app/admin(auth)/admin.controller.js rename to templates/app/client/app/admin(auth)/admin.controller.js diff --git a/app/templates/client/app/admin(auth)/admin.module.js b/templates/app/client/app/admin(auth)/admin.module.js similarity index 100% rename from app/templates/client/app/admin(auth)/admin.module.js rename to templates/app/client/app/admin(auth)/admin.module.js diff --git a/app/templates/client/app/admin(auth)/admin.router.js b/templates/app/client/app/admin(auth)/admin.router.js similarity index 100% rename from app/templates/client/app/admin(auth)/admin.router.js rename to templates/app/client/app/admin(auth)/admin.router.js diff --git a/app/templates/client/app/app(css).css b/templates/app/client/app/app(css).css similarity index 100% rename from app/templates/client/app/app(css).css rename to templates/app/client/app/app(css).css diff --git a/app/templates/client/app/app(less).less b/templates/app/client/app/app(less).less similarity index 100% rename from app/templates/client/app/app(less).less rename to templates/app/client/app/app(less).less diff --git a/app/templates/client/app/app(sass).scss b/templates/app/client/app/app(sass).scss similarity index 100% rename from app/templates/client/app/app(sass).scss rename to templates/app/client/app/app(sass).scss diff --git a/app/templates/client/app/app(stylus).styl b/templates/app/client/app/app(stylus).styl similarity index 100% rename from app/templates/client/app/app(stylus).styl rename to templates/app/client/app/app(stylus).styl diff --git a/app/templates/client/app/app.js b/templates/app/client/app/app.js similarity index 100% rename from app/templates/client/app/app.js rename to templates/app/client/app/app.js diff --git a/app/templates/client/app/main/main(css).css b/templates/app/client/app/main/main(css).css similarity index 100% rename from app/templates/client/app/main/main(css).css rename to templates/app/client/app/main/main(css).css diff --git a/app/templates/client/app/main/main(html).html b/templates/app/client/app/main/main(html).html similarity index 100% rename from app/templates/client/app/main/main(html).html rename to templates/app/client/app/main/main(html).html diff --git a/app/templates/client/app/main/main(jade).jade b/templates/app/client/app/main/main(jade).jade similarity index 100% rename from app/templates/client/app/main/main(jade).jade rename to templates/app/client/app/main/main(jade).jade diff --git a/app/templates/client/app/main/main(less).less b/templates/app/client/app/main/main(less).less similarity index 100% rename from app/templates/client/app/main/main(less).less rename to templates/app/client/app/main/main(less).less diff --git a/app/templates/client/app/main/main(sass).scss b/templates/app/client/app/main/main(sass).scss similarity index 100% rename from app/templates/client/app/main/main(sass).scss rename to templates/app/client/app/main/main(sass).scss diff --git a/app/templates/client/app/main/main(stylus).styl b/templates/app/client/app/main/main(stylus).styl similarity index 100% rename from app/templates/client/app/main/main(stylus).styl rename to templates/app/client/app/main/main(stylus).styl diff --git a/app/templates/client/app/main/main.controller.js b/templates/app/client/app/main/main.controller.js similarity index 100% rename from app/templates/client/app/main/main.controller.js rename to templates/app/client/app/main/main.controller.js diff --git a/app/templates/client/app/main/main.controller.spec.js b/templates/app/client/app/main/main.controller.spec.js similarity index 100% rename from app/templates/client/app/main/main.controller.spec.js rename to templates/app/client/app/main/main.controller.spec.js diff --git a/app/templates/client/app/main/main.js b/templates/app/client/app/main/main.js similarity index 100% rename from app/templates/client/app/main/main.js rename to templates/app/client/app/main/main.js diff --git a/app/templates/client/assets/images/!yeoman.png b/templates/app/client/assets/images/!yeoman.png similarity index 100% rename from app/templates/client/assets/images/!yeoman.png rename to templates/app/client/assets/images/!yeoman.png diff --git a/app/templates/client/components/auth(auth)/auth.module.js b/templates/app/client/components/auth(auth)/auth.module.js similarity index 100% rename from app/templates/client/components/auth(auth)/auth.module.js rename to templates/app/client/components/auth(auth)/auth.module.js diff --git a/app/templates/client/components/auth(auth)/auth.service.js b/templates/app/client/components/auth(auth)/auth.service.js similarity index 100% rename from app/templates/client/components/auth(auth)/auth.service.js rename to templates/app/client/components/auth(auth)/auth.service.js diff --git a/app/templates/client/components/auth(auth)/interceptor.service.js b/templates/app/client/components/auth(auth)/interceptor.service.js similarity index 100% rename from app/templates/client/components/auth(auth)/interceptor.service.js rename to templates/app/client/components/auth(auth)/interceptor.service.js diff --git a/app/templates/client/components/auth(auth)/router.decorator.js b/templates/app/client/components/auth(auth)/router.decorator.js similarity index 100% rename from app/templates/client/components/auth(auth)/router.decorator.js rename to templates/app/client/components/auth(auth)/router.decorator.js diff --git a/app/templates/client/components/auth(auth)/user.service.js b/templates/app/client/components/auth(auth)/user.service.js similarity index 100% rename from app/templates/client/components/auth(auth)/user.service.js rename to templates/app/client/components/auth(auth)/user.service.js diff --git a/app/templates/client/components/footer/footer(css).css b/templates/app/client/components/footer/footer(css).css similarity index 100% rename from app/templates/client/components/footer/footer(css).css rename to templates/app/client/components/footer/footer(css).css diff --git a/app/templates/client/components/footer/footer(html).html b/templates/app/client/components/footer/footer(html).html similarity index 100% rename from app/templates/client/components/footer/footer(html).html rename to templates/app/client/components/footer/footer(html).html diff --git a/app/templates/client/components/footer/footer(jade).jade b/templates/app/client/components/footer/footer(jade).jade similarity index 100% rename from app/templates/client/components/footer/footer(jade).jade rename to templates/app/client/components/footer/footer(jade).jade diff --git a/app/templates/client/components/footer/footer(less).less b/templates/app/client/components/footer/footer(less).less similarity index 100% rename from app/templates/client/components/footer/footer(less).less rename to templates/app/client/components/footer/footer(less).less diff --git a/app/templates/client/components/footer/footer(sass).scss b/templates/app/client/components/footer/footer(sass).scss similarity index 100% rename from app/templates/client/components/footer/footer(sass).scss rename to templates/app/client/components/footer/footer(sass).scss diff --git a/app/templates/client/components/footer/footer(stylus).styl b/templates/app/client/components/footer/footer(stylus).styl similarity index 100% rename from app/templates/client/components/footer/footer(stylus).styl rename to templates/app/client/components/footer/footer(stylus).styl diff --git a/app/templates/client/components/footer/footer.directive.js b/templates/app/client/components/footer/footer.directive.js similarity index 100% rename from app/templates/client/components/footer/footer.directive.js rename to templates/app/client/components/footer/footer.directive.js diff --git a/app/templates/client/components/modal(uibootstrap)/modal(css).css b/templates/app/client/components/modal(uibootstrap)/modal(css).css similarity index 100% rename from app/templates/client/components/modal(uibootstrap)/modal(css).css rename to templates/app/client/components/modal(uibootstrap)/modal(css).css diff --git a/app/templates/client/components/modal(uibootstrap)/modal(html).html b/templates/app/client/components/modal(uibootstrap)/modal(html).html similarity index 100% rename from app/templates/client/components/modal(uibootstrap)/modal(html).html rename to templates/app/client/components/modal(uibootstrap)/modal(html).html diff --git a/app/templates/client/components/modal(uibootstrap)/modal(jade).jade b/templates/app/client/components/modal(uibootstrap)/modal(jade).jade similarity index 100% rename from app/templates/client/components/modal(uibootstrap)/modal(jade).jade rename to templates/app/client/components/modal(uibootstrap)/modal(jade).jade diff --git a/app/templates/client/components/modal(uibootstrap)/modal(less).less b/templates/app/client/components/modal(uibootstrap)/modal(less).less similarity index 100% rename from app/templates/client/components/modal(uibootstrap)/modal(less).less rename to templates/app/client/components/modal(uibootstrap)/modal(less).less diff --git a/app/templates/client/components/modal(uibootstrap)/modal(sass).scss b/templates/app/client/components/modal(uibootstrap)/modal(sass).scss similarity index 100% rename from app/templates/client/components/modal(uibootstrap)/modal(sass).scss rename to templates/app/client/components/modal(uibootstrap)/modal(sass).scss diff --git a/app/templates/client/components/modal(uibootstrap)/modal(stylus).styl b/templates/app/client/components/modal(uibootstrap)/modal(stylus).styl similarity index 100% rename from app/templates/client/components/modal(uibootstrap)/modal(stylus).styl rename to templates/app/client/components/modal(uibootstrap)/modal(stylus).styl diff --git a/app/templates/client/components/modal(uibootstrap)/modal.service.js b/templates/app/client/components/modal(uibootstrap)/modal.service.js similarity index 100% rename from app/templates/client/components/modal(uibootstrap)/modal.service.js rename to templates/app/client/components/modal(uibootstrap)/modal.service.js diff --git a/app/templates/client/components/mongoose-error(auth)/mongoose-error.directive.js b/templates/app/client/components/mongoose-error(auth)/mongoose-error.directive.js similarity index 100% rename from app/templates/client/components/mongoose-error(auth)/mongoose-error.directive.js rename to templates/app/client/components/mongoose-error(auth)/mongoose-error.directive.js diff --git a/app/templates/client/components/navbar/navbar(html).html b/templates/app/client/components/navbar/navbar(html).html similarity index 100% rename from app/templates/client/components/navbar/navbar(html).html rename to templates/app/client/components/navbar/navbar(html).html diff --git a/app/templates/client/components/navbar/navbar(jade).jade b/templates/app/client/components/navbar/navbar(jade).jade similarity index 100% rename from app/templates/client/components/navbar/navbar(jade).jade rename to templates/app/client/components/navbar/navbar(jade).jade diff --git a/app/templates/client/components/navbar/navbar.controller.js b/templates/app/client/components/navbar/navbar.controller.js similarity index 100% rename from app/templates/client/components/navbar/navbar.controller.js rename to templates/app/client/components/navbar/navbar.controller.js diff --git a/app/templates/client/components/navbar/navbar.directive.js b/templates/app/client/components/navbar/navbar.directive.js similarity index 100% rename from app/templates/client/components/navbar/navbar.directive.js rename to templates/app/client/components/navbar/navbar.directive.js diff --git a/app/templates/client/components/oauth-buttons(oauth)/oauth-buttons(css).css b/templates/app/client/components/oauth-buttons(oauth)/oauth-buttons(css).css similarity index 100% rename from app/templates/client/components/oauth-buttons(oauth)/oauth-buttons(css).css rename to templates/app/client/components/oauth-buttons(oauth)/oauth-buttons(css).css diff --git a/app/templates/client/components/oauth-buttons(oauth)/oauth-buttons(html).html b/templates/app/client/components/oauth-buttons(oauth)/oauth-buttons(html).html similarity index 100% rename from app/templates/client/components/oauth-buttons(oauth)/oauth-buttons(html).html rename to templates/app/client/components/oauth-buttons(oauth)/oauth-buttons(html).html diff --git a/app/templates/client/components/oauth-buttons(oauth)/oauth-buttons(jade).jade b/templates/app/client/components/oauth-buttons(oauth)/oauth-buttons(jade).jade similarity index 100% rename from app/templates/client/components/oauth-buttons(oauth)/oauth-buttons(jade).jade rename to templates/app/client/components/oauth-buttons(oauth)/oauth-buttons(jade).jade diff --git a/app/templates/client/components/oauth-buttons(oauth)/oauth-buttons(less).less b/templates/app/client/components/oauth-buttons(oauth)/oauth-buttons(less).less similarity index 100% rename from app/templates/client/components/oauth-buttons(oauth)/oauth-buttons(less).less rename to templates/app/client/components/oauth-buttons(oauth)/oauth-buttons(less).less diff --git a/app/templates/client/components/oauth-buttons(oauth)/oauth-buttons(sass).scss b/templates/app/client/components/oauth-buttons(oauth)/oauth-buttons(sass).scss similarity index 100% rename from app/templates/client/components/oauth-buttons(oauth)/oauth-buttons(sass).scss rename to templates/app/client/components/oauth-buttons(oauth)/oauth-buttons(sass).scss diff --git a/app/templates/client/components/oauth-buttons(oauth)/oauth-buttons(stylus).styl b/templates/app/client/components/oauth-buttons(oauth)/oauth-buttons(stylus).styl similarity index 100% rename from app/templates/client/components/oauth-buttons(oauth)/oauth-buttons(stylus).styl rename to templates/app/client/components/oauth-buttons(oauth)/oauth-buttons(stylus).styl diff --git a/app/templates/client/components/oauth-buttons(oauth)/oauth-buttons.controller.js b/templates/app/client/components/oauth-buttons(oauth)/oauth-buttons.controller.js similarity index 100% rename from app/templates/client/components/oauth-buttons(oauth)/oauth-buttons.controller.js rename to templates/app/client/components/oauth-buttons(oauth)/oauth-buttons.controller.js diff --git a/app/templates/client/components/oauth-buttons(oauth)/oauth-buttons.controller.spec.js b/templates/app/client/components/oauth-buttons(oauth)/oauth-buttons.controller.spec.js similarity index 100% rename from app/templates/client/components/oauth-buttons(oauth)/oauth-buttons.controller.spec.js rename to templates/app/client/components/oauth-buttons(oauth)/oauth-buttons.controller.spec.js diff --git a/app/templates/client/components/oauth-buttons(oauth)/oauth-buttons.directive.js b/templates/app/client/components/oauth-buttons(oauth)/oauth-buttons.directive.js similarity index 100% rename from app/templates/client/components/oauth-buttons(oauth)/oauth-buttons.directive.js rename to templates/app/client/components/oauth-buttons(oauth)/oauth-buttons.directive.js diff --git a/app/templates/client/components/oauth-buttons(oauth)/oauth-buttons.directive.spec.js b/templates/app/client/components/oauth-buttons(oauth)/oauth-buttons.directive.spec.js similarity index 100% rename from app/templates/client/components/oauth-buttons(oauth)/oauth-buttons.directive.spec.js rename to templates/app/client/components/oauth-buttons(oauth)/oauth-buttons.directive.spec.js diff --git a/app/templates/client/components/socket(socketio)/socket.mock.js b/templates/app/client/components/socket(socketio)/socket.mock.js similarity index 100% rename from app/templates/client/components/socket(socketio)/socket.mock.js rename to templates/app/client/components/socket(socketio)/socket.mock.js diff --git a/app/templates/client/components/socket(socketio)/socket.service.js b/templates/app/client/components/socket(socketio)/socket.service.js similarity index 100% rename from app/templates/client/components/socket(socketio)/socket.service.js rename to templates/app/client/components/socket(socketio)/socket.service.js diff --git a/app/templates/client/components/ui-router(uirouter)/ui-router.mock.js b/templates/app/client/components/ui-router(uirouter)/ui-router.mock.js similarity index 100% rename from app/templates/client/components/ui-router(uirouter)/ui-router.mock.js rename to templates/app/client/components/ui-router(uirouter)/ui-router.mock.js diff --git a/app/templates/client/components/util/util.module.js b/templates/app/client/components/util/util.module.js similarity index 100% rename from app/templates/client/components/util/util.module.js rename to templates/app/client/components/util/util.module.js diff --git a/app/templates/client/components/util/util.service.js b/templates/app/client/components/util/util.service.js similarity index 100% rename from app/templates/client/components/util/util.service.js rename to templates/app/client/components/util/util.service.js diff --git a/app/templates/client/favicon.ico b/templates/app/client/favicon.ico similarity index 100% rename from app/templates/client/favicon.ico rename to templates/app/client/favicon.ico diff --git a/app/templates/client/index.html b/templates/app/client/index.html similarity index 100% rename from app/templates/client/index.html rename to templates/app/client/index.html diff --git a/app/templates/client/robots.txt b/templates/app/client/robots.txt similarity index 100% rename from app/templates/client/robots.txt rename to templates/app/client/robots.txt diff --git a/app/templates/client/tslint.json(ts) b/templates/app/client/tslint.json(ts) similarity index 100% rename from app/templates/client/tslint.json(ts) rename to templates/app/client/tslint.json(ts) diff --git a/app/templates/e2e/account(auth)/login/login.po.js b/templates/app/e2e/account(auth)/login/login.po.js similarity index 100% rename from app/templates/e2e/account(auth)/login/login.po.js rename to templates/app/e2e/account(auth)/login/login.po.js diff --git a/app/templates/e2e/account(auth)/login/login.spec(jasmine).js b/templates/app/e2e/account(auth)/login/login.spec(jasmine).js similarity index 100% rename from app/templates/e2e/account(auth)/login/login.spec(jasmine).js rename to templates/app/e2e/account(auth)/login/login.spec(jasmine).js diff --git a/app/templates/e2e/account(auth)/login/login.spec(mocha).js b/templates/app/e2e/account(auth)/login/login.spec(mocha).js similarity index 100% rename from app/templates/e2e/account(auth)/login/login.spec(mocha).js rename to templates/app/e2e/account(auth)/login/login.spec(mocha).js diff --git a/app/templates/e2e/account(auth)/logout/logout.spec(jasmine).js b/templates/app/e2e/account(auth)/logout/logout.spec(jasmine).js similarity index 100% rename from app/templates/e2e/account(auth)/logout/logout.spec(jasmine).js rename to templates/app/e2e/account(auth)/logout/logout.spec(jasmine).js diff --git a/app/templates/e2e/account(auth)/logout/logout.spec(mocha).js b/templates/app/e2e/account(auth)/logout/logout.spec(mocha).js similarity index 100% rename from app/templates/e2e/account(auth)/logout/logout.spec(mocha).js rename to templates/app/e2e/account(auth)/logout/logout.spec(mocha).js diff --git a/app/templates/e2e/account(auth)/signup/signup.po.js b/templates/app/e2e/account(auth)/signup/signup.po.js similarity index 100% rename from app/templates/e2e/account(auth)/signup/signup.po.js rename to templates/app/e2e/account(auth)/signup/signup.po.js diff --git a/app/templates/e2e/account(auth)/signup/signup.spec(jasmine).js b/templates/app/e2e/account(auth)/signup/signup.spec(jasmine).js similarity index 100% rename from app/templates/e2e/account(auth)/signup/signup.spec(jasmine).js rename to templates/app/e2e/account(auth)/signup/signup.spec(jasmine).js diff --git a/app/templates/e2e/account(auth)/signup/signup.spec(mocha).js b/templates/app/e2e/account(auth)/signup/signup.spec(mocha).js similarity index 100% rename from app/templates/e2e/account(auth)/signup/signup.spec(mocha).js rename to templates/app/e2e/account(auth)/signup/signup.spec(mocha).js diff --git a/app/templates/e2e/components/navbar/navbar.po.js b/templates/app/e2e/components/navbar/navbar.po.js similarity index 100% rename from app/templates/e2e/components/navbar/navbar.po.js rename to templates/app/e2e/components/navbar/navbar.po.js diff --git a/app/templates/e2e/components/oauth-buttons(oauth)/oauth-buttons.po.js b/templates/app/e2e/components/oauth-buttons(oauth)/oauth-buttons.po.js similarity index 100% rename from app/templates/e2e/components/oauth-buttons(oauth)/oauth-buttons.po.js rename to templates/app/e2e/components/oauth-buttons(oauth)/oauth-buttons.po.js diff --git a/app/templates/e2e/main/main.po.js b/templates/app/e2e/main/main.po.js similarity index 100% rename from app/templates/e2e/main/main.po.js rename to templates/app/e2e/main/main.po.js diff --git a/app/templates/e2e/main/main.spec(jasmine).js b/templates/app/e2e/main/main.spec(jasmine).js similarity index 100% rename from app/templates/e2e/main/main.spec(jasmine).js rename to templates/app/e2e/main/main.spec(jasmine).js diff --git a/app/templates/e2e/main/main.spec(mocha).js b/templates/app/e2e/main/main.spec(mocha).js similarity index 100% rename from app/templates/e2e/main/main.spec(mocha).js rename to templates/app/e2e/main/main.spec(mocha).js diff --git a/app/templates/gulpfile.babel(gulp).js b/templates/app/gulpfile.babel(gulp).js similarity index 100% rename from app/templates/gulpfile.babel(gulp).js rename to templates/app/gulpfile.babel(gulp).js diff --git a/app/templates/karma.conf.js b/templates/app/karma.conf.js similarity index 100% rename from app/templates/karma.conf.js rename to templates/app/karma.conf.js diff --git a/app/templates/mocha.conf.js b/templates/app/mocha.conf.js similarity index 100% rename from app/templates/mocha.conf.js rename to templates/app/mocha.conf.js diff --git a/app/templates/mocha.global(gulp).js b/templates/app/mocha.global(gulp).js similarity index 100% rename from app/templates/mocha.global(gulp).js rename to templates/app/mocha.global(gulp).js diff --git a/app/templates/protractor.conf.js b/templates/app/protractor.conf.js similarity index 100% rename from app/templates/protractor.conf.js rename to templates/app/protractor.conf.js diff --git a/app/templates/server/.jshintrc b/templates/app/server/.jshintrc similarity index 100% rename from app/templates/server/.jshintrc rename to templates/app/server/.jshintrc diff --git a/app/templates/server/.jshintrc-spec b/templates/app/server/.jshintrc-spec similarity index 100% rename from app/templates/server/.jshintrc-spec rename to templates/app/server/.jshintrc-spec diff --git a/app/templates/server/api/user(auth)/index.js b/templates/app/server/api/user(auth)/index.js similarity index 100% rename from app/templates/server/api/user(auth)/index.js rename to templates/app/server/api/user(auth)/index.js diff --git a/app/templates/server/api/user(auth)/index.spec.js b/templates/app/server/api/user(auth)/index.spec.js similarity index 100% rename from app/templates/server/api/user(auth)/index.spec.js rename to templates/app/server/api/user(auth)/index.spec.js diff --git a/app/templates/server/api/user(auth)/user.controller.js b/templates/app/server/api/user(auth)/user.controller.js similarity index 100% rename from app/templates/server/api/user(auth)/user.controller.js rename to templates/app/server/api/user(auth)/user.controller.js diff --git a/app/templates/server/api/user(auth)/user.events.js b/templates/app/server/api/user(auth)/user.events.js similarity index 100% rename from app/templates/server/api/user(auth)/user.events.js rename to templates/app/server/api/user(auth)/user.events.js diff --git a/app/templates/server/api/user(auth)/user.integration.js b/templates/app/server/api/user(auth)/user.integration.js similarity index 100% rename from app/templates/server/api/user(auth)/user.integration.js rename to templates/app/server/api/user(auth)/user.integration.js diff --git a/app/templates/server/api/user(auth)/user.model(mongooseModels).js b/templates/app/server/api/user(auth)/user.model(mongooseModels).js similarity index 100% rename from app/templates/server/api/user(auth)/user.model(mongooseModels).js rename to templates/app/server/api/user(auth)/user.model(mongooseModels).js diff --git a/app/templates/server/api/user(auth)/user.model(sequelizeModels).js b/templates/app/server/api/user(auth)/user.model(sequelizeModels).js similarity index 100% rename from app/templates/server/api/user(auth)/user.model(sequelizeModels).js rename to templates/app/server/api/user(auth)/user.model(sequelizeModels).js diff --git a/app/templates/server/api/user(auth)/user.model.spec(mongooseModels).js b/templates/app/server/api/user(auth)/user.model.spec(mongooseModels).js similarity index 100% rename from app/templates/server/api/user(auth)/user.model.spec(mongooseModels).js rename to templates/app/server/api/user(auth)/user.model.spec(mongooseModels).js diff --git a/app/templates/server/api/user(auth)/user.model.spec(sequelizeModels).js b/templates/app/server/api/user(auth)/user.model.spec(sequelizeModels).js similarity index 100% rename from app/templates/server/api/user(auth)/user.model.spec(sequelizeModels).js rename to templates/app/server/api/user(auth)/user.model.spec(sequelizeModels).js diff --git a/app/templates/server/app.js b/templates/app/server/app.js similarity index 100% rename from app/templates/server/app.js rename to templates/app/server/app.js diff --git a/app/templates/server/auth(auth)/auth.service.js b/templates/app/server/auth(auth)/auth.service.js similarity index 100% rename from app/templates/server/auth(auth)/auth.service.js rename to templates/app/server/auth(auth)/auth.service.js diff --git a/app/templates/server/auth(auth)/facebook(facebookAuth)/index.js b/templates/app/server/auth(auth)/facebook(facebookAuth)/index.js similarity index 100% rename from app/templates/server/auth(auth)/facebook(facebookAuth)/index.js rename to templates/app/server/auth(auth)/facebook(facebookAuth)/index.js diff --git a/app/templates/server/auth(auth)/facebook(facebookAuth)/passport.js b/templates/app/server/auth(auth)/facebook(facebookAuth)/passport.js similarity index 100% rename from app/templates/server/auth(auth)/facebook(facebookAuth)/passport.js rename to templates/app/server/auth(auth)/facebook(facebookAuth)/passport.js diff --git a/app/templates/server/auth(auth)/google(googleAuth)/index.js b/templates/app/server/auth(auth)/google(googleAuth)/index.js similarity index 100% rename from app/templates/server/auth(auth)/google(googleAuth)/index.js rename to templates/app/server/auth(auth)/google(googleAuth)/index.js diff --git a/app/templates/server/auth(auth)/google(googleAuth)/passport.js b/templates/app/server/auth(auth)/google(googleAuth)/passport.js similarity index 100% rename from app/templates/server/auth(auth)/google(googleAuth)/passport.js rename to templates/app/server/auth(auth)/google(googleAuth)/passport.js diff --git a/app/templates/server/auth(auth)/index.js b/templates/app/server/auth(auth)/index.js similarity index 100% rename from app/templates/server/auth(auth)/index.js rename to templates/app/server/auth(auth)/index.js diff --git a/app/templates/server/auth(auth)/local/index.js b/templates/app/server/auth(auth)/local/index.js similarity index 100% rename from app/templates/server/auth(auth)/local/index.js rename to templates/app/server/auth(auth)/local/index.js diff --git a/app/templates/server/auth(auth)/local/passport.js b/templates/app/server/auth(auth)/local/passport.js similarity index 100% rename from app/templates/server/auth(auth)/local/passport.js rename to templates/app/server/auth(auth)/local/passport.js diff --git a/app/templates/server/auth(auth)/twitter(twitterAuth)/index.js b/templates/app/server/auth(auth)/twitter(twitterAuth)/index.js similarity index 100% rename from app/templates/server/auth(auth)/twitter(twitterAuth)/index.js rename to templates/app/server/auth(auth)/twitter(twitterAuth)/index.js diff --git a/app/templates/server/auth(auth)/twitter(twitterAuth)/passport.js b/templates/app/server/auth(auth)/twitter(twitterAuth)/passport.js similarity index 100% rename from app/templates/server/auth(auth)/twitter(twitterAuth)/passport.js rename to templates/app/server/auth(auth)/twitter(twitterAuth)/passport.js diff --git a/app/templates/server/components/errors/index.js b/templates/app/server/components/errors/index.js similarity index 100% rename from app/templates/server/components/errors/index.js rename to templates/app/server/components/errors/index.js diff --git a/app/templates/server/config/_local.env.js b/templates/app/server/config/_local.env.js similarity index 100% rename from app/templates/server/config/_local.env.js rename to templates/app/server/config/_local.env.js diff --git a/app/templates/server/config/_local.env.sample.js b/templates/app/server/config/_local.env.sample.js similarity index 100% rename from app/templates/server/config/_local.env.sample.js rename to templates/app/server/config/_local.env.sample.js diff --git a/app/templates/server/config/environment/development.js b/templates/app/server/config/environment/development.js similarity index 100% rename from app/templates/server/config/environment/development.js rename to templates/app/server/config/environment/development.js diff --git a/app/templates/server/config/environment/index.js b/templates/app/server/config/environment/index.js similarity index 100% rename from app/templates/server/config/environment/index.js rename to templates/app/server/config/environment/index.js diff --git a/app/templates/server/config/environment/production.js b/templates/app/server/config/environment/production.js similarity index 100% rename from app/templates/server/config/environment/production.js rename to templates/app/server/config/environment/production.js diff --git a/app/templates/server/config/environment/shared.js b/templates/app/server/config/environment/shared.js similarity index 100% rename from app/templates/server/config/environment/shared.js rename to templates/app/server/config/environment/shared.js diff --git a/app/templates/server/config/environment/test.js b/templates/app/server/config/environment/test.js similarity index 100% rename from app/templates/server/config/environment/test.js rename to templates/app/server/config/environment/test.js diff --git a/app/templates/server/config/express.js b/templates/app/server/config/express.js similarity index 100% rename from app/templates/server/config/express.js rename to templates/app/server/config/express.js diff --git a/app/templates/server/config/seed(models).js b/templates/app/server/config/seed(models).js similarity index 100% rename from app/templates/server/config/seed(models).js rename to templates/app/server/config/seed(models).js diff --git a/app/templates/server/config/socketio(socketio).js b/templates/app/server/config/socketio(socketio).js similarity index 100% rename from app/templates/server/config/socketio(socketio).js rename to templates/app/server/config/socketio(socketio).js diff --git a/app/templates/server/index.js b/templates/app/server/index.js similarity index 100% rename from app/templates/server/index.js rename to templates/app/server/index.js diff --git a/app/templates/server/routes.js b/templates/app/server/routes.js similarity index 100% rename from app/templates/server/routes.js rename to templates/app/server/routes.js diff --git a/app/templates/server/sqldb(sequelize)/index.js b/templates/app/server/sqldb(sequelize)/index.js similarity index 100% rename from app/templates/server/sqldb(sequelize)/index.js rename to templates/app/server/sqldb(sequelize)/index.js diff --git a/app/templates/server/views/404(html).html b/templates/app/server/views/404(html).html similarity index 100% rename from app/templates/server/views/404(html).html rename to templates/app/server/views/404(html).html diff --git a/app/templates/server/views/404(jade).jade b/templates/app/server/views/404(jade).jade similarity index 100% rename from app/templates/server/views/404(jade).jade rename to templates/app/server/views/404(jade).jade diff --git a/app/templates/tsconfig.client(ts).json b/templates/app/tsconfig.client(ts).json similarity index 100% rename from app/templates/tsconfig.client(ts).json rename to templates/app/tsconfig.client(ts).json diff --git a/app/templates/tsconfig.client.test(ts).json b/templates/app/tsconfig.client.test(ts).json similarity index 100% rename from app/templates/tsconfig.client.test(ts).json rename to templates/app/tsconfig.client.test(ts).json diff --git a/app/templates/tsd(ts).json b/templates/app/tsd(ts).json similarity index 100% rename from app/templates/tsd(ts).json rename to templates/app/tsd(ts).json diff --git a/app/templates/tsd_test(ts).json b/templates/app/tsd_test(ts).json similarity index 100% rename from app/templates/tsd_test(ts).json rename to templates/app/tsd_test(ts).json diff --git a/endpoint/templates/basename.controller.js b/templates/endpoint/basename.controller.js similarity index 100% rename from endpoint/templates/basename.controller.js rename to templates/endpoint/basename.controller.js diff --git a/endpoint/templates/basename.events(models).js b/templates/endpoint/basename.events(models).js similarity index 100% rename from endpoint/templates/basename.events(models).js rename to templates/endpoint/basename.events(models).js diff --git a/endpoint/templates/basename.integration.js b/templates/endpoint/basename.integration.js similarity index 100% rename from endpoint/templates/basename.integration.js rename to templates/endpoint/basename.integration.js diff --git a/endpoint/templates/basename.model(mongooseModels).js b/templates/endpoint/basename.model(mongooseModels).js similarity index 100% rename from endpoint/templates/basename.model(mongooseModels).js rename to templates/endpoint/basename.model(mongooseModels).js diff --git a/endpoint/templates/basename.model(sequelizeModels).js b/templates/endpoint/basename.model(sequelizeModels).js similarity index 100% rename from endpoint/templates/basename.model(sequelizeModels).js rename to templates/endpoint/basename.model(sequelizeModels).js diff --git a/endpoint/templates/basename.socket(socketio).js b/templates/endpoint/basename.socket(socketio).js similarity index 100% rename from endpoint/templates/basename.socket(socketio).js rename to templates/endpoint/basename.socket(socketio).js diff --git a/endpoint/templates/index.js b/templates/endpoint/index.js similarity index 100% rename from endpoint/templates/index.js rename to templates/endpoint/index.js diff --git a/endpoint/templates/index.spec.js b/templates/endpoint/index.spec.js similarity index 100% rename from endpoint/templates/index.spec.js rename to templates/endpoint/index.spec.js From 104efc635b15e76bba5a48dfadfeb6e4f4fd91fb Mon Sep 17 00:00:00 2001 From: Andrew Koroluk Date: Sat, 23 Apr 2016 19:26:34 -0400 Subject: [PATCH 06/81] fix(gen:grunt): update paths --- Gruntfile.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Gruntfile.js b/Gruntfile.js index ca5178fc7..37efd2c0d 100644 --- a/Gruntfile.js +++ b/Gruntfile.js @@ -87,7 +87,7 @@ module.exports = function (grunt) { curly: false, node: true }, - all: ['Gruntfile.js', '*/index.js'] + all: ['Gruntfile.js', 'src/**/*.js'] }, env: { fast: { @@ -276,8 +276,8 @@ module.exports = function (grunt) { fs.writeFileSync(path.resolve(d), JSON.stringify(json, null, 2)); }; - processJson('app/templates/_package.json', dest + 'package.json'); - processJson('app/templates/_bower.json', dest + 'bower.json'); + processJson('templates/app/_package.json', dest + 'package.json'); + processJson('templates/app/_bower.json', dest + 'bower.json'); }); grunt.registerTask('installFixtures', 'install package and bower fixtures', function() { From d970e5cc91c2fdf2dd2d30935cf9825026ae1e07 Mon Sep 17 00:00:00 2001 From: Andrew Koroluk Date: Sat, 23 Apr 2016 19:27:19 -0400 Subject: [PATCH 07/81] refactor(gen:endpoint): remove deprecated NamedBase --- src/endpoint/index.js | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/endpoint/index.js b/src/endpoint/index.js index 9ea93f7e8..675e61c07 100644 --- a/src/endpoint/index.js +++ b/src/endpoint/index.js @@ -1,14 +1,16 @@ 'use strict'; import path from 'path'; -import {NamedBase} from 'yeoman-generator'; +import {Base} from 'yeoman-generator'; import {genNamedBase} from '../generator-base'; -export class Generator extends NamedBase { +export class Generator extends Base { constructor(...args) { super(...args); + this.argument('name', { type: String, required: true }); + this.option('route', { desc: 'URL for the endpoint', type: String From 73238813a3a01f4d88345454c2d59804d02d1390 Mon Sep 17 00:00:00 2001 From: Andrew Koroluk Date: Sat, 23 Apr 2016 19:27:38 -0400 Subject: [PATCH 08/81] fix(test): update paths --- test/test-file-creation.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/test-file-creation.js b/test/test-file-creation.js index 80ae2538c..a61a2ad87 100644 --- a/test/test-file-creation.js +++ b/test/test-file-creation.js @@ -351,8 +351,8 @@ describe('angular-fullstack generator', function () { beforeEach(function (done) { this.timeout(10000); var deps = [ - '../../app', - '../../endpoint', + '../../generators/app', + '../../generators/endpoint', [ helpers.createDummyGenerator(), 'ng-component:app' From 97d7fcc3c2ccf6529fc367287a38335d3720cb15 Mon Sep 17 00:00:00 2001 From: Andrew Koroluk Date: Sat, 23 Apr 2016 19:38:32 -0400 Subject: [PATCH 09/81] chore(npm): add a few more files to `.npmignore` [skip ci] --- .npmignore | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/.npmignore b/.npmignore index 58e92379e..29dc7d501 100644 --- a/.npmignore +++ b/.npmignore @@ -5,3 +5,7 @@ src scripts ISSUE_TEMPLATE.md PULL_REQUEST_TEMPLATE.md +.travis.yml +gulpfile.babel.js +Gruntfile.js +.jshintrc From 61f70f626ccebd308c28dd7c4dad8ef29fec63fa Mon Sep 17 00:00:00 2001 From: Andrew Koroluk Date: Sat, 23 Apr 2016 19:44:38 -0400 Subject: [PATCH 10/81] fix(test): add `gulp build` to npm `test` script (I know, gulp thing, then grunt thing, get over it) --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 0db5e59e0..5483708c7 100644 --- a/package.json +++ b/package.json @@ -31,7 +31,7 @@ "url": "git://github.com/angular-fullstack/generator-angular-fullstack.git" }, "scripts": { - "test": "grunt test" + "test": "gulp build && grunt test" }, "dependencies": { "babel-plugin-syntax-class-properties": "^6.5.0", From c857b2742f9251afe715908a28502b845b7b8e23 Mon Sep 17 00:00:00 2001 From: Andrew Koroluk Date: Sat, 23 Apr 2016 19:56:36 -0400 Subject: [PATCH 11/81] fix(package): include gulp devDependency --- package.json | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/package.json b/package.json index 5483708c7..6af1f196d 100644 --- a/package.json +++ b/package.json @@ -50,10 +50,10 @@ "yeoman-welcome": "^1.0.1" }, "devDependencies": { - "chai": "^3.2.0", - "babel-register": "^6.6.5", - "babel-preset-es2015": "^6.6.0", "babel-plugin-transform-class-properties": "^6.6.0", + "babel-preset-es2015": "^6.6.0", + "babel-register": "^6.6.5", + "chai": "^3.2.0", "del": "^2.2.0", "grunt": "^1.0.1", "grunt-build-control": "^0.7.0", @@ -64,6 +64,7 @@ "grunt-env": "^0.4.1", "grunt-mocha-test": "^0.12.7", "grunt-release": "^0.13.0", + "gulp": "^3.9.1", "jit-grunt": "~0.10.0", "mocha": "^2.2.5", "q": "^1.0.1", From 07b6f8bc79443fc84dcc55389924a4f61614543d Mon Sep 17 00:00:00 2001 From: Andrew Koroluk Date: Sat, 23 Apr 2016 20:36:49 -0400 Subject: [PATCH 12/81] fix(test): fix some more paths --- test/test-file-creation.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/test-file-creation.js b/test/test-file-creation.js index a61a2ad87..b2e4c59d8 100644 --- a/test/test-file-creation.js +++ b/test/test-file-creation.js @@ -484,8 +484,8 @@ describe('angular-fullstack generator', function () { this.timeout(60000); copySync(__dirname + '/fixtures/.yo-rc.json', __dirname + '/temp/.yo-rc.json'); var gen = helpers.createGenerator('angular-fullstack:app', [ - '../../app', - '../../endpoint', + '../../generators/app', + '../../generators/endpoint', [ helpers.createDummyGenerator(), 'ng-component:app' From c5a1b41820ac269a1fac160d8a8817f9a0445d36 Mon Sep 17 00:00:00 2001 From: Andrew Koroluk Date: Sat, 23 Apr 2016 21:16:40 -0400 Subject: [PATCH 13/81] fix(test): fix another path! fml! I'm dying inside --- test/test-file-creation.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/test-file-creation.js b/test/test-file-creation.js index b2e4c59d8..5c4c29e5d 100644 --- a/test/test-file-creation.js +++ b/test/test-file-creation.js @@ -32,7 +32,7 @@ describe('angular-fullstack generator', function () { function generatorTest(generatorType, name, mockPrompt, callback) { gen.run(function () { var afGenerator; - var deps = [path.join('../..', generatorType)]; + var deps = [path.join('../../generators', generatorType)]; afGenerator = helpers.createGenerator('angular-fullstack:' + generatorType, deps, [name], { skipInstall: true }); From 11f5719efecadceaaa05b0e172dbb325c9b0ff72 Mon Sep 17 00:00:00 2001 From: Andrew Koroluk Date: Sat, 23 Apr 2016 22:06:46 -0400 Subject: [PATCH 14/81] refactor(gen:gulp): don't use babel --- gulpfile.babel.js => gulpfile.js | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) rename gulpfile.babel.js => gulpfile.js (75%) diff --git a/gulpfile.babel.js b/gulpfile.js similarity index 75% rename from gulpfile.babel.js rename to gulpfile.js index a8c2ecfe1..6636000b2 100644 --- a/gulpfile.babel.js +++ b/gulpfile.js @@ -1,10 +1,8 @@ 'use strict'; -// import _ from 'lodash'; -// import fs from 'fs'; -import gulp from 'gulp'; -import babel from 'gulp-babel'; -import del from 'del'; -import runSequence from 'run-sequence'; +var gulp = require('gulp'); +var babel = require('gulp-babel'); +var del = require('del'); +var runSequence = require('run-sequence'); gulp.task('clean', () => { return del(['generators/**/*']); From 94d69dae395911fd1a0a6442257a89182081306f Mon Sep 17 00:00:00 2001 From: Andrew Koroluk Date: Sat, 23 Apr 2016 22:39:32 -0400 Subject: [PATCH 15/81] feat(gen:gulp): port updateFixtures to Gulp (hot damn is it faster :fire:) [skip ci] --- gulpfile.js | 47 +++++++++++++++++++++++++++++++++++++++++++++++ package.json | 1 + 2 files changed, 48 insertions(+) diff --git a/gulpfile.js b/gulpfile.js index 6636000b2..f98f08d45 100644 --- a/gulpfile.js +++ b/gulpfile.js @@ -1,4 +1,7 @@ 'use strict'; +var fs = require('fs'); +var path = require('path'); +var Promise = require('bluebird'); var gulp = require('gulp'); var babel = require('gulp-babel'); var del = require('del'); @@ -31,3 +34,47 @@ gulp.task('build', cb => { cb ); }); + +var processJson = function(src, dest, opt) { + return new Promise((resolve, reject) => { + // read file, strip all ejs conditionals, and parse as json + fs.readFile(path.resolve(src), 'utf8', (err, data) => { + if(err) return reject(err); + + var json = JSON.parse(data.replace(/<%(.*)%>/g, '')); + + // set properties + json.name = opt.appName; + json.version = opt.genVer; + json.private = opt.private; + + // stringify json and write it to the destination + fs.writeFile(path.resolve(dest), JSON.stringify(json, null, 2), err => { + if(err) reject(err); + else resolve(); + }); + }); + }); +}; + +function updateFixtures(target) { + const deps = target === 'deps'; + const genVer = require('./package.json').version; + const dest = __dirname + (deps ? '/angular-fullstack-deps/' : '/test/fixtures/'); + const appName = deps ? 'angular-fullstack-deps' : 'tempApp'; + + return Promise.all([ + processJson('templates/app/_package.json', dest + 'package.json', {appName, genVer, private: !!deps}), + processJson('templates/app/_bower.json', dest + 'bower.json', {appName, genVer, private: !!deps}) + ]); +} + +gulp.task('updateFixtures', cb => { + return runSequence(['updateFixtures:test', 'updateFixtures:deps'], cb); +}); +gulp.task('updateFixtures:test', () => { + return updateFixtures('test'); +}); +gulp.task('updateFixtures:deps', () => { + return updateFixtures('deps'); +}); diff --git a/package.json b/package.json index 6af1f196d..7f10960f0 100644 --- a/package.json +++ b/package.json @@ -53,6 +53,7 @@ "babel-plugin-transform-class-properties": "^6.6.0", "babel-preset-es2015": "^6.6.0", "babel-register": "^6.6.5", + "bluebird": "^3.3.5", "chai": "^3.2.0", "del": "^2.2.0", "grunt": "^1.0.1", From a2cecab2c70a02e7b918e7520ce58725185aadd7 Mon Sep 17 00:00:00 2001 From: Andrew Koroluk Date: Sat, 23 Apr 2016 22:41:11 -0400 Subject: [PATCH 16/81] fix(gen:gulp:updateFixtures): fix saving as private/public [skip ci] --- gulpfile.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/gulpfile.js b/gulpfile.js index f98f08d45..ba2b2dab7 100644 --- a/gulpfile.js +++ b/gulpfile.js @@ -64,8 +64,8 @@ function updateFixtures(target) { const appName = deps ? 'angular-fullstack-deps' : 'tempApp'; return Promise.all([ - processJson('templates/app/_package.json', dest + 'package.json', {appName, genVer, private: !!deps}), - processJson('templates/app/_bower.json', dest + 'bower.json', {appName, genVer, private: !!deps}) + processJson('templates/app/_package.json', dest + 'package.json', {appName, genVer, private: !deps}), + processJson('templates/app/_bower.json', dest + 'bower.json', {appName, genVer, private: !deps}) ]); } From db3d9e783f317cd5cde1426e1c2283acc7521c6c Mon Sep 17 00:00:00 2001 From: Andrew Koroluk Date: Sat, 23 Apr 2016 22:46:36 -0400 Subject: [PATCH 17/81] feat(gen:gulp:updateFixtures): stop deleting the deps description! [skip ci] --- gulpfile.js | 3 +++ 1 file changed, 3 insertions(+) diff --git a/gulpfile.js b/gulpfile.js index ba2b2dab7..7aeb1de2c 100644 --- a/gulpfile.js +++ b/gulpfile.js @@ -45,6 +45,9 @@ var processJson = function(src, dest, opt) { // set properties json.name = opt.appName; + json.description = opt.private + ? null + : 'The purpose of this repository is to track all the possible dependencies of an application created by generator-angular-fullstack.'; json.version = opt.genVer; json.private = opt.private; From 04b42d4421b732bec8fc90f547ed1895dd06370a Mon Sep 17 00:00:00 2001 From: Andrew Koroluk Date: Sat, 23 Apr 2016 22:57:47 -0400 Subject: [PATCH 18/81] 3.7.0-beta.1 --- angular-fullstack-deps | 2 +- package.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/angular-fullstack-deps b/angular-fullstack-deps index efd5dd3fb..7bfa34baa 160000 --- a/angular-fullstack-deps +++ b/angular-fullstack-deps @@ -1 +1 @@ -Subproject commit efd5dd3fb81daafcea3a1da6df1fde64c7d8084c +Subproject commit 7bfa34baa078ab2ee9d7be5850c568b968566fd0 diff --git a/package.json b/package.json index 1a68c954c..766158e47 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "generator-angular-fullstack", - "version": "3.6.1", + "version": "3.7.0-beta.1", "description": "Yeoman generator for creating MEAN stack applications, using MongoDB, Express, AngularJS, and Node", "keywords": [ "yeoman-generator", From 621acecb0f25ff5531c4e66d931877e2ff738c1f Mon Sep 17 00:00:00 2001 From: Andrew Koroluk Date: Mon, 25 Apr 2016 11:27:25 -0400 Subject: [PATCH 19/81] chore(package): add prepublish (gulp build) --- package.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/package.json b/package.json index 766158e47..7cc2759bf 100644 --- a/package.json +++ b/package.json @@ -31,7 +31,8 @@ "url": "git://github.com/angular-fullstack/generator-angular-fullstack.git" }, "scripts": { - "test": "gulp build && grunt test" + "test": "gulp build && grunt test", + "prepublish": "gulp build" }, "dependencies": { "babel-plugin-syntax-class-properties": "^6.5.0", From e09fb76c3380c36e8378880703e9e5b95659ed6b Mon Sep 17 00:00:00 2001 From: Andrew Koroluk Date: Sun, 24 Apr 2016 00:02:15 -0400 Subject: [PATCH 20/81] feat(gen): also build test dir (just like generators dir) --- .gitignore | 8 ++--- gulpfile.js | 16 +++++++-- package.json | 1 + src/{ => generators}/app/USAGE | 0 src/{ => generators}/app/index.js | 0 src/{ => generators}/controller/index.js | 0 src/{ => generators}/decorator/index.js | 0 src/{ => generators}/directive/index.js | 0 src/{ => generators}/endpoint/index.js | 0 src/{ => generators}/factory/index.js | 0 src/{ => generators}/filter/index.js | 0 src/{ => generators}/generator-base.js | 0 src/{ => generators}/heroku/USAGE | 0 src/{ => generators}/heroku/index.js | 0 .../heroku/templates/Procfile | 0 src/{ => generators}/insight-init.js | 0 src/{ => generators}/openshift/USAGE | 0 src/{ => generators}/openshift/index.js | 0 .../openshift/templates/hot_deploy | 0 src/{ => generators}/provider/index.js | 0 src/{ => generators}/route/index.js | 0 src/{ => generators}/service/index.js | 0 src/{ => generators}/util.js | 0 src/test/fixtures/.bowerrc | 3 ++ src/test/fixtures/.yo-rc.json | 36 +++++++++++++++++++ {test => src/test}/test-file-creation.js | 0 26 files changed, 57 insertions(+), 7 deletions(-) rename src/{ => generators}/app/USAGE (100%) rename src/{ => generators}/app/index.js (100%) rename src/{ => generators}/controller/index.js (100%) rename src/{ => generators}/decorator/index.js (100%) rename src/{ => generators}/directive/index.js (100%) rename src/{ => generators}/endpoint/index.js (100%) rename src/{ => generators}/factory/index.js (100%) rename src/{ => generators}/filter/index.js (100%) rename src/{ => generators}/generator-base.js (100%) rename src/{ => generators}/heroku/USAGE (100%) rename src/{ => generators}/heroku/index.js (100%) rename src/{ => generators}/heroku/templates/Procfile (100%) rename src/{ => generators}/insight-init.js (100%) rename src/{ => generators}/openshift/USAGE (100%) rename src/{ => generators}/openshift/index.js (100%) rename src/{ => generators}/openshift/templates/hot_deploy (100%) rename src/{ => generators}/provider/index.js (100%) rename src/{ => generators}/route/index.js (100%) rename src/{ => generators}/service/index.js (100%) rename src/{ => generators}/util.js (100%) create mode 100644 src/test/fixtures/.bowerrc create mode 100644 src/test/fixtures/.yo-rc.json rename {test => src/test}/test-file-creation.js (100%) diff --git a/.gitignore b/.gitignore index f9b1763a8..230257f1f 100644 --- a/.gitignore +++ b/.gitignore @@ -1,10 +1,8 @@ node_modules bower_components -test/temp +/generators/* +/test/* demo .idea .DS_Store -release.txt -test/fixtures/bower.json -test/fixtures/package.json -generators \ No newline at end of file +release.txt \ No newline at end of file diff --git a/gulpfile.js b/gulpfile.js index 7aeb1de2c..2fa763455 100644 --- a/gulpfile.js +++ b/gulpfile.js @@ -6,15 +6,22 @@ var gulp = require('gulp'); var babel = require('gulp-babel'); var del = require('del'); var runSequence = require('run-sequence'); +var merge = require('merge-stream'); gulp.task('clean', () => { return del(['generators/**/*']); }); gulp.task('babel', () => { - return gulp.src(['src/**/*.js']) + let generators = gulp.src(['src/generators/**/*.js']) .pipe(babel()) .pipe(gulp.dest('generators')); + + let test = gulp.src(['src/test/**/*.js']) + .pipe(babel()) + .pipe(gulp.dest('test')); + + return merge(generators); }); gulp.task('watch', () => { @@ -22,8 +29,13 @@ gulp.task('watch', () => { }); gulp.task('copy', () => { - return gulp.src(['src/**/*', '!src/**/*.js']) + let nonJsGen = gulp.src(['src/generators/**/*', '!src/generators/**/*.js'], {dot: true}) .pipe(gulp.dest('generators')); + + let nonJsTest = gulp.src(['src/test/**/*', '!src/test/**/*.js'], {dot: true}) + .pipe(gulp.dest('test')); + + return merge(nonJsGen, nonJsTest); }); gulp.task('build', cb => { diff --git a/package.json b/package.json index 7cc2759bf..a6f769767 100644 --- a/package.json +++ b/package.json @@ -68,6 +68,7 @@ "grunt-release": "^0.13.0", "gulp": "^3.9.1", "jit-grunt": "~0.10.0", + "merge-stream": "^1.0.0", "mocha": "^2.2.5", "q": "^1.0.1", "recursive-readdir": "^2.0.0", diff --git a/src/app/USAGE b/src/generators/app/USAGE similarity index 100% rename from src/app/USAGE rename to src/generators/app/USAGE diff --git a/src/app/index.js b/src/generators/app/index.js similarity index 100% rename from src/app/index.js rename to src/generators/app/index.js diff --git a/src/controller/index.js b/src/generators/controller/index.js similarity index 100% rename from src/controller/index.js rename to src/generators/controller/index.js diff --git a/src/decorator/index.js b/src/generators/decorator/index.js similarity index 100% rename from src/decorator/index.js rename to src/generators/decorator/index.js diff --git a/src/directive/index.js b/src/generators/directive/index.js similarity index 100% rename from src/directive/index.js rename to src/generators/directive/index.js diff --git a/src/endpoint/index.js b/src/generators/endpoint/index.js similarity index 100% rename from src/endpoint/index.js rename to src/generators/endpoint/index.js diff --git a/src/factory/index.js b/src/generators/factory/index.js similarity index 100% rename from src/factory/index.js rename to src/generators/factory/index.js diff --git a/src/filter/index.js b/src/generators/filter/index.js similarity index 100% rename from src/filter/index.js rename to src/generators/filter/index.js diff --git a/src/generator-base.js b/src/generators/generator-base.js similarity index 100% rename from src/generator-base.js rename to src/generators/generator-base.js diff --git a/src/heroku/USAGE b/src/generators/heroku/USAGE similarity index 100% rename from src/heroku/USAGE rename to src/generators/heroku/USAGE diff --git a/src/heroku/index.js b/src/generators/heroku/index.js similarity index 100% rename from src/heroku/index.js rename to src/generators/heroku/index.js diff --git a/src/heroku/templates/Procfile b/src/generators/heroku/templates/Procfile similarity index 100% rename from src/heroku/templates/Procfile rename to src/generators/heroku/templates/Procfile diff --git a/src/insight-init.js b/src/generators/insight-init.js similarity index 100% rename from src/insight-init.js rename to src/generators/insight-init.js diff --git a/src/openshift/USAGE b/src/generators/openshift/USAGE similarity index 100% rename from src/openshift/USAGE rename to src/generators/openshift/USAGE diff --git a/src/openshift/index.js b/src/generators/openshift/index.js similarity index 100% rename from src/openshift/index.js rename to src/generators/openshift/index.js diff --git a/src/openshift/templates/hot_deploy b/src/generators/openshift/templates/hot_deploy similarity index 100% rename from src/openshift/templates/hot_deploy rename to src/generators/openshift/templates/hot_deploy diff --git a/src/provider/index.js b/src/generators/provider/index.js similarity index 100% rename from src/provider/index.js rename to src/generators/provider/index.js diff --git a/src/route/index.js b/src/generators/route/index.js similarity index 100% rename from src/route/index.js rename to src/generators/route/index.js diff --git a/src/service/index.js b/src/generators/service/index.js similarity index 100% rename from src/service/index.js rename to src/generators/service/index.js diff --git a/src/util.js b/src/generators/util.js similarity index 100% rename from src/util.js rename to src/generators/util.js diff --git a/src/test/fixtures/.bowerrc b/src/test/fixtures/.bowerrc new file mode 100644 index 000000000..69fad3580 --- /dev/null +++ b/src/test/fixtures/.bowerrc @@ -0,0 +1,3 @@ +{ + "directory": "bower_components" +} diff --git a/src/test/fixtures/.yo-rc.json b/src/test/fixtures/.yo-rc.json new file mode 100644 index 000000000..716e42b6c --- /dev/null +++ b/src/test/fixtures/.yo-rc.json @@ -0,0 +1,36 @@ +{ + "generator-angular-fullstack": { + "endpointDirectory": "server/api/", + "insertRoutes": true, + "registerRoutesFile": "server/routes.js", + "routesNeedle": "// Insert routes below", + "routesBase": "/api/", + "pluralizeRoutes": true, + "insertSockets": true, + "registerSocketsFile": "server/config/socketio.js", + "socketsNeedle": "// Insert sockets below", + "insertModels": true, + "registerModelsFile": "server/sqldb/index.js", + "modelsNeedle": "// Insert models below", + "filters": { + "babel": true, + "html": true, + "less": true, + "uirouter": true, + "bootstrap": false, + "uibootstrap": false, + "socketio": true, + "auth": true, + "models": true, + "mongooseModels": true, + "mongoose": true, + "oauth": true, + "googleAuth": true, + "grunt": true, + "mocha": true, + "jasmine": false, + "should": true, + "expect": false + } + } +} diff --git a/test/test-file-creation.js b/src/test/test-file-creation.js similarity index 100% rename from test/test-file-creation.js rename to src/test/test-file-creation.js From f852113cb88f959412d60e4a437d5647c1baa669 Mon Sep 17 00:00:00 2001 From: Andrew Koroluk Date: Sun, 24 Apr 2016 01:20:09 -0400 Subject: [PATCH 21/81] fix(gen:gulp:watch): use plumber when watching --- gulpfile.js | 7 +++++++ package.json | 2 ++ 2 files changed, 9 insertions(+) diff --git a/gulpfile.js b/gulpfile.js index 2fa763455..e10855420 100644 --- a/gulpfile.js +++ b/gulpfile.js @@ -4,6 +4,8 @@ var path = require('path'); var Promise = require('bluebird'); var gulp = require('gulp'); var babel = require('gulp-babel'); +var plumber = require('gulp-plumber'); +var gulpIf = require('gulp-if'); var del = require('del'); var runSequence = require('run-sequence'); var merge = require('merge-stream'); @@ -12,12 +14,16 @@ gulp.task('clean', () => { return del(['generators/**/*']); }); +var watching = false; + gulp.task('babel', () => { let generators = gulp.src(['src/generators/**/*.js']) + .pipe(gulpIf(watching, plumber())) .pipe(babel()) .pipe(gulp.dest('generators')); let test = gulp.src(['src/test/**/*.js']) + .pipe(gulpIf(watching, plumber())) .pipe(babel()) .pipe(gulp.dest('test')); @@ -25,6 +31,7 @@ gulp.task('babel', () => { }); gulp.task('watch', () => { + watching = true; return gulp.watch('src/**/*.js', ['babel']); }); diff --git a/package.json b/package.json index a6f769767..c35fe4c42 100644 --- a/package.json +++ b/package.json @@ -67,6 +67,8 @@ "grunt-mocha-test": "^0.12.7", "grunt-release": "^0.13.0", "gulp": "^3.9.1", + "gulp-if": "^2.0.0", + "gulp-plumber": "^1.1.0", "jit-grunt": "~0.10.0", "merge-stream": "^1.0.0", "mocha": "^2.2.5", From 6398160cfcdb16b62af8c17782656833ac96b5b5 Mon Sep 17 00:00:00 2001 From: Andrew Koroluk Date: Sun, 24 Apr 2016 01:22:59 -0400 Subject: [PATCH 22/81] refactor(gen:test): promisify `fs`, use the promises --- src/test/test-file-creation.js | 70 ++++++++++++++++++++-------------- 1 file changed, 42 insertions(+), 28 deletions(-) diff --git a/src/test/test-file-creation.js b/src/test/test-file-creation.js index 5c4c29e5d..4d0d97882 100644 --- a/src/test/test-file-creation.js +++ b/src/test/test-file-creation.js @@ -1,7 +1,9 @@ /*global describe, beforeEach, it */ 'use strict'; var path = require('path'); +var Promise = require('bluebird'); var fs = require('fs'); +Promise.promisifyAll(fs); var exec = require('child_process').exec; var helpers = require('yeoman-test'); var assert = require('yeoman-assert'); @@ -9,8 +11,18 @@ var chai = require('chai'); var expect = chai.expect; var recursiveReadDir = require('recursive-readdir'); +/**************** + * FileSystem Utils + ****************/ + +function copyAsync(src, dest) { + return fs.readFileAsync(src) + .then(data => fs.writeFileAsync(data, dest)); +} + describe('angular-fullstack generator', function () { - var gen, defaultOptions = { + var gen; + var defaultOptions = { buildtool: 'grunt', script: 'js', transpiler: 'babel', @@ -21,13 +33,12 @@ describe('angular-fullstack generator', function () { chai: 'expect', bootstrap: true, uibootstrap: true, - odms: [ 'mongoose' ], + odms: ['mongoose'], auth: true, oauth: [], socketio: true - }, dependenciesInstalled = false; - - function copySync(s, d) { fs.writeFileSync(d, fs.readFileSync(s)); } + }; + var dependenciesInstalled = false; function generatorTest(generatorType, name, mockPrompt, callback) { gen.run(function () { @@ -411,9 +422,11 @@ describe('angular-fullstack generator', function () { beforeEach(function() { this.timeout(20000); - fs.mkdirSync(__dirname + '/temp/client'); - fs.symlinkSync(__dirname + '/fixtures/node_modules', __dirname + '/temp/node_modules'); - fs.symlinkSync(__dirname +'/fixtures/bower_components', __dirname +'/temp/client/bower_components'); + return Promise.all([ + fs.mkdirAsync(__dirname + '/temp/client'), + fs.symlinkAsync(__dirname + '/fixtures/node_modules', __dirname + '/temp/node_modules'), + fs.symlinkAsync(__dirname +'/fixtures/bower_components', __dirname +'/temp/client/bower_components') + ]); }); describe('with default options', function() { @@ -482,26 +495,27 @@ describe('angular-fullstack generator', function () { it('should use existing config if available', function(done) { this.timeout(60000); - copySync(__dirname + '/fixtures/.yo-rc.json', __dirname + '/temp/.yo-rc.json'); - var gen = helpers.createGenerator('angular-fullstack:app', [ - '../../generators/app', - '../../generators/endpoint', - [ - helpers.createDummyGenerator(), - 'ng-component:app' - ] - ], [], { - skipInstall: true - }); - helpers.mockPrompt(gen, { - skipConfig: true - }); - gen.run(function () { - assert.file([ - 'client/app/main/main.less', - 'server/auth/google/passport.js' - ]); - done(); + return copyAsync(__dirname + '/fixtures/.yo-rc.json', __dirname + '/temp/.yo-rc.json').then(() => { + var gen = helpers.createGenerator('angular-fullstack:app', [ + '../../generators/app', + '../../generators/endpoint', + [ + helpers.createDummyGenerator(), + 'ng-component:app' + ] + ], [], { + skipInstall: true + }); + helpers.mockPrompt(gen, { + skipConfig: true + }); + gen.run(function () { + assert.file([ + 'client/app/main/main.less', + 'server/auth/google/passport.js' + ]); + done(); + }); }); }); From 8f5c120fd9e4ca182fbff8e9d2c7df76ff262fa0 Mon Sep 17 00:00:00 2001 From: Andrew Koroluk Date: Sun, 24 Apr 2016 01:38:03 -0400 Subject: [PATCH 23/81] fix(gen:test): fix copyAsync --- src/test/test-file-creation.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/test/test-file-creation.js b/src/test/test-file-creation.js index 4d0d97882..200e49852 100644 --- a/src/test/test-file-creation.js +++ b/src/test/test-file-creation.js @@ -17,7 +17,7 @@ var recursiveReadDir = require('recursive-readdir'); function copyAsync(src, dest) { return fs.readFileAsync(src) - .then(data => fs.writeFileAsync(data, dest)); + .then(data => fs.writeFileAsync(dest, data)); } describe('angular-fullstack generator', function () { From 27806c564e3fd64859e5bb779b45f8f1cd9191e8 Mon Sep 17 00:00:00 2001 From: Andrew Koroluk Date: Sun, 24 Apr 2016 04:28:17 -0400 Subject: [PATCH 24/81] refactor(gen:gulp): use lazypipe --- gulpfile.js | 15 +++++++++------ package.json | 1 + 2 files changed, 10 insertions(+), 6 deletions(-) diff --git a/gulpfile.js b/gulpfile.js index e10855420..f6d5e244a 100644 --- a/gulpfile.js +++ b/gulpfile.js @@ -7,24 +7,27 @@ var babel = require('gulp-babel'); var plumber = require('gulp-plumber'); var gulpIf = require('gulp-if'); var del = require('del'); +var lazypipe = require('lazypipe'); var runSequence = require('run-sequence'); var merge = require('merge-stream'); +var watching = false; + +const transpile = lazypipe() + .pipe(() => gulpIf(watching, plumber())) + .pipe(babel); + gulp.task('clean', () => { return del(['generators/**/*']); }); -var watching = false; - gulp.task('babel', () => { let generators = gulp.src(['src/generators/**/*.js']) - .pipe(gulpIf(watching, plumber())) - .pipe(babel()) + .pipe(transpile()) .pipe(gulp.dest('generators')); let test = gulp.src(['src/test/**/*.js']) - .pipe(gulpIf(watching, plumber())) - .pipe(babel()) + .pipe(transpile()) .pipe(gulp.dest('test')); return merge(generators); diff --git a/package.json b/package.json index c35fe4c42..28d95ad7d 100644 --- a/package.json +++ b/package.json @@ -70,6 +70,7 @@ "gulp-if": "^2.0.0", "gulp-plumber": "^1.1.0", "jit-grunt": "~0.10.0", + "lazypipe": "^1.0.1", "merge-stream": "^1.0.0", "mocha": "^2.2.5", "q": "^1.0.1", From 3748953ba08d2821a16df522b01ed4d6ff15b8bf Mon Sep 17 00:00:00 2001 From: Andrew Koroluk Date: Sun, 24 Apr 2016 04:28:54 -0400 Subject: [PATCH 25/81] fix(gen:gulp:babel): return the two merged streams --- gulpfile.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gulpfile.js b/gulpfile.js index f6d5e244a..a625a1f0a 100644 --- a/gulpfile.js +++ b/gulpfile.js @@ -30,7 +30,7 @@ gulp.task('babel', () => { .pipe(transpile()) .pipe(gulp.dest('test')); - return merge(generators); + return merge(generators, test); }); gulp.task('watch', () => { From ead201a24b993e8e017a9d4988c1c6705fdc41de Mon Sep 17 00:00:00 2001 From: Andrew Koroluk Date: Sun, 24 Apr 2016 04:29:20 -0400 Subject: [PATCH 26/81] feat(gen:gulp): add mocha --- gulpfile.js | 15 +++++++++++++++ package.json | 2 ++ 2 files changed, 17 insertions(+) diff --git a/gulpfile.js b/gulpfile.js index a625a1f0a..257025cf3 100644 --- a/gulpfile.js +++ b/gulpfile.js @@ -4,6 +4,7 @@ var path = require('path'); var Promise = require('bluebird'); var gulp = require('gulp'); var babel = require('gulp-babel'); +var gulpMocha = require('gulp-mocha'); var plumber = require('gulp-plumber'); var gulpIf = require('gulp-if'); var del = require('del'); @@ -13,6 +14,15 @@ var merge = require('merge-stream'); var watching = false; +const mocha = lazypipe() + .pipe(gulpMocha, { + reporter: 'spec', + timeout: 120000, + globals: { + should: require('should') + } + }); + const transpile = lazypipe() .pipe(() => gulpIf(watching, plumber())) .pipe(babel); @@ -103,3 +113,8 @@ gulp.task('updateFixtures:test', () => { gulp.task('updateFixtures:deps', () => { return updateFixtures('deps'); }); + +gulp.task('test', () => { + return gulp.src('test/*.test.js') + .pipe(mocha()) +}); diff --git a/package.json b/package.json index 28d95ad7d..f961d8549 100644 --- a/package.json +++ b/package.json @@ -68,6 +68,7 @@ "grunt-release": "^0.13.0", "gulp": "^3.9.1", "gulp-if": "^2.0.0", + "gulp-mocha": "^2.2.0", "gulp-plumber": "^1.1.0", "jit-grunt": "~0.10.0", "lazypipe": "^1.0.1", @@ -77,6 +78,7 @@ "recursive-readdir": "^2.0.0", "run-sequence": "^1.1.5", "shelljs": "^0.6.0", + "should": "^8.3.1", "yeoman-assert": "^2.0.0", "yeoman-test": "^1.1.0" }, From 316e93f2897216b8fbc50fd3b920292087b1601c Mon Sep 17 00:00:00 2001 From: Andrew Koroluk Date: Mon, 25 Apr 2016 11:25:57 -0400 Subject: [PATCH 27/81] feat(gen:tests): step 1 of new test structure --- src/test/get-expected-files.js | 237 ++++++++++++++++++ src/test/main.test.js | 96 +++++++ ...test-file-creation.js => main.test.off.js} | 37 ++- 3 files changed, 348 insertions(+), 22 deletions(-) create mode 100644 src/test/get-expected-files.js create mode 100644 src/test/main.test.js rename src/test/{test-file-creation.js => main.test.off.js} (96%) diff --git a/src/test/get-expected-files.js b/src/test/get-expected-files.js new file mode 100644 index 000000000..6a435b3dd --- /dev/null +++ b/src/test/get-expected-files.js @@ -0,0 +1,237 @@ +/** + * Generate an array of files to expect from a set of options + * + * @param {Object} options - generator options + * @return {Array} - array of files + * + */ +export function app(options) { + var mapping = { + stylesheet: { + sass: 'scss', + stylus: 'styl', + less: 'less', + css: 'css' + }, + markup: { + jade: 'jade', + html: 'html' + }, + script: { + js: 'js', + ts: 'ts' + } + }, + files = []; + + /** + * Generate an array of OAuth files based on type + * + * @param {String} type - type of oauth + * @return {Array} - array of files + * + */ + var oauthFiles = function(type) { + return [ + 'server/auth/' + type + '/index.js', + 'server/auth/' + type + '/passport.js', + ]; + }; + + + var script = mapping.script[options.transpiler === 'ts' ? 'ts' : 'js'], + markup = mapping.markup[options.markup], + stylesheet = mapping.stylesheet[options.stylesheet], + models = options.models ? options.models : options.odms[0]; + + /* Core Files */ + files = files.concat([ + 'client/.htaccess', + 'client/favicon.ico', + 'client/robots.txt', + 'client/index.html', + 'client/app/app.' + script, + 'client/app/app.' + stylesheet, + 'client/app/main/main.' + script, + 'client/app/main/main.' + markup, + 'client/app/main/main.' + stylesheet, + 'client/app/main/main.controller.' + script, + 'client/app/main/main.controller.spec.' + script, + 'client/assets/images/yeoman.png', + 'client/components/footer/footer.' + stylesheet, + 'client/components/footer/footer.' + markup, + 'client/components/footer/footer.directive.' + script, + 'client/components/navbar/navbar.' + markup, + 'client/components/navbar/navbar.controller.' + script, + 'client/components/navbar/navbar.directive.' + script, + 'client/components/util/util.module.' + script, + 'client/components/util/util.service.' + script, + 'server/.jshintrc', + 'server/.jshintrc-spec', + 'server/app.js', + 'server/index.js', + 'server/routes.js', + 'server/api/thing/index.js', + 'server/api/thing/index.spec.js', + 'server/api/thing/thing.controller.js', + 'server/api/thing/thing.integration.js', + 'server/components/errors/index.js', + 'server/config/local.env.js', + 'server/config/local.env.sample.js', + 'server/config/express.js', + 'server/config/environment/index.js', + 'server/config/environment/development.js', + 'server/config/environment/production.js', + 'server/config/environment/test.js', + 'server/config/environment/shared.js', + 'server/views/404.' + markup, + 'e2e/main/main.po.js', + 'e2e/main/main.spec.js', + 'e2e/components/navbar/navbar.po.js', + '.babelrc', + '.bowerrc', + '.buildignore', + '.editorconfig', + '.gitattributes', + '.gitignore', + '.travis.yml', + '.jscsrc', + '.yo-rc.json', + 'Gruntfile.js', + 'package.json', + 'bower.json', + 'karma.conf.js', + 'mocha.conf.js', + 'protractor.conf.js', + 'README.md' + ]); + + /* TypeScript */ + if (options.transpiler === 'ts') { + files = files.concat([ + 'tsconfig.client.test.json', + 'tsconfig.client.json', + 'tsd.json', + 'tsd_test.json', + 'client/tslint.json' + ]); + } else { + files = files.concat([ + 'client/.jshintrc' + ]); + } + + /* Ui-Router */ + if (options.router === 'uirouter') { + files = files.concat([ + 'client/components/ui-router/ui-router.mock.' + script + ]); + } + + /* Ui-Bootstrap */ + if (options.uibootstrap) { + files = files.concat([ + 'client/components/modal/modal.' + markup, + 'client/components/modal/modal.' + stylesheet, + 'client/components/modal/modal.service.' + script + ]); + } + + /* Models - Mongoose or Sequelize */ + if (models) { + files = files.concat([ + 'server/api/thing/thing.model.js', + 'server/api/thing/thing.events.js', + 'server/config/seed.js' + ]); + } + + /* Sequelize */ + if (options.odms.indexOf('sequelize') !== -1) { + files = files.concat([ + 'server/sqldb/index.js' + ]); + } + + /* Authentication */ + if (options.auth) { + files = files.concat([ + 'client/app/account/account.' + script, + 'client/app/account/login/login.' + markup, + 'client/app/account/login/login.controller.' + script, + 'client/app/account/settings/settings.' + markup, + 'client/app/account/settings/settings.controller.' + script, + 'client/app/account/signup/signup.' + markup, + 'client/app/account/signup/signup.controller.' + script, + 'client/app/admin/admin.' + markup, + 'client/app/admin/admin.' + stylesheet, + 'client/app/admin/admin.module.' + script, + 'client/app/admin/admin.router.' + script, + 'client/app/admin/admin.controller.' + script, + 'client/components/auth/auth.module.' + script, + 'client/components/auth/auth.service.' + script, + 'client/components/auth/interceptor.service.' + script, + 'client/components/auth/router.decorator.' + script, + 'client/components/auth/user.service.' + script, + 'client/components/mongoose-error/mongoose-error.directive.' + script, + 'server/api/user/index.js', + 'server/api/user/index.spec.js', + 'server/api/user/user.controller.js', + 'server/api/user/user.integration.js', + 'server/api/user/user.model.js', + 'server/api/user/user.model.spec.js', + 'server/api/user/user.events.js', + 'server/auth/index.js', + 'server/auth/auth.service.js', + 'server/auth/local/index.js', + 'server/auth/local/passport.js', + 'e2e/account/login/login.po.js', + 'e2e/account/login/login.spec.js', + 'e2e/account/logout/logout.spec.js', + 'e2e/account/signup/signup.po.js', + 'e2e/account/signup/signup.spec.js' + ]); + } + + if (options.oauth && options.oauth.length) { + /* OAuth (see oauthFiles function above) */ + options.oauth.forEach(function(type, i) { + files = files.concat(oauthFiles(type.replace('Auth', ''))); + }); + + + files = files.concat([ + 'client/components/oauth-buttons/oauth-buttons.' + stylesheet, + 'client/components/oauth-buttons/oauth-buttons.' + markup, + 'client/components/oauth-buttons/oauth-buttons.controller.' + script, + 'client/components/oauth-buttons/oauth-buttons.controller.spec.' + script, + 'client/components/oauth-buttons/oauth-buttons.directive.' + script, + 'client/components/oauth-buttons/oauth-buttons.directive.spec.' + script, + 'e2e/components/oauth-buttons/oauth-buttons.po.js' + ]); + } + + /* Socket.IO */ + if (options.socketio) { + files = files.concat([ + 'client/components/socket/socket.service.' + script, + 'client/components/socket/socket.mock.' + script, + 'server/api/thing/thing.socket.js', + 'server/config/socketio.js' + ]); + } + + return files; +} + +export function endpoint(name, options) { + return [ + `server/api/${name}/index.js`, + `server/api/${name}/index.spec.js`, + `server/api/${name}/bar.controller.js`, + `server/api/${name}/bar.events.js`, + `server/api/${name}/bar.integration.js`, + `server/api/${name}/bar.model.js`, + `server/api/${name}/bar.socket.js` + ]; +} diff --git a/src/test/main.test.js b/src/test/main.test.js new file mode 100644 index 000000000..deed2c25b --- /dev/null +++ b/src/test/main.test.js @@ -0,0 +1,96 @@ +'use strict'; +import path from 'path'; +import fs from 'fs'; +import Promise from 'bluebird'; +Promise.promisifyAll(fs); +import {exec} from 'child_process'; +import helpers from 'yeoman-test'; +import assert from 'yeoman-assert'; +import * as getExpectedFiles from './get-expected-files'; + +const defaultOptions = { + buildtool: 'grunt', + script: 'js', + transpiler: 'babel', + markup: 'html', + stylesheet: 'sass', + router: 'uirouter', + testing: 'mocha', + chai: 'expect', + bootstrap: true, + uibootstrap: true, + odms: ['mongoose'], + auth: true, + oauth: [], + socketio: true +}; +// var DEBUG = true; +var DEBUG = false; + +function runCmd(cmd, done) { + exec(cmd, {}, function(err, stdout, stderr) { + if(err) { + console.error(stdout); + throw new Error(`Error running command: ${cmd}`); + done(err); + } else { + if(DEBUG) console.log(stdout); + done(); + } + }); +} + +describe('angular-fullstack:app', function() { + beforeEach(function() { + this.gen = helpers + .run(require.resolve('../generators/app')) + .inTmpDir(function(dir) { + var done = this.async(); + if(DEBUG) console.log(`TEMP DIR: ${dir}`); + + return Promise.all([ + fs.mkdirAsync(dir + '/client').then(() => { + return fs.symlinkAsync(__dirname + '/fixtures/bower_components', dir + '/client/bower_components'); + }), + fs.symlinkAsync(__dirname + '/fixtures/node_modules', dir + '/node_modules') + ]).then(done); + }) + .withGenerators([ + require.resolve('../generators/endpoint'), + // [helpers.createDummyGenerator(), 'ng-component:app'] + ]) + .withOptions({ + skipInstall: true, + force: true + }) + // .withArguments(['upperCaseBug']) + .withPrompts(defaultOptions); + }); + + describe('default settings', function() { + beforeEach(function(done) { + this.gen.on('end', done); + }); + + it('generates the proper files', function(done) { + assert.file(getExpectedFiles.app(defaultOptions)); + done(); + }); + + it('passes JSCS', function(done) { + runCmd('grunt jscs', done); + }); + + it('passes JSHint', function(done) { + runCmd('grunt jshint', done); + }); + + it('passes client tests', function(done) { + runCmd('grunt test:client', done); + }); + + it('passes client tests', function(done) { + runCmd('grunt test:server', done); + }); + }); +}); \ No newline at end of file diff --git a/src/test/test-file-creation.js b/src/test/main.test.off.js similarity index 96% rename from src/test/test-file-creation.js rename to src/test/main.test.off.js index 200e49852..6f706cc70 100644 --- a/src/test/test-file-creation.js +++ b/src/test/main.test.off.js @@ -64,12 +64,13 @@ describe('angular-fullstack generator', function () { * @param {Array} skip - array of paths to skip/ignore (optional) * */ - function assertOnlyFiles(expectedFiles, done, topLevelPath, skip) { - topLevelPath = topLevelPath || './'; - skip = skip || ['node_modules', 'client/bower_components']; - + function assertOnlyFiles( + expectedFiles, + done, + topLevelPath='./', + skip=['node_modules', 'client/bower_components']) { recursiveReadDir(topLevelPath, skip, function(err, actualFiles) { - if (err) { return done(err); } + if (err) return done(err); var files = actualFiles.concat(); expectedFiles.forEach(function(file, i) { @@ -101,9 +102,9 @@ describe('angular-fullstack generator', function () { * */ function runTest(cmd, self, cb) { - var args = Array.prototype.slice.call(arguments), - endpoint = (args[3] && typeof args[3] === 'string') ? args.splice(3, 1)[0] : null, - timeout = (args[3] && typeof args[3] === 'number') ? args.splice(3, 1)[0] : null; + var args = Array.prototype.slice.call(arguments); + var endpoint = (args[3] && typeof args[3] === 'string') ? args.splice(3, 1)[0] : null; + var timeout = (args[3] && typeof args[3] === 'number') ? args.splice(3, 1)[0] : null; self.timeout(timeout || 60000); @@ -370,31 +371,24 @@ describe('angular-fullstack generator', function () { ] ]; - helpers.testDirectory(path.join(__dirname, 'temp'), function (err) { - if (err) { - return done(err); - } + helpers.testDirectory(path.join(__dirname, 'temp'), err => { + if(err) return done(err); gen = helpers.createGenerator('angular-fullstack:app', deps, [], { skipInstall: true }); gen.conflicter.force = true; done(); - }.bind(this)); + }); }); describe('making sure test fixtures are present', function() { - it('should have package.json in fixtures', function() { - assert.file([ - path.join(__dirname, 'fixtures', 'package.json') - ]); + assert.file([path.join(__dirname, 'fixtures', 'package.json')]); }); it('should have bower.json in fixtures', function() { - assert.file([ - path.join(__dirname, 'fixtures', 'bower.json') - ]); + assert.file([path.join(__dirname, 'fixtures', 'bower.json')]); }); it('should have all npm packages in fixtures/node_modules', function() { @@ -419,7 +413,6 @@ describe('angular-fullstack generator', function () { }); describe('running app', function() { - beforeEach(function() { this.timeout(20000); return Promise.all([ @@ -438,7 +431,7 @@ describe('angular-fullstack generator', function () { runTest('grunt test:client', this, done); }); - it('should pass jscs', function(done) { + it.only('should pass jscs', function(done) { runTest('grunt jscs', this, done); }); From 7c8795371cfa2a7c6afdf5f7f1bc93d393972feb Mon Sep 17 00:00:00 2001 From: Andrew Koroluk Date: Mon, 25 Apr 2016 13:00:25 -0400 Subject: [PATCH 28/81] chore(package): update test command to use `gulp test` instead of grunt --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index f961d8549..1827ba07e 100644 --- a/package.json +++ b/package.json @@ -31,7 +31,7 @@ "url": "git://github.com/angular-fullstack/generator-angular-fullstack.git" }, "scripts": { - "test": "gulp build && grunt test", + "test": "gulp build && gulp test", "prepublish": "gulp build" }, "dependencies": { From 04a787884ad05d0cc1facf662725bcdbdd294e8b Mon Sep 17 00:00:00 2001 From: Andrew Koroluk Date: Mon, 25 Apr 2016 13:51:57 -0400 Subject: [PATCH 29/81] feat(gen:gulp): add installFixtures task --- gulpfile.js | 45 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 45 insertions(+) diff --git a/gulpfile.js b/gulpfile.js index 257025cf3..e4529953e 100644 --- a/gulpfile.js +++ b/gulpfile.js @@ -11,6 +11,10 @@ var del = require('del'); var lazypipe = require('lazypipe'); var runSequence = require('run-sequence'); var merge = require('merge-stream'); +const exec = require('child_process').exec; +const _ = require('lodash'); +const gutil = require('gulp-util'); +const shell = require('shelljs'); var watching = false; @@ -114,6 +118,47 @@ gulp.task('updateFixtures:deps', () => { return updateFixtures('deps'); }); +function execAsync(cmd, opt) { + return new Promise((resolve, reject) => { + exec(cmd, opt, (err, stdout, stderr) => { + if(err) { + console.log(`stderr: ${stderr}`); + return reject(err); + } + + return resolve(stdout); + }) + }); +} + +gulp.task('installFixtures', function() { + gutil.log('installing npm & bower dependencies for generated app'); + let progress = setInterval(() => { + process.stdout.write('.'); + }, 1 * 1000); + shell.cd('test/fixtures'); + + return Promise.all([ + execAsync('npm install --quiet', {cwd: '../fixtures'}), + execAsync('bower install', {cwd: '../fixtures'}) + ]).then(() => { + process.stdout.write('\n'); + if(!process.env.SAUCE_USERNAME) { + gutil.log('running npm run-script update-webdriver'); + return execAsync('npm run-script update-webdriver').then(() => { + clearInterval(progress); + process.stdout.write('\n'); + shell.cd('../../'); + }); + } else { + clearInterval(progress); + process.stdout.write('\n'); + shell.cd('../../'); + return Promise.resolve(); + } + }); +}); + gulp.task('test', () => { return gulp.src('test/*.test.js') .pipe(mocha()) From 62577eafb4c4f8c5c8e45e464aa89db1f6f126ce Mon Sep 17 00:00:00 2001 From: Andrew Koroluk Date: Mon, 25 Apr 2016 13:52:51 -0400 Subject: [PATCH 30/81] style(gen:gulp): use const for imports, add semicolon --- gulpfile.js | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/gulpfile.js b/gulpfile.js index e4529953e..8310337f7 100644 --- a/gulpfile.js +++ b/gulpfile.js @@ -1,19 +1,19 @@ 'use strict'; -var fs = require('fs'); -var path = require('path'); -var Promise = require('bluebird'); -var gulp = require('gulp'); -var babel = require('gulp-babel'); -var gulpMocha = require('gulp-mocha'); -var plumber = require('gulp-plumber'); -var gulpIf = require('gulp-if'); -var del = require('del'); -var lazypipe = require('lazypipe'); -var runSequence = require('run-sequence'); -var merge = require('merge-stream'); +const fs = require('fs'); +const path = require('path'); const exec = require('child_process').exec; const _ = require('lodash'); +const Promise = require('bluebird'); +const gulp = require('gulp'); const gutil = require('gulp-util'); +const babel = require('gulp-babel'); +const gulpMocha = require('gulp-mocha'); +const plumber = require('gulp-plumber'); +const gulpIf = require('gulp-if'); +const del = require('del'); +const lazypipe = require('lazypipe'); +const runSequence = require('run-sequence'); +const merge = require('merge-stream'); const shell = require('shelljs'); var watching = false; @@ -161,5 +161,5 @@ gulp.task('installFixtures', function() { gulp.task('test', () => { return gulp.src('test/*.test.js') - .pipe(mocha()) + .pipe(mocha()); }); From 9b9c781fbd97048eb42b31b2e8e852cc2f8b74a2 Mon Sep 17 00:00:00 2001 From: Andrew Koroluk Date: Mon, 25 Apr 2016 13:53:16 -0400 Subject: [PATCH 31/81] chore(package): add gulp-util --- package.json | 1 + 1 file changed, 1 insertion(+) diff --git a/package.json b/package.json index 1827ba07e..f373d4df7 100644 --- a/package.json +++ b/package.json @@ -70,6 +70,7 @@ "gulp-if": "^2.0.0", "gulp-mocha": "^2.2.0", "gulp-plumber": "^1.1.0", + "gulp-util": "^3.0.7", "jit-grunt": "~0.10.0", "lazypipe": "^1.0.1", "merge-stream": "^1.0.0", From 5a21831029bf107665b8111239dc755f72e2a5a8 Mon Sep 17 00:00:00 2001 From: Andrew Koroluk Date: Mon, 25 Apr 2016 13:53:43 -0400 Subject: [PATCH 32/81] chore(package): add updateFixtures:deps & installFixtures to `test` script --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index f373d4df7..524ab175b 100644 --- a/package.json +++ b/package.json @@ -31,7 +31,7 @@ "url": "git://github.com/angular-fullstack/generator-angular-fullstack.git" }, "scripts": { - "test": "gulp build && gulp test", + "test": "gulp updateFixtures:test && gulp installFixtures && gulp build && gulp test", "prepublish": "gulp build" }, "dependencies": { From 57477392d315faa8b9db1e2915c206f3c3e97e50 Mon Sep 17 00:00:00 2001 From: Andrew Koroluk Date: Mon, 25 Apr 2016 16:40:09 -0400 Subject: [PATCH 33/81] fix(gen:gulp:watch): for some reason gulp-if isn't working inside lazypipe --- gulpfile.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/gulpfile.js b/gulpfile.js index 8310337f7..3b47197d6 100644 --- a/gulpfile.js +++ b/gulpfile.js @@ -28,7 +28,6 @@ const mocha = lazypipe() }); const transpile = lazypipe() - .pipe(() => gulpIf(watching, plumber())) .pipe(babel); gulp.task('clean', () => { @@ -37,10 +36,12 @@ gulp.task('clean', () => { gulp.task('babel', () => { let generators = gulp.src(['src/generators/**/*.js']) + .pipe(gulpIf(watching, plumber())) .pipe(transpile()) .pipe(gulp.dest('generators')); let test = gulp.src(['src/test/**/*.js']) + .pipe(gulpIf(watching, plumber())) .pipe(transpile()) .pipe(gulp.dest('test')); From 0787039881bec29280b9fafeadbf8fe14fb95058 Mon Sep 17 00:00:00 2001 From: Andrew Koroluk Date: Mon, 25 Apr 2016 16:41:16 -0400 Subject: [PATCH 34/81] fix(gen:endpoint): typo --- src/generators/endpoint/index.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/generators/endpoint/index.js b/src/generators/endpoint/index.js index 675e61c07..4c05c8e97 100644 --- a/src/generators/endpoint/index.js +++ b/src/generators/endpoint/index.js @@ -22,7 +22,7 @@ export class Generator extends Base { }); this.option('endpointDirectory', { - desc: 'Parent directory for enpoints', + desc: 'Parent directory for endpoints', type: String }); } From d51295a84b0149496d904a775954f65ec1a6945f Mon Sep 17 00:00:00 2001 From: Andrew Koroluk Date: Mon, 25 Apr 2016 16:42:10 -0400 Subject: [PATCH 35/81] docs(gen:tests): add some JSDoc to `runCmd` --- src/test/main.test.js | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/test/main.test.js b/src/test/main.test.js index deed2c25b..802d2c6b1 100644 --- a/src/test/main.test.js +++ b/src/test/main.test.js @@ -27,6 +27,16 @@ const defaultOptions = { // var DEBUG = true; var DEBUG = false; +/** + * @callback doneCallback + * @param {null|Error} err + */ + +/** + * Run the given command in a child process + * @param {string} cmd - command to run + * @param {doneCallback} done + */ function runCmd(cmd, done) { exec(cmd, {}, function(err, stdout, stderr) { if(err) { From 36d79c2f98bfddce0f3f85077e6a9fc39491614b Mon Sep 17 00:00:00 2001 From: Andrew Koroluk Date: Mon, 25 Apr 2016 16:43:47 -0400 Subject: [PATCH 36/81] feat(gen:tests): a bunch of test progress --- src/test/main.test.js | 177 ++++++++++++++++++++++++++++++++++++++---- 1 file changed, 163 insertions(+), 14 deletions(-) diff --git a/src/test/main.test.js b/src/test/main.test.js index 802d2c6b1..64f80e796 100644 --- a/src/test/main.test.js +++ b/src/test/main.test.js @@ -1,12 +1,14 @@ 'use strict'; import path from 'path'; import fs from 'fs'; +import _ from 'lodash'; import Promise from 'bluebird'; Promise.promisifyAll(fs); import {exec} from 'child_process'; import helpers from 'yeoman-test'; import assert from 'yeoman-assert'; import * as getExpectedFiles from './get-expected-files'; +import recursiveReadDir from 'recursive-readdir'; const defaultOptions = { buildtool: 'grunt', @@ -26,6 +28,12 @@ const defaultOptions = { }; // var DEBUG = true; var DEBUG = false; +const TEST_DIR = __dirname; + +function copyAsync(src, dest) { + return fs.readFileAsync(src) + .then(data => fs.writeFileAsync(dest, data)); +} /** * @callback doneCallback @@ -50,14 +58,36 @@ function runCmd(cmd, done) { }); } -describe('angular-fullstack:app', function() { - beforeEach(function() { - this.gen = helpers +function assertOnlyFiles(expectedFiles, topLevelPath='./', skip=['node_modules', 'bower_components']) { + return new Promise((resolve, reject) => { + recursiveReadDir(topLevelPath, skip, function(err, actualFiles) { + if(err) return reject(err); + + actualFiles = _.map(actualFiles.concat(), file => path.normalize(file.replace(path.normalize(`${topLevelPath}/`), ''))); + expectedFiles = _.map(expectedFiles, file => path.normalize(file)); + + let extras = _.pullAll(actualFiles, expectedFiles); + + if(extras.length !== 0) { + return reject(extras); + } + resolve(); + }); + }); +} + +function runGen(prompts) { + return new Promise((resolve, reject) => { + let dir; + helpers .run(require.resolve('../generators/app')) - .inTmpDir(function(dir) { + .inTmpDir(function(_dir) { + // this will create a new temporary directory for each new generator run var done = this.async(); - if(DEBUG) console.log(`TEMP DIR: ${dir}`); + if(DEBUG) console.log(`TEMP DIR: ${_dir}`); + dir = _dir; + // symlink our dependency directories return Promise.all([ fs.mkdirAsync(dir + '/client').then(() => { return fs.symlinkAsync(__dirname + '/fixtures/bower_components', dir + '/client/bower_components'); @@ -70,21 +100,62 @@ describe('angular-fullstack:app', function() { // [helpers.createDummyGenerator(), 'ng-component:app'] ]) .withOptions({ - skipInstall: true, - force: true + skipInstall: true }) // .withArguments(['upperCaseBug']) - .withPrompts(defaultOptions); + .withPrompts(prompts) + .on('error', reject) + .on('end', () => resolve(dir)); + }); +} + +function runEndpointGen(name, opt={}) { + let prompts = opt.prompts || {}; + let options = opt.options || {}; + let config = opt.config; + + return new Promise((resolve, reject) => { + let gen = helpers + .run(require.resolve('../generators/endpoint'), {tmpdir: false}) + .withOptions(options) + .withArguments([name]) + .withPrompts(prompts); + + if(config) { + gen + .withLocalConfig(config); + } + + gen + .on('error', reject) + .on('end', () => resolve()) + }); +} + +function getConfig(dir) { + return fs.readFileAsync(path.join(dir, '.yo-rc.json'), 'utf8').then(data => { + return JSON.parse(data); + }); +} + +describe('angular-fullstack:app', function() { + beforeEach(function() { + this.gen = runGen(defaultOptions); }); describe('default settings', function() { - beforeEach(function(done) { - this.gen.on('end', done); + var dir; + + beforeEach(function() { + return this.gen.then(_dir => { + dir = _dir; + }); }); - it('generates the proper files', function(done) { - assert.file(getExpectedFiles.app(defaultOptions)); - done(); + it('generates the proper files', function() { + const expectedFiles = getExpectedFiles.app(defaultOptions); + assert.file(expectedFiles); + return assertOnlyFiles(expectedFiles, path.normalize(dir)).should.eventually.be.fulfilled; }); it('passes JSCS', function(done) { @@ -99,8 +170,86 @@ describe('angular-fullstack:app', function() { runCmd('grunt test:client', done); }); - it('passes client tests', function(done) { + it('passes server tests', function(done) { runCmd('grunt test:server', done); }); + + describe('with a generated endpont', function() { + beforeEach(function() { + getConfig(dir).then(config => { + return runEndpointGen('foo', {config: config['generator-angular-fullstack']}); + }); + }); + + it('should pass jscs'); //'foo' + + it('should pass lint'); + + it('should run server tests successfully', function(done) { + runCmd('grunt test:server', done); + }); + }); + + describe.only('with a generated capitalized endpont', function() { + beforeEach(function() { + getConfig(dir).then(config => { + return runEndpointGen('Foo', {config: config['generator-angular-fullstack']}); + }); + }); + + it('should pass jscs'); + + it('should pass lint'); + + it('should run server tests successfully', function(done) { + runCmd('grunt test:server', done); + }); + }); + + it('should pass lint with generated path name endpoint'); //'foo/bar' + + it('should run server tests successfully with generated path name endpoint'); + + it('should generate expected files with path name endpoint'); + // [ + // 'server/api/foo/bar/index.js', + // 'server/api/foo/bar/index.spec.js', + // 'server/api/foo/bar/bar.controller.js', + // 'server/api/foo/bar/bar.events.js', + // 'server/api/foo/bar/bar.integration.js', + // 'server/api/foo/bar/bar.model.js', + // 'server/api/foo/bar/bar.socket.js' + // ] + + it('should use existing config if available'); + // this.timeout(60000); + // return copyAsync(__dirname + '/fixtures/.yo-rc.json', __dirname + '/temp/.yo-rc.json').then(() => { + // var gen = helpers.createGenerator('angular-fullstack:app', [ + // '../../generators/app', + // '../../generators/endpoint', + // [ + // helpers.createDummyGenerator(), + // 'ng-component:app' + // ] + // ], [], { + // skipInstall: true + // }); + // helpers.mockPrompt(gen, { + // skipConfig: true + // }); + // gen.run(function () { + // assert.file([ + // 'client/app/main/main.less', + // 'server/auth/google/passport.js' + // ]); + // done(); + // }); + // }); + + if(!process.env.SKIP_E2E) { + it('should run e2e tests successfully'); //'grunt test:e2e' + + it('should run e2e tests successfully for production app'); //'grunt test:e2e:prod' + } }); }); \ No newline at end of file From 3310a1cebf417394b6b702ac87be04b374e73631 Mon Sep 17 00:00:00 2001 From: Andrew Koroluk Date: Mon, 25 Apr 2016 16:50:00 -0400 Subject: [PATCH 37/81] fix(gen:test): remove my `.only` --- src/test/main.test.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/test/main.test.js b/src/test/main.test.js index 64f80e796..62eeed2b0 100644 --- a/src/test/main.test.js +++ b/src/test/main.test.js @@ -190,7 +190,7 @@ describe('angular-fullstack:app', function() { }); }); - describe.only('with a generated capitalized endpont', function() { + describe('with a generated capitalized endpont', function() { beforeEach(function() { getConfig(dir).then(config => { return runEndpointGen('Foo', {config: config['generator-angular-fullstack']}); From 1c91686baa0c24eade8fb8b34361417c7ff2c94e Mon Sep 17 00:00:00 2001 From: Andrew Koroluk Date: Wed, 27 Apr 2016 01:51:01 -0400 Subject: [PATCH 38/81] refactor(gen:test): move DEBUG var to mocha.conf.js --- gulpfile.js | 5 ++++- mocha.conf.js | 3 +++ src/test/main.test.js | 2 -- 3 files changed, 7 insertions(+), 3 deletions(-) create mode 100644 mocha.conf.js diff --git a/gulpfile.js b/gulpfile.js index 3b47197d6..6ffef6e65 100644 --- a/gulpfile.js +++ b/gulpfile.js @@ -24,7 +24,10 @@ const mocha = lazypipe() timeout: 120000, globals: { should: require('should') - } + }, + require: [ + './mocha.conf' + ] }); const transpile = lazypipe() diff --git a/mocha.conf.js b/mocha.conf.js new file mode 100644 index 000000000..8fbbb39e6 --- /dev/null +++ b/mocha.conf.js @@ -0,0 +1,3 @@ +'use strict'; + +global.DEBUG = !!process.env.DEBUG; diff --git a/src/test/main.test.js b/src/test/main.test.js index 62eeed2b0..1f5f8a70e 100644 --- a/src/test/main.test.js +++ b/src/test/main.test.js @@ -26,8 +26,6 @@ const defaultOptions = { oauth: [], socketio: true }; -// var DEBUG = true; -var DEBUG = false; const TEST_DIR = __dirname; function copyAsync(src, dest) { From fdd5b68899f22057829066363c2c047333875f58 Mon Sep 17 00:00:00 2001 From: Andrew Koroluk Date: Wed, 27 Apr 2016 02:04:55 -0400 Subject: [PATCH 39/81] refactor(gen:test): pull 4 helper functions out into a separate module --- src/test/main.test.js | 60 ++++---------------------------------- src/test/test-helpers.js | 63 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 69 insertions(+), 54 deletions(-) create mode 100644 src/test/test-helpers.js diff --git a/src/test/main.test.js b/src/test/main.test.js index 1f5f8a70e..8f7a0836f 100644 --- a/src/test/main.test.js +++ b/src/test/main.test.js @@ -4,11 +4,15 @@ import fs from 'fs'; import _ from 'lodash'; import Promise from 'bluebird'; Promise.promisifyAll(fs); -import {exec} from 'child_process'; import helpers from 'yeoman-test'; import assert from 'yeoman-assert'; import * as getExpectedFiles from './get-expected-files'; -import recursiveReadDir from 'recursive-readdir'; +import { + copyAsync, + runCmd, + assertOnlyFiles, + getConfig +} from './test-helpers'; const defaultOptions = { buildtool: 'grunt', @@ -28,52 +32,6 @@ const defaultOptions = { }; const TEST_DIR = __dirname; -function copyAsync(src, dest) { - return fs.readFileAsync(src) - .then(data => fs.writeFileAsync(dest, data)); -} - -/** - * @callback doneCallback - * @param {null|Error} err - */ - -/** - * Run the given command in a child process - * @param {string} cmd - command to run - * @param {doneCallback} done - */ -function runCmd(cmd, done) { - exec(cmd, {}, function(err, stdout, stderr) { - if(err) { - console.error(stdout); - throw new Error(`Error running command: ${cmd}`); - done(err); - } else { - if(DEBUG) console.log(stdout); - done(); - } - }); -} - -function assertOnlyFiles(expectedFiles, topLevelPath='./', skip=['node_modules', 'bower_components']) { - return new Promise((resolve, reject) => { - recursiveReadDir(topLevelPath, skip, function(err, actualFiles) { - if(err) return reject(err); - - actualFiles = _.map(actualFiles.concat(), file => path.normalize(file.replace(path.normalize(`${topLevelPath}/`), ''))); - expectedFiles = _.map(expectedFiles, file => path.normalize(file)); - - let extras = _.pullAll(actualFiles, expectedFiles); - - if(extras.length !== 0) { - return reject(extras); - } - resolve(); - }); - }); -} - function runGen(prompts) { return new Promise((resolve, reject) => { let dir; @@ -130,12 +88,6 @@ function runEndpointGen(name, opt={}) { }); } -function getConfig(dir) { - return fs.readFileAsync(path.join(dir, '.yo-rc.json'), 'utf8').then(data => { - return JSON.parse(data); - }); -} - describe('angular-fullstack:app', function() { beforeEach(function() { this.gen = runGen(defaultOptions); diff --git a/src/test/test-helpers.js b/src/test/test-helpers.js new file mode 100644 index 000000000..7ddf890cb --- /dev/null +++ b/src/test/test-helpers.js @@ -0,0 +1,63 @@ +'use strict'; +import path from 'path'; +import fs from 'fs'; +import _ from 'lodash'; +import Promise from 'bluebird'; +Promise.promisifyAll(fs); +import {exec} from 'child_process'; +import helpers from 'yeoman-test'; +import assert from 'yeoman-assert'; +import * as getExpectedFiles from './get-expected-files'; +import recursiveReadDir from 'recursive-readdir'; + +export function copyAsync(src, dest) { + return fs.readFileAsync(src) + .then(data => fs.writeFileAsync(dest, data)); +} + +/** + * @callback doneCallback + * @param {null|Error} err + */ + +/** + * Run the given command in a child process + * @param {string} cmd - command to run + * @param {doneCallback} done + */ +export function runCmd(cmd, done) { + exec(cmd, {}, function(err, stdout, stderr) { + if(err) { + console.error(stdout); + throw new Error(`Error running command: ${cmd}`); + done(err); + } else { + if(DEBUG) console.log(stdout); + done(); + } + }); +} + +export function assertOnlyFiles(expectedFiles, topLevelPath='./', skip=['node_modules', 'bower_components']) { + return new Promise((resolve, reject) => { + recursiveReadDir(topLevelPath, skip, function(err, actualFiles) { + if(err) return reject(err); + + actualFiles = _.map(actualFiles.concat(), file => path.normalize(file.replace(path.normalize(`${topLevelPath}/`), ''))); + expectedFiles = _.map(expectedFiles, file => path.normalize(file)); + + let extras = _.pullAll(actualFiles, expectedFiles); + + if(extras.length !== 0) { + return reject(extras); + } + resolve(); + }); + }); +} + +export function getConfig(dir) { + return fs.readFileAsync(path.join(dir, '.yo-rc.json'), 'utf8').then(data => { + return JSON.parse(data); + }); +} From 0b363756b62263396c45165741ef1ef88b0d5bba Mon Sep 17 00:00:00 2001 From: Andrew Koroluk Date: Wed, 27 Apr 2016 02:20:15 -0400 Subject: [PATCH 40/81] feat(gen:test): add endpoint path name test --- src/test/main.test.js | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/src/test/main.test.js b/src/test/main.test.js index 8f7a0836f..84756b05c 100644 --- a/src/test/main.test.js +++ b/src/test/main.test.js @@ -156,9 +156,21 @@ describe('angular-fullstack:app', function() { }); }); - it('should pass lint with generated path name endpoint'); //'foo/bar' + describe('with a generated path name endpont', function() { + beforeEach(function() { + getConfig(dir).then(config => { + return runEndpointGen('foo/bar', {config: config['generator-angular-fullstack']}); + }); + }); + + it('should pass jscs'); - it('should run server tests successfully with generated path name endpoint'); + it('should pass lint'); + + it('should run server tests successfully', function(done) { + runCmd('grunt test:server', done); + }); + }); it('should generate expected files with path name endpoint'); // [ From babb03fa5b38dd345ae58bc330aee5842d784c2a Mon Sep 17 00:00:00 2001 From: Andrew Koroluk Date: Wed, 27 Apr 2016 02:25:41 -0400 Subject: [PATCH 41/81] fix(gen:test): fix `getConfig` path --- src/test/main.test.js | 6 +++--- src/test/test-helpers.js | 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/test/main.test.js b/src/test/main.test.js index 84756b05c..49823798c 100644 --- a/src/test/main.test.js +++ b/src/test/main.test.js @@ -126,7 +126,7 @@ describe('angular-fullstack:app', function() { describe('with a generated endpont', function() { beforeEach(function() { - getConfig(dir).then(config => { + getConfig(path.join(dir, '.yo-rc.json')).then(config => { return runEndpointGen('foo', {config: config['generator-angular-fullstack']}); }); }); @@ -142,7 +142,7 @@ describe('angular-fullstack:app', function() { describe('with a generated capitalized endpont', function() { beforeEach(function() { - getConfig(dir).then(config => { + getConfig(path.join(dir, '.yo-rc.json')).then(config => { return runEndpointGen('Foo', {config: config['generator-angular-fullstack']}); }); }); @@ -158,7 +158,7 @@ describe('angular-fullstack:app', function() { describe('with a generated path name endpont', function() { beforeEach(function() { - getConfig(dir).then(config => { + getConfig(path.join(dir, '.yo-rc.json')).then(config => { return runEndpointGen('foo/bar', {config: config['generator-angular-fullstack']}); }); }); diff --git a/src/test/test-helpers.js b/src/test/test-helpers.js index 7ddf890cb..7a45e4b25 100644 --- a/src/test/test-helpers.js +++ b/src/test/test-helpers.js @@ -56,8 +56,8 @@ export function assertOnlyFiles(expectedFiles, topLevelPath='./', skip=['node_mo }); } -export function getConfig(dir) { - return fs.readFileAsync(path.join(dir, '.yo-rc.json'), 'utf8').then(data => { +export function getConfig(path) { + return fs.readFileAsync(path, 'utf8').then(data => { return JSON.parse(data); }); } From 2a1d702860dda8540c043ee90271eebb68c1ed79 Mon Sep 17 00:00:00 2001 From: Andrew Koroluk Date: Thu, 28 Apr 2016 02:56:19 -0400 Subject: [PATCH 42/81] refactor(gen:test): runCmd returns a Promise instead of taking a callback --- src/test/main.test.js | 28 ++++++++++++++-------------- src/test/test-helpers.js | 23 ++++++++++++----------- 2 files changed, 26 insertions(+), 25 deletions(-) diff --git a/src/test/main.test.js b/src/test/main.test.js index 49823798c..d6bc3eac6 100644 --- a/src/test/main.test.js +++ b/src/test/main.test.js @@ -108,20 +108,20 @@ describe('angular-fullstack:app', function() { return assertOnlyFiles(expectedFiles, path.normalize(dir)).should.eventually.be.fulfilled; }); - it('passes JSCS', function(done) { - runCmd('grunt jscs', done); + it('passes JSCS', function() { + return runCmd('grunt jscs').should.be.fulfilled(); }); - it('passes JSHint', function(done) { - runCmd('grunt jshint', done); + it('passes JSHint', function() { + return runCmd('grunt jshint').should.be.fulfilled(); }); - it('passes client tests', function(done) { - runCmd('grunt test:client', done); + it('passes client tests', function() { + return runCmd('grunt test:client').should.be.fulfilled(); }); - it('passes server tests', function(done) { - runCmd('grunt test:server', done); + it('passes server tests', function() { + return runCmd('grunt test:server').should.be.fulfilled(); }); describe('with a generated endpont', function() { @@ -135,8 +135,8 @@ describe('angular-fullstack:app', function() { it('should pass lint'); - it('should run server tests successfully', function(done) { - runCmd('grunt test:server', done); + it('should run server tests successfully', function() { + return runCmd('grunt test:server').should.be.fulfilled(); }); }); @@ -151,8 +151,8 @@ describe('angular-fullstack:app', function() { it('should pass lint'); - it('should run server tests successfully', function(done) { - runCmd('grunt test:server', done); + it('should run server tests successfully', function() { + return runCmd('grunt test:server').should.be.fulfilled(); }); }); @@ -167,8 +167,8 @@ describe('angular-fullstack:app', function() { it('should pass lint'); - it('should run server tests successfully', function(done) { - runCmd('grunt test:server', done); + it('should run server tests successfully', function() { + return runCmd('grunt test:server').should.be.fulfilled(); }); }); diff --git a/src/test/test-helpers.js b/src/test/test-helpers.js index 7a45e4b25..9745c2cfe 100644 --- a/src/test/test-helpers.js +++ b/src/test/test-helpers.js @@ -23,18 +23,19 @@ export function copyAsync(src, dest) { /** * Run the given command in a child process * @param {string} cmd - command to run - * @param {doneCallback} done + * @returns {Promise} */ -export function runCmd(cmd, done) { - exec(cmd, {}, function(err, stdout, stderr) { - if(err) { - console.error(stdout); - throw new Error(`Error running command: ${cmd}`); - done(err); - } else { - if(DEBUG) console.log(stdout); - done(); - } +export function runCmd(cmd) { + return new Promise((resolve, reject) => { + exec(cmd, {}, function(err, stdout, stderr) { + if(err) { + console.error(stdout); + return reject(err); + } else { + if(DEBUG) console.log(`${cmd} stdout: ${stdout}`); + return resolve(); + } + }); }); } From 887476fc5988c4781730c5f9a69a9c0fad17e752 Mon Sep 17 00:00:00 2001 From: Andrew Koroluk Date: Thu, 28 Apr 2016 02:58:09 -0400 Subject: [PATCH 43/81] feat(gen:test): add endpoint-specific tests --- package.json | 1 + src/test/endpoint.test.js | 192 +++++++++++++++++++++++++++++++++ src/test/get-expected-files.js | 17 +-- 3 files changed, 202 insertions(+), 8 deletions(-) create mode 100644 src/test/endpoint.test.js diff --git a/package.json b/package.json index 524ab175b..0e6ebf82e 100644 --- a/package.json +++ b/package.json @@ -74,6 +74,7 @@ "jit-grunt": "~0.10.0", "lazypipe": "^1.0.1", "merge-stream": "^1.0.0", + "minimatch": "^3.0.0", "mocha": "^2.2.5", "q": "^1.0.1", "recursive-readdir": "^2.0.0", diff --git a/src/test/endpoint.test.js b/src/test/endpoint.test.js new file mode 100644 index 000000000..7c925c93e --- /dev/null +++ b/src/test/endpoint.test.js @@ -0,0 +1,192 @@ +'use strict'; +import path from 'path'; +import fs from 'fs'; +import _ from 'lodash'; +import Promise from 'bluebird'; +Promise.promisifyAll(fs); +import helpers from 'yeoman-test'; +import assert from 'yeoman-assert'; +import minimatch from 'minimatch'; +import * as getExpectedFiles from './get-expected-files'; +import { + copyAsync, + runCmd, + assertOnlyFiles, + getConfig +} from './test-helpers'; + +const TEST_DIR = __dirname; + +const defaultOptions = { + buildtool: 'grunt', + script: 'js', + transpiler: 'babel', + markup: 'html', + stylesheet: 'sass', + router: 'uirouter', + testing: 'mocha', + chai: 'expect', + bootstrap: true, + uibootstrap: true, + odms: ['mongoose'], + auth: true, + oauth: [], + socketio: true +}; +function runGen(prompts) { + return new Promise((resolve, reject) => { + let dir; + helpers + .run(require.resolve('../generators/app')) + .inTmpDir(function(_dir) { + // this will create a new temporary directory for each new generator run + var done = this.async(); + if(DEBUG) console.log(`TEMP DIR: ${_dir}`); + dir = _dir; + + // symlink our dependency directories + return Promise.all([ + fs.mkdirAsync(dir + '/client').then(() => { + return fs.symlinkAsync(__dirname + '/fixtures/bower_components', dir + '/client/bower_components'); + }), + fs.symlinkAsync(__dirname + '/fixtures/node_modules', dir + '/node_modules') + ]).then(done); + }) + .withGenerators([ + require.resolve('../generators/endpoint'), + // [helpers.createDummyGenerator(), 'ng-component:app'] + ]) + .withOptions({ + skipInstall: true + }) + .withPrompts(prompts) + .on('error', reject) + .on('end', () => resolve(dir)); + }); +} + +function runEndpointGen(name, opt={}) { + let prompts = opt.prompts || {}; + let options = opt.options || {}; + let config = opt.config; + + return new Promise((resolve, reject) => { + let dir; + let gen = helpers + .run(require.resolve('../generators/endpoint')) + .inTmpDir(function(_dir) { + // this will create a new temporary directory for each new generator run + var done = this.async(); + if(DEBUG) console.log(`TEMP DIR: ${_dir}`); + dir = _dir; + + // symlink our dependency directories + return Promise.all([ + fs.mkdirAsync(dir + '/client').then(() => { + return fs.symlinkAsync(__dirname + '/fixtures/bower_components', dir + '/client/bower_components'); + }), + fs.symlinkAsync(__dirname + '/fixtures/node_modules', dir + '/node_modules') + ]).then(done); + }) + .withOptions(options) + .withArguments([name]) + .withPrompts(prompts); + + if(config) { + gen + .withLocalConfig(config); + } + + gen + .on('error', reject) + .on('end', () => resolve(dir)) + }); +} + +let jshintCmd = path.join(TEST_DIR, '/fixtures/node_modules/.bin/jshint'); +function jshint(_path, opt={}) { + let {exclude, config} = opt; + let cmd = `${jshintCmd} ${path.normalize(_path)}`; + if(exclude) cmd += ` --exclude ${exclude}`; + if(config) cmd += ` --config ${config}`; + return runCmd(cmd); +} + +var config; +var genDir; + +before(function() { + return Promise.all([ + runGen(defaultOptions).then(_dir => { + genDir = _dir; + }), + getConfig(path.join(TEST_DIR, 'fixtures/.yo-rc.json')).then(_config => { + _config['generator-angular-fullstack'].insertRoutes = false; + _config['generator-angular-fullstack'].pluralizeRoutes = false; + _config['generator-angular-fullstack'].insertSockets = false; + _config['generator-angular-fullstack'].insertModels = false; + config = _config; + }) + ]); +}); + +describe('angular-fullstack:endpoint', function() { + describe(`with a generated endpont 'foo'`, function() { + var dir; + beforeEach(function() { + return runEndpointGen('foo', {config: config['generator-angular-fullstack']}).then(_dir => { + dir = _dir; + + return Promise.all([ + copyAsync(path.join(genDir, '/server/.jshintrc'), './server/.jshintrc'), + copyAsync(path.join(genDir, '/server/.jshintrc-spec'), './server/.jshintrc-spec') + ]); + }); + }); + + it('should generate the expected files', function() { + assert.file(getExpectedFiles.endpoint('foo')); + }); + + it('should pass jscs'); + + it('should pass lint', function() { + let endpointDir = path.join(dir, 'server/api/foo/'); + let regFiles = fs.readdirAsync(endpointDir) + .then(files => files.filter(file => minimatch(file, '**/!(*.spec|*.mock|*.integration).js', {dot: true}))) + .map(file => jshint(`./server/api/foo/${file}`)); + + let specFiles = fs.readdirAsync(endpointDir) + .then(files => files.filter(file => minimatch(file, '**/+(*.spec|*.mock|*.integration).js', {dot: true}))) + .map(file => jshint(`./server/api/food/${file}`, {config: 'server/.jshintrc-spec'})); + + return Promise.all([regFiles, specFiles]).should.be.fulfilled(); + }); + }); + + describe('with a generated capitalized endpont', function() { + var dir; + beforeEach(function() { + return runEndpointGen('foo', {config: config['generator-angular-fullstack']}).then(_dir => { + dir = _dir; + }); + }); + + it('should pass jscs'); + + it('should pass lint'); + }); + + describe('with a generated path name endpont', function() { + var dir; + beforeEach(function() { + return runEndpointGen('foo', {config: config['generator-angular-fullstack']}).then(_dir => { + dir = _dir; + }); + }); + + it('should pass jscs'); + + it('should pass lint'); + }); +}); \ No newline at end of file diff --git a/src/test/get-expected-files.js b/src/test/get-expected-files.js index 6a435b3dd..c3ac9a338 100644 --- a/src/test/get-expected-files.js +++ b/src/test/get-expected-files.js @@ -224,14 +224,15 @@ export function app(options) { return files; } -export function endpoint(name, options) { +export function endpoint(name, path) { + if(!path) path = name; return [ - `server/api/${name}/index.js`, - `server/api/${name}/index.spec.js`, - `server/api/${name}/bar.controller.js`, - `server/api/${name}/bar.events.js`, - `server/api/${name}/bar.integration.js`, - `server/api/${name}/bar.model.js`, - `server/api/${name}/bar.socket.js` + `server/api/${path}/index.js`, + `server/api/${path}/index.spec.js`, + `server/api/${path}/${name}.controller.js`, + `server/api/${path}/${name}.events.js`, + `server/api/${path}/${name}.integration.js`, + `server/api/${path}/${name}.model.js`, + `server/api/${path}/${name}.socket.js` ]; } From cfa3152319a19355bff10fd1f59cf32bee7835d4 Mon Sep 17 00:00:00 2001 From: Andrew Koroluk Date: Thu, 28 Apr 2016 13:36:24 -0400 Subject: [PATCH 44/81] test(gen:main): remove pending endpoint lint tasks --- src/test/main.test.js | 12 ------------ 1 file changed, 12 deletions(-) diff --git a/src/test/main.test.js b/src/test/main.test.js index d6bc3eac6..c334174ce 100644 --- a/src/test/main.test.js +++ b/src/test/main.test.js @@ -131,10 +131,6 @@ describe('angular-fullstack:app', function() { }); }); - it('should pass jscs'); //'foo' - - it('should pass lint'); - it('should run server tests successfully', function() { return runCmd('grunt test:server').should.be.fulfilled(); }); @@ -147,10 +143,6 @@ describe('angular-fullstack:app', function() { }); }); - it('should pass jscs'); - - it('should pass lint'); - it('should run server tests successfully', function() { return runCmd('grunt test:server').should.be.fulfilled(); }); @@ -163,10 +155,6 @@ describe('angular-fullstack:app', function() { }); }); - it('should pass jscs'); - - it('should pass lint'); - it('should run server tests successfully', function() { return runCmd('grunt test:server').should.be.fulfilled(); }); From 17d9985d6afef905aa2edccc2c69923d70d778bd Mon Sep 17 00:00:00 2001 From: Andrew Koroluk Date: Thu, 28 Apr 2016 13:53:10 -0400 Subject: [PATCH 45/81] fix(gen:test:endpoint): `jshint` function also checks that the file exists --- src/test/endpoint.test.js | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/src/test/endpoint.test.js b/src/test/endpoint.test.js index 7c925c93e..2950448ab 100644 --- a/src/test/endpoint.test.js +++ b/src/test/endpoint.test.js @@ -105,11 +105,14 @@ function runEndpointGen(name, opt={}) { let jshintCmd = path.join(TEST_DIR, '/fixtures/node_modules/.bin/jshint'); function jshint(_path, opt={}) { - let {exclude, config} = opt; - let cmd = `${jshintCmd} ${path.normalize(_path)}`; - if(exclude) cmd += ` --exclude ${exclude}`; - if(config) cmd += ` --config ${config}`; - return runCmd(cmd); + _path = path.normalize(_path); + return fs.accessAsync(_path, fs.R_OK).then(err => { + let {config} = opt; + let cmd = `${jshintCmd} ${path.normalize(_path)}`; + if(config) cmd += ` --config ${config}`; + return runCmd(cmd); + }); +} } var config; From 61eb160ffe7ac2d8c2877dfc52511b8619d975c7 Mon Sep 17 00:00:00 2001 From: Andrew Koroluk Date: Thu, 28 Apr 2016 13:54:16 -0400 Subject: [PATCH 46/81] refactor(test:endpoint): break out jshint suite into helper function --- src/test/endpoint.test.js | 25 +++++++++++++++---------- 1 file changed, 15 insertions(+), 10 deletions(-) diff --git a/src/test/endpoint.test.js b/src/test/endpoint.test.js index 2950448ab..8bb10bb30 100644 --- a/src/test/endpoint.test.js +++ b/src/test/endpoint.test.js @@ -113,6 +113,20 @@ function jshint(_path, opt={}) { return runCmd(cmd); }); } + +function jshintDir(dir, name, folder) { + if(!folder) folder = name; + let endpointDir = path.join(dir, 'server/api', folder); + + let regFiles = fs.readdirAsync(endpointDir) + .then(files => files.filter(file => minimatch(file, '**/!(*.spec|*.mock|*.integration).js', {dot: true}))) + .map(file => jshint(path.join('./server/api/', folder, file))); + + let specFiles = fs.readdirAsync(endpointDir) + .then(files => files.filter(file => minimatch(file, '**/+(*.spec|*.mock|*.integration).js', {dot: true}))) + .map(file => jshint(path.join('./server/api/', folder, file), {config: 'server/.jshintrc-spec'})); + + return Promise.all([regFiles, specFiles]); } var config; @@ -154,16 +168,7 @@ describe('angular-fullstack:endpoint', function() { it('should pass jscs'); it('should pass lint', function() { - let endpointDir = path.join(dir, 'server/api/foo/'); - let regFiles = fs.readdirAsync(endpointDir) - .then(files => files.filter(file => minimatch(file, '**/!(*.spec|*.mock|*.integration).js', {dot: true}))) - .map(file => jshint(`./server/api/foo/${file}`)); - - let specFiles = fs.readdirAsync(endpointDir) - .then(files => files.filter(file => minimatch(file, '**/+(*.spec|*.mock|*.integration).js', {dot: true}))) - .map(file => jshint(`./server/api/food/${file}`, {config: 'server/.jshintrc-spec'})); - - return Promise.all([regFiles, specFiles]).should.be.fulfilled(); + return jshintDir(dir, 'foo').should.be.fulfilled(); }); }); From 20cfbe62bebabcbcdee00b2917a8d8e71651b15a Mon Sep 17 00:00:00 2001 From: Andrew Koroluk Date: Thu, 28 Apr 2016 18:52:23 -0400 Subject: [PATCH 47/81] test(gen:endpoint): add other 2 lint tests, file assert stubs --- src/test/endpoint.test.js | 26 ++++++++++++++++++++++---- 1 file changed, 22 insertions(+), 4 deletions(-) diff --git a/src/test/endpoint.test.js b/src/test/endpoint.test.js index 8bb10bb30..ed06d1575 100644 --- a/src/test/endpoint.test.js +++ b/src/test/endpoint.test.js @@ -175,26 +175,44 @@ describe('angular-fullstack:endpoint', function() { describe('with a generated capitalized endpont', function() { var dir; beforeEach(function() { - return runEndpointGen('foo', {config: config['generator-angular-fullstack']}).then(_dir => { + return runEndpointGen('Foo', {config: config['generator-angular-fullstack']}).then(_dir => { dir = _dir; + + return Promise.all([ + copyAsync(path.join(genDir, '/server/.jshintrc'), './server/.jshintrc'), + copyAsync(path.join(genDir, '/server/.jshintrc-spec'), './server/.jshintrc-spec') + ]); }); }); + it('should generate the expected files'); + it('should pass jscs'); - it('should pass lint'); + it('should pass lint', function() { + return jshintDir(dir, 'Foo').should.be.fulfilled(); + }); }); describe('with a generated path name endpont', function() { var dir; beforeEach(function() { - return runEndpointGen('foo', {config: config['generator-angular-fullstack']}).then(_dir => { + return runEndpointGen('foo/bar', {config: config['generator-angular-fullstack']}).then(_dir => { dir = _dir; + + return Promise.all([ + copyAsync(path.join(genDir, '/server/.jshintrc'), './server/.jshintrc'), + copyAsync(path.join(genDir, '/server/.jshintrc-spec'), './server/.jshintrc-spec') + ]); }); }); + it('should generate the expected files'); + it('should pass jscs'); - it('should pass lint'); + it('should pass lint', function() { + return jshintDir(dir, 'foo', 'foo/bar').should.be.fulfilled(); + }); }); }); \ No newline at end of file From 07d78eb971b8271d75c393b1437630dbc775d5da Mon Sep 17 00:00:00 2001 From: Andrew Koroluk Date: Fri, 29 Apr 2016 19:32:13 -0400 Subject: [PATCH 48/81] refactor(gen:test:endpoint): refactor `jshint` into more generic `testFile`, add jscsCmd --- src/test/endpoint.test.js | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-) diff --git a/src/test/endpoint.test.js b/src/test/endpoint.test.js index ed06d1575..f57589f26 100644 --- a/src/test/endpoint.test.js +++ b/src/test/endpoint.test.js @@ -99,18 +99,16 @@ function runEndpointGen(name, opt={}) { gen .on('error', reject) - .on('end', () => resolve(dir)) + .on('end', () => resolve(dir)); }); } let jshintCmd = path.join(TEST_DIR, '/fixtures/node_modules/.bin/jshint'); -function jshint(_path, opt={}) { +let jscsCmd = path.join(TEST_DIR, '/fixtures/node_modules/gulp-jscs/node_modules/.bin/jscs'); +function testFile(command, _path) { _path = path.normalize(_path); - return fs.accessAsync(_path, fs.R_OK).then(err => { - let {config} = opt; - let cmd = `${jshintCmd} ${path.normalize(_path)}`; - if(config) cmd += ` --config ${config}`; - return runCmd(cmd); + return fs.accessAsync(_path, fs.R_OK).then(() => { + return runCmd(`${command} ${_path}`); }); } @@ -120,11 +118,11 @@ function jshintDir(dir, name, folder) { let regFiles = fs.readdirAsync(endpointDir) .then(files => files.filter(file => minimatch(file, '**/!(*.spec|*.mock|*.integration).js', {dot: true}))) - .map(file => jshint(path.join('./server/api/', folder, file))); + .map(file => testFile(jshintCmd, path.join('./server/api/', folder, file))); let specFiles = fs.readdirAsync(endpointDir) .then(files => files.filter(file => minimatch(file, '**/+(*.spec|*.mock|*.integration).js', {dot: true}))) - .map(file => jshint(path.join('./server/api/', folder, file), {config: 'server/.jshintrc-spec'})); + .map(file => testFile(`${jshintCmd} --config server/.jshintrc-spec`, path.join('./server/api/', folder, file))); return Promise.all([regFiles, specFiles]); } From f145af27d306a6db3962df6dcd59b2ed7fc656b6 Mon Sep 17 00:00:00 2001 From: Andrew Koroluk Date: Fri, 29 Apr 2016 19:33:38 -0400 Subject: [PATCH 49/81] test(gen:endpoint): jshint other 2 endpoints --- src/test/endpoint.test.js | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/test/endpoint.test.js b/src/test/endpoint.test.js index f57589f26..31078f1dc 100644 --- a/src/test/endpoint.test.js +++ b/src/test/endpoint.test.js @@ -183,7 +183,9 @@ describe('angular-fullstack:endpoint', function() { }); }); - it('should generate the expected files'); + it('should generate the expected files', function() { + assert.file(getExpectedFiles.endpoint('Foo')); + }); it('should pass jscs'); @@ -205,7 +207,9 @@ describe('angular-fullstack:endpoint', function() { }); }); - it('should generate the expected files'); + it('should generate the expected files', function() { + assert.file(getExpectedFiles.endpoint('bar', 'foo/bar')); + }); it('should pass jscs'); From 5389c143c634627206043c6512e1ec6437f4df7f Mon Sep 17 00:00:00 2001 From: Andrew Koroluk Date: Fri, 29 Apr 2016 19:50:16 -0400 Subject: [PATCH 50/81] test(gen:endpoint): add jscs endpoint tests --- src/test/endpoint.test.js | 28 ++++++++++++++++++++++------ 1 file changed, 22 insertions(+), 6 deletions(-) diff --git a/src/test/endpoint.test.js b/src/test/endpoint.test.js index 31078f1dc..e0d074a98 100644 --- a/src/test/endpoint.test.js +++ b/src/test/endpoint.test.js @@ -126,6 +126,13 @@ function jshintDir(dir, name, folder) { return Promise.all([regFiles, specFiles]); } +function jscsDir(dir, name, folder) { + if(!folder) folder = name; + let endpointDir = path.join(dir, 'server/api', folder); + + return fs.readdirAsync(endpointDir) + .map(file => testFile(jscsCmd, path.join('./server/api/', folder, file)));; +} var config; var genDir; @@ -154,7 +161,8 @@ describe('angular-fullstack:endpoint', function() { return Promise.all([ copyAsync(path.join(genDir, '/server/.jshintrc'), './server/.jshintrc'), - copyAsync(path.join(genDir, '/server/.jshintrc-spec'), './server/.jshintrc-spec') + copyAsync(path.join(genDir, '/server/.jshintrc-spec'), './server/.jshintrc-spec'), + copyAsync(path.join(genDir, '/.jscsrc'), './.jscsrc') ]); }); }); @@ -163,7 +171,9 @@ describe('angular-fullstack:endpoint', function() { assert.file(getExpectedFiles.endpoint('foo')); }); - it('should pass jscs'); + it('should pass jscs', function() { + return jscsDir(dir, 'foo').should.be.fulfilled(); + }); it('should pass lint', function() { return jshintDir(dir, 'foo').should.be.fulfilled(); @@ -178,7 +188,8 @@ describe('angular-fullstack:endpoint', function() { return Promise.all([ copyAsync(path.join(genDir, '/server/.jshintrc'), './server/.jshintrc'), - copyAsync(path.join(genDir, '/server/.jshintrc-spec'), './server/.jshintrc-spec') + copyAsync(path.join(genDir, '/server/.jshintrc-spec'), './server/.jshintrc-spec'), + copyAsync(path.join(genDir, '/.jscsrc'), './.jscsrc') ]); }); }); @@ -187,7 +198,9 @@ describe('angular-fullstack:endpoint', function() { assert.file(getExpectedFiles.endpoint('Foo')); }); - it('should pass jscs'); + it('should pass jscs', function() { + return jscsDir(dir, 'Foo').should.be.fulfilled(); + }); it('should pass lint', function() { return jshintDir(dir, 'Foo').should.be.fulfilled(); @@ -202,7 +215,8 @@ describe('angular-fullstack:endpoint', function() { return Promise.all([ copyAsync(path.join(genDir, '/server/.jshintrc'), './server/.jshintrc'), - copyAsync(path.join(genDir, '/server/.jshintrc-spec'), './server/.jshintrc-spec') + copyAsync(path.join(genDir, '/server/.jshintrc-spec'), './server/.jshintrc-spec'), + copyAsync(path.join(genDir, '/.jscsrc'), './.jscsrc') ]); }); }); @@ -211,7 +225,9 @@ describe('angular-fullstack:endpoint', function() { assert.file(getExpectedFiles.endpoint('bar', 'foo/bar')); }); - it('should pass jscs'); + it('should pass jscs', function() { + return jscsDir(dir, 'foo', 'foo/bar').should.be.fulfilled(); + }); it('should pass lint', function() { return jshintDir(dir, 'foo', 'foo/bar').should.be.fulfilled(); From 93d7cb6e2c0fbb495d5309fc30b51d102917e533 Mon Sep 17 00:00:00 2001 From: Andrew Koroluk Date: Sat, 30 Apr 2016 03:37:16 -0400 Subject: [PATCH 51/81] test(gen:endpont): use jscs programmatically --- package.json | 1 + src/test/endpoint.test.js | 27 ++++++++++++++++++++++++--- templates/app/.jscsrc | 1 - 3 files changed, 25 insertions(+), 4 deletions(-) diff --git a/package.json b/package.json index 0e6ebf82e..168f15fed 100644 --- a/package.json +++ b/package.json @@ -72,6 +72,7 @@ "gulp-plumber": "^1.1.0", "gulp-util": "^3.0.7", "jit-grunt": "~0.10.0", + "jscs": "^3.0.3", "lazypipe": "^1.0.1", "merge-stream": "^1.0.0", "minimatch": "^3.0.0", diff --git a/src/test/endpoint.test.js b/src/test/endpoint.test.js index e0d074a98..e52ae077f 100644 --- a/src/test/endpoint.test.js +++ b/src/test/endpoint.test.js @@ -7,6 +7,9 @@ Promise.promisifyAll(fs); import helpers from 'yeoman-test'; import assert from 'yeoman-assert'; import minimatch from 'minimatch'; +import Checker from 'jscs'; +const jscs = new Checker(); +jscs.registerDefaultRules(); import * as getExpectedFiles from './get-expected-files'; import { copyAsync, @@ -104,7 +107,6 @@ function runEndpointGen(name, opt={}) { } let jshintCmd = path.join(TEST_DIR, '/fixtures/node_modules/.bin/jshint'); -let jscsCmd = path.join(TEST_DIR, '/fixtures/node_modules/gulp-jscs/node_modules/.bin/jscs'); function testFile(command, _path) { _path = path.normalize(_path); return fs.accessAsync(_path, fs.R_OK).then(() => { @@ -130,8 +132,23 @@ function jscsDir(dir, name, folder) { if(!folder) folder = name; let endpointDir = path.join(dir, 'server/api', folder); - return fs.readdirAsync(endpointDir) - .map(file => testFile(jscsCmd, path.join('./server/api/', folder, file)));; + return fs.readdirAsync(endpointDir).then(files => { + return Promise.map(files, file => { + return fs.readFileAsync(path.join('server/api', folder, file), 'utf8').then(data => { + let results = jscs.checkString(data) + let errors = results.getErrorList(); + if(errors.length === 0) { + return Promise.resolve(); + } else { + errors.forEach(error => { + var colorizeOutput = true; + console.log(results.explainError(error, colorizeOutput) + '\n'); + }); + return Promise.reject(); + } + }); + }); + }); } var config; @@ -141,6 +158,10 @@ before(function() { return Promise.all([ runGen(defaultOptions).then(_dir => { genDir = _dir; + + return fs.readFileAsync(path.join(genDir, '.jscsrc'), 'utf8').then(data => { + jscs.configure(JSON.parse(data)); + }); }), getConfig(path.join(TEST_DIR, 'fixtures/.yo-rc.json')).then(_config => { _config['generator-angular-fullstack'].insertRoutes = false; diff --git a/templates/app/.jscsrc b/templates/app/.jscsrc index 8923ad53e..e05f83c6c 100644 --- a/templates/app/.jscsrc +++ b/templates/app/.jscsrc @@ -2,7 +2,6 @@ "excludeFiles": [ "client/app/app.constant.js" ], - "esnext": true, "maximumLineLength": { "value": 100, "allowComments": true, From c70d35a79ddfb3d0a022c4df337f60fc448a138d Mon Sep 17 00:00:00 2001 From: Andrew Koroluk Date: Sat, 30 Apr 2016 04:06:12 -0400 Subject: [PATCH 52/81] test(gen): add pre-test (check fixtures) --- gulpfile.js | 2 +- src/test/pre.test.js | 46 ++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 47 insertions(+), 1 deletion(-) create mode 100644 src/test/pre.test.js diff --git a/gulpfile.js b/gulpfile.js index 6ffef6e65..b08c3968e 100644 --- a/gulpfile.js +++ b/gulpfile.js @@ -164,6 +164,6 @@ gulp.task('installFixtures', function() { }); gulp.task('test', () => { - return gulp.src('test/*.test.js') + return gulp.src(['test/pre.test.js', 'test/*.test.js']) .pipe(mocha()); }); diff --git a/src/test/pre.test.js b/src/test/pre.test.js new file mode 100644 index 000000000..d877cfb95 --- /dev/null +++ b/src/test/pre.test.js @@ -0,0 +1,46 @@ +'use strict'; +import path from 'path'; +import fs from 'fs'; +import _ from 'lodash'; +import Promise from 'bluebird'; +Promise.promisifyAll(fs); +import helpers from 'yeoman-test'; +import assert from 'yeoman-assert'; +import minimatch from 'minimatch'; +import * as getExpectedFiles from './get-expected-files'; +import { + copyAsync, + runCmd, + assertOnlyFiles, + getConfig +} from './test-helpers'; + +describe('test fixtures', function() { + it('should have package.json in fixtures', function() { + assert.file([path.join(__dirname, 'fixtures', 'package.json')]); + }); + + it('should have bower.json in fixtures', function() { + assert.file([path.join(__dirname, 'fixtures', 'bower.json')]); + }); + + it('should have all npm packages in fixtures/node_modules', function() { + var packageJson = require('./fixtures/package.json'); + var deps = Object.keys(packageJson.dependencies); + deps = deps.concat(Object.keys(packageJson.devDependencies)); + deps = deps.map(function(dep) { + return path.join(__dirname, 'fixtures', 'node_modules', dep); + }); + assert.file(deps); + }); + + it('should have all bower packages in fixtures/bower_components', function() { + var bowerJson = require('./fixtures/bower.json'); + var deps = Object.keys(bowerJson.dependencies); + deps = deps.concat(Object.keys(bowerJson.devDependencies)); + deps = deps.map(function(dep) { + return path.join(__dirname, 'fixtures', 'bower_components', dep); + }); + assert.file(deps); + }); +}); \ No newline at end of file From 0445fcc5a0a50f7e0048d2ad7c993cafb84db1b9 Mon Sep 17 00:00:00 2001 From: Andrew Koroluk Date: Sat, 30 Apr 2016 17:12:23 -0400 Subject: [PATCH 53/81] test(gen:main): test using existing config --- src/test/fixtures/.yo-rc.json | 47 +++++++++++++++++++---- src/test/main.test.js | 72 +++++++++++++++++++++++++++-------- test/fixtures/.yo-rc.json | 47 +++++++++++++++++++---- 3 files changed, 137 insertions(+), 29 deletions(-) diff --git a/src/test/fixtures/.yo-rc.json b/src/test/fixtures/.yo-rc.json index 716e42b6c..3f652f692 100644 --- a/src/test/fixtures/.yo-rc.json +++ b/src/test/fixtures/.yo-rc.json @@ -13,24 +13,57 @@ "registerModelsFile": "server/sqldb/index.js", "modelsNeedle": "// Insert models below", "filters": { + "js": true, "babel": true, + "flow": false, "html": true, - "less": true, + "sass": true, "uirouter": true, - "bootstrap": false, - "uibootstrap": false, + "bootstrap": true, + "uibootstrap": true, "socketio": true, "auth": true, "models": true, "mongooseModels": true, "mongoose": true, - "oauth": true, - "googleAuth": true, "grunt": true, "mocha": true, "jasmine": false, - "should": true, - "expect": false + "expect": true } + }, + "generator-ng-component": { + "routeDirectory": "client/app/", + "directiveDirectory": "client/app/", + "componentDirectory": "app/components/", + "filterDirectory": "client/app/", + "serviceDirectory": "client/app/", + "basePath": "client", + "moduleName": "", + "modulePrompt": true, + "filters": [ + "uirouter", + "mocha", + "expect", + "should", + "uirouter", + "es6" + ], + "extensions": [ + "babel", + "js", + "html", + "scss" + ], + "directiveSimpleTemplates": "", + "directiveComplexTemplates": "", + "filterTemplates": "", + "serviceTemplates": "", + "factoryTemplates": "", + "controllerTemplates": "", + "componentTemplates": "", + "decoratorTemplates": "", + "providerTemplates": "", + "routeTemplates": "" } } diff --git a/src/test/main.test.js b/src/test/main.test.js index c334174ce..8459e6fab 100644 --- a/src/test/main.test.js +++ b/src/test/main.test.js @@ -16,7 +16,6 @@ import { const defaultOptions = { buildtool: 'grunt', - script: 'js', transpiler: 'babel', markup: 'html', stylesheet: 'sass', @@ -32,10 +31,12 @@ const defaultOptions = { }; const TEST_DIR = __dirname; -function runGen(prompts) { +function runGen(prompts, opts={}) { + let options = opts.options || {skipInstall: true}; + return new Promise((resolve, reject) => { let dir; - helpers + let gen = helpers .run(require.resolve('../generators/app')) .inTmpDir(function(_dir) { // this will create a new temporary directory for each new generator run @@ -43,23 +44,30 @@ function runGen(prompts) { if(DEBUG) console.log(`TEMP DIR: ${_dir}`); dir = _dir; - // symlink our dependency directories - return Promise.all([ + let promises = [ fs.mkdirAsync(dir + '/client').then(() => { return fs.symlinkAsync(__dirname + '/fixtures/bower_components', dir + '/client/bower_components'); }), fs.symlinkAsync(__dirname + '/fixtures/node_modules', dir + '/node_modules') - ]).then(done); + ]; + + if(opts.copyConfigFile) { + promises.push(copyAsync(path.join(TEST_DIR, 'fixtures/.yo-rc.json'), path.join(dir, '.yo-rc.json'))); + } + + // symlink our dependency directories + return Promise.all(promises).then(done); }) .withGenerators([ require.resolve('../generators/endpoint'), // [helpers.createDummyGenerator(), 'ng-component:app'] ]) - .withOptions({ - skipInstall: true - }) // .withArguments(['upperCaseBug']) - .withPrompts(prompts) + .withOptions(options); + + if(prompts) gen.withPrompts(prompts); + + gen .on('error', reject) .on('end', () => resolve(dir)); }); @@ -89,15 +97,11 @@ function runEndpointGen(name, opt={}) { } describe('angular-fullstack:app', function() { - beforeEach(function() { - this.gen = runGen(defaultOptions); - }); - describe('default settings', function() { var dir; beforeEach(function() { - return this.gen.then(_dir => { + return runGen(defaultOptions).then(_dir => { dir = _dir; }); }); @@ -202,4 +206,42 @@ describe('angular-fullstack:app', function() { it('should run e2e tests successfully for production app'); //'grunt test:e2e:prod' } }); + + describe('default settings using existing `.yo-rc.json`', function() { + var dir; + + beforeEach(function() { + return runGen(null, { + copyConfigFile: true, + options: { + skipInstall: true, + skipConfig: true + } + }).then(_dir => { + dir = _dir; + }); + }); + + it('generates the proper files', function() { + const expectedFiles = getExpectedFiles.app(defaultOptions); + assert.file(expectedFiles); + return assertOnlyFiles(expectedFiles, path.normalize(dir)).should.be.fulfilled(); + }); + + it('passes JSCS', function() { + return runCmd('grunt jscs').should.be.fulfilled(); + }); + + it('passes JSHint', function() { + return runCmd('grunt jshint').should.be.fulfilled(); + }); + + it('passes client tests', function() { + return runCmd('grunt test:client').should.be.fulfilled(); + }); + + it('passes server tests', function() { + return runCmd('grunt test:server').should.be.fulfilled(); + }); + }); }); \ No newline at end of file diff --git a/test/fixtures/.yo-rc.json b/test/fixtures/.yo-rc.json index 716e42b6c..3f652f692 100644 --- a/test/fixtures/.yo-rc.json +++ b/test/fixtures/.yo-rc.json @@ -13,24 +13,57 @@ "registerModelsFile": "server/sqldb/index.js", "modelsNeedle": "// Insert models below", "filters": { + "js": true, "babel": true, + "flow": false, "html": true, - "less": true, + "sass": true, "uirouter": true, - "bootstrap": false, - "uibootstrap": false, + "bootstrap": true, + "uibootstrap": true, "socketio": true, "auth": true, "models": true, "mongooseModels": true, "mongoose": true, - "oauth": true, - "googleAuth": true, "grunt": true, "mocha": true, "jasmine": false, - "should": true, - "expect": false + "expect": true } + }, + "generator-ng-component": { + "routeDirectory": "client/app/", + "directiveDirectory": "client/app/", + "componentDirectory": "app/components/", + "filterDirectory": "client/app/", + "serviceDirectory": "client/app/", + "basePath": "client", + "moduleName": "", + "modulePrompt": true, + "filters": [ + "uirouter", + "mocha", + "expect", + "should", + "uirouter", + "es6" + ], + "extensions": [ + "babel", + "js", + "html", + "scss" + ], + "directiveSimpleTemplates": "", + "directiveComplexTemplates": "", + "filterTemplates": "", + "serviceTemplates": "", + "factoryTemplates": "", + "controllerTemplates": "", + "componentTemplates": "", + "decoratorTemplates": "", + "providerTemplates": "", + "routeTemplates": "" } } From a1f2c6df0dc6dd30634ecff07979b4ef66235fbb Mon Sep 17 00:00:00 2001 From: Andrew Koroluk Date: Sat, 30 Apr 2016 18:31:13 -0400 Subject: [PATCH 54/81] test(gen:pre): add .bowerrc & .yo-rc.json checks --- src/test/pre.test.js | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/src/test/pre.test.js b/src/test/pre.test.js index d877cfb95..d08a90e59 100644 --- a/src/test/pre.test.js +++ b/src/test/pre.test.js @@ -17,11 +17,15 @@ import { describe('test fixtures', function() { it('should have package.json in fixtures', function() { - assert.file([path.join(__dirname, 'fixtures', 'package.json')]); + assert.file([path.join(__dirname, 'fixtures/package.json')]); }); - it('should have bower.json in fixtures', function() { - assert.file([path.join(__dirname, 'fixtures', 'bower.json')]); + it('should have .bowerrc & bower.json in fixtures', function() { + assert.file([path.join(__dirname, 'fixtures/bower.json'), path.join(__dirname, 'fixtures/.bowerrc')]); + }); + + it('should have .yo-rc.json in fixtures', function() { + assert.file([path.join(__dirname, 'fixtures/.yo-rc.json')]); }); it('should have all npm packages in fixtures/node_modules', function() { From df20c8ec95fc54524b15c268d059da5630766524 Mon Sep 17 00:00:00 2001 From: Andrew Koroluk Date: Sat, 30 Apr 2016 18:32:03 -0400 Subject: [PATCH 55/81] test(gen:main): various fixes/etc --- src/test/main.test.js | 44 +++++-------------------------------------- 1 file changed, 5 insertions(+), 39 deletions(-) diff --git a/src/test/main.test.js b/src/test/main.test.js index 8459e6fab..794f6e085 100644 --- a/src/test/main.test.js +++ b/src/test/main.test.js @@ -109,7 +109,7 @@ describe('angular-fullstack:app', function() { it('generates the proper files', function() { const expectedFiles = getExpectedFiles.app(defaultOptions); assert.file(expectedFiles); - return assertOnlyFiles(expectedFiles, path.normalize(dir)).should.eventually.be.fulfilled; + return assertOnlyFiles(expectedFiles, path.normalize(dir)).should.be.fulfilled(); }); it('passes JSCS', function() { @@ -128,7 +128,7 @@ describe('angular-fullstack:app', function() { return runCmd('grunt test:server').should.be.fulfilled(); }); - describe('with a generated endpont', function() { + describe('with a generated endpoint', function() { beforeEach(function() { getConfig(path.join(dir, '.yo-rc.json')).then(config => { return runEndpointGen('foo', {config: config['generator-angular-fullstack']}); @@ -140,7 +140,7 @@ describe('angular-fullstack:app', function() { }); }); - describe('with a generated capitalized endpont', function() { + describe('with a generated capitalized endpoint', function() { beforeEach(function() { getConfig(path.join(dir, '.yo-rc.json')).then(config => { return runEndpointGen('Foo', {config: config['generator-angular-fullstack']}); @@ -152,7 +152,7 @@ describe('angular-fullstack:app', function() { }); }); - describe('with a generated path name endpont', function() { + describe('with a generated path name endpoint', function() { beforeEach(function() { getConfig(path.join(dir, '.yo-rc.json')).then(config => { return runEndpointGen('foo/bar', {config: config['generator-angular-fullstack']}); @@ -164,41 +164,7 @@ describe('angular-fullstack:app', function() { }); }); - it('should generate expected files with path name endpoint'); - // [ - // 'server/api/foo/bar/index.js', - // 'server/api/foo/bar/index.spec.js', - // 'server/api/foo/bar/bar.controller.js', - // 'server/api/foo/bar/bar.events.js', - // 'server/api/foo/bar/bar.integration.js', - // 'server/api/foo/bar/bar.model.js', - // 'server/api/foo/bar/bar.socket.js' - // ] - - it('should use existing config if available'); - // this.timeout(60000); - // return copyAsync(__dirname + '/fixtures/.yo-rc.json', __dirname + '/temp/.yo-rc.json').then(() => { - // var gen = helpers.createGenerator('angular-fullstack:app', [ - // '../../generators/app', - // '../../generators/endpoint', - // [ - // helpers.createDummyGenerator(), - // 'ng-component:app' - // ] - // ], [], { - // skipInstall: true - // }); - // helpers.mockPrompt(gen, { - // skipConfig: true - // }); - // gen.run(function () { - // assert.file([ - // 'client/app/main/main.less', - // 'server/auth/google/passport.js' - // ]); - // done(); - // }); - // }); + it('should run server tests successfully with generated snake-case endpoint'); //'foo-bar' if(!process.env.SKIP_E2E) { it('should run e2e tests successfully'); //'grunt test:e2e' From a24643a446e29eb30bdedc415281cbdf95982b49 Mon Sep 17 00:00:00 2001 From: Andrew Koroluk Date: Sat, 30 Apr 2016 18:32:43 -0400 Subject: [PATCH 56/81] test(gen:main): add 'with TypeScript, Jade, Jasmine, LESS, & OAuth' suite --- src/test/main.test.js | 66 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 66 insertions(+) diff --git a/src/test/main.test.js b/src/test/main.test.js index 794f6e085..3efac0104 100644 --- a/src/test/main.test.js +++ b/src/test/main.test.js @@ -210,4 +210,70 @@ describe('angular-fullstack:app', function() { return runCmd('grunt test:server').should.be.fulfilled(); }); }); + + describe('with TypeScript, Jade, Jasmine, LESS, & OAuth', function() { + var dir; + var testOptions = { + buildtool: 'grunt', + transpiler: 'ts', + markup: 'jade', + stylesheet: 'less', + router: 'uirouter', + testing: 'jasmine', + odms: ['mongoose'], + auth: true, + oauth: ['twitterAuth', 'facebookAuth', 'googleAuth'], + socketio: true, + bootstrap: true, + uibootstrap: true + }; + + beforeEach(function() { + return runGen(testOptions).then(_dir => { + dir = _dir; + }); + }); + + it('should generate the proper files', function() { + const expectedFiles = getExpectedFiles.app(testOptions); + assert.file(expectedFiles); + return assertOnlyFiles(expectedFiles, path.normalize(dir)).should.be.fulfilled(); + }); + + it('passes JSCS', function() { + return runCmd('grunt jscs').should.be.fulfilled(); + }); + + it('passes lint', function() { + return runCmd('grunt tslint').should.be.fulfilled(); + }); + + it('should run client tests successfully', function() { + return runCmd('grunt test:client').should.be.fulfilled(); + }); + + it('should run server tests successfully', function() { + return runCmd('grunt test:server').should.be.fulfilled(); + }); + + describe('with a generated endpoint', function() { + beforeEach(function() { + getConfig(path.join(dir, '.yo-rc.json')).then(config => { + return runEndpointGen('foo', {config: config['generator-angular-fullstack']}); + }); + }); + + it('should run server tests successfully', function() { + return runCmd('grunt test:server').should.be.fulfilled(); + }); + }); + + if(!process.env.SKIP_E2E) { + it('should run e2e tests successfully'); + + //it('should run e2e tests successfully for production app', function (done) { + // runTest('grunt test:e2e:prod', this, done, 240000); + //}); + } + }); }); \ No newline at end of file From a75b1d4881b21d132b965f972d917f8816a9a5aa Mon Sep 17 00:00:00 2001 From: Andrew Koroluk Date: Sat, 30 Apr 2016 22:30:53 -0400 Subject: [PATCH 57/81] fix(client:navbar.controller): refactor EJS, exclude constructor if empty --- .../client/components/navbar/navbar.controller.js | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/templates/app/client/components/navbar/navbar.controller.js b/templates/app/client/components/navbar/navbar.controller.js index 958355f9f..12ae0b351 100644 --- a/templates/app/client/components/navbar/navbar.controller.js +++ b/templates/app/client/components/navbar/navbar.controller.js @@ -9,13 +9,19 @@ class NavbarController { isCollapsed = true; //end-non-standard + <%_ if(filters.ngroute || filters.auth) { _%> - constructor(<% if(!filters.uirouter) { %>$location<% } if(!filters.uirouter && filters.auth) { %>, <% } if (filters.auth) { %>Auth<% } %>) {<% if(!filters.uirouter) { %> - this.$location = $location;<% } %> - <% if (filters.auth) { %>this.isLoggedIn = Auth.isLoggedIn; + constructor(<% if(!filters.uirouter) { %>$location<% } if(!filters.uirouter && filters.auth) { %>, <% } if (filters.auth) { %>Auth<% } %>) { + <%_ if(!filters.uirouter) { _%> + this.$location = $location; + <%_ } _%> + <%_ if (filters.auth) { _%> + this.isLoggedIn = Auth.isLoggedIn; this.isAdmin = Auth.isAdmin; this.getCurrentUser = Auth.getCurrentUser; - <% } %>}<% if(!filters.uirouter) { %> + <%_ } _%> + }<% } %> + <%_ if(!filters.uirouter) { _%> isActive(route) { return route === this.$location.path(); From 4b4db99d73985bba4db20e7664b12fafe09ccaf1 Mon Sep 17 00:00:00 2001 From: Andrew Koroluk Date: Sun, 1 May 2016 03:35:31 -0400 Subject: [PATCH 58/81] fix(e2e:main): fix yeoman.png regex allow for revved image name, fixes e2e tests on a prod environment --- templates/app/e2e/main/main.spec(jasmine).js | 2 +- templates/app/e2e/main/main.spec(mocha).js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/templates/app/e2e/main/main.spec(jasmine).js b/templates/app/e2e/main/main.spec(jasmine).js index 57284495a..3d56cb5d3 100644 --- a/templates/app/e2e/main/main.spec(jasmine).js +++ b/templates/app/e2e/main/main.spec(jasmine).js @@ -12,7 +12,7 @@ describe('Main View', function() { it('should include jumbotron with correct data', function() { expect(page.h1El.getText()).toBe('\'Allo, \'Allo!'); - expect(page.imgEl.getAttribute('src')).toMatch(/yeoman.png$/); + expect(page.imgEl.getAttribute('src')).toMatch(/yeoman(\.[a-zA-Z0-9]*)?\.png$/); expect(page.imgEl.getAttribute('alt')).toBe('I\'m Yeoman'); }); }); diff --git a/templates/app/e2e/main/main.spec(mocha).js b/templates/app/e2e/main/main.spec(mocha).js index 798b58c41..12b0781db 100644 --- a/templates/app/e2e/main/main.spec(mocha).js +++ b/templates/app/e2e/main/main.spec(mocha).js @@ -13,7 +13,7 @@ describe('Main View', function() { it('should include jumbotron with correct data', function() { <%= expect() %>page.h1El.getText()<%= to() %>.eventually.equal('\'Allo, \'Allo!'); - <%= expect() %>page.imgEl.getAttribute('src')<%= to() %>.eventually.match(/yeoman.png$/); + <%= expect() %>page.imgEl.getAttribute('src')<%= to() %>.eventually.match(/yeoman(\.[a-zA-Z0-9]*)?\.png$/); <%= expect() %>page.imgEl.getAttribute('alt')<%= to() %>.eventually.equal('I\'m Yeoman'); }); }); From d21082d9b25c801cb68aad8de9722539e7fae8b0 Mon Sep 17 00:00:00 2001 From: Andrew Koroluk Date: Sun, 1 May 2016 04:25:33 -0400 Subject: [PATCH 59/81] style(grunt): less whitespace please --- templates/app/Gruntfile(grunt).js | 96 +++++++++++++------------------ 1 file changed, 39 insertions(+), 57 deletions(-) diff --git a/templates/app/Gruntfile(grunt).js b/templates/app/Gruntfile(grunt).js index a39fd5d18..0d137d551 100644 --- a/templates/app/Gruntfile(grunt).js +++ b/templates/app/Gruntfile(grunt).js @@ -1,7 +1,7 @@ // Generated on <%= (new Date).toISOString().split('T')[0] %> using <%= rootGeneratorName() %> <%= rootGeneratorVersion() %> 'use strict'; -module.exports = function (grunt) { +module.exports = function(grunt) { var localConfig; try { localConfig = require('./server/config/local.env'); @@ -26,7 +26,6 @@ module.exports = function (grunt) { // Define the configuration for all the tasks grunt.initConfig({ - // Project settings pkg: grunt.file.readJSON('package.json'), yeoman: { @@ -87,7 +86,7 @@ module.exports = function (grunt) { jsTest: { files: ['<%%= yeoman.client %>/{app,components}/**/*.{spec,mock}.<%= scriptExt %>'], tasks: [<% if(filters.babel) { %>'newer:jshint:all'<% } if(filters.ts) { %>'newer:tslint:all', 'newer:ts:client_test',<% } %>, 'wiredep:test', 'karma'] - },<% if (filters.stylus) { %> + },<% if(filters.stylus) { %> injectStylus: { files: ['<%%= yeoman.client %>/{app,components}/**/*.styl'], tasks: ['injector:stylus'] @@ -95,7 +94,7 @@ module.exports = function (grunt) { stylus: { files: ['<%%= yeoman.client %>/{app,components}/**/*.styl'], tasks: ['stylus', 'postcss'] - },<% } if (filters.sass) { %> + },<% } if(filters.sass) { %> injectSass: { files: ['<%%= yeoman.client %>/{app,components}/**/*.{scss,sass}'], tasks: ['injector:sass'] @@ -103,7 +102,7 @@ module.exports = function (grunt) { sass: { files: ['<%%= yeoman.client %>/{app,components}/**/*.{scss,sass}'], tasks: ['sass', 'postcss'] - },<% } if (filters.less) { %> + },<% } if(filters.less) { %> injectLess: { files: ['<%%= yeoman.client %>/{app,components}/**/*.less'], tasks: ['injector:less'] @@ -111,7 +110,7 @@ module.exports = function (grunt) { less: { files: ['<%%= yeoman.client %>/{app,components}/**/*.less'], tasks: ['less', 'postcss'] - },<% } if (filters.jade) { %> + },<% } if(filters.jade) { %> jade: { files: ['<%%= yeoman.client %>/{app,components}/**/*.jade'], tasks: ['jade'] @@ -240,14 +239,14 @@ module.exports = function (grunt) { env: { PORT: process.env.PORT || 9000 }, - callback: function (nodemon) { - nodemon.on('log', function (event) { + callback: function(nodemon) { + nodemon.on('log', function(event) { console.log(event.colour); }); // opens browser on initial server start - nodemon.on('config:update', function () { - setTimeout(function () { + nodemon.on('config:update', function() { + setTimeout(function() { require('open')('http://localhost:8080/debug?port=5858'); }, 500); }); @@ -469,9 +468,9 @@ module.exports = function (grunt) { // Run some tasks in parallel to speed up the build process concurrent: { - pre: [<% if (filters.stylus) { %> - 'injector:stylus',<% } if (filters.less) { %> - 'injector:less',<% } if (filters.sass) { %> + pre: [<% if(filters.stylus) { %> + 'injector:stylus',<% } if(filters.less) { %> + 'injector:less',<% } if(filters.sass) { %> 'injector:sass',<% } %> 'ngconstant'<% if(filters.ts) { %>, 'copy:constant'<% } %> @@ -596,7 +595,7 @@ module.exports = function (grunt) { NODE_ENV: 'production' }, all: localConfig - },<% if (filters.jade) { %> + },<% if(filters.jade) { %> // Compiles Jade to html jade: { @@ -688,7 +687,7 @@ module.exports = function (grunt) { '.tmp/app/app.css' : '<%%= yeoman.client %>/app/app.styl' } } - },<% } if (filters.sass) { %> + },<% } if(filters.sass) { %> // Compiles Sass to CSS sass: { @@ -700,7 +699,7 @@ module.exports = function (grunt) { '.tmp/app/app.css' : '<%%= yeoman.client %>/app/app.scss' } } - },<% } if (filters.less) { %> + },<% } if(filters.less) { %> // Compiles Less to CSS less: { @@ -742,7 +741,7 @@ module.exports = function (grunt) { ] ] } - },<% if (filters.stylus) { %> + },<% if(filters.stylus) { %> // Inject component styl into app.styl stylus: { @@ -762,7 +761,7 @@ module.exports = function (grunt) { '!<%%= yeoman.client %>/app/app.styl' ] } - },<% } if (filters.sass) { %> + },<% } if(filters.sass) { %> // Inject component scss into app.scss sass: { @@ -782,7 +781,7 @@ module.exports = function (grunt) { '!<%%= yeoman.client %>/app/app.{scss,sass}' ] } - },<% } if (filters.less) { %> + },<% } if(filters.less) { %> // Inject component less into app.less less: { @@ -826,12 +825,12 @@ module.exports = function (grunt) { }); // Used for delaying livereload until after server has restarted - grunt.registerTask('wait', function () { + grunt.registerTask('wait', function() { grunt.log.ok('Waiting for server reload...'); var done = this.async(); - setTimeout(function () { + setTimeout(function() { grunt.log.writeln('Done waiting!'); done(); }, 1500); @@ -841,12 +840,12 @@ module.exports = function (grunt) { this.async(); }); - grunt.registerTask('serve', function (target) { - if (target === 'dist') { + grunt.registerTask('serve', function(target) { + if(target === 'dist') { return grunt.task.run(['build', 'env:all', 'env:prod', 'express:prod', 'wait', 'open', 'express-keepalive']); } - if (target === 'debug') { + if(target === 'debug') { return grunt.task.run([ 'clean:server', 'env:all', @@ -876,22 +875,20 @@ module.exports = function (grunt) { ]); }); - grunt.registerTask('server', function () { + grunt.registerTask('server', function() { grunt.log.warn('The `server` task has been deprecated. Use `grunt serve` to start a server.'); grunt.task.run(['serve']); }); grunt.registerTask('test', function(target, option) { - if (target === 'server') { + if(target === 'server') { return grunt.task.run([ 'env:all', 'env:test', 'mochaTest:unit', 'mochaTest:integration' ]); - } - - else if (target === 'client') { + } else if(target === 'client') { return grunt.task.run([ 'clean:server', 'env:all', @@ -905,11 +902,8 @@ module.exports = function (grunt) { 'wiredep:test', 'karma' ]); - } - - else if (target === 'e2e') { - - if (option === 'prod') { + } else if(target === 'e2e') { + if(option === 'prod') { return grunt.task.run([ 'build', 'env:all', @@ -917,9 +911,7 @@ module.exports = function (grunt) { 'express:prod', 'protractor' ]); - } - - else { + } else { return grunt.task.run([ 'clean:server', 'env:all', @@ -937,33 +929,24 @@ module.exports = function (grunt) { 'protractor' ]); } - } - - else if (target === 'coverage') { - - if (option === 'unit') { + } else if(target === 'coverage') { + if(option === 'unit') { return grunt.task.run([ 'env:all', 'env:test', 'mocha_istanbul:unit' ]); - } - - else if (option === 'integration') { + } else if(option === 'integration') { return grunt.task.run([ 'env:all', 'env:test', 'mocha_istanbul:integration' ]); - } - - else if (option === 'check') { + } else if(option === 'check') { return grunt.task.run([ 'istanbul_check_coverage' ]); - } - - else { + } else { return grunt.task.run([ 'env:all', 'env:test', @@ -971,13 +954,12 @@ module.exports = function (grunt) { 'istanbul_check_coverage' ]); } - + } else { + grunt.task.run([ + 'test:server', + 'test:client' + ]); } - - else grunt.task.run([ - 'test:server', - 'test:client' - ]); }); grunt.registerTask('build', [ From 9d5e9451183914220aa9a77d17358acd0c8932b1 Mon Sep 17 00:00:00 2001 From: Andrew Koroluk Date: Sun, 1 May 2016 04:31:06 -0400 Subject: [PATCH 60/81] test(gen:main): add snake-case endpoint test --- src/test/main.test.js | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/src/test/main.test.js b/src/test/main.test.js index 3efac0104..96b00036f 100644 --- a/src/test/main.test.js +++ b/src/test/main.test.js @@ -164,7 +164,17 @@ describe('angular-fullstack:app', function() { }); }); - it('should run server tests successfully with generated snake-case endpoint'); //'foo-bar' + describe('with a generated snake-case endpoint', function() { + beforeEach(function() { + getConfig(path.join(dir, '.yo-rc.json')).then(config => { + return runEndpointGen('foo-bar', {config: config['generator-angular-fullstack']}); + }); + }); + + it('should run server tests successfully', function() { + return runCmd('grunt test:server').should.be.fulfilled(); + }); + }); if(!process.env.SKIP_E2E) { it('should run e2e tests successfully'); //'grunt test:e2e' From 43ce8eef1f470943ea6362df7184bad88b1fd5b5 Mon Sep 17 00:00:00 2001 From: Andrew Koroluk Date: Sun, 1 May 2016 04:31:57 -0400 Subject: [PATCH 61/81] test(gen:main): add e2e tests --- src/test/main.test.js | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/src/test/main.test.js b/src/test/main.test.js index 96b00036f..e83a98aa8 100644 --- a/src/test/main.test.js +++ b/src/test/main.test.js @@ -177,9 +177,13 @@ describe('angular-fullstack:app', function() { }); if(!process.env.SKIP_E2E) { - it('should run e2e tests successfully'); //'grunt test:e2e' + it('should run e2e tests successfully', function() { + return runCmd('grunt test:e2e').should.be.fulfilled(); + }); - it('should run e2e tests successfully for production app'); //'grunt test:e2e:prod' + it('should run e2e tests successfully for production app', function() { + return runCmd('grunt test:e2e:prod').should.be.fulfilled(); + }); } }); @@ -279,7 +283,15 @@ describe('angular-fullstack:app', function() { }); if(!process.env.SKIP_E2E) { - it('should run e2e tests successfully'); + it('should run e2e tests successfully', function() { + return runCmd('grunt test:e2e:prod').should.be.fulfilled(); + }); + + it('should run e2e tests successfully for production app', function() { + return runCmd('grunt test:e2e:prod').should.be.fulfilled(); + }); + } + }); //it('should run e2e tests successfully for production app', function (done) { // runTest('grunt test:e2e:prod', this, done, 240000); From 8827e939f472be719d1c286ec933ea88867f81e6 Mon Sep 17 00:00:00 2001 From: Andrew Koroluk Date: Sun, 1 May 2016 04:33:02 -0400 Subject: [PATCH 62/81] test(gen:main): add the 2 other test suites (sql, no server) --- src/test/main.test.js | 137 +++++++++++++++++++++++++++++++++++++++++- 1 file changed, 134 insertions(+), 3 deletions(-) diff --git a/src/test/main.test.js b/src/test/main.test.js index e83a98aa8..b6cdea51c 100644 --- a/src/test/main.test.js +++ b/src/test/main.test.js @@ -293,9 +293,140 @@ describe('angular-fullstack:app', function() { } }); - //it('should run e2e tests successfully for production app', function (done) { - // runTest('grunt test:e2e:prod', this, done, 240000); - //}); + describe('with sequelize models, auth', function() { + var dir; + var testOptions = { + buildtool: 'grunt', + transpiler: 'babel', + markup: 'jade', + stylesheet: 'css', + router: 'uirouter', + testing: 'jasmine', + odms: ['sequelize'], + auth: true, + oauth: ['twitterAuth', 'facebookAuth', 'googleAuth'], + socketio: true, + bootstrap: true, + uibootstrap: true + }; + + beforeEach(function() { + return runGen(testOptions).then(_dir => { + dir = _dir; + }); + }); + + it('should generate the proper files', function() { + const expectedFiles = getExpectedFiles.app(testOptions); + assert.file(expectedFiles); + return assertOnlyFiles(expectedFiles, path.normalize(dir)).should.be.fulfilled(); + }); + + it('passes JSCS', function() { + return runCmd('grunt jscs').should.be.fulfilled(); + }); + + it('passes lint', function() { + return runCmd('grunt jshint').should.be.fulfilled(); + }); + + it('should run client tests successfully', function() { + return runCmd('grunt test:client').should.be.fulfilled(); + }); + + it('should run server tests successfully', function() { + return runCmd('grunt test:server').should.be.fulfilled(); + }); + + describe('with a generated endpoint', function() { + beforeEach(function() { + getConfig(path.join(dir, '.yo-rc.json')).then(config => { + return runEndpointGen('foo', {config: config['generator-angular-fullstack']}); + }); + }); + + it('should run server tests successfully', function() { + return runCmd('grunt test:server').should.be.fulfilled(); + }); + }); + + if(!process.env.SKIP_E2E) { + it('should run e2e tests successfully', function() { + return runCmd('grunt test:e2e:prod').should.be.fulfilled(); + }); + + it('should run e2e tests successfully for production app', function() { + return runCmd('grunt test:e2e:prod').should.be.fulfilled(); + }); + } + }); + + describe('with TypeScript, Mocha + Chai (should) and no server options', function() { + var dir; + var testOptions = { + buildtool: 'grunt', + transpiler: 'ts', + markup: 'jade', + stylesheet: 'stylus', + router: 'uirouter', + testing: 'mocha', + chai: 'should', + odms: [], + auth: false, + oauth: [], + socketio: false, + bootstrap: false, + uibootstrap: false + }; + + beforeEach(function() { + return runGen(testOptions).then(_dir => { + dir = _dir; + }); + }); + + it('should generate the proper files', function() { + const expectedFiles = getExpectedFiles.app(testOptions); + assert.file(expectedFiles); + return assertOnlyFiles(expectedFiles, path.normalize(dir)).should.be.fulfilled(); + }); + + it('passes JSCS', function() { + return runCmd('grunt jscs').should.be.fulfilled(); + }); + + it('passes lint', function() { + return runCmd('grunt tslint').should.be.fulfilled(); + }); + + it('should run client tests successfully', function() { + return runCmd('grunt test:client').should.be.fulfilled(); + }); + + it('should run server tests successfully', function() { + return runCmd('grunt test:server').should.be.fulfilled(); + }); + + describe('with a generated endpoint', function() { + beforeEach(function() { + getConfig(path.join(dir, '.yo-rc.json')).then(config => { + return runEndpointGen('foo', {config: config['generator-angular-fullstack']}); + }); + }); + + it('should run server tests successfully', function() { + return runCmd('grunt test:server').should.be.fulfilled(); + }); + }); + + if(!process.env.SKIP_E2E) { + it('should run e2e tests successfully', function() { + return runCmd('grunt test:e2e:prod').should.be.fulfilled(); + }); + + it('should run e2e tests successfully for production app', function() { + return runCmd('grunt test:e2e:prod').should.be.fulfilled(); + }); } }); }); \ No newline at end of file From 5aca55f08af7ddec213f6202939bb8d445c27ecf Mon Sep 17 00:00:00 2001 From: Andrew Koroluk Date: Sun, 1 May 2016 16:36:35 -0400 Subject: [PATCH 63/81] fix(e2e:prod): turn off lusca if using saucelabs --- templates/app/server/config/express.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/templates/app/server/config/express.js b/templates/app/server/config/express.js index eeca74e6e..84f82043b 100644 --- a/templates/app/server/config/express.js +++ b/templates/app/server/config/express.js @@ -56,7 +56,7 @@ export default function(app) { * Lusca - express server security * https://github.com/krakenjs/lusca */ - if ('test' !== env) { + if (env !== 'test' && !process.env.SAUCE_USERNAME) { app.use(lusca({ csrf: { angular: true From 53a24a32242fdb155e85485db61cbde03ab59438 Mon Sep 17 00:00:00 2001 From: Andrew Koroluk Date: Sun, 1 May 2016 17:48:30 -0400 Subject: [PATCH 64/81] test(gen:main): fix reg e2e tests running prod tests instead --- src/test/main.test.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/test/main.test.js b/src/test/main.test.js index b6cdea51c..69a3b0509 100644 --- a/src/test/main.test.js +++ b/src/test/main.test.js @@ -284,7 +284,7 @@ describe('angular-fullstack:app', function() { if(!process.env.SKIP_E2E) { it('should run e2e tests successfully', function() { - return runCmd('grunt test:e2e:prod').should.be.fulfilled(); + return runCmd('grunt test:e2e').should.be.fulfilled(); }); it('should run e2e tests successfully for production app', function() { @@ -352,7 +352,7 @@ describe('angular-fullstack:app', function() { if(!process.env.SKIP_E2E) { it('should run e2e tests successfully', function() { - return runCmd('grunt test:e2e:prod').should.be.fulfilled(); + return runCmd('grunt test').should.be.fulfilled(); }); it('should run e2e tests successfully for production app', function() { @@ -421,7 +421,7 @@ describe('angular-fullstack:app', function() { if(!process.env.SKIP_E2E) { it('should run e2e tests successfully', function() { - return runCmd('grunt test:e2e:prod').should.be.fulfilled(); + return runCmd('grunt test:e2e').should.be.fulfilled(); }); it('should run e2e tests successfully for production app', function() { From b41d4a6936da0ec9938c4bccce93202280713bc2 Mon Sep 17 00:00:00 2001 From: Andrew Koroluk Date: Sun, 1 May 2016 19:10:46 -0400 Subject: [PATCH 65/81] test(gen:endpoint): add snake-case tests --- src/test/endpoint.test.js | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/src/test/endpoint.test.js b/src/test/endpoint.test.js index e52ae077f..aa53858d1 100644 --- a/src/test/endpoint.test.js +++ b/src/test/endpoint.test.js @@ -254,4 +254,31 @@ describe('angular-fullstack:endpoint', function() { return jshintDir(dir, 'foo', 'foo/bar').should.be.fulfilled(); }); }); + + describe('with a generated snake-case endpoint', function() { + var dir; + beforeEach(function() { + return runEndpointGen('foo-bar', {config: config['generator-angular-fullstack']}).then(_dir => { + dir = _dir; + + return Promise.all([ + copyAsync(path.join(genDir, '/server/.jshintrc'), './server/.jshintrc'), + copyAsync(path.join(genDir, '/server/.jshintrc-spec'), './server/.jshintrc-spec'), + copyAsync(path.join(genDir, '/.jscsrc'), './.jscsrc') + ]); + }); + }); + + it('should generate the expected files', function() { + assert.file(getExpectedFiles.endpoint('foo-bar')); + }); + + it('should pass jscs', function() { + return jscsDir(dir, 'foo-bar').should.be.fulfilled(); + }); + + it('should pass lint', function() { + return jshintDir(dir, 'foo-bar').should.be.fulfilled(); + }); + }); }); \ No newline at end of file From 54d4ebd370beb2a22e00af0b41a351b0c4fcc3b0 Mon Sep 17 00:00:00 2001 From: Andrew Koroluk Date: Sun, 1 May 2016 19:11:10 -0400 Subject: [PATCH 66/81] fix(grunt): exclude jshint config if using TypeScript --- templates/app/Gruntfile(grunt).js | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/templates/app/Gruntfile(grunt).js b/templates/app/Gruntfile(grunt).js index 0d137d551..7f5d4e83f 100644 --- a/templates/app/Gruntfile(grunt).js +++ b/templates/app/Gruntfile(grunt).js @@ -141,6 +141,7 @@ module.exports = function(grunt) { tasks: ['wiredep'] }, }, + <%_ if(!filters.ts) { _%> // Make sure code styles are up to par and there are no obvious mistakes jshint: { @@ -164,7 +165,8 @@ module.exports = function(grunt) { test: { src: ['<%%= yeoman.client %>/{app,components}/**/*.{spec,mock}.js'] } - },<% if(filters.ts) { %> + },<% } %> + <%_ if(filters.ts) { _%> tslint: { options: { From daf0540793dbea9457769146adaa19f378fa2156 Mon Sep 17 00:00:00 2001 From: Andrew Koroluk Date: Sun, 1 May 2016 19:47:58 -0400 Subject: [PATCH 67/81] perf(gen:test:main): lets get some concurrency/re-use going --- src/test/main.test.js | 82 ++++++++++++++++++++++++++++++------------- 1 file changed, 57 insertions(+), 25 deletions(-) diff --git a/src/test/main.test.js b/src/test/main.test.js index 69a3b0509..1d73022aa 100644 --- a/src/test/main.test.js +++ b/src/test/main.test.js @@ -130,7 +130,7 @@ describe('angular-fullstack:app', function() { describe('with a generated endpoint', function() { beforeEach(function() { - getConfig(path.join(dir, '.yo-rc.json')).then(config => { + return getConfig(path.join(dir, '.yo-rc.json')).then(config => { return runEndpointGen('foo', {config: config['generator-angular-fullstack']}); }); }); @@ -142,7 +142,7 @@ describe('angular-fullstack:app', function() { describe('with a generated capitalized endpoint', function() { beforeEach(function() { - getConfig(path.join(dir, '.yo-rc.json')).then(config => { + return getConfig(path.join(dir, '.yo-rc.json')).then(config => { return runEndpointGen('Foo', {config: config['generator-angular-fullstack']}); }); }); @@ -154,7 +154,7 @@ describe('angular-fullstack:app', function() { describe('with a generated path name endpoint', function() { beforeEach(function() { - getConfig(path.join(dir, '.yo-rc.json')).then(config => { + return getConfig(path.join(dir, '.yo-rc.json')).then(config => { return runEndpointGen('foo/bar', {config: config['generator-angular-fullstack']}); }); }); @@ -166,7 +166,7 @@ describe('angular-fullstack:app', function() { describe('with a generated snake-case endpoint', function() { beforeEach(function() { - getConfig(path.join(dir, '.yo-rc.json')).then(config => { + return getConfig(path.join(dir, '.yo-rc.json')).then(config => { return runEndpointGen('foo-bar', {config: config['generator-angular-fullstack']}); }); }); @@ -189,8 +189,12 @@ describe('angular-fullstack:app', function() { describe('default settings using existing `.yo-rc.json`', function() { var dir; + var jscsResult; + var lintResult; + var clientTestResult; + var serverTestResult; - beforeEach(function() { + before(function() { return runGen(null, { copyConfigFile: true, options: { @@ -199,6 +203,10 @@ describe('angular-fullstack:app', function() { } }).then(_dir => { dir = _dir; + jscsResult = runCmd('grunt jscs'); + lintResult = runCmd('grunt jshint'); + clientTestResult = runCmd('grunt test:client'); + serverTestResult = runCmd('grunt test:server'); }); }); @@ -209,24 +217,28 @@ describe('angular-fullstack:app', function() { }); it('passes JSCS', function() { - return runCmd('grunt jscs').should.be.fulfilled(); + return jscsResult.should.be.fulfilled(); }); it('passes JSHint', function() { - return runCmd('grunt jshint').should.be.fulfilled(); + return lintResult.should.be.fulfilled(); }); it('passes client tests', function() { - return runCmd('grunt test:client').should.be.fulfilled(); + return clientTestResult.should.be.fulfilled(); }); it('passes server tests', function() { - return runCmd('grunt test:server').should.be.fulfilled(); + return serverTestResult.should.be.fulfilled(); }); }); describe('with TypeScript, Jade, Jasmine, LESS, & OAuth', function() { var dir; + var jscsResult; + var lintResult; + var clientTestResult; + var serverTestResult; var testOptions = { buildtool: 'grunt', transpiler: 'ts', @@ -242,9 +254,13 @@ describe('angular-fullstack:app', function() { uibootstrap: true }; - beforeEach(function() { + before(function() { return runGen(testOptions).then(_dir => { dir = _dir; + jscsResult = runCmd('grunt jscs'); + lintResult = runCmd('grunt tslint'); + clientTestResult = runCmd('grunt test:client'); + serverTestResult = runCmd('grunt test:server'); }); }); @@ -255,24 +271,24 @@ describe('angular-fullstack:app', function() { }); it('passes JSCS', function() { - return runCmd('grunt jscs').should.be.fulfilled(); + return jscsResult.should.be.fulfilled(); }); it('passes lint', function() { - return runCmd('grunt tslint').should.be.fulfilled(); + return lintResult.should.be.fulfilled(); }); it('should run client tests successfully', function() { - return runCmd('grunt test:client').should.be.fulfilled(); + return clientTestResult.should.be.fulfilled(); }); it('should run server tests successfully', function() { - return runCmd('grunt test:server').should.be.fulfilled(); + return serverTestResult.should.be.fulfilled(); }); describe('with a generated endpoint', function() { beforeEach(function() { - getConfig(path.join(dir, '.yo-rc.json')).then(config => { + return getConfig(path.join(dir, '.yo-rc.json')).then(config => { return runEndpointGen('foo', {config: config['generator-angular-fullstack']}); }); }); @@ -295,6 +311,10 @@ describe('angular-fullstack:app', function() { describe('with sequelize models, auth', function() { var dir; + var jscsResult; + var lintResult; + var clientTestResult; + var serverTestResult; var testOptions = { buildtool: 'grunt', transpiler: 'babel', @@ -313,6 +333,10 @@ describe('angular-fullstack:app', function() { beforeEach(function() { return runGen(testOptions).then(_dir => { dir = _dir; + jscsResult = runCmd('grunt jscs'); + lintResult = runCmd('grunt jshint'); + clientTestResult = runCmd('grunt test:client'); + serverTestResult = runCmd('grunt test:server'); }); }); @@ -323,24 +347,24 @@ describe('angular-fullstack:app', function() { }); it('passes JSCS', function() { - return runCmd('grunt jscs').should.be.fulfilled(); + return jscsResult.should.be.fulfilled(); }); it('passes lint', function() { - return runCmd('grunt jshint').should.be.fulfilled(); + return lintResult.should.be.fulfilled(); }); it('should run client tests successfully', function() { - return runCmd('grunt test:client').should.be.fulfilled(); + return clientTestResult.should.be.fulfilled(); }); it('should run server tests successfully', function() { - return runCmd('grunt test:server').should.be.fulfilled(); + return serverTestResult.should.be.fulfilled(); }); describe('with a generated endpoint', function() { beforeEach(function() { - getConfig(path.join(dir, '.yo-rc.json')).then(config => { + return getConfig(path.join(dir, '.yo-rc.json')).then(config => { return runEndpointGen('foo', {config: config['generator-angular-fullstack']}); }); }); @@ -363,6 +387,10 @@ describe('angular-fullstack:app', function() { describe('with TypeScript, Mocha + Chai (should) and no server options', function() { var dir; + var jscsResult; + var lintResult; + var clientTestResult; + var serverTestResult; var testOptions = { buildtool: 'grunt', transpiler: 'ts', @@ -382,6 +410,10 @@ describe('angular-fullstack:app', function() { beforeEach(function() { return runGen(testOptions).then(_dir => { dir = _dir; + jscsResult = runCmd('grunt jscs'); + lintResult = runCmd('grunt tslint'); + clientTestResult = runCmd('grunt test:client'); + serverTestResult = runCmd('grunt test:server'); }); }); @@ -392,24 +424,24 @@ describe('angular-fullstack:app', function() { }); it('passes JSCS', function() { - return runCmd('grunt jscs').should.be.fulfilled(); + return jscsResult.should.be.fulfilled(); }); it('passes lint', function() { - return runCmd('grunt tslint').should.be.fulfilled(); + return lintResult.should.be.fulfilled(); }); it('should run client tests successfully', function() { - return runCmd('grunt test:client').should.be.fulfilled(); + return clientTestResult.should.be.fulfilled(); }); it('should run server tests successfully', function() { - return runCmd('grunt test:server').should.be.fulfilled(); + return serverTestResult.should.be.fulfilled(); }); describe('with a generated endpoint', function() { beforeEach(function() { - getConfig(path.join(dir, '.yo-rc.json')).then(config => { + return getConfig(path.join(dir, '.yo-rc.json')).then(config => { return runEndpointGen('foo', {config: config['generator-angular-fullstack']}); }); }); From d64029febdde1ab2ea60ee052815a50525f35af8 Mon Sep 17 00:00:00 2001 From: Andrew Koroluk Date: Sun, 1 May 2016 20:48:27 -0400 Subject: [PATCH 68/81] refactor(gen:test): rm dead code, promisify fs in mocha.conf, del old test file --- mocha.conf.js | 4 + src/test/endpoint.test.js | 1 - src/test/main.test.js | 1 - src/test/main.test.off.js | 765 -------------------------------------- src/test/pre.test.js | 13 - src/test/test-helpers.js | 2 - 6 files changed, 4 insertions(+), 782 deletions(-) delete mode 100644 src/test/main.test.off.js diff --git a/mocha.conf.js b/mocha.conf.js index 8fbbb39e6..4a47ecbec 100644 --- a/mocha.conf.js +++ b/mocha.conf.js @@ -1,3 +1,7 @@ 'use strict'; global.DEBUG = !!process.env.DEBUG; + +var fs = require('fs'); +var Promise = require('bluebird'); +Promise.promisifyAll(fs); diff --git a/src/test/endpoint.test.js b/src/test/endpoint.test.js index aa53858d1..d35523c65 100644 --- a/src/test/endpoint.test.js +++ b/src/test/endpoint.test.js @@ -3,7 +3,6 @@ import path from 'path'; import fs from 'fs'; import _ from 'lodash'; import Promise from 'bluebird'; -Promise.promisifyAll(fs); import helpers from 'yeoman-test'; import assert from 'yeoman-assert'; import minimatch from 'minimatch'; diff --git a/src/test/main.test.js b/src/test/main.test.js index 1d73022aa..38add4ef9 100644 --- a/src/test/main.test.js +++ b/src/test/main.test.js @@ -3,7 +3,6 @@ import path from 'path'; import fs from 'fs'; import _ from 'lodash'; import Promise from 'bluebird'; -Promise.promisifyAll(fs); import helpers from 'yeoman-test'; import assert from 'yeoman-assert'; import * as getExpectedFiles from './get-expected-files'; diff --git a/src/test/main.test.off.js b/src/test/main.test.off.js deleted file mode 100644 index 6f706cc70..000000000 --- a/src/test/main.test.off.js +++ /dev/null @@ -1,765 +0,0 @@ -/*global describe, beforeEach, it */ -'use strict'; -var path = require('path'); -var Promise = require('bluebird'); -var fs = require('fs'); -Promise.promisifyAll(fs); -var exec = require('child_process').exec; -var helpers = require('yeoman-test'); -var assert = require('yeoman-assert'); -var chai = require('chai'); -var expect = chai.expect; -var recursiveReadDir = require('recursive-readdir'); - -/**************** - * FileSystem Utils - ****************/ - -function copyAsync(src, dest) { - return fs.readFileAsync(src) - .then(data => fs.writeFileAsync(dest, data)); -} - -describe('angular-fullstack generator', function () { - var gen; - var defaultOptions = { - buildtool: 'grunt', - script: 'js', - transpiler: 'babel', - markup: 'html', - stylesheet: 'sass', - router: 'uirouter', - testing: 'mocha', - chai: 'expect', - bootstrap: true, - uibootstrap: true, - odms: ['mongoose'], - auth: true, - oauth: [], - socketio: true - }; - var dependenciesInstalled = false; - - function generatorTest(generatorType, name, mockPrompt, callback) { - gen.run(function () { - var afGenerator; - var deps = [path.join('../../generators', generatorType)]; - afGenerator = helpers.createGenerator('angular-fullstack:' + generatorType, deps, [name], { - skipInstall: true - }); - - helpers.mockPrompt(afGenerator, mockPrompt); - afGenerator.run(function () { - callback(); - }); - }); - } - - /** - * Assert that only an array of files exist at a given path - * - * @param {Array} expectedFiles - array of files - * @param {Function} done - callback(error{Error}) - * @param {String} topLevelPath - top level path to assert files at (optional) - * @param {Array} skip - array of paths to skip/ignore (optional) - * - */ - function assertOnlyFiles( - expectedFiles, - done, - topLevelPath='./', - skip=['node_modules', 'client/bower_components']) { - recursiveReadDir(topLevelPath, skip, function(err, actualFiles) { - if (err) return done(err); - var files = actualFiles.concat(); - - expectedFiles.forEach(function(file, i) { - var index = files.indexOf(path.normalize(file)); - if (index >= 0) { - files.splice(index, 1); - } - }); - - if (files.length !== 0) { - err = new Error('unexpected files found'); - err.expected = expectedFiles.join('\n'); - err.actual = files.join('\n'); - return done(err); - } - - done(); - }); - } - - /** - * Exec a command and run test assertion(s) based on command type - * - * @param {String} cmd - the command to exec - * @param {Object} self - context of the test - * @param {Function} cb - callback() - * @param {String} endpoint - endpoint to generate before exec (optional) - * @param {Number} timeout - timeout for the exec and test (optional) - * - */ - function runTest(cmd, self, cb) { - var args = Array.prototype.slice.call(arguments); - var endpoint = (args[3] && typeof args[3] === 'string') ? args.splice(3, 1)[0] : null; - var timeout = (args[3] && typeof args[3] === 'number') ? args.splice(3, 1)[0] : null; - - self.timeout(timeout || 60000); - - var execFn = function() { - var cmdCode; - var cp = exec(cmd, function(error, stdout, stderr) { - if(cmdCode !== 0) { - console.error(stdout); - throw new Error('Error running command: ' + cmd); - } - cb(); - }); - cp.on('exit', function (code) { - cmdCode = code; - }); - }; - - if (endpoint) { - generatorTest('endpoint', endpoint, {}, execFn); - } else { - gen.run(execFn); - } - } - - /** - * Generate an array of files to expect from a set of options - * - * @param {Object} ops - generator options - * @return {Array} - array of files - * - */ - function genFiles(ops) { - var mapping = { - stylesheet: { - sass: 'scss', - stylus: 'styl', - less: 'less', - css: 'css' - }, - markup: { - jade: 'jade', - html: 'html' - }, - script: { - js: 'js', - ts: 'ts' - } - }, - files = []; - - /** - * Generate an array of OAuth files based on type - * - * @param {String} type - type of oauth - * @return {Array} - array of files - * - */ - var oauthFiles = function(type) { - return [ - 'server/auth/' + type + '/index.js', - 'server/auth/' + type + '/passport.js', - ]; - }; - - - var script = mapping.script[ops.transpiler === 'ts' ? 'ts' : 'js'], - markup = mapping.markup[ops.markup], - stylesheet = mapping.stylesheet[ops.stylesheet], - models = ops.models ? ops.models : ops.odms[0]; - - /* Core Files */ - files = files.concat([ - 'client/.htaccess', - 'client/favicon.ico', - 'client/robots.txt', - 'client/index.html', - 'client/app/app.' + script, - 'client/app/app.' + stylesheet, - 'client/app/main/main.' + script, - 'client/app/main/main.' + markup, - 'client/app/main/main.' + stylesheet, - 'client/app/main/main.controller.' + script, - 'client/app/main/main.controller.spec.' + script, - 'client/assets/images/yeoman.png', - 'client/components/footer/footer.' + stylesheet, - 'client/components/footer/footer.' + markup, - 'client/components/footer/footer.directive.' + script, - 'client/components/navbar/navbar.' + markup, - 'client/components/navbar/navbar.controller.' + script, - 'client/components/navbar/navbar.directive.' + script, - 'client/components/util/util.module.' + script, - 'client/components/util/util.service.' + script, - 'server/.jshintrc', - 'server/.jshintrc-spec', - 'server/app.js', - 'server/index.js', - 'server/routes.js', - 'server/api/thing/index.js', - 'server/api/thing/index.spec.js', - 'server/api/thing/thing.controller.js', - 'server/api/thing/thing.integration.js', - 'server/components/errors/index.js', - 'server/config/local.env.js', - 'server/config/local.env.sample.js', - 'server/config/express.js', - 'server/config/environment/index.js', - 'server/config/environment/development.js', - 'server/config/environment/production.js', - 'server/config/environment/test.js', - 'server/config/environment/shared.js', - 'server/views/404.' + markup, - 'e2e/main/main.po.js', - 'e2e/main/main.spec.js', - 'e2e/components/navbar/navbar.po.js', - '.babelrc', - '.bowerrc', - '.buildignore', - '.editorconfig', - '.gitattributes', - '.gitignore', - '.travis.yml', - '.jscsrc', - '.yo-rc.json', - 'Gruntfile.js', - 'package.json', - 'bower.json', - 'karma.conf.js', - 'mocha.conf.js', - 'protractor.conf.js', - 'README.md' - ]); - - /* TypeScript */ - if (ops.transpiler === 'ts') { - files = files.concat([ - 'tsconfig.client.test.json', - 'tsconfig.client.json', - 'tsd.json', - 'tsd_test.json', - 'client/tslint.json' - ]); - } else { - files = files.concat([ - 'client/.jshintrc' - ]); - } - - /* Ui-Router */ - if (ops.router === 'uirouter') { - files = files.concat([ - 'client/components/ui-router/ui-router.mock.' + script - ]); - } - - /* Ui-Bootstrap */ - if (ops.uibootstrap) { - files = files.concat([ - 'client/components/modal/modal.' + markup, - 'client/components/modal/modal.' + stylesheet, - 'client/components/modal/modal.service.' + script - ]); - } - - /* Models - Mongoose or Sequelize */ - if (models) { - files = files.concat([ - 'server/api/thing/thing.model.js', - 'server/api/thing/thing.events.js', - 'server/config/seed.js' - ]); - } - - /* Sequelize */ - if (ops.odms.indexOf('sequelize') !== -1) { - files = files.concat([ - 'server/sqldb/index.js' - ]); - } - - /* Authentication */ - if (ops.auth) { - files = files.concat([ - 'client/app/account/account.' + script, - 'client/app/account/login/login.' + markup, - 'client/app/account/login/login.controller.' + script, - 'client/app/account/settings/settings.' + markup, - 'client/app/account/settings/settings.controller.' + script, - 'client/app/account/signup/signup.' + markup, - 'client/app/account/signup/signup.controller.' + script, - 'client/app/admin/admin.' + markup, - 'client/app/admin/admin.' + stylesheet, - 'client/app/admin/admin.module.' + script, - 'client/app/admin/admin.router.' + script, - 'client/app/admin/admin.controller.' + script, - 'client/components/auth/auth.module.' + script, - 'client/components/auth/auth.service.' + script, - 'client/components/auth/interceptor.service.' + script, - 'client/components/auth/router.decorator.' + script, - 'client/components/auth/user.service.' + script, - 'client/components/mongoose-error/mongoose-error.directive.' + script, - 'server/api/user/index.js', - 'server/api/user/index.spec.js', - 'server/api/user/user.controller.js', - 'server/api/user/user.integration.js', - 'server/api/user/user.model.js', - 'server/api/user/user.model.spec.js', - 'server/api/user/user.events.js', - 'server/auth/index.js', - 'server/auth/auth.service.js', - 'server/auth/local/index.js', - 'server/auth/local/passport.js', - 'e2e/account/login/login.po.js', - 'e2e/account/login/login.spec.js', - 'e2e/account/logout/logout.spec.js', - 'e2e/account/signup/signup.po.js', - 'e2e/account/signup/signup.spec.js' - ]); - } - - if (ops.oauth && ops.oauth.length) { - /* OAuth (see oauthFiles function above) */ - ops.oauth.forEach(function(type, i) { - files = files.concat(oauthFiles(type.replace('Auth', ''))); - }); - - - files = files.concat([ - 'client/components/oauth-buttons/oauth-buttons.' + stylesheet, - 'client/components/oauth-buttons/oauth-buttons.' + markup, - 'client/components/oauth-buttons/oauth-buttons.controller.' + script, - 'client/components/oauth-buttons/oauth-buttons.controller.spec.' + script, - 'client/components/oauth-buttons/oauth-buttons.directive.' + script, - 'client/components/oauth-buttons/oauth-buttons.directive.spec.' + script, - 'e2e/components/oauth-buttons/oauth-buttons.po.js' - ]); - } - - /* Socket.IO */ - if (ops.socketio) { - files = files.concat([ - 'client/components/socket/socket.service.' + script, - 'client/components/socket/socket.mock.' + script, - 'server/api/thing/thing.socket.js', - 'server/config/socketio.js' - ]); - } - - return files; - } - - - /** - * Generator tests - */ - - beforeEach(function (done) { - this.timeout(10000); - var deps = [ - '../../generators/app', - '../../generators/endpoint', - [ - helpers.createDummyGenerator(), - 'ng-component:app' - ] - ]; - - helpers.testDirectory(path.join(__dirname, 'temp'), err => { - if(err) return done(err); - - gen = helpers.createGenerator('angular-fullstack:app', deps, [], { - skipInstall: true - }); - gen.conflicter.force = true; - done(); - }); - }); - - describe('making sure test fixtures are present', function() { - it('should have package.json in fixtures', function() { - assert.file([path.join(__dirname, 'fixtures', 'package.json')]); - }); - - it('should have bower.json in fixtures', function() { - assert.file([path.join(__dirname, 'fixtures', 'bower.json')]); - }); - - it('should have all npm packages in fixtures/node_modules', function() { - var packageJson = require('./fixtures/package.json'); - var deps = Object.keys(packageJson.dependencies); - deps = deps.concat(Object.keys(packageJson.devDependencies)); - deps = deps.map(function(dep) { - return path.join(__dirname, 'fixtures', 'node_modules', dep); - }); - assert.file(deps); - }); - - it('should have all bower packages in fixtures/bower_components', function() { - var bowerJson = require('./fixtures/bower.json'); - var deps = Object.keys(bowerJson.dependencies); - deps = deps.concat(Object.keys(bowerJson.devDependencies)); - deps = deps.map(function(dep) { - return path.join(__dirname, 'fixtures', 'bower_components', dep); - }); - assert.file(deps); - }); - }); - - describe('running app', function() { - beforeEach(function() { - this.timeout(20000); - return Promise.all([ - fs.mkdirAsync(__dirname + '/temp/client'), - fs.symlinkAsync(__dirname + '/fixtures/node_modules', __dirname + '/temp/node_modules'), - fs.symlinkAsync(__dirname +'/fixtures/bower_components', __dirname +'/temp/client/bower_components') - ]); - }); - - describe('with default options', function() { - beforeEach(function() { - helpers.mockPrompt(gen, defaultOptions); - }); - - it('should run client tests successfully', function(done) { - runTest('grunt test:client', this, done); - }); - - it.only('should pass jscs', function(done) { - runTest('grunt jscs', this, done); - }); - - it('should pass lint', function(done) { - runTest('grunt jshint', this, done); - }); - - it('should run server tests successfully', function(done) { - runTest('grunt test:server', this, done); - }); - - it('should pass jscs with generated endpoint', function(done) { - runTest('grunt jscs', this, done, 'foo'); - }); - - it('should pass lint with generated endpoint', function(done) { - runTest('grunt jshint', this, done, 'foo'); - }); - - it('should run server tests successfully with generated endpoint', function(done) { - runTest('grunt test:server', this, done, 'foo'); - }); - - it('should pass lint with generated capitalized endpoint', function(done) { - runTest('grunt jshint', this, done, 'Foo'); - }); - - it('should run server tests successfully with generated capitalized endpoint', function(done) { - runTest('grunt test:server', this, done, 'Foo'); - }); - - it('should pass lint with generated path name endpoint', function(done) { - runTest('grunt jshint', this, done, 'foo/bar'); - }); - - it('should run server tests successfully with generated path name endpoint', function(done) { - runTest('grunt test:server', this, done, 'foo/bar'); - }); - - it('should generate expected files with path name endpoint', function(done) { - runTest('(exit 0)', this, function() { - assert.file([ - 'server/api/foo/bar/index.js', - 'server/api/foo/bar/index.spec.js', - 'server/api/foo/bar/bar.controller.js', - 'server/api/foo/bar/bar.events.js', - 'server/api/foo/bar/bar.integration.js', - 'server/api/foo/bar/bar.model.js', - 'server/api/foo/bar/bar.socket.js' - ]); - done(); - }, 'foo/bar'); - }); - - it('should use existing config if available', function(done) { - this.timeout(60000); - return copyAsync(__dirname + '/fixtures/.yo-rc.json', __dirname + '/temp/.yo-rc.json').then(() => { - var gen = helpers.createGenerator('angular-fullstack:app', [ - '../../generators/app', - '../../generators/endpoint', - [ - helpers.createDummyGenerator(), - 'ng-component:app' - ] - ], [], { - skipInstall: true - }); - helpers.mockPrompt(gen, { - skipConfig: true - }); - gen.run(function () { - assert.file([ - 'client/app/main/main.less', - 'server/auth/google/passport.js' - ]); - done(); - }); - }); - }); - - it('should generate expected files', function (done) { - gen.run(function () { - assert.file(genFiles(defaultOptions)); - done(); - }); - }); - - it('should not generate unexpected files', function (done) { - gen.run(function () { - assertOnlyFiles(genFiles(defaultOptions), done); - }); - }); - - if(!process.env.SKIP_E2E) { - it('should run e2e tests successfully', function(done) { - runTest('grunt test:e2e', this, done, 240000); - }); - - //it('should run e2e tests successfully for production app', function(done) { - // runTest('grunt test:e2e:prod', this, done, 240000); - //}); - } - }); - - describe('with other preprocessors and oauth', function() { - var testOptions = { - buildtool: 'grunt', - script: 'js', - transpiler: 'ts', - markup: 'jade', - stylesheet: 'less', - router: 'uirouter', - testing: 'jasmine', - odms: [ 'mongoose' ], - auth: true, - oauth: ['twitterAuth', 'facebookAuth', 'googleAuth'], - socketio: true, - bootstrap: true, - uibootstrap: true - }; - - beforeEach(function() { - helpers.mockPrompt(gen, testOptions); - }); - - it('should run client tests successfully', function(done) { - runTest('grunt test:client', this, done); - }); - - it('should pass jscs', function(done) { - runTest('grunt jscs', this, done); - }); - - it('should pass lint', function(done) { - runTest('grunt tslint', this, done); - }); - - it('should run server tests successfully', function(done) { - runTest('grunt test:server', this, done); - }); - - it('should pass jscs with generated endpoint', function(done) { - runTest('grunt jscs', this, done, 'foo'); - }); - - // TODO: generator-ng-component needs TS support - // it('should pass lint with generated snake-case endpoint', function(done) { - // runTest('grunt jshint', this, done, 'foo-bar'); - // }); - - it('should run server tests successfully with generated snake-case endpoint', function(done) { - runTest('grunt test:server', this, done, 'foo-bar'); - }); - - it('should generate expected files', function (done) { - gen.run(function () { - assert.file(genFiles(testOptions)); - done(); - }); - }); - - it('should not generate unexpected files', function (done) { - gen.run(function () { - assertOnlyFiles(genFiles(testOptions), done); - }); - }); - - if(!process.env.SKIP_E2E) { - it('should run e2e tests successfully', function (done) { - runTest('grunt test:e2e', this, done, 240000); - }); - - //it('should run e2e tests successfully for production app', function (done) { - // runTest('grunt test:e2e:prod', this, done, 240000); - //}); - } - - }); - - describe('with sequelize models, auth', function() { - var testOptions = { - buildtool: 'grunt', - script: 'js', - transpiler: 'babel', - markup: 'jade', - stylesheet: 'stylus', - router: 'uirouter', - testing: 'jasmine', - odms: [ 'sequelize' ], - auth: true, - oauth: ['twitterAuth', 'facebookAuth', 'googleAuth'], - socketio: true, - bootstrap: true, - uibootstrap: true - }; - - beforeEach(function() { - helpers.mockPrompt(gen, testOptions); - }); - - it('should run client tests successfully', function(done) { - runTest('grunt test:client', this, done); - }); - - it('should pass jscs', function(done) { - runTest('grunt jscs', this, done); - }); - - it('should pass lint', function(done) { - runTest('grunt jshint', this, done); - }); - - it('should run server tests successfully', function(done) { - runTest('grunt test:server', this, done); - }); - - it('should pass jscs with generated endpoint', function(done) { - runTest('grunt jscs', this, done, 'foo'); - }); - - it('should pass lint with generated snake-case endpoint', function(done) { - runTest('grunt jshint', this, done, 'foo-bar'); - }); - - it('should run server tests successfully with generated snake-case endpoint', function(done) { - runTest('grunt test:server', this, done, 'foo-bar'); - }); - - it('should generate expected files', function (done) { - gen.run(function () { - assert.file(genFiles(testOptions)); - done(); - }); - }); - - it('should not generate unexpected files', function (done) { - gen.run(function () { - assertOnlyFiles(genFiles(testOptions), done); - }); - }); - - if(!process.env.SKIP_E2E) { - it('should run e2e tests successfully', function (done) { - runTest('grunt test:e2e', this, done, 240000); - }); - - //it('should run e2e tests successfully for production app', function (done) { - // runTest('grunt test:e2e:prod', this, done, 240000); - //}); - } - - }); - - describe('with other preprocessors and no server options', function() { - var testOptions = { - buildtool: 'grunt', - script: 'js', - transpiler: 'ts', - markup: 'jade', - stylesheet: 'stylus', - router: 'ngroute', - testing: 'mocha', - chai: 'should', - odms: [], - auth: false, - oauth: [], - socketio: false, - bootstrap: false, - uibootstrap: false - }; - - beforeEach(function(done) { - helpers.mockPrompt(gen, testOptions); - done(); - }); - - it('should run client tests successfully', function(done) { - runTest('grunt test:client', this, done); - }); - - it('should pass jscs', function(done) { - runTest('grunt jscs', this, done); - }); - - it('should pass lint', function(done) { - runTest('grunt tslint', this, done); - }); - - it('should run server tests successfully', function(done) { - runTest('grunt test:server', this, done); - }); - - it('should pass jscs with generated endpoint', function(done) { - runTest('grunt jscs', this, done, 'foo'); - }); - - // TODO: generator-ng-component needs TS support - // it('should pass lint with generated endpoint', function(done) { - // runTest('grunt jshint', this, done, 'foo'); - // }); - - it('should run server tests successfully with generated endpoint', function(done) { - runTest('grunt test:server', this, done, 'foo'); - }); - - it('should generate expected files', function (done) { - gen.run(function () { - assert.file(genFiles(testOptions)); - done(); - }); - }); - - it('should not generate unexpected files', function (done) { - gen.run(function () { - assertOnlyFiles(genFiles(testOptions), done); - }); - }); - - if(!process.env.SKIP_E2E) { - it('should run e2e tests successfully', function (done) { - runTest('grunt test:e2e', this, done, 240000); - }); - - //it('should run e2e tests successfully for production app', function (done) { - // runTest('grunt test:e2e:prod', this, done, 240000); - //}); - } - - }); - }); -}); diff --git a/src/test/pre.test.js b/src/test/pre.test.js index d08a90e59..61c88de27 100644 --- a/src/test/pre.test.js +++ b/src/test/pre.test.js @@ -1,19 +1,6 @@ 'use strict'; import path from 'path'; -import fs from 'fs'; -import _ from 'lodash'; -import Promise from 'bluebird'; -Promise.promisifyAll(fs); -import helpers from 'yeoman-test'; import assert from 'yeoman-assert'; -import minimatch from 'minimatch'; -import * as getExpectedFiles from './get-expected-files'; -import { - copyAsync, - runCmd, - assertOnlyFiles, - getConfig -} from './test-helpers'; describe('test fixtures', function() { it('should have package.json in fixtures', function() { diff --git a/src/test/test-helpers.js b/src/test/test-helpers.js index 9745c2cfe..4a3149eff 100644 --- a/src/test/test-helpers.js +++ b/src/test/test-helpers.js @@ -3,11 +3,9 @@ import path from 'path'; import fs from 'fs'; import _ from 'lodash'; import Promise from 'bluebird'; -Promise.promisifyAll(fs); import {exec} from 'child_process'; import helpers from 'yeoman-test'; import assert from 'yeoman-assert'; -import * as getExpectedFiles from './get-expected-files'; import recursiveReadDir from 'recursive-readdir'; export function copyAsync(src, dest) { From 3febf4c722bcdc7f771768a8d7b9f411438641c4 Mon Sep 17 00:00:00 2001 From: Andrew Koroluk Date: Sun, 1 May 2016 20:50:15 -0400 Subject: [PATCH 69/81] refactor(gen:test): move runGen to test-helpers, rename getConfig to readJSON --- src/test/endpoint.test.js | 36 ++------------------ src/test/main.test.js | 59 +++++--------------------------- src/test/test-helpers.js | 71 ++++++++++++++++++++++++++++++++++++++- 3 files changed, 82 insertions(+), 84 deletions(-) diff --git a/src/test/endpoint.test.js b/src/test/endpoint.test.js index d35523c65..16cb76c38 100644 --- a/src/test/endpoint.test.js +++ b/src/test/endpoint.test.js @@ -14,7 +14,8 @@ import { copyAsync, runCmd, assertOnlyFiles, - getConfig + readJSON, + runGen } from './test-helpers'; const TEST_DIR = __dirname; @@ -35,37 +36,6 @@ const defaultOptions = { oauth: [], socketio: true }; -function runGen(prompts) { - return new Promise((resolve, reject) => { - let dir; - helpers - .run(require.resolve('../generators/app')) - .inTmpDir(function(_dir) { - // this will create a new temporary directory for each new generator run - var done = this.async(); - if(DEBUG) console.log(`TEMP DIR: ${_dir}`); - dir = _dir; - - // symlink our dependency directories - return Promise.all([ - fs.mkdirAsync(dir + '/client').then(() => { - return fs.symlinkAsync(__dirname + '/fixtures/bower_components', dir + '/client/bower_components'); - }), - fs.symlinkAsync(__dirname + '/fixtures/node_modules', dir + '/node_modules') - ]).then(done); - }) - .withGenerators([ - require.resolve('../generators/endpoint'), - // [helpers.createDummyGenerator(), 'ng-component:app'] - ]) - .withOptions({ - skipInstall: true - }) - .withPrompts(prompts) - .on('error', reject) - .on('end', () => resolve(dir)); - }); -} function runEndpointGen(name, opt={}) { let prompts = opt.prompts || {}; @@ -162,7 +132,7 @@ before(function() { jscs.configure(JSON.parse(data)); }); }), - getConfig(path.join(TEST_DIR, 'fixtures/.yo-rc.json')).then(_config => { + readJSON(path.join(TEST_DIR, 'fixtures/.yo-rc.json')).then(_config => { _config['generator-angular-fullstack'].insertRoutes = false; _config['generator-angular-fullstack'].pluralizeRoutes = false; _config['generator-angular-fullstack'].insertSockets = false; diff --git a/src/test/main.test.js b/src/test/main.test.js index 38add4ef9..cfe269f2a 100644 --- a/src/test/main.test.js +++ b/src/test/main.test.js @@ -10,7 +10,8 @@ import { copyAsync, runCmd, assertOnlyFiles, - getConfig + readJSON, + runGen } from './test-helpers'; const defaultOptions = { @@ -30,48 +31,6 @@ const defaultOptions = { }; const TEST_DIR = __dirname; -function runGen(prompts, opts={}) { - let options = opts.options || {skipInstall: true}; - - return new Promise((resolve, reject) => { - let dir; - let gen = helpers - .run(require.resolve('../generators/app')) - .inTmpDir(function(_dir) { - // this will create a new temporary directory for each new generator run - var done = this.async(); - if(DEBUG) console.log(`TEMP DIR: ${_dir}`); - dir = _dir; - - let promises = [ - fs.mkdirAsync(dir + '/client').then(() => { - return fs.symlinkAsync(__dirname + '/fixtures/bower_components', dir + '/client/bower_components'); - }), - fs.symlinkAsync(__dirname + '/fixtures/node_modules', dir + '/node_modules') - ]; - - if(opts.copyConfigFile) { - promises.push(copyAsync(path.join(TEST_DIR, 'fixtures/.yo-rc.json'), path.join(dir, '.yo-rc.json'))); - } - - // symlink our dependency directories - return Promise.all(promises).then(done); - }) - .withGenerators([ - require.resolve('../generators/endpoint'), - // [helpers.createDummyGenerator(), 'ng-component:app'] - ]) - // .withArguments(['upperCaseBug']) - .withOptions(options); - - if(prompts) gen.withPrompts(prompts); - - gen - .on('error', reject) - .on('end', () => resolve(dir)); - }); -} - function runEndpointGen(name, opt={}) { let prompts = opt.prompts || {}; let options = opt.options || {}; @@ -129,7 +88,7 @@ describe('angular-fullstack:app', function() { describe('with a generated endpoint', function() { beforeEach(function() { - return getConfig(path.join(dir, '.yo-rc.json')).then(config => { + return readJSON(path.join(dir, '.yo-rc.json')).then(config => { return runEndpointGen('foo', {config: config['generator-angular-fullstack']}); }); }); @@ -141,7 +100,7 @@ describe('angular-fullstack:app', function() { describe('with a generated capitalized endpoint', function() { beforeEach(function() { - return getConfig(path.join(dir, '.yo-rc.json')).then(config => { + return readJSON(path.join(dir, '.yo-rc.json')).then(config => { return runEndpointGen('Foo', {config: config['generator-angular-fullstack']}); }); }); @@ -153,7 +112,7 @@ describe('angular-fullstack:app', function() { describe('with a generated path name endpoint', function() { beforeEach(function() { - return getConfig(path.join(dir, '.yo-rc.json')).then(config => { + return readJSON(path.join(dir, '.yo-rc.json')).then(config => { return runEndpointGen('foo/bar', {config: config['generator-angular-fullstack']}); }); }); @@ -165,7 +124,7 @@ describe('angular-fullstack:app', function() { describe('with a generated snake-case endpoint', function() { beforeEach(function() { - return getConfig(path.join(dir, '.yo-rc.json')).then(config => { + return readJSON(path.join(dir, '.yo-rc.json')).then(config => { return runEndpointGen('foo-bar', {config: config['generator-angular-fullstack']}); }); }); @@ -287,7 +246,7 @@ describe('angular-fullstack:app', function() { describe('with a generated endpoint', function() { beforeEach(function() { - return getConfig(path.join(dir, '.yo-rc.json')).then(config => { + return readJSON(path.join(dir, '.yo-rc.json')).then(config => { return runEndpointGen('foo', {config: config['generator-angular-fullstack']}); }); }); @@ -363,7 +322,7 @@ describe('angular-fullstack:app', function() { describe('with a generated endpoint', function() { beforeEach(function() { - return getConfig(path.join(dir, '.yo-rc.json')).then(config => { + return readJSON(path.join(dir, '.yo-rc.json')).then(config => { return runEndpointGen('foo', {config: config['generator-angular-fullstack']}); }); }); @@ -440,7 +399,7 @@ describe('angular-fullstack:app', function() { describe('with a generated endpoint', function() { beforeEach(function() { - return getConfig(path.join(dir, '.yo-rc.json')).then(config => { + return readJSON(path.join(dir, '.yo-rc.json')).then(config => { return runEndpointGen('foo', {config: config['generator-angular-fullstack']}); }); }); diff --git a/src/test/test-helpers.js b/src/test/test-helpers.js index 4a3149eff..5a192e936 100644 --- a/src/test/test-helpers.js +++ b/src/test/test-helpers.js @@ -8,6 +8,14 @@ import helpers from 'yeoman-test'; import assert from 'yeoman-assert'; import recursiveReadDir from 'recursive-readdir'; +const TEST_DIR = __dirname; + +/** + * Copy file from src to dest + * @param {string} src + * @param {string} dest + * @returns {Promise} + */ export function copyAsync(src, dest) { return fs.readFileAsync(src) .then(data => fs.writeFileAsync(dest, data)); @@ -37,6 +45,13 @@ export function runCmd(cmd) { }); } +/** + * Assert that only the expected files are present + * @param {string[]} expectedFiles - array of expected files + * @param {string} [topLevelPath='./'] - root dir of expected files to recursively search + * @param {string[]} [skip=['node_modules','bower_components']] - files/folders recursiveReadDir should skip + * @returns {Promise} + */ export function assertOnlyFiles(expectedFiles, topLevelPath='./', skip=['node_modules', 'bower_components']) { return new Promise((resolve, reject) => { recursiveReadDir(topLevelPath, skip, function(err, actualFiles) { @@ -55,8 +70,62 @@ export function assertOnlyFiles(expectedFiles, topLevelPath='./', skip=['node_mo }); } -export function getConfig(path) { +/** + * Read JSON from a file + * @param {string} path + * @returns {Promise} - parsed JSON + */ +export function readJSON(path) { return fs.readFileAsync(path, 'utf8').then(data => { return JSON.parse(data); }); } + +/** + * Run angular-fullstack:app + * @param {object} [prompts] + * @param {object} [opts={}] + * @param {boolean} [opts.copyConfigFile] - copy default .yo-rc.json + * @returns {Promise} + */ +export function runGen(prompts, opts={}) { + let options = opts.options || {skipInstall: true}; + + return new Promise((resolve, reject) => { + let dir; + let gen = helpers + .run(require.resolve('../generators/app')) + .inTmpDir(function(_dir) { + // this will create a new temporary directory for each new generator run + var done = this.async(); + if(DEBUG) console.log(`TEMP DIR: ${_dir}`); + dir = _dir; + + let promises = [ + fs.mkdirAsync(dir + '/client').then(() => { + return fs.symlinkAsync(__dirname + '/fixtures/bower_components', dir + '/client/bower_components'); + }), + fs.symlinkAsync(__dirname + '/fixtures/node_modules', dir + '/node_modules') + ]; + + if(opts.copyConfigFile) { + promises.push(copyAsync(path.join(TEST_DIR, 'fixtures/.yo-rc.json'), path.join(dir, '.yo-rc.json'))); + } + + // symlink our dependency directories + return Promise.all(promises).then(done); + }) + .withGenerators([ + require.resolve('../generators/endpoint'), + // [helpers.createDummyGenerator(), 'ng-component:app'] + ]) + // .withArguments(['upperCaseBug']) + .withOptions(options); + + if(prompts) gen.withPrompts(prompts); + + gen + .on('error', reject) + .on('end', () => resolve(dir)); + }); +} \ No newline at end of file From 97ddb8bc95d60316ff70644c603a7c6830e7155c Mon Sep 17 00:00:00 2001 From: Andrew Koroluk Date: Sun, 1 May 2016 23:54:40 -0400 Subject: [PATCH 70/81] chore(package): bump yeoman-test to ^1.3.0 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 168f15fed..6d407e4c0 100644 --- a/package.json +++ b/package.json @@ -83,7 +83,7 @@ "shelljs": "^0.6.0", "should": "^8.3.1", "yeoman-assert": "^2.0.0", - "yeoman-test": "^1.1.0" + "yeoman-test": "^1.3.0" }, "engines": { "node": "^5.10.1", From ae514e117e079a85108b54812476479a3b85bafe Mon Sep 17 00:00:00 2001 From: Andrew Koroluk Date: Mon, 2 May 2016 15:20:26 -0400 Subject: [PATCH 71/81] test(gen): slow tests are 500ms and above [skip ci] --- gulpfile.js | 1 + 1 file changed, 1 insertion(+) diff --git a/gulpfile.js b/gulpfile.js index b08c3968e..0f6dcdf23 100644 --- a/gulpfile.js +++ b/gulpfile.js @@ -22,6 +22,7 @@ const mocha = lazypipe() .pipe(gulpMocha, { reporter: 'spec', timeout: 120000, + slow: 500, globals: { should: require('should') }, From 3b613e70e1f8973954689a4f6dab11fe66075b5e Mon Sep 17 00:00:00 2001 From: Andrew Koroluk Date: Mon, 2 May 2016 15:26:04 -0400 Subject: [PATCH 72/81] test(gen:main): retry e2e tests twice --- src/test/main.test.js | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/test/main.test.js b/src/test/main.test.js index cfe269f2a..849b221b5 100644 --- a/src/test/main.test.js +++ b/src/test/main.test.js @@ -136,10 +136,12 @@ describe('angular-fullstack:app', function() { if(!process.env.SKIP_E2E) { it('should run e2e tests successfully', function() { + this.retries(2); return runCmd('grunt test:e2e').should.be.fulfilled(); }); it('should run e2e tests successfully for production app', function() { + this.retries(2); return runCmd('grunt test:e2e:prod').should.be.fulfilled(); }); } @@ -258,10 +260,12 @@ describe('angular-fullstack:app', function() { if(!process.env.SKIP_E2E) { it('should run e2e tests successfully', function() { + this.retries(2); return runCmd('grunt test:e2e').should.be.fulfilled(); }); it('should run e2e tests successfully for production app', function() { + this.retries(2); return runCmd('grunt test:e2e:prod').should.be.fulfilled(); }); } @@ -334,10 +338,12 @@ describe('angular-fullstack:app', function() { if(!process.env.SKIP_E2E) { it('should run e2e tests successfully', function() { + this.retries(2); return runCmd('grunt test').should.be.fulfilled(); }); it('should run e2e tests successfully for production app', function() { + this.retries(2); return runCmd('grunt test:e2e:prod').should.be.fulfilled(); }); } @@ -411,10 +417,12 @@ describe('angular-fullstack:app', function() { if(!process.env.SKIP_E2E) { it('should run e2e tests successfully', function() { + this.retries(2); return runCmd('grunt test:e2e').should.be.fulfilled(); }); it('should run e2e tests successfully for production app', function() { + this.retries(2); return runCmd('grunt test:e2e:prod').should.be.fulfilled(); }); } From aedb37ecc8850dc40dbc74672f07fd2bd8a0504a Mon Sep 17 00:00:00 2001 From: Andrew Koroluk Date: Tue, 3 May 2016 13:28:00 -0600 Subject: [PATCH 73/81] fix(gen:gulp:clean): also clean test dir --- gulpfile.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gulpfile.js b/gulpfile.js index 0f6dcdf23..2a66b5681 100644 --- a/gulpfile.js +++ b/gulpfile.js @@ -35,7 +35,7 @@ const transpile = lazypipe() .pipe(babel); gulp.task('clean', () => { - return del(['generators/**/*']); + return del(['generators/**/*', './test/(**|!fixtures/node_modules|!fixtures/bower_components)/*']); }); gulp.task('babel', () => { From a644812aa7594ee77e7f6dd97369d3a6e41d73cf Mon Sep 17 00:00:00 2001 From: Andrew Koroluk Date: Tue, 3 May 2016 16:39:50 -0600 Subject: [PATCH 74/81] chore(gen): update yeoman-generator to 0.23.0 --- package.json | 2 +- src/generators/app/index.js | 30 ++++++++---------------------- src/generators/endpoint/index.js | 4 +--- 3 files changed, 10 insertions(+), 26 deletions(-) diff --git a/package.json b/package.json index 6d407e4c0..42dafd1c9 100644 --- a/package.json +++ b/package.json @@ -47,7 +47,7 @@ "insight": "~0.8.1", "lodash": "^4.6.1", "underscore.string": "^3.1.1", - "yeoman-generator": "^0.22.5", + "yeoman-generator": "~0.23.0", "yeoman-welcome": "^1.0.1" }, "devDependencies": { diff --git a/src/generators/app/index.js b/src/generators/app/index.js index 1bfaa9e16..b2814b718 100644 --- a/src/generators/app/index.js +++ b/src/generators/app/index.js @@ -63,16 +63,15 @@ export class Generator extends Base { this.log('Out of the box I create an AngularJS app with an Express server.\n'); }, checkForConfig: function() { - var cb = this.async(); var existingFilters = this.config.get('filters'); if(existingFilters) { - this.prompt([{ + return this.prompt([{ type: 'confirm', name: 'skipConfig', message: 'Existing .yo-rc configuration found, would you like to use it?', default: true, - }], answers => { + }]).then(answers => { this.skipConfig = answers.skipConfig; if(this.skipConfig) { @@ -92,11 +91,7 @@ export class Generator extends Base { this.config.set('filters', this.filters); this.config.forceSave(); } - - cb(); }); - } else { - cb(); } } }; @@ -106,11 +101,10 @@ export class Generator extends Base { return { clientPrompts: function() { if(this.skipConfig) return; - var cb = this.async(); this.log('# Client\n'); - this.prompt([{ + return this.prompt([{ type: 'list', name: 'transpiler', message: 'What would you like to write scripts with?', @@ -156,7 +150,7 @@ export class Generator extends Base { name: 'uibootstrap', message: 'Would you like to include UI Bootstrap?', when: answers => answers.bootstrap - }], answers => { + }]).then(answers => { this.filters.js = true; this.filters[answers.transpiler] = true; insight.track('transpiler', answers.transpiler); @@ -184,18 +178,15 @@ export class Generator extends Base { var styleExt = {sass: 'scss', stylus: 'styl'}[answers.stylesheet]; this.styleExt = styleExt ? styleExt : answers.stylesheet; - - cb(); }); }, serverPrompts: function() { if(this.skipConfig) return; - var cb = this.async(); var self = this; this.log('\n# Server\n'); - this.prompt([{ + return this.prompt([{ type: 'checkbox', name: 'odms', message: 'What would you like to use for data modeling?', @@ -245,7 +236,7 @@ export class Generator extends Base { // to-do: should not be dependent on ODMs when: answers => answers.odms && answers.odms.length !== 0, default: true - }], answers => { + }]).then(answers => { if(answers.socketio) this.filters.socketio = true; insight.track('socketio', !!answers.socketio); @@ -284,18 +275,15 @@ export class Generator extends Base { insight.track('google-oauth', !!this.filters['googleAuth']); insight.track('facebook-oauth', !!this.filters['facebookAuth']); insight.track('twitter-oauth', !!this.filters['twitterAuth']); - - cb(); }); }, projectPrompts: function() { if(this.skipConfig) return; - var cb = this.async(); var self = this; this.log('\n# Project\n'); - this.prompt([{ + return this.prompt([{ type: 'list', name: 'buildtool', message: 'Would you like to use Gulp or Grunt?', @@ -320,7 +308,7 @@ export class Generator extends Base { choices: ['Expect', 'Should'], filter: val => val.toLowerCase(), when: answers => answers.testing === 'mocha' - }], answers => { + }]).then(answers => { this.filters[answers.buildtool] = true; insight.track('buildtool', answers.buildtool); @@ -338,8 +326,6 @@ export class Generator extends Base { this.filters.should = false; this.filters.expect = false; } - - cb(); }); } }; diff --git a/src/generators/endpoint/index.js b/src/generators/endpoint/index.js index 4c05c8e97..b48a8815f 100644 --- a/src/generators/endpoint/index.js +++ b/src/generators/endpoint/index.js @@ -33,7 +33,6 @@ export class Generator extends Base { } prompting() { - var done = this.async(); var promptCb = (props) => { if(props.route.charAt(0) !== '/') { props.route = '/' + props.route; @@ -50,7 +49,6 @@ export class Generator extends Base { this.filters[props.models] = true; this.filters[props.models + 'Models'] = true; } - done(); }; if (this.options.route) { @@ -92,7 +90,7 @@ export class Generator extends Base { when: () => this.filters.mongoose && this.filters.sequelize }]; - this.prompt(prompts, promptCb); + return this.prompt(prompts).then(promptCb); } configuring() { From 6666ddb56f6c93157728a3f9037da11d464f4655 Mon Sep 17 00:00:00 2001 From: Andrew Koroluk Date: Tue, 3 May 2016 16:51:29 -0600 Subject: [PATCH 75/81] fix(gen:test): endpoint gen `before` should be inside the `describe` else it would run before every suite, not just that suite --- src/test/endpoint.test.js | 38 +++++++++++++++++++------------------- 1 file changed, 19 insertions(+), 19 deletions(-) diff --git a/src/test/endpoint.test.js b/src/test/endpoint.test.js index 16cb76c38..729535b9f 100644 --- a/src/test/endpoint.test.js +++ b/src/test/endpoint.test.js @@ -123,26 +123,26 @@ function jscsDir(dir, name, folder) { var config; var genDir; -before(function() { - return Promise.all([ - runGen(defaultOptions).then(_dir => { - genDir = _dir; - - return fs.readFileAsync(path.join(genDir, '.jscsrc'), 'utf8').then(data => { - jscs.configure(JSON.parse(data)); - }); - }), - readJSON(path.join(TEST_DIR, 'fixtures/.yo-rc.json')).then(_config => { - _config['generator-angular-fullstack'].insertRoutes = false; - _config['generator-angular-fullstack'].pluralizeRoutes = false; - _config['generator-angular-fullstack'].insertSockets = false; - _config['generator-angular-fullstack'].insertModels = false; - config = _config; - }) - ]); -}); - describe('angular-fullstack:endpoint', function() { + before(function() { + return Promise.all([ + runGen(defaultOptions).then(_dir => { + genDir = _dir; + + return fs.readFileAsync(path.join(genDir, '.jscsrc'), 'utf8').then(data => { + jscs.configure(JSON.parse(data)); + }); + }), + readJSON(path.join(TEST_DIR, 'fixtures/.yo-rc.json')).then(_config => { + _config['generator-angular-fullstack'].insertRoutes = false; + _config['generator-angular-fullstack'].pluralizeRoutes = false; + _config['generator-angular-fullstack'].insertSockets = false; + _config['generator-angular-fullstack'].insertModels = false; + config = _config; + }) + ]); + }); + describe(`with a generated endpont 'foo'`, function() { var dir; beforeEach(function() { From 4863f7c98c888fcf82addb998c6d2ddaf9c25d27 Mon Sep 17 00:00:00 2001 From: Andrew Koroluk Date: Tue, 3 May 2016 17:58:43 -0600 Subject: [PATCH 76/81] chore(gen): update yeoman-test to 1.4.0, use `toPromise` --- package.json | 2 +- src/test/test-helpers.js | 69 +++++++++++++++++++--------------------- 2 files changed, 33 insertions(+), 38 deletions(-) diff --git a/package.json b/package.json index 42dafd1c9..d1f0792f0 100644 --- a/package.json +++ b/package.json @@ -83,7 +83,7 @@ "shelljs": "^0.6.0", "should": "^8.3.1", "yeoman-assert": "^2.0.0", - "yeoman-test": "^1.3.0" + "yeoman-test": "^1.4.0" }, "engines": { "node": "^5.10.1", diff --git a/src/test/test-helpers.js b/src/test/test-helpers.js index 5a192e936..f82ef4b8d 100644 --- a/src/test/test-helpers.js +++ b/src/test/test-helpers.js @@ -91,41 +91,36 @@ export function readJSON(path) { export function runGen(prompts, opts={}) { let options = opts.options || {skipInstall: true}; - return new Promise((resolve, reject) => { - let dir; - let gen = helpers - .run(require.resolve('../generators/app')) - .inTmpDir(function(_dir) { - // this will create a new temporary directory for each new generator run - var done = this.async(); - if(DEBUG) console.log(`TEMP DIR: ${_dir}`); - dir = _dir; - - let promises = [ - fs.mkdirAsync(dir + '/client').then(() => { - return fs.symlinkAsync(__dirname + '/fixtures/bower_components', dir + '/client/bower_components'); - }), - fs.symlinkAsync(__dirname + '/fixtures/node_modules', dir + '/node_modules') - ]; - - if(opts.copyConfigFile) { - promises.push(copyAsync(path.join(TEST_DIR, 'fixtures/.yo-rc.json'), path.join(dir, '.yo-rc.json'))); - } - - // symlink our dependency directories - return Promise.all(promises).then(done); - }) - .withGenerators([ - require.resolve('../generators/endpoint'), - // [helpers.createDummyGenerator(), 'ng-component:app'] - ]) - // .withArguments(['upperCaseBug']) - .withOptions(options); - - if(prompts) gen.withPrompts(prompts); - - gen - .on('error', reject) - .on('end', () => resolve(dir)); - }); + // let dir; + let gen = helpers + .run(require.resolve('../generators/app')) + .inTmpDir(function(dir) { + // this will create a new temporary directory for each new generator run + var done = this.async(); + if(DEBUG) console.log(`TEMP DIR: ${dir}`); + + let promises = [ + fs.mkdirAsync(dir + '/client').then(() => { + return fs.symlinkAsync(__dirname + '/fixtures/bower_components', dir + '/client/bower_components'); + }), + fs.symlinkAsync(__dirname + '/fixtures/node_modules', dir + '/node_modules') + ]; + + if(opts.copyConfigFile) { + promises.push(copyAsync(path.join(TEST_DIR, 'fixtures/.yo-rc.json'), path.join(dir, '.yo-rc.json'))); + } + + // symlink our dependency directories + return Promise.all(promises).then(done); + }) + .withGenerators([ + require.resolve('../generators/endpoint'), + // [helpers.createDummyGenerator(), 'ng-component:app'] + ]) + // .withArguments(['upperCaseBug']) + .withOptions(options); + + if(prompts) gen.withPrompts(prompts); + + return gen.toPromise(); } \ No newline at end of file From a9d238c9d136aa71dbf70df22c58f27bba90b570 Mon Sep 17 00:00:00 2001 From: Andrew Koroluk Date: Wed, 4 May 2016 10:47:40 -0600 Subject: [PATCH 77/81] fix(gen:test:main): fix sql e2e --- src/test/main.test.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/test/main.test.js b/src/test/main.test.js index 849b221b5..d23add9cd 100644 --- a/src/test/main.test.js +++ b/src/test/main.test.js @@ -339,7 +339,7 @@ describe('angular-fullstack:app', function() { if(!process.env.SKIP_E2E) { it('should run e2e tests successfully', function() { this.retries(2); - return runCmd('grunt test').should.be.fulfilled(); + return runCmd('grunt test:e2e').should.be.fulfilled(); }); it('should run e2e tests successfully for production app', function() { From 5cbd6034739558f4a9bd7dc0083ea56558510681 Mon Sep 17 00:00:00 2001 From: thegitfather Date: Wed, 4 May 2016 13:41:47 +0200 Subject: [PATCH 78/81] fix(server:oauth): fix mongoose validation when re-login using twitter oauth Problem occurs after second login attempt using passport-twitter. Error message: "ValidationError: The specified email address is already in use." --- .../app/server/api/user(auth)/user.model(mongooseModels).js | 3 +++ 1 file changed, 3 insertions(+) diff --git a/templates/app/server/api/user(auth)/user.model(mongooseModels).js b/templates/app/server/api/user(auth)/user.model(mongooseModels).js index d11f5d4d1..60120b3b6 100644 --- a/templates/app/server/api/user(auth)/user.model(mongooseModels).js +++ b/templates/app/server/api/user(auth)/user.model(mongooseModels).js @@ -95,6 +95,9 @@ UserSchema .path('email') .validate(function(value, respond) { var self = this; + if (authTypes.indexOf(this.provider) !== -1) { + return respond(true); + } return this.constructor.findOne({ email: value }).exec() .then(function(user) { if (user) { From 8cf7f9e0629c86596811886ca4bf0b6f68bce69f Mon Sep 17 00:00:00 2001 From: Andrew Koroluk Date: Wed, 4 May 2016 11:16:19 -0600 Subject: [PATCH 79/81] fix(server): fix oauth PR --- .../app/server/api/user(auth)/user.model(mongooseModels).js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/templates/app/server/api/user(auth)/user.model(mongooseModels).js b/templates/app/server/api/user(auth)/user.model(mongooseModels).js index 60120b3b6..5394bad3c 100644 --- a/templates/app/server/api/user(auth)/user.model(mongooseModels).js +++ b/templates/app/server/api/user(auth)/user.model(mongooseModels).js @@ -95,9 +95,10 @@ UserSchema .path('email') .validate(function(value, respond) { var self = this; + <%_ if(filters.oauth) { _%> if (authTypes.indexOf(this.provider) !== -1) { return respond(true); - } + }<% } %> return this.constructor.findOne({ email: value }).exec() .then(function(user) { if (user) { From b52a71be89d365cae45e9ed275613d722258eb0e Mon Sep 17 00:00:00 2001 From: Andrew Koroluk Date: Wed, 4 May 2016 14:13:19 -0600 Subject: [PATCH 80/81] chore(gen:package): update yeoman deps, generator-ng-component --- package.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/package.json b/package.json index d1f0792f0..50e500b75 100644 --- a/package.json +++ b/package.json @@ -39,7 +39,7 @@ "babel-plugin-syntax-flow": "^6.5.0", "babel-plugin-transform-flow-strip-types": "^6.7.0", "chalk": "^1.1.0", - "generator-ng-component": "~0.2.1", + "generator-ng-component": "~0.3.0", "glob": "^7.0.3", "gulp-babel": "^6.1.2", "gulp-beautify": "^2.0.0", @@ -47,7 +47,7 @@ "insight": "~0.8.1", "lodash": "^4.6.1", "underscore.string": "^3.1.1", - "yeoman-generator": "~0.23.0", + "yeoman-generator": "~0.23.3", "yeoman-welcome": "^1.0.1" }, "devDependencies": { @@ -83,7 +83,7 @@ "shelljs": "^0.6.0", "should": "^8.3.1", "yeoman-assert": "^2.0.0", - "yeoman-test": "^1.4.0" + "yeoman-test": "~1.4.0" }, "engines": { "node": "^5.10.1", From 69933c6fb1208fb611cb7a6bb2c20f5d516aa46c Mon Sep 17 00:00:00 2001 From: Andrew Koroluk Date: Wed, 4 May 2016 14:31:25 -0600 Subject: [PATCH 81/81] test(gen:sequelize): retry all sequelize tests 3 times --- src/test/main.test.js | 1 + 1 file changed, 1 insertion(+) diff --git a/src/test/main.test.js b/src/test/main.test.js index d23add9cd..9e4e53fef 100644 --- a/src/test/main.test.js +++ b/src/test/main.test.js @@ -291,6 +291,7 @@ describe('angular-fullstack:app', function() { bootstrap: true, uibootstrap: true }; + this.retries(3); // Sequelize seems to be quite flaky beforeEach(function() { return runGen(testOptions).then(_dir => {