diff --git a/.gitignore b/.gitignore index 78a6835b7..230257f1f 100644 --- a/.gitignore +++ b/.gitignore @@ -1,9 +1,8 @@ node_modules bower_components -test/temp +/generators/* +/test/* demo .idea .DS_Store -release.txt -test/fixtures/bower.json -test/fixtures/package.json \ No newline at end of file +release.txt \ No newline at end of file diff --git a/.npmignore b/.npmignore index c823223d9..29dc7d501 100644 --- a/.npmignore +++ b/.npmignore @@ -1,3 +1,11 @@ angular-fullstack-deps test .idea +src +scripts +ISSUE_TEMPLATE.md +PULL_REQUEST_TEMPLATE.md +.travis.yml +gulpfile.babel.js +Gruntfile.js +.jshintrc 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() { 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/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.js b/gulpfile.js new file mode 100644 index 000000000..2a66b5681 --- /dev/null +++ b/gulpfile.js @@ -0,0 +1,170 @@ +'use strict'; +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; + +const mocha = lazypipe() + .pipe(gulpMocha, { + reporter: 'spec', + timeout: 120000, + slow: 500, + globals: { + should: require('should') + }, + require: [ + './mocha.conf' + ] + }); + +const transpile = lazypipe() + .pipe(babel); + +gulp.task('clean', () => { + return del(['generators/**/*', './test/(**|!fixtures/node_modules|!fixtures/bower_components)/*']); +}); + +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')); + + return merge(generators, test); +}); + +gulp.task('watch', () => { + watching = true; + return gulp.watch('src/**/*.js', ['babel']); +}); + +gulp.task('copy', () => { + 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 => { + return runSequence( + 'clean', + 'babel', + 'copy', + 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.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; + + // 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'); +}); + +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/pre.test.js', 'test/*.test.js']) + .pipe(mocha()); +}); diff --git a/mocha.conf.js b/mocha.conf.js new file mode 100644 index 000000000..4a47ecbec --- /dev/null +++ b/mocha.conf.js @@ -0,0 +1,7 @@ +'use strict'; + +global.DEBUG = !!process.env.DEBUG; + +var fs = require('fs'); +var Promise = require('bluebird'); +Promise.promisifyAll(fs); diff --git a/package.json b/package.json index 9ce89d117..e0a84bc24 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", @@ -31,24 +31,32 @@ "url": "git://github.com/angular-fullstack/generator-angular-fullstack.git" }, "scripts": { - "test": "grunt test" + "test": "gulp updateFixtures:test && gulp installFixtures && gulp build && gulp test", + "prepublish": "gulp build" }, "dependencies": { - "babel-core": "^6.7.0", - "babel-plugin-transform-class-properties": "^6.6.0", - "babel-preset-es2015": "^6.6.0", - "babel-register": "^6.6.5", + "babel-plugin-syntax-class-properties": "^6.5.0", + "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", + "gulp-filter": "^4.0.0", "insight": "~0.8.1", "lodash": "^4.6.1", "underscore.string": "^3.1.1", - "yeoman-generator": "^0.22.5", + "yeoman-generator": "~0.23.3", "yeoman-welcome": "^1.0.1" }, "devDependencies": { + "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", "grunt-build-control": "^0.7.0", "grunt-contrib-clean": "^1.0.0", @@ -58,13 +66,24 @@ "grunt-env": "^0.4.1", "grunt-mocha-test": "^0.12.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", + "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", "mocha": "^2.2.5", "q": "^1.0.1", "recursive-readdir": "^2.0.0", + "run-sequence": "^1.1.5", "shelljs": "^0.7.0", + "should": "^8.3.1", "yeoman-assert": "^2.0.0", - "yeoman-test": "^1.1.0" + "yeoman-test": "~1.4.0" }, "engines": { "node": "^5.10.1", diff --git a/app/USAGE b/src/generators/app/USAGE similarity index 100% rename from app/USAGE rename to src/generators/app/USAGE diff --git a/app/generator.js b/src/generators/app/index.js similarity index 82% rename from app/generator.js rename to src/generators/app/index.js index c74d42b2f..b2814b718 100644 --- a/app/generator.js +++ b/src/generators/app/index.js @@ -7,8 +7,11 @@ 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 { +export class Generator extends Base { constructor(...args) { super(...args); @@ -60,16 +63,15 @@ export default 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) { @@ -89,11 +91,7 @@ export default class Generator extends Base { this.config.set('filters', this.filters); this.config.forceSave(); } - - cb(); }); - } else { - cb(); } } }; @@ -103,11 +101,10 @@ export default 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?', @@ -119,6 +116,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?', @@ -147,11 +150,14 @@ export default 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); + this.filters.flow = !!answers.flow; + insight.track('flow', !!answers.flow); + this.filters[answers.markup] = true; insight.track('markup', answers.markup); @@ -172,18 +178,15 @@ export default 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?', @@ -233,7 +236,7 @@ export default 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); @@ -272,18 +275,15 @@ export default 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?', @@ -308,7 +308,7 @@ export default 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); @@ -326,8 +326,6 @@ export default class Generator extends Base { this.filters.should = false; this.filters.expect = false; } - - cb(); }); } }; @@ -425,15 +423,67 @@ export default class Generator extends Base { get writing() { return { generateProject: function() { - 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'); - } + /** + * 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' + ]; - return dest; - }); + // 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/app')); + this.processDirectory('.', '.'); }, generateEndpoint: function() { var models; @@ -467,3 +517,5 @@ export default class Generator extends Base { return {}; } } + +module.exports = Generator; diff --git a/controller/index.js b/src/generators/controller/index.js similarity index 100% rename from controller/index.js rename to src/generators/controller/index.js diff --git a/decorator/index.js b/src/generators/decorator/index.js similarity index 100% rename from decorator/index.js rename to src/generators/decorator/index.js diff --git a/directive/index.js b/src/generators/directive/index.js similarity index 100% rename from directive/index.js rename to src/generators/directive/index.js diff --git a/endpoint/generator.js b/src/generators/endpoint/index.js similarity index 92% rename from endpoint/generator.js rename to src/generators/endpoint/index.js index a7c968093..b48a8815f 100644 --- a/endpoint/generator.js +++ b/src/generators/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 default 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 @@ -20,7 +22,7 @@ export default class Generator extends NamedBase { }); this.option('endpointDirectory', { - desc: 'Parent directory for enpoints', + desc: 'Parent directory for endpoints', type: String }); } @@ -31,7 +33,6 @@ export default class Generator extends NamedBase { } prompting() { - var done = this.async(); var promptCb = (props) => { if(props.route.charAt(0) !== '/') { props.route = '/' + props.route; @@ -48,7 +49,6 @@ export default class Generator extends NamedBase { this.filters[props.models] = true; this.filters[props.models + 'Models'] = true; } - done(); }; if (this.options.route) { @@ -90,7 +90,7 @@ export default class Generator extends NamedBase { when: () => this.filters.mongoose && this.filters.sequelize }]; - this.prompt(prompts, promptCb); + return this.prompt(prompts).then(promptCb); } configuring() { @@ -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/generators/factory/index.js similarity index 100% rename from factory/index.js rename to src/generators/factory/index.js diff --git a/filter/index.js b/src/generators/filter/index.js similarity index 100% rename from filter/index.js rename to src/generators/filter/index.js diff --git a/generator-base.js b/src/generators/generator-base.js similarity index 100% rename from generator-base.js rename to src/generators/generator-base.js diff --git a/heroku/USAGE b/src/generators/heroku/USAGE similarity index 100% rename from heroku/USAGE rename to src/generators/heroku/USAGE diff --git a/heroku/index.js b/src/generators/heroku/index.js similarity index 100% rename from heroku/index.js rename to src/generators/heroku/index.js diff --git a/heroku/templates/Procfile b/src/generators/heroku/templates/Procfile similarity index 100% rename from heroku/templates/Procfile rename to src/generators/heroku/templates/Procfile diff --git a/insight-init.js b/src/generators/insight-init.js similarity index 92% rename from insight-init.js rename to src/generators/insight-init.js index b9fede03b..66984352d 100644 --- a/insight-init.js +++ b/src/generators/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/generators/openshift/USAGE similarity index 100% rename from openshift/USAGE rename to src/generators/openshift/USAGE diff --git a/openshift/index.js b/src/generators/openshift/index.js similarity index 100% rename from openshift/index.js rename to src/generators/openshift/index.js diff --git a/openshift/templates/hot_deploy b/src/generators/openshift/templates/hot_deploy similarity index 100% rename from openshift/templates/hot_deploy rename to src/generators/openshift/templates/hot_deploy diff --git a/provider/index.js b/src/generators/provider/index.js similarity index 100% rename from provider/index.js rename to src/generators/provider/index.js diff --git a/route/index.js b/src/generators/route/index.js similarity index 100% rename from route/index.js rename to src/generators/route/index.js diff --git a/service/index.js b/src/generators/service/index.js similarity index 100% rename from service/index.js rename to src/generators/service/index.js diff --git a/util.js b/src/generators/util.js similarity index 95% rename from util.js rename to src/generators/util.js index 6b8c65e73..4ed6205c2 100644 --- a/util.js +++ b/src/generators/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(/^_/, ''); diff --git a/src/test/endpoint.test.js b/src/test/endpoint.test.js new file mode 100644 index 000000000..729535b9f --- /dev/null +++ b/src/test/endpoint.test.js @@ -0,0 +1,253 @@ +'use strict'; +import path from 'path'; +import fs from 'fs'; +import _ from 'lodash'; +import Promise from 'bluebird'; +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, + runCmd, + assertOnlyFiles, + readJSON, + runGen +} 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 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 testFile(command, _path) { + _path = path.normalize(_path); + return fs.accessAsync(_path, fs.R_OK).then(() => { + return runCmd(`${command} ${_path}`); + }); +} + +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 => 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 => testFile(`${jshintCmd} --config server/.jshintrc-spec`, path.join('./server/api/', folder, file))); + + 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).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; +var genDir; + +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() { + 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'), + copyAsync(path.join(genDir, '/.jscsrc'), './.jscsrc') + ]); + }); + }); + + it('should generate the expected files', function() { + assert.file(getExpectedFiles.endpoint('foo')); + }); + + it('should pass jscs', function() { + return jscsDir(dir, 'foo').should.be.fulfilled(); + }); + + it('should pass lint', function() { + return jshintDir(dir, 'foo').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; + + 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')); + }); + + it('should pass jscs', function() { + return jscsDir(dir, 'Foo').should.be.fulfilled(); + }); + + 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/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('bar', 'foo/bar')); + }); + + 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(); + }); + }); + + 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 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..3f652f692 --- /dev/null +++ b/src/test/fixtures/.yo-rc.json @@ -0,0 +1,69 @@ +{ + "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": { + "js": true, + "babel": true, + "flow": false, + "html": true, + "sass": true, + "uirouter": true, + "bootstrap": true, + "uibootstrap": true, + "socketio": true, + "auth": true, + "models": true, + "mongooseModels": true, + "mongoose": true, + "grunt": true, + "mocha": true, + "jasmine": 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/get-expected-files.js b/src/test/get-expected-files.js new file mode 100644 index 000000000..c3ac9a338 --- /dev/null +++ b/src/test/get-expected-files.js @@ -0,0 +1,238 @@ +/** + * 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, path) { + if(!path) path = name; + return [ + `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` + ]; +} diff --git a/src/test/main.test.js b/src/test/main.test.js new file mode 100644 index 000000000..9e4e53fef --- /dev/null +++ b/src/test/main.test.js @@ -0,0 +1,431 @@ +'use strict'; +import path from 'path'; +import fs from 'fs'; +import _ from 'lodash'; +import Promise from 'bluebird'; +import helpers from 'yeoman-test'; +import assert from 'yeoman-assert'; +import * as getExpectedFiles from './get-expected-files'; +import { + copyAsync, + runCmd, + assertOnlyFiles, + readJSON, + runGen +} from './test-helpers'; + +const defaultOptions = { + buildtool: 'grunt', + transpiler: 'babel', + markup: 'html', + stylesheet: 'sass', + router: 'uirouter', + testing: 'mocha', + chai: 'expect', + bootstrap: true, + uibootstrap: true, + odms: ['mongoose'], + auth: true, + oauth: [], + socketio: true +}; +const TEST_DIR = __dirname; + +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()) + }); +} + +describe('angular-fullstack:app', function() { + describe('default settings', function() { + var dir; + + beforeEach(function() { + return runGen(defaultOptions).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(); + }); + + describe('with a generated endpoint', function() { + beforeEach(function() { + return readJSON(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(); + }); + }); + + describe('with a generated capitalized endpoint', function() { + beforeEach(function() { + return readJSON(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(); + }); + }); + + describe('with a generated path name endpoint', function() { + beforeEach(function() { + return readJSON(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(); + }); + }); + + describe('with a generated snake-case endpoint', function() { + beforeEach(function() { + return readJSON(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', 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(); + }); + } + }); + + describe('default settings using existing `.yo-rc.json`', function() { + var dir; + var jscsResult; + var lintResult; + var clientTestResult; + var serverTestResult; + + before(function() { + return runGen(null, { + copyConfigFile: true, + options: { + skipInstall: true, + skipConfig: true + } + }).then(_dir => { + dir = _dir; + jscsResult = runCmd('grunt jscs'); + lintResult = runCmd('grunt jshint'); + clientTestResult = runCmd('grunt test:client'); + serverTestResult = runCmd('grunt test:server'); + }); + }); + + 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 jscsResult.should.be.fulfilled(); + }); + + it('passes JSHint', function() { + return lintResult.should.be.fulfilled(); + }); + + it('passes client tests', function() { + return clientTestResult.should.be.fulfilled(); + }); + + it('passes server tests', function() { + 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', + markup: 'jade', + stylesheet: 'less', + router: 'uirouter', + testing: 'jasmine', + odms: ['mongoose'], + auth: true, + oauth: ['twitterAuth', 'facebookAuth', 'googleAuth'], + socketio: true, + bootstrap: true, + uibootstrap: true + }; + + 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'); + }); + }); + + 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 jscsResult.should.be.fulfilled(); + }); + + it('passes lint', function() { + return lintResult.should.be.fulfilled(); + }); + + it('should run client tests successfully', function() { + return clientTestResult.should.be.fulfilled(); + }); + + it('should run server tests successfully', function() { + return serverTestResult.should.be.fulfilled(); + }); + + describe('with a generated endpoint', function() { + beforeEach(function() { + return readJSON(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() { + 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(); + }); + } + }); + + describe('with sequelize models, auth', function() { + var dir; + var jscsResult; + var lintResult; + var clientTestResult; + var serverTestResult; + 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 + }; + this.retries(3); // Sequelize seems to be quite flaky + + 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'); + }); + }); + + 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 jscsResult.should.be.fulfilled(); + }); + + it('passes lint', function() { + return lintResult.should.be.fulfilled(); + }); + + it('should run client tests successfully', function() { + return clientTestResult.should.be.fulfilled(); + }); + + it('should run server tests successfully', function() { + return serverTestResult.should.be.fulfilled(); + }); + + describe('with a generated endpoint', function() { + beforeEach(function() { + return readJSON(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() { + 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(); + }); + } + }); + + 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', + 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; + jscsResult = runCmd('grunt jscs'); + lintResult = runCmd('grunt tslint'); + clientTestResult = runCmd('grunt test:client'); + serverTestResult = runCmd('grunt test:server'); + }); + }); + + 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 jscsResult.should.be.fulfilled(); + }); + + it('passes lint', function() { + return lintResult.should.be.fulfilled(); + }); + + it('should run client tests successfully', function() { + return clientTestResult.should.be.fulfilled(); + }); + + it('should run server tests successfully', function() { + return serverTestResult.should.be.fulfilled(); + }); + + describe('with a generated endpoint', function() { + beforeEach(function() { + return readJSON(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() { + 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(); + }); + } + }); +}); \ No newline at end of file diff --git a/src/test/pre.test.js b/src/test/pre.test.js new file mode 100644 index 000000000..61c88de27 --- /dev/null +++ b/src/test/pre.test.js @@ -0,0 +1,37 @@ +'use strict'; +import path from 'path'; +import assert from 'yeoman-assert'; + +describe('test fixtures', function() { + it('should have package.json in fixtures', function() { + assert.file([path.join(__dirname, 'fixtures/package.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() { + 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 diff --git a/src/test/test-helpers.js b/src/test/test-helpers.js new file mode 100644 index 000000000..f82ef4b8d --- /dev/null +++ b/src/test/test-helpers.js @@ -0,0 +1,126 @@ +'use strict'; +import path from 'path'; +import fs from 'fs'; +import _ from 'lodash'; +import Promise from 'bluebird'; +import {exec} from 'child_process'; +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)); +} + +/** + * @callback doneCallback + * @param {null|Error} err + */ + +/** + * Run the given command in a child process + * @param {string} cmd - command to run + * @returns {Promise} + */ +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(); + } + }); + }); +} + +/** + * 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) { + 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(); + }); + }); +} + +/** + * 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}; + + // 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 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 98% rename from app/templates/.jscsrc rename to templates/app/.jscsrc index 8923ad53e..e05f83c6c 100644 --- a/app/templates/.jscsrc +++ b/templates/app/.jscsrc @@ -2,7 +2,6 @@ "excludeFiles": [ "client/app/app.constant.js" ], - "esnext": true, "maximumLineLength": { "value": 100, "allowComments": true, 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 94% rename from app/templates/Gruntfile(grunt).js rename to templates/app/Gruntfile(grunt).js index a39fd5d18..7f5d4e83f 100644 --- a/app/templates/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'] @@ -142,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: { @@ -165,7 +165,8 @@ module.exports = function (grunt) { test: { src: ['<%%= yeoman.client %>/{app,components}/**/*.{spec,mock}.js'] } - },<% if(filters.ts) { %> + },<% } %> + <%_ if(filters.ts) { _%> tslint: { options: { @@ -240,14 +241,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 +470,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 +597,7 @@ module.exports = function (grunt) { NODE_ENV: 'production' }, all: localConfig - },<% if (filters.jade) { %> + },<% if(filters.jade) { %> // Compiles Jade to html jade: { @@ -688,7 +689,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 +701,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 +743,7 @@ module.exports = function (grunt) { ] ] } - },<% if (filters.stylus) { %> + },<% if(filters.stylus) { %> // Inject component styl into app.styl stylus: { @@ -762,7 +763,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 +783,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 +827,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 +842,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 +877,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 +904,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 +913,7 @@ module.exports = function (grunt) { 'express:prod', 'protractor' ]); - } - - else { + } else { return grunt.task.run([ 'clean:server', 'env:all', @@ -937,33 +931,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 +956,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', [ 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 98% rename from app/templates/_package.json rename to templates/app/_package.json index 3f51be985..7e4f6532c 100644 --- a/app/templates/_package.json +++ b/templates/app/_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", 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 98% rename from app/templates/client/components/auth(auth)/auth.service.js rename to templates/app/client/components/auth(auth)/auth.service.js index dbb13603a..3a75c5a9a 100644 --- a/app/templates/client/components/auth(auth)/auth.service.js +++ b/templates/app/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 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 68% rename from app/templates/client/components/navbar/navbar.controller.js rename to templates/app/client/components/navbar/navbar.controller.js index 958355f9f..12ae0b351 100644 --- a/app/templates/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(); 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 82% rename from app/templates/e2e/main/main.spec(jasmine).js rename to templates/app/e2e/main/main.spec(jasmine).js index 57284495a..3d56cb5d3 100644 --- a/app/templates/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/app/templates/e2e/main/main.spec(mocha).js b/templates/app/e2e/main/main.spec(mocha).js similarity index 91% rename from app/templates/e2e/main/main.spec(mocha).js rename to templates/app/e2e/main/main.spec(mocha).js index 798b58c41..12b0781db 100644 --- a/app/templates/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'); }); }); 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 99% rename from app/templates/server/api/user(auth)/user.model(mongooseModels).js rename to templates/app/server/api/user(auth)/user.model(mongooseModels).js index 60120b3b6..5394bad3c 100644 --- a/app/templates/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) { 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 98% rename from app/templates/server/config/express.js rename to templates/app/server/config/express.js index eeca74e6e..84f82043b 100644 --- a/app/templates/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 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 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": "" } } diff --git a/test/test-file-creation.js b/test/test-file-creation.js deleted file mode 100644 index 80ae2538c..000000000 --- a/test/test-file-creation.js +++ /dev/null @@ -1,758 +0,0 @@ -/*global describe, beforeEach, it */ -'use strict'; -var path = require('path'); -var fs = require('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'); - -describe('angular-fullstack generator', function () { - var gen, 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 - }, dependenciesInstalled = false; - - function copySync(s, d) { fs.writeFileSync(d, fs.readFileSync(s)); } - - function generatorTest(generatorType, name, mockPrompt, callback) { - gen.run(function () { - var afGenerator; - var deps = [path.join('../..', 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) { - topLevelPath = topLevelPath || './'; - skip = 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), - 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; - - 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 = [ - '../../app', - '../../endpoint', - [ - helpers.createDummyGenerator(), - 'ng-component:app' - ] - ]; - - helpers.testDirectory(path.join(__dirname, 'temp'), function (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') - ]); - }); - - 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); - 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'); - }); - - 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('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); - copySync(__dirname + '/fixtures/.yo-rc.json', __dirname + '/temp/.yo-rc.json'); - var gen = helpers.createGenerator('angular-fullstack:app', [ - '../../app', - '../../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); - //}); - } - - }); - }); -});