├── .gitignore
├── .jscsrc
├── .jshintrc
├── .travis.yml
├── LICENSE
├── Makefile
├── README.md
├── app
└── index.js
├── assets
├── angular.png
├── bower.png
├── cordova.png
├── gulp.png
├── libsass.png
└── yeoman.png
├── c
└── index.js
├── cp
└── index.js
├── d
└── index.js
├── decorator
└── index.js
├── default-settings.js
├── f
└── index.js
├── filter
└── index.js
├── helper.js
├── p
└── index.js
├── package-lock.json
├── package.json
├── r
└── index.js
├── s
└── index.js
├── sub-generator-base.js
├── templates
├── app
│ ├── _app.js
│ ├── _app.spec.js
│ ├── _component.scss
│ ├── _controller.scss
│ ├── _directive.scss
│ ├── component.html
│ ├── component.js
│ ├── component.spec.js
│ ├── controller.html
│ ├── controller.js
│ ├── controller.spec.js
│ ├── decorator.js
│ ├── decorator.spec.js
│ ├── directive.html
│ ├── directive.js
│ ├── directive.spec.js
│ ├── factory.js
│ ├── factory.spec.js
│ ├── filter.js
│ ├── filter.spec.js
│ ├── provider.js
│ ├── provider.spec.js
│ ├── routes.js
│ ├── routes.spec.js
│ ├── service.js
│ └── service.spec.js
├── e2e-tests
│ ├── example.e2e.js
│ └── po
│ │ └── home.po.js
├── index.html
├── root
│ ├── README.md
│ ├── _bower.json
│ ├── _bowerrc
│ ├── _config.xml
│ ├── _editorconfig
│ ├── _gitattributes
│ ├── _gitignore
│ ├── _gulpfile.js
│ ├── _jshintrc
│ ├── _karma-e2e.conf.js
│ ├── _karma.conf.js
│ ├── _package.json
│ └── _travis.yml
├── styles
│ ├── _functions
│ │ └── _some-function.scss
│ ├── _mixins
│ │ └── _some-mixin.scss
│ ├── _placeholders
│ │ └── _some-placeholder.scss
│ ├── _variables.scss
│ ├── base
│ │ ├── _buttons.scss
│ │ ├── _fonts.scss
│ │ ├── _forms.scss
│ │ ├── _icons.scss
│ │ ├── _lists.scss
│ │ ├── _page.scss
│ │ ├── _tables.scss
│ │ └── _typography.scss
│ └── main.scss
└── tasks
│ ├── build.js
│ ├── config.js
│ ├── cordova.js
│ ├── deploy.js
│ ├── dev.js
│ └── e2e.js
├── test-app
├── injections.spec.js
└── styles.spec.js
└── test
├── app.spec.js
├── component.spec.js
├── controller.spec.js
├── custom-templates-from-file.spec.js
├── custom-templates-in-yo-rc.spec.js
├── decorator.spec.js
├── directive.spec.js
├── factory.spec.js
├── filter.spec.js
├── helper.spec.js
├── provider.spec.js
├── route.spec.js
└── service.spec.js
/.gitignore:
--------------------------------------------------------------------------------
1 | node_modules/
2 | .tmp
3 | .sass-cache
4 | .grunt
5 | bower_components
6 | dist/example
7 | .idea/
8 | *.DS_*
9 | npm-debug.log
10 | coverage/
11 | .test-instance/
--------------------------------------------------------------------------------
/.jscsrc:
--------------------------------------------------------------------------------
1 | {
2 | "requireCurlyBraces": [
3 | "if",
4 | "else",
5 | "for",
6 | "while",
7 | "do",
8 | "try",
9 | "catch"
10 | ],
11 | "requireOperatorBeforeLineBreak": true,
12 | "requireCamelCaseOrUpperCaseIdentifiers": {
13 | "allowedPrefixes": [
14 | "opt_"
15 | ],
16 | "allExcept": [
17 | "var_args"
18 | ]
19 | },
20 | "maximumLineLength": false,
21 | "validateIndentation": 4,
22 | "validateQuoteMarks": "'",
23 | "disallowMultipleLineStrings": true,
24 | "disallowMixedSpacesAndTabs": true,
25 | "disallowTrailingWhitespace": true,
26 | "disallowSpaceAfterPrefixUnaryOperators": true,
27 | "disallowMultipleVarDecl": true,
28 | "disallowKeywordsOnNewLine": [
29 | "else"
30 | ],
31 | "requireSpaceAfterKeywords": [
32 | "if",
33 | "else",
34 | "for",
35 | "while",
36 | "do",
37 | "switch",
38 | "return",
39 | "try",
40 | "catch"
41 | ],
42 | "requireSpaceBeforeBinaryOperators": [
43 | "=",
44 | "+=",
45 | "-=",
46 | "*=",
47 | "/=",
48 | "%=",
49 | "<<=",
50 | ">>=",
51 | ">>>=",
52 | "&=",
53 | "|=",
54 | "^=",
55 | "+=",
56 | "+",
57 | "-",
58 | "*",
59 | "/",
60 | "%",
61 | "<<",
62 | ">>",
63 | ">>>",
64 | "&",
65 | "|",
66 | "^",
67 | "&&",
68 | "||",
69 | "===",
70 | "==",
71 | ">=",
72 | "<=",
73 | "<",
74 | ">",
75 | "!=",
76 | "!=="
77 | ],
78 | "requireSpaceAfterBinaryOperators": true,
79 | "requireSpacesInConditionalExpression": true,
80 | "requireSpaceBeforeBlockStatements": true,
81 | "requireSpacesInForStatement": true,
82 | "requireLineFeedAtFileEnd": true,
83 | "requireSpacesInFunctionExpression": {
84 | "beforeOpeningCurlyBrace": true
85 | },
86 | "disallowSpacesInAnonymousFunctionExpression": {
87 | "beforeOpeningRoundBrace": true
88 | },
89 | "disallowSpacesInsideObjectBrackets": "all",
90 | "disallowSpacesInsideArrayBrackets": "all",
91 | "disallowSpacesInsideParentheses": true,
92 | "disallowMultipleLineBreaks": false,
93 | "disallowNewlineBeforeBlockStatements": true,
94 | "disallowKeywords": [
95 | "with"
96 | ],
97 | "disallowSpacesInFunctionExpression": {
98 | "beforeOpeningRoundBrace": true
99 | },
100 | "disallowSpacesInFunctionDeclaration": {
101 | "beforeOpeningRoundBrace": true
102 | },
103 | "disallowSpacesInCallExpression": true,
104 | "disallowSpaceAfterObjectKeys": true,
105 | "requireSpaceBeforeObjectValues": true,
106 | "requireCapitalizedConstructors": true,
107 | "requireDotNotation": true,
108 | "requireSemicolons": true,
109 | "validateParameterSeparator": ", ",
110 | "jsDoc": {
111 | "checkParamNames": true,
112 | "requireParamTypes": true,
113 | "checkRedundantParams": true,
114 | "checkReturnTypes": true,
115 | "checkRedundantReturns": true,
116 | "requireReturnTypes": true,
117 | "checkTypes": true,
118 | "checkRedundantAccess": true,
119 | "requireNewlineAfterDescription": true
120 | }
121 | }
122 |
--------------------------------------------------------------------------------
/.jshintrc:
--------------------------------------------------------------------------------
1 | {
2 | "node": true,
3 | "browser": true,
4 | "esnext": true,
5 | "bitwise": true,
6 | "camelcase": true,
7 | "curly": true,
8 | "eqeqeq": true,
9 | "indent": 4,
10 | "latedef": "nofunc",
11 | "noarg": true,
12 | "quotmark": "single",
13 | "undef": true,
14 | "unused": true,
15 | "strict": true,
16 | "trailing": true,
17 | "smarttabs": true,
18 | "globals": {
19 | "angular": false,
20 | "browser": false,
21 | "jasmine": false,
22 | "describe": false,
23 | "xdescribe": false,
24 | "before": false,
25 | "beforeEach": false,
26 | "after": false,
27 | "afterEach": false,
28 | "it": false,
29 | "xit": false,
30 | "it": false,
31 | "inject": false,
32 | "expect": false,
33 | "spyOn": false
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/.travis.yml:
--------------------------------------------------------------------------------
1 | language: node_js
2 | before_install:
3 | - "export DISPLAY=:99.0"
4 | - "sh -e /etc/init.d/xvfb start"
5 | node_js:
6 | - '5'
7 | before_script:
8 | - npm install -g istanbul
9 | - npm install -g mocha
10 |
11 | script: make test-full
12 | after_success:
13 | - make coveralls
14 | addons:
15 | apt:
16 | sources:
17 | - ubuntu-toolchain-r-test
18 | packages:
19 | - gcc-4.9
20 | - g++-4.9
21 | before_install:
22 | - export CC="gcc-4.9" CXX="g++-4.9"
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | The MIT License (MIT)
2 |
3 | Copyright (c) 2015 Johannes Millan
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
23 |
--------------------------------------------------------------------------------
/Makefile:
--------------------------------------------------------------------------------
1 | TESTS = ./test/**/*.spec.js
2 | INSTANCE_TESTS_DIR = .test-instance
3 | INSTANCE_TESTS = ./test-app/**/*.spec.js
4 | REPORTER = spec
5 | COVERAGE_REPORT = ./coverage/lcov.info
6 | COVERALLS = ./node_modules/.bin/coveralls
7 |
8 | test: test-mocha
9 |
10 | test-mocha:
11 | @NODE_ENV=test ./node_modules/.bin/mocha \
12 | --timeout 200 \
13 | --reporter $(REPORTER) \
14 | $(TESTS)
15 |
16 | test-full: ./node_modules/.bin/istanbul create-app-instance test-app-instance test-node-module
17 |
18 | istanbul:
19 | ./node_modules/.bin/istanbul cover ./node_modules/.bin/_mocha -- -R spec $(TESTS)
20 |
21 | coveralls:
22 | cat $(COVERAGE_REPORT) | $(COVERALLS)
23 |
24 | cov-html: test-cov html-cov-report
25 |
26 | html-cov-report:
27 | ./node_modules/.bin/istanbul report html
28 |
29 | npm:
30 | npm publish ./
31 |
32 | check:
33 | travis-lint .travis.yml
34 |
35 | clean:
36 | rm -rf ./coverage
37 |
38 | test-app-instance:
39 | ./node_modules/.bin/istanbul cover ./node_modules/.bin/_mocha -- -R spec $(INSTANCE_TESTS)
40 |
41 | create-app-instance:
42 | rm -rf $(INSTANCE_TESTS_DIR)/
43 | mkdir $(INSTANCE_TESTS_DIR)
44 | npm install -g yo bower node-gyp
45 | npm link
46 | cd $(INSTANCE_TESTS_DIR) && echo "CDing into $(INSTANCE_TESTS_DIR)" && \
47 | yo moda --skip-install --skipPrompts && \
48 | npm install && \
49 | bower install
50 |
51 | test-node-module:
52 | rm -rf $(INSTANCE_TESTS_DIR)/
53 | mkdir $(INSTANCE_TESTS_DIR)
54 | npm install -g yo bower generator-moda node-gyp
55 | cd $(INSTANCE_TESTS_DIR) && echo "CDing into $(INSTANCE_TESTS_DIR)" && \
56 | yo moda --skipPrompts --skip-install && \
57 | npm cache clean && \
58 | npm install && \
59 | bower install && \
60 | gulp injectAll && \
61 | yo moda:r hello-route --useDefaults && \
62 | yo moda:d hello-directive --useDefaults && \
63 | yo moda:s hello-service --useDefaults && \
64 | gulp testSingle && \
65 | gulp build
--------------------------------------------------------------------------------
/app/index.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 | var fs = require('fs');
3 | var path = require('path');
4 | var util = require('util');
5 | var helper = require('../helper.js');
6 | var defaultSettings = require('../default-settings.js');
7 | var yeoman = require('yeoman-generator');
8 | var wiredep = require('wiredep');
9 | var chalk = require('chalk');
10 | var _s = require('underscore.string');
11 |
12 | module.exports = yeoman.Base.extend({
13 | constructor: function() {
14 | yeoman.Base.apply(this, arguments);
15 |
16 | // get app name
17 | this.argument('appname', {type: String, required: false});
18 | this.appname = this.appname || path.basename(process.cwd());
19 | this.appname = _s.camelize(_s.slugify(_s.humanize(this.appname)));
20 | this.slugAppName = _s.slugify(this.appname);
21 | this.humanizedAppName = _s.humanize(this.appname);
22 | this.scriptAppName = this.appname;
23 |
24 |
25 | // get app path
26 | try {
27 | this.env.options.appPath = require(path.join(process.cwd(), 'bower.json')).appPath;
28 | } catch (e) {
29 | }
30 | this.env.options.appPath = this.env.options.appPath || 'app';
31 | this.options.appPath = this.env.options.appPath;
32 | this.appPath = this.env.options.appPath;
33 |
34 |
35 | this.pkg = require('../package.json');
36 | this.sourceRoot(path.join(__dirname, '../templates'));
37 | },
38 |
39 | config: function() {
40 | this.config.defaults(defaultSettings);
41 | },
42 |
43 | askForModules: function askForModules() {
44 | var cb = this.async();
45 |
46 | if (this.options.skipPrompts) {
47 | cb();
48 | // set defaults if skipping this one
49 | this.animateModule = false;
50 | this.ariaModule = false;
51 | this.cookiesModule = false;
52 | this.messagesModule = false;
53 | this.resourceModule = false;
54 | this.routeModule = false;
55 | this.uiRouterModule = false;
56 | this.ngFabFormModule = false;
57 | this.sanitizeModule = false;
58 | this.ngMaterialModule = false;
59 | this.touchModule = false;
60 | return;
61 | }
62 |
63 | var prompts = [{
64 | type: 'checkbox',
65 | name: 'modules',
66 | message: 'Which modules would you like to include?',
67 | choices: [
68 | {
69 | value: 'animateModule',
70 | name: 'angular-animate.js',
71 | checked: true
72 | }, {
73 | value: 'ariaModule',
74 | name: 'angular-aria.js',
75 | checked: true
76 | }, {
77 | value: 'cookiesModule',
78 | name: 'angular-cookies.js',
79 | checked: false
80 | }, {
81 | value: 'resourceModule',
82 | name: 'angular-resource.js',
83 | checked: true
84 | }, {
85 | value: 'sanitizeModule',
86 | name: 'angular-sanitize.js',
87 | checked: false
88 | }, {
89 | value: 'touchModule',
90 | name: 'angular-touch.js',
91 | checked: false
92 | }, {
93 | value: 'ngMaterialModule',
94 | name: 'angular material design',
95 | checked: false
96 | }, {
97 | value: 'ngFabFormModule',
98 | name: 'ng-fab-form (form helper)',
99 | checked: false
100 | }, {
101 | value: 'messagesModule',
102 | name: 'angular-messages.js (included with ngFabForm)',
103 | checked: false
104 | }, {
105 | value: 'uiRouterModule',
106 | name: 'ui-router.js',
107 | checked: true
108 | }, {
109 | value: 'routeModule',
110 | name: 'angular-route.js (standard router dot\'t use with ui-router)',
111 | checked: false
112 | }
113 | ]
114 | }];
115 |
116 | this.prompt(prompts, function(props) {
117 | var hasMod = function(mod) {
118 | // prevent test errors if no values mocked
119 | if (props && props.modules) {
120 | return props.modules.indexOf(mod) !== -1;
121 | }
122 | };
123 | this.animateModule = hasMod('animateModule');
124 | this.ariaModule = hasMod('ariaModule');
125 | this.cookiesModule = hasMod('cookiesModule');
126 | this.messagesModule = hasMod('messagesModule');
127 | this.resourceModule = hasMod('resourceModule');
128 | this.routeModule = hasMod('routeModule');
129 | this.uiRouterModule = hasMod('uiRouterModule');
130 | this.ngFabFormModule = hasMod('ngFabFormModule');
131 | this.sanitizeModule = hasMod('sanitizeModule');
132 | this.ngMaterialModule = hasMod('ngMaterialModule');
133 | this.touchModule = hasMod('touchModule');
134 |
135 | var angMods = [];
136 |
137 | if (this.animateModule) {
138 | angMods.push('\'ngAnimate\'');
139 | }
140 |
141 | if (this.ariaModule) {
142 | angMods.push('\'ngAria\'');
143 | }
144 |
145 | if (this.cookiesModule) {
146 | angMods.push('\'ngCookies\'');
147 | }
148 |
149 | if (this.messagesModule) {
150 | angMods.push('\'ngMessages\'');
151 | }
152 |
153 | if (this.resourceModule) {
154 | angMods.push('\'ngResource\'');
155 | }
156 |
157 | if (this.routeModule) {
158 | angMods.push('\'ngRoute\'');
159 | this.env.options.ngRoute = true;
160 | }
161 |
162 | if (this.sanitizeModule) {
163 | angMods.push('\'ngSanitize\'');
164 | }
165 |
166 | if (this.touchModule) {
167 | angMods.push('\'ngTouch\'');
168 | }
169 |
170 | if (this.uiRouterModule) {
171 | angMods.push('\'ui.router\'');
172 | this.config.set('uiRouter', true);
173 | this.env.options.uiRouter = true;
174 | }
175 |
176 | if (this.ngMaterialModule) {
177 | angMods.push('\'ngMaterial\'');
178 | this.env.options.ngMaterial = true;
179 | }
180 |
181 | if (this.ngFabFormModule) {
182 | angMods.push('\'ngFabForm\'');
183 | }
184 |
185 | if (angMods.length) {
186 | this.env.options.angularDeps = '\n ' + angMods.join(',\n ') + '\n ';
187 | }
188 |
189 | cb();
190 | }.bind(this));
191 | },
192 |
193 | askForCodingStyle: function askForModules() {
194 | var cb = this.async();
195 |
196 | if (this.options.skipPrompts) {
197 | cb();
198 | return;
199 | }
200 |
201 | var prompts = [{
202 | type: 'list',
203 | name: 'jscsCfg',
204 | message: 'What javascript coding style would you like to use (JSCS - see: http://jscs.info/)?',
205 | choices: [
206 | {
207 | value: 'emptyCfg',
208 | name: 'empty configuration file'
209 | },
210 | {
211 | value: 'manualCfg',
212 | name: 'configure via --auto-configure'
213 | }
214 | ]
215 | }];
216 |
217 | this.prompt(prompts, function(props) {
218 | var that = this;
219 |
220 | fs.writeFile('./.jscsrc', '{}', function(err) {
221 | if (err) {
222 | return console.log(err);
223 | }
224 | if (props.jscsCfg === 'manualCfg') {
225 | var jscsrcPath = path.join('./.jscsrc')
226 | that.spawnCommand('jscs', ['--auto-configure', jscsrcPath])
227 | .on('close', function() {
228 | cb();
229 | });
230 | } else {
231 | cb();
232 | }
233 | });
234 |
235 | }.bind(this));
236 | },
237 |
238 | readOptions: function readOptions() {
239 | this.ngRoute = this.env.options.ngRoute;
240 | this.uiRouter = this.env.options.uiRouter;
241 | this.ngMaterial = this.env.options.ngMaterial;
242 | },
243 |
244 | cssFiles: function copyCssFiles() {
245 | this.fs.copy(
246 | this.templatePath('styles/**/*'),
247 | this.destinationPath(path.join(this.appPath, 'styles/')
248 | )
249 | );
250 | },
251 |
252 | createIndexHtml: function createIndexHtml() {
253 | this.template('index.html', path.join(this.appPath, 'index.html'));
254 | },
255 |
256 | appJs: function appJs() {
257 | this.angularModules = this.env.options.angularDeps;
258 |
259 | this.template('app/_app.js', this.appPath + '/scripts/_app.js');
260 | this.template('app/_app.spec.js', this.appPath + '/scripts/_app.spec.js');
261 | if (this.env.options.uiRouter) {
262 | this.template('app/routes.js', this.appPath + '/scripts/routes.js');
263 | this.template('app/routes.spec.js', this.appPath + '/scripts/routes.spec.js');
264 | }
265 | },
266 |
267 | packageFiles: function packageFiles() {
268 | this.template('root/_bower.json', 'bower.json');
269 | this.template('root/_bowerrc', '.bowerrc');
270 | this.template('root/_package.json', 'package.json');
271 | this.template('root/_gulpfile.js', 'gulpfile.js');
272 | this.template('root/_config.xml', 'config.xml');
273 | this.template('root/_gitignore', '.gitignore');
274 | this.template('root/_gitattributes', '.gitattributes');
275 | this.template('root/_editorconfig', '.editorconfig');
276 | this.template('root/_jshintrc', '.jshintrc');
277 | this.template('root/README.md', 'README.md');
278 | this.template('root/_travis.yml', '.travis.yml');
279 | this.template('root/_karma.conf.js', 'karma.conf.js');
280 | this.template('root/_karma-e2e.conf.js', 'karma-e2e.conf.js');
281 | },
282 |
283 | tasks: function packageFiles() {
284 | // fixing lodash issue with ngconfig
285 | this.ngConfModulePlaceholder = '<%= module %>';
286 |
287 | this.template('tasks/config.js', 'tasks/config.js');
288 | this.template('tasks/build.js', 'tasks/build.js');
289 | this.template('tasks/dev.js', 'tasks/dev.js');
290 | this.template('tasks/deploy.js', 'tasks/deploy.js');
291 | this.template('tasks/e2e.js', 'tasks/e2e.js');
292 |
293 | // TODO make cordova optional
294 | this.template('tasks/cordova.js', 'tasks/cordova.js');
295 | },
296 |
297 | install: function packageFiles() {
298 | this.on('end', function() {
299 | //save configuration
300 | this.config.save();
301 | if (!this.options['skip-install']) {
302 | this.installDependencies({
303 | callback: function() {
304 | // Emit a new event - dependencies installed
305 | this.emit('dependenciesInstalled');
306 | }.bind(this)
307 | });
308 | }
309 | });
310 | },
311 | postRun: function() {
312 | this.on('dependenciesInstalled', function() {
313 | this.spawnCommand('gulp', ['serve']);
314 | });
315 | }
316 | });
317 |
318 |
--------------------------------------------------------------------------------
/assets/angular.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/johannesjo/generator-modular-angular/06e3d19b171ab4beba97cdcfa5c60b9d827c7d7b/assets/angular.png
--------------------------------------------------------------------------------
/assets/bower.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/johannesjo/generator-modular-angular/06e3d19b171ab4beba97cdcfa5c60b9d827c7d7b/assets/bower.png
--------------------------------------------------------------------------------
/assets/cordova.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/johannesjo/generator-modular-angular/06e3d19b171ab4beba97cdcfa5c60b9d827c7d7b/assets/cordova.png
--------------------------------------------------------------------------------
/assets/gulp.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/johannesjo/generator-modular-angular/06e3d19b171ab4beba97cdcfa5c60b9d827c7d7b/assets/gulp.png
--------------------------------------------------------------------------------
/assets/libsass.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/johannesjo/generator-modular-angular/06e3d19b171ab4beba97cdcfa5c60b9d827c7d7b/assets/libsass.png
--------------------------------------------------------------------------------
/assets/yeoman.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/johannesjo/generator-modular-angular/06e3d19b171ab4beba97cdcfa5c60b9d827c7d7b/assets/yeoman.png
--------------------------------------------------------------------------------
/c/index.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 | var ScriptBase = require('../sub-generator-base.js');
3 |
4 | module.exports = ScriptBase.extend({
5 | initializing: function() {
6 | // needs to be called manually
7 | this.init();
8 | },
9 | createFactoryFiles: function createFactoryFiles() {
10 | var cb = this.async(),
11 | defaults = {
12 | createTemplate: true,
13 | createService: false
14 | };
15 |
16 | var createFiles = function(props) {
17 | this.createService = props.createService;
18 | this.createTemplate = props.createTemplate;
19 |
20 | this.generateSourceAndTest('controller');
21 | // NOTE: never forget the callback!
22 | cb();
23 | };
24 |
25 | if (this.options.useDefaults || this.config.get('alwaysSkipDialog')) {
26 | createFiles.bind(this)(defaults);
27 | } else {
28 | this.prompt(
29 | [
30 | {
31 | type: 'confirm',
32 | name: 'createTemplate',
33 | message: 'Would you like to create a html-template-file and a scss-file for the controller?',
34 | default: defaults.createTemplate
35 | },
36 | {
37 | type: 'list',
38 | name: 'createService',
39 | message: 'Would you like to create a service or factory for the controller?',
40 | default: defaults.createService,
41 | choices: [
42 | {
43 | name: 'No',
44 | value: false
45 | },
46 | {
47 | name: 'a service',
48 | value: 'service'
49 | },
50 | {
51 | name: 'a factory',
52 | value: 'service'
53 | }
54 | ]
55 | }
56 | ],
57 | createFiles.bind(this));
58 | }
59 | }
60 | });
61 |
--------------------------------------------------------------------------------
/cp/index.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 | var ScriptBase = require('../sub-generator-base.js');
3 |
4 | module.exports = ScriptBase.extend({
5 | initializing: function() {
6 | // needs to be called manually
7 | this.init();
8 | },
9 | createFactoryFiles: function createFactoryFiles() {
10 | var cb = this.async(),
11 | defaults = {
12 | createTemplate: true,
13 | createService: false
14 | };
15 |
16 | var createFiles = function(props) {
17 | this.createService = props.createService;
18 | this.createTemplate = props.createTemplate;
19 |
20 | this.generateSourceAndTest('component');
21 | // NOTE: never forget the callback!
22 | cb();
23 | };
24 |
25 | if (this.options.useDefaults || this.config.get('alwaysSkipDialog')) {
26 | createFiles.bind(this)(defaults);
27 | } else {
28 | this.prompt(
29 | [
30 | {
31 | type: 'confirm',
32 | name: 'createTemplate',
33 | message: 'Would you like to create a html-template-file and a scss-file for the component?',
34 | default: defaults.createTemplate
35 | },
36 | {
37 | type: 'list',
38 | name: 'createService',
39 | message: 'Would you like to create a service or factory for the component?',
40 | default: defaults.createService,
41 | choices: [
42 | {
43 | name: 'No',
44 | value: false
45 | },
46 | {
47 | name: 'a service',
48 | value: 'service'
49 | },
50 | {
51 | name: 'a factory',
52 | value: 'service'
53 | }
54 | ]
55 | }
56 | ],
57 | createFiles.bind(this));
58 | }
59 | }
60 | });
61 |
62 |
--------------------------------------------------------------------------------
/d/index.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 | var ScriptBase = require('../sub-generator-base.js');
3 |
4 | module.exports = ScriptBase.extend({
5 | initializing: function() {
6 | // needs to be called manually
7 | this.init();
8 | },
9 | createFactoryFiles: function createFactoryFiles() {
10 | var cb = this.async(),
11 | defaults = {
12 | createTemplate: true,
13 | createService: false
14 | };
15 |
16 | var createFiles = function(props) {
17 | this.createService = props.createService;
18 | this.createTemplate = props.createTemplate;
19 |
20 | this.generateSourceAndTest('directive');
21 | // NOTE: never forget the callback!
22 | cb();
23 | };
24 |
25 | if (this.options.useDefaults || this.config.get('alwaysSkipDialog')) {
26 | createFiles.bind(this)(defaults);
27 | } else {
28 | this.prompt(
29 | [
30 | {
31 | type: 'confirm',
32 | name: 'createTemplate',
33 | message: 'Would you like to create a html-template-file and a scss-file for the directive?',
34 | default: defaults.createTemplate
35 | },
36 | {
37 | type: 'list',
38 | name: 'createService',
39 | message: 'Would you like to create a service or factory for the directive?',
40 | default: defaults.createService,
41 | choices: [
42 | {
43 | name: 'No',
44 | value: false
45 | },
46 | {
47 | name: 'a service',
48 | value: 'service'
49 | },
50 | {
51 | name: 'a factory',
52 | value: 'service'
53 | }
54 | ]
55 | }
56 | ],
57 | createFiles.bind(this));
58 | }
59 | }
60 | });
61 |
62 |
--------------------------------------------------------------------------------
/decorator/index.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 | var ScriptBase = require('../sub-generator-base.js');
3 |
4 | module.exports = ScriptBase.extend({
5 | initializing: function() {
6 | // needs to be called manually
7 | this.init();
8 | },
9 | createFactoryFiles: function createFactoryFiles() {
10 | this.generateSourceAndTest('decorator');
11 | }
12 | });
13 |
14 |
15 |
--------------------------------------------------------------------------------
/default-settings.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | testSuffix: '.spec',
3 | testPassOnDefault: true,
4 | alwaysSkipDialog: false,
5 | stylePrefix: '_',
6 | editorCommand: 'idea',
7 | uiRouter: false,
8 | pathOutputStyle: 'dasherize',
9 | routesFile: 'app/scripts/routes.js',
10 | fileExt: {
11 | script: '.js',
12 | tpl: '.html',
13 | style: '.scss'
14 | },
15 | dirs: {
16 | app: 'app',
17 | appModules: 'scripts',
18 | globalComponents: 'main',
19 | routes: 'routes'
20 | },
21 | subGenerators: {
22 | directive: {
23 | suffix: '-d',
24 | globalDir: '',
25 | createDirectory: true
26 | },
27 | controller: {
28 | suffix: '-c',
29 | nameSuffix: 'Ctrl',
30 | globalDir: '',
31 | createDirectory: true
32 | },
33 | component: {
34 | suffix: '-cp',
35 | globalDir: '',
36 | createDirectory: true
37 | },
38 | service: {
39 | suffix: '-s',
40 | globalDir: 'main/global-services'
41 | },
42 | factory: {
43 | suffix: '-f',
44 | globalDir: 'main/global-services'
45 | },
46 | filter: {
47 | suffix: '-filter',
48 | globalDir: 'main/global-filters'
49 | },
50 | provider: {
51 | suffix: '-p',
52 | globalDir: 'main/global-services'
53 | },
54 | decorator: {
55 | suffix: '-decorator',
56 | nameSuffix: 'Decorator',
57 | globalDir: 'main/global-services'
58 | },
59 | mod: {
60 | prefix: '_',
61 | createDirectory: true
62 | }
63 | }
64 | };
--------------------------------------------------------------------------------
/f/index.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 | var ScriptBase = require('../sub-generator-base.js');
3 |
4 | module.exports = ScriptBase.extend({
5 | initializing: function() {
6 | // needs to be called manually
7 | this.init();
8 | },
9 | createFactoryFiles: function createFactoryFiles() {
10 | this.generateSourceAndTest('factory');
11 | }
12 | });
13 |
14 |
15 |
--------------------------------------------------------------------------------
/filter/index.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 | var ScriptBase = require('../sub-generator-base.js');
3 |
4 | module.exports = ScriptBase.extend({
5 | initializing: function() {
6 | // needs to be called manually
7 | this.init();
8 | },
9 | createFactoryFiles: function createFactoryFiles() {
10 | this.generateSourceAndTest('filter');
11 | }
12 | });
13 |
--------------------------------------------------------------------------------
/helper.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 | var path = require('path');
3 | var fs = require('fs');
4 | var chalk = require('chalk');
5 |
6 | exports.STATE_NEEDLE = '/* STATES-NEEDLE - DO NOT REMOVE THIS */';
7 |
8 | // inspired by https://github.com/cgross/generator-cg-angular/blob/master/utils.js
9 | exports.addToFile = function(filename, lineToAdd, beforeMarker) {
10 | try {
11 | var fullPath = path.resolve(process.cwd(), filename);
12 | var fileSrc = fs.readFileSync(fullPath, 'utf8');
13 |
14 | var indexOf = fileSrc.indexOf(beforeMarker);
15 | var lineStart = fileSrc.substring(0, indexOf)
16 | .lastIndexOf('\n') + 1;
17 | var indent = fileSrc.substring(lineStart, indexOf);
18 | fileSrc = fileSrc.substring(0, indexOf) + lineToAdd + '\n' + indent + fileSrc.substring(indexOf);
19 |
20 | fs.writeFileSync(fullPath, fileSrc);
21 | } catch (e) {
22 | throw e;
23 | }
24 | };
25 |
26 | exports.injectRoute = function(routesFile, name, url, tplUrl, ctrl, that) {
27 | var IND = ' ';
28 | var template = tplUrl ? ',\n' + IND + IND + IND + IND + 'templateUrl: \'' + tplUrl + '\'' : '';
29 | ctrl = ctrl ? ',\n' + IND + IND + IND + IND + 'controller: \'' + ctrl + '\'' : '';
30 | var ctrlAs = ctrl ? ',\n' + IND + IND + IND + IND + 'controllerAs: \'vm\'' : '';
31 |
32 | var code = '' +
33 | '.state(\'' + name + '\', {' +
34 | '\n' + IND + IND + IND + IND + 'url: \'' + url + '\'' +
35 | ctrl +
36 | ctrlAs +
37 | template +
38 | '\n' + IND + IND + IND + '})';
39 | exports.addToFile(routesFile, code, exports.STATE_NEEDLE);
40 |
41 | that.log.writeln(chalk.green(' updating') + ' %s', path.basename(routesFile));
42 | };
43 |
44 |
--------------------------------------------------------------------------------
/p/index.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 | var ScriptBase = require('../sub-generator-base.js');
3 |
4 | module.exports = ScriptBase.extend({
5 | initializing: function() {
6 | // needs to be called manually
7 | this.init();
8 | },
9 | createFactoryFiles: function createFactoryFiles() {
10 | this.generateSourceAndTest('provider');
11 | }
12 | });
13 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "generator-moda",
3 | "version": "2.0.0",
4 | "description": "A truly modular yeoman generator for AngularJS all device apps.",
5 | "keywords": [
6 | "yeoman-generator",
7 | "scaffold",
8 | "front-end",
9 | "app",
10 | "angular",
11 | "modular",
12 | "sass",
13 | "scss",
14 | "cordova",
15 | "gulp"
16 | ],
17 | "author": "johannesjo",
18 | "repository": {
19 | "type": "git",
20 | "url": "https://github.com/johannesjo/generator-modular-angular.git"
21 | },
22 | "dependencies": {
23 | "chalk": "latest",
24 | "lodash": "latest",
25 | "underscore.string": "latest",
26 | "wiredep": "latest",
27 | "yeoman-generator": "^0.22.5",
28 | "yosay": "latest"
29 | },
30 | "engines": {
31 | "node": ">=4.1"
32 | },
33 | "licenses": [
34 | {
35 | "type": "MIT"
36 | }
37 | ],
38 | "main": "app/index.js",
39 | "scripts": {
40 | "test": "istanbul cover _mocha -- -R list"
41 | },
42 | "files": [
43 | "app",
44 | "c",
45 | "cp",
46 | "constant",
47 | "d",
48 | "decorator",
49 | "f",
50 | "filter",
51 | "m",
52 | "mod",
53 | "p",
54 | "route",
55 | "r",
56 | "sr",
57 | "s",
58 | "templates",
59 | "script-base.js",
60 | "util.js",
61 | "helper.js",
62 | "default-settings.js",
63 | "sub-generator-base.js"
64 | ],
65 | "devDependencies": {
66 | "coveralls": "latest",
67 | "gulp": "latest",
68 | "istanbul": "latest",
69 | "mocha": "latest",
70 | "mocha-lcov-reporter": "latest",
71 | "underscore": "latest"
72 | }
73 | }
74 |
--------------------------------------------------------------------------------
/r/index.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 | var ScriptBase = require('../sub-generator-base.js');
3 | var helper = require('../helper.js');
4 | var path = require('path');
5 | var fs = require('fs');
6 | var chalk = require('chalk');
7 | var defaultSettings = require('../default-settings.js');
8 |
9 | module.exports = ScriptBase.extend({
10 | initializing: function() {
11 | // needs to be called manually
12 | this.init();
13 |
14 | // the state name is the argument
15 | this.stateName = this.name;
16 |
17 | // create path string from name
18 | var PARENT_STATES_REG_EXP = new RegExp('([^\\.]+)\\.', 'g');
19 | var parentStates = this.name.match(PARENT_STATES_REG_EXP);
20 | var parentStatePath = '';
21 | if (parentStates) {
22 | for (var i = 0; i < parentStates.length; i++) {
23 | var stateStr = parentStates[i].replace('.', '');
24 | stateStr = this.formatNamePath(stateStr);
25 | parentStatePath = path.join(parentStatePath, stateStr);
26 | }
27 | }
28 |
29 | // set name to base-name only to work with the usual generators
30 | this.name = this.name.replace(PARENT_STATES_REG_EXP, '');
31 | // instead use target folder to set the path
32 | this.targetFolder = path.join(this.dirs.routes, parentStatePath);
33 |
34 | // names need to be reset
35 | this.setModuleNames(this.name);
36 | },
37 |
38 | prompting: function() {
39 | var done = this.async();
40 | var defaults = {
41 | createTemplate: true,
42 | createService: false,
43 | createCtrl: true
44 | };
45 |
46 | function createControllerFiles(props) {
47 | // set context vars
48 | this.createService = props.createService;
49 | this.createTemplate = props.createTemplate;
50 | this.skipMainFiles = !props.createCtrl;
51 | this.createController = props.createCtrl;
52 |
53 | // create controller files
54 | this.generateSourceAndTest('controller');
55 | done();
56 | }
57 |
58 | if (this.options.useDefaults || this.config.get('alwaysSkipDialog')) {
59 | createControllerFiles.bind(this)(defaults);
60 | } else {
61 | this.prompt(
62 | [
63 | {
64 | type: 'confirm',
65 | name: 'createCtrl',
66 | message: 'Would you like to create a controller for the route?',
67 | default: defaults.createCtrl
68 | },
69 | {
70 | type: 'confirm',
71 | name: 'createTemplate',
72 | message: 'Would you like to create a html-template-file and a scss-file for the route?',
73 | default: defaults.createTemplate
74 | },
75 | {
76 | type: 'list',
77 | name: 'createService',
78 | message: 'Would you like to create a service or factory for the route?',
79 | default: defaults.createService,
80 | choices: [
81 | {
82 | name: 'No',
83 | value: false
84 | },
85 | {
86 | name: 'a service',
87 | value: 'service'
88 | },
89 | {
90 | name: 'a factory',
91 | value: 'service'
92 | }
93 | ]
94 | }
95 | ],
96 | createControllerFiles.bind(this));
97 | }
98 | },
99 |
100 | writing: function(props) {
101 | var that = this;
102 | var done = this.async();
103 |
104 | // check if routes file does exist and create it if not
105 | if (that.uiRouter && that.routesFile) {
106 | fs.stat(that.routesFile, function(err, stat) {
107 | // if no route-file exist
108 | if (err) {
109 | that.fs.copyTpl(
110 | that.templatePath('routes' + that.fileExt.script),
111 | that.destinationPath(that.routesFile),
112 | that
113 | );
114 | that.log.writeln(chalk.yellow('Creating routes file at ' + that.routesFile + ' as none was present at the specified location'));
115 | that.injectIntoRoutesFile = true;
116 | done();
117 | } else {
118 | that.injectIntoRoutesFile = true;
119 | done();
120 | }
121 | });
122 | } else {
123 | this.log.writeln(chalk.yellow('No routes file provided in config or injection deactivated'));
124 | done();
125 | }
126 | },
127 |
128 | install: function() {
129 | // SOMEWHAT HACKY, but not possible otherwise to run
130 | // after file creation due to how the run queue works
131 | // @see http://yeoman.io/authoring/running-context.html
132 |
133 | if (this.injectIntoRoutesFile) {
134 | this.log.writeln(chalk.yellow('injecting state into ' + this.routesFile));
135 |
136 | var routeUrl = '/' + this.formatNamePath(this.name),
137 | tplUrl = this.tplUrl,
138 | ctrl = !!this.createController && this.classedName + (this.subGenerators.controller.nameSuffix || '');
139 |
140 | helper.injectRoute(
141 | this.routesFile,
142 | this.stateName,
143 | routeUrl,
144 | tplUrl,
145 | ctrl,
146 | this
147 | );
148 | }
149 | }
150 | });
151 |
--------------------------------------------------------------------------------
/s/index.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 | var ScriptBase = require('../sub-generator-base.js');
3 |
4 | module.exports = ScriptBase.extend({
5 | initializing: function() {
6 | // needs to be called manually
7 | this.init();
8 | },
9 | createFactoryFiles: function createFactoryFiles() {
10 | this.generateSourceAndTest('service');
11 | }
12 | });
--------------------------------------------------------------------------------
/sub-generator-base.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 | var path = require('path');
3 | var yeoman = require('yeoman-generator');
4 | var defaultSettings = require('./default-settings.js');
5 | var helper = require('./helper.js');
6 | var chalk = require('chalk');
7 | var fs = require('fs');
8 | var _s = require('underscore.string');
9 | var _ = require('lodash');
10 |
11 | module.exports = yeoman.Base.extend({
12 | constructor: function() {
13 | // super constructor needs to be called manually
14 | // as the constructor-function is overwritten by this
15 | yeoman.Base.apply(this, arguments);
16 | this.argument('name', {type: String, required: true});
17 |
18 | // define global options
19 | this.option('useDefaults');
20 | this.option('openInEditor');
21 | this.option('noParentFolder');
22 | this.option('skipInject');
23 |
24 | // define arguments
25 | this.argument('targetFolder', {
26 | type: String,
27 | required: false,
28 | description: 'The path of the parent module. Strips app and scripts folders'
29 | });
30 |
31 |
32 | // set all the different name versions to be used in the templates
33 | this.setModuleNames(this.name);
34 |
35 | // set app name
36 | this.setAppVariables();
37 |
38 |
39 | // set sources root (for file-templates)
40 | var sourceRoot = '/templates/app';
41 | this.sourceRoot(path.join(__dirname, sourceRoot));
42 |
43 | // additional variables
44 | this.createdFiles = [];
45 |
46 | // init here, although its double the trouble for now
47 | //this.mergeConfig();
48 | },
49 |
50 | /**
51 | * parent initialize function, inherited by sub-gens
52 | */
53 | init: function() {
54 | this.mergeConfig();
55 | this.overWriteTplPathIfSet();
56 | },
57 |
58 | /**
59 | * helper function to merge default settings with the ones
60 | * provided by the .yo-rc.json
61 | */
62 | mergeConfig: function() {
63 | // get either default or from config
64 |
65 | // create a clone to avoid testing issues
66 | var defaultCfg = _.cloneDeep(defaultSettings);
67 | _.merge(defaultCfg, this.config.getAll());
68 | _.merge(this, defaultCfg);
69 | },
70 |
71 | /**
72 | * allows overwriting of the template path of the generator
73 | * so users can specifiy their own template path
74 | */
75 | overWriteTplPathIfSet: function() {
76 | if (this.customTemplatesPath) {
77 | if (fs.existsSync(this.customTemplatesPath)) {
78 | this.sourceRoot(this.customTemplatesPath);
79 | } else {
80 | throw (new Error('custom template path ' + this.customTemplatesPath + ' does not exist. Check your .yo-rc.json.'));
81 | }
82 | }
83 | },
84 |
85 | /**
86 | * set the app variables, e.g. the name of the app in the
87 | * different required formats such as camelized or slugified
88 | */
89 | setAppVariables: function() {
90 | // define app name variables
91 | var bowerJson = {};
92 | try {
93 | bowerJson = require(path.join(process.cwd(), 'bower.json'));
94 | } catch (e) {
95 | }
96 | if (bowerJson.name) {
97 | this.appname = bowerJson.name;
98 | } else {
99 | this.appname = path.basename(process.cwd());
100 | }
101 | this.appname = _s.camelize(_s.slugify(_s.humanize(this.appname)));
102 | this.scriptAppName = bowerJson.moduleName || this.appname;
103 |
104 | // define app path variable
105 | if (typeof this.env.options.appPath === 'undefined') {
106 | this.env.options.appPath = this.options.appPath || bowerJson.appPath || 'app';
107 | this.options.appPath = this.env.options.appPath;
108 | }
109 | },
110 |
111 | /**
112 | * sets all the different name versions to be used in the templates
113 | */
114 | setModuleNames: function(name) {
115 | this.cameledName = _s.camelize(name);
116 | this.classedName = _s.classify(name);
117 | this.sluggedName = _s.slugify(name);
118 | this.dashedName = _s.dasherize(name);
119 | this.humanizedName = _s.humanize(name);
120 | },
121 |
122 | /**
123 | * helper function to get rid of potential parent paths
124 | * @param path{string}
125 | * @returns {string}
126 | */
127 | cleanUpPath: function(path) {
128 | path = path
129 | .replace(this.dirs.appModules, '')
130 | .replace(this.dirs.app, '');
131 | return path;
132 | },
133 |
134 | /**
135 | * helper function to format the path names to the preferred
136 | * style as configured in the .yo-rc.json
137 | * @param name{string}
138 | * @returns {string}
139 | */
140 | formatNamePath: function(name) {
141 | var style = this.config.get('pathOutputStyle') || 'dasherize';
142 | return _s[style](name);
143 | },
144 |
145 | /**
146 | *
147 | * @returns {string}
148 | */
149 | defineTargetFolder: function() {
150 | var realTargetFolder;
151 |
152 | // allow creating sub-modules via reading and parsing the path argument
153 | if (this.targetFolder) {
154 | this.targetFolder = this.cleanUpPath(this.targetFolder);
155 | realTargetFolder = path.join(this.targetFolder);
156 | } else {
157 |
158 | if (this.curGenCfg.globalDir) {
159 | realTargetFolder = this.curGenCfg.globalDir;
160 | } else {
161 | realTargetFolder = '.'
162 | }
163 | }
164 |
165 | // check if a same named parent directory should be created
166 | // for directives and routes
167 | if (this.curGenCfg.createDirectory && !this.options.noParentFolder) {
168 | realTargetFolder = path.join(realTargetFolder, this.formatNamePath(this.name));
169 | }
170 |
171 | return realTargetFolder;
172 | },
173 |
174 | /**
175 | * main file-creation pipeline function
176 | * @param templateName
177 | */
178 | generateSourceAndTest: function(templateName) {
179 | this.templateName = templateName;
180 | this.curGenCfg = this.subGenerators[templateName];
181 |
182 | var realTargetFolder = this.defineTargetFolder(),
183 | filesToCreate = [];
184 |
185 | // create file paths
186 | var inAppPath = path.join(this.dirs.appModules, realTargetFolder);
187 | var generatorTargetPath = path.join(this.env.options.appPath, inAppPath);
188 | var standardFileName = (this.curGenCfg.prefix || '') + this.formatNamePath(this.name) + (this.curGenCfg.suffix || '');
189 |
190 | // prepare template template and data
191 | if (this.createTemplate) {
192 | this.tplUrl = path.join(inAppPath, standardFileName + this.fileExt.tpl)
193 | // windows fix for url path
194 | .replace(/\\/g, '/');
195 | filesToCreate.push({
196 | tpl: this.templateName + this.fileExt.tpl,
197 | targetFileName: standardFileName + this.fileExt.tpl
198 | });
199 | filesToCreate.push({
200 | tpl: this.stylePrefix + this.templateName + this.fileExt.style,
201 | targetFileName: this.stylePrefix + standardFileName + this.fileExt.style
202 | });
203 | } else {
204 | // needs to be set for the _s.templates to work
205 | this.tplUrl = false;
206 | }
207 |
208 | // run create service or factory if option is given
209 | if (this.createService === 'service' || this.createService === 'factory') {
210 | // add service to queue
211 | this.svcName = this.classedName;
212 |
213 | // add service or factory to queue
214 | filesToCreate.push({
215 | tpl: this.createService + this.fileExt.script,
216 | targetFileName: this.formatNamePath(this.name) + (this.subGenerators[this.createService].suffix || '') + this.fileExt.script,
217 | gen: this.createService
218 | });
219 | // add service test to queue
220 | filesToCreate.push({
221 | tpl: this.createService + this.testSuffix + this.fileExt.script,
222 | targetFileName: this.formatNamePath(this.name) + (this.subGenerators[this.createService].suffix || '') + this.testSuffix + this.fileExt.script,
223 | gen: this.createService
224 | });
225 | }
226 |
227 | if (!this.skipMainFiles) {
228 | // add main file to queue
229 | filesToCreate.push({
230 | tpl: templateName + this.fileExt.script,
231 | targetFileName: standardFileName + this.fileExt.script
232 | });
233 |
234 | // add test file to queue
235 | filesToCreate.push({
236 | tpl: templateName + this.testSuffix + this.fileExt.script,
237 | targetFileName: standardFileName + this.testSuffix + this.fileExt.script
238 | });
239 | }
240 |
241 | // create files and create a files array for further use
242 | for (var i = 0; i < filesToCreate.length; i++) {
243 | var fileToCreate = filesToCreate[i];
244 | var outputFile = path.join(generatorTargetPath, fileToCreate.targetFileName);
245 | var customYoRcTpl = this.getCustomTplFromYoRc(fileToCreate);
246 |
247 | // add to created files array
248 | this.createdFiles.push(outputFile);
249 |
250 | // set name suffix accordingly to template
251 | if (fileToCreate.gen) {
252 | this.nameSuffix = fileToCreate.gen.nameSuffix || '';
253 | } else {
254 | this.nameSuffix = this.curGenCfg.nameSuffix || '';
255 | }
256 |
257 |
258 | if (customYoRcTpl) {
259 | this.writeCustomYoRcTpl(customYoRcTpl, outputFile);
260 | } else {
261 | this.fs.copyTpl(
262 | this.templatePath(fileToCreate.tpl),
263 | this.destinationPath(outputFile),
264 | this
265 | );
266 | }
267 | }
268 | this.afterFileCreationHook();
269 | },
270 |
271 | /**
272 | * checks for custom templates defined in the .yo-rc.json
273 | * if set they will be used instead of the default ones
274 | * @param fileToCreate
275 | * @returns {string}
276 | */
277 | getCustomTplFromYoRc: function(fileToCreate) {
278 | var customYoRcTpl;
279 | var curGenCfg = null;
280 | var SPEC_REG_EX = new RegExp(this.testSuffix + '\\' + this.fileExt.script + '$');
281 | var SCRIPTS_REG_EX = new RegExp(this.fileExt.script + '$');
282 | var TPL_REG_EX = new RegExp(this.fileExt.tpl + '$');
283 | var STYLE_REG_EX = new RegExp(this.fileExt.style + '$');
284 |
285 | if (fileToCreate.gen) {
286 | curGenCfg = this.subGenerators[fileToCreate.gen];
287 | } else {
288 | curGenCfg = this.curGenCfg;
289 | }
290 |
291 | // WHY is this necessary??
292 | if (curGenCfg.tpl) {
293 | if (fileToCreate.tpl.match(SPEC_REG_EX)) {
294 | customYoRcTpl = curGenCfg.tpl['spec'];
295 | } else if (fileToCreate.tpl.match(SCRIPTS_REG_EX)) {
296 | customYoRcTpl = curGenCfg.tpl['script'];
297 | } else if (fileToCreate.tpl.match(TPL_REG_EX)) {
298 | customYoRcTpl = curGenCfg.tpl['tpl'];
299 | } else if (fileToCreate.tpl.match(STYLE_REG_EX)) {
300 | customYoRcTpl = curGenCfg.tpl['style'];
301 | }
302 |
303 | if (customYoRcTpl && typeof customYoRcTpl === 'string') {
304 | return customYoRcTpl;
305 | }
306 | }
307 | },
308 |
309 | /**
310 | * helper function used to create files by using the custom
311 | * template string and underscores templating language
312 | * @param customYoRcTpl{string}
313 | * @param targetDir{string}
314 | */
315 | writeCustomYoRcTpl: function(customYoRcTpl, targetDir) {
316 | var tpl = _.template(customYoRcTpl, {})(this);
317 | this.fs.write(targetDir, tpl);
318 | },
319 |
320 | /**
321 | * things done after all files are created
322 | */
323 | afterFileCreationHook: function() {
324 | // run favorite ide (first to smooth the experiance)
325 | if (this.options.openInEditor) {
326 | this.spawnCommand(this.editorCommand, this.createdFiles);
327 | }
328 |
329 | // inject all files after creation
330 | if (!this.options.skipInject) {
331 | this.spawnCommand('gulp', ['injectAll']);
332 | }
333 | }
334 | });
335 |
336 |
337 |
--------------------------------------------------------------------------------
/templates/app/_app.js:
--------------------------------------------------------------------------------
1 | /**
2 | * @ngdoc overview
3 | * @name <%= scriptAppName %>
4 | * @description
5 | * # <%= scriptAppName %>
6 | *
7 | * Main module of the application.
8 | */
9 |
10 | (() => {
11 | 'use strict';
12 |
13 | angular
14 | .module('<%= scriptAppName %>', [<%- angularModules %>]);
15 | })();
--------------------------------------------------------------------------------
/templates/app/_app.spec.js:
--------------------------------------------------------------------------------
1 | describe('<%= scriptAppName %>', () => {
2 | 'use strict';
3 |
4 | beforeEach(module('<%= scriptAppName %>'));
5 |
6 | it('should always work', () => {
7 | expect(true)
8 | .toBe(true);
9 | });
10 | });
11 |
--------------------------------------------------------------------------------
/templates/app/_component.scss:
--------------------------------------------------------------------------------
1 | <%=sluggedName %> {
2 |
3 | }
--------------------------------------------------------------------------------
/templates/app/_controller.scss:
--------------------------------------------------------------------------------
1 | .page-<%=sluggedName %> {
2 |
3 | }
--------------------------------------------------------------------------------
/templates/app/_directive.scss:
--------------------------------------------------------------------------------
1 | <%=sluggedName %> {
2 |
3 | }
--------------------------------------------------------------------------------
/templates/app/component.html:
--------------------------------------------------------------------------------
1 | This is the <%= cameledName %> component.
2 |
3 |
--------------------------------------------------------------------------------
/templates/app/component.js:
--------------------------------------------------------------------------------
1 | /**
2 | * @ngdoc component
3 | * @name <%= scriptAppName %>.component:<%= cameledName %><%= nameSuffix %>
4 | * @description
5 | * # <%= cameledName %><%= nameSuffix %>
6 | */
7 |
8 | (() => {
9 | 'use strict';
10 |
11 | class <%= classedName %><%= nameSuffix %>Ctrl {
12 | /* @ngInject */
13 | constructor(<% if(createService) {%><%= svcName %><% } %>){
14 | }
15 | }
16 |
17 | angular
18 | .module('<%= scriptAppName %>')
19 | .component('<%= cameledName %><%= nameSuffix %>', {<% if(tplUrl) {%>
20 | templateUrl: '<%= tplUrl %>',<% } %>
21 | controller: <%= classedName %><%= nameSuffix %>Ctrl,
22 | controllerAs: '$ctrl',
23 | bindToController: {
24 | },
25 | });
26 |
27 | // hacky fix for ff
28 | <%= classedName %><%= nameSuffix %>Ctrl.$$ngIsClass = true;
29 | })();
30 |
--------------------------------------------------------------------------------
/templates/app/component.spec.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | describe('Component: <%= cameledName %><%= nameSuffix %>', () => {
4 |
5 | // load the directive's module
6 | beforeEach(module('<%= scriptAppName %>'));
7 | beforeEach(module('templates'));
8 |
9 | let element;
10 | let scope;
11 |
12 | beforeEach(inject(($rootScope) => {
13 | scope = $rootScope.$new();
14 | }));
15 |
16 | it('should do something', inject(($compile) => {
17 | element = $compile('<<%= dashedName %>><%= dashedName %>>')(scope);
18 | scope.$digest();
19 | expect(true).toBe(<%= testPassOnDefault %>);
20 | }));
21 | });
--------------------------------------------------------------------------------
/templates/app/controller.html:
--------------------------------------------------------------------------------
1 |
2 |
This is the <%= classedName %> view
3 |
4 |
--------------------------------------------------------------------------------
/templates/app/controller.js:
--------------------------------------------------------------------------------
1 | /**
2 | * @ngdoc function
3 | * @name <%= scriptAppName %>.controller:<%= classedName %><%= nameSuffix %>
4 | * @description
5 | * # <%= classedName %><%= nameSuffix %>
6 | * Controller of the <%= scriptAppName %>
7 | */
8 |
9 | (() => {
10 | 'use strict';
11 |
12 | class <%= classedName %><%= nameSuffix %> {
13 | /* @ngInject */
14 | constructor(<% if(createService) {%><%= svcName %><% } %>){
15 | }
16 | }
17 |
18 | angular
19 | .module('<%= scriptAppName %>')
20 | .controller('<%= classedName %><%= nameSuffix %>', <%= classedName %><%= nameSuffix %>);
21 |
22 | // hacky fix for ff
23 | <%= classedName %><%= nameSuffix %>.$$ngIsClass = true;
24 |
25 | })();
26 |
--------------------------------------------------------------------------------
/templates/app/controller.spec.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | describe('Controller: <%= classedName %><%= nameSuffix %>', () => {
4 |
5 | // load the controller's module
6 | beforeEach(module('<%= scriptAppName %>'));
7 |
8 | let <%= classedName %><%= nameSuffix %>;
9 | let scope;
10 |
11 | // Initialize the controller and a mock scope
12 | beforeEach(inject(($controller, $rootScope) => {
13 | scope = $rootScope.$new();
14 | <%= classedName %><%= nameSuffix %> = $controller('<%= classedName %><%= nameSuffix %>', {
15 | $scope: scope
16 | // place mocked dependencies here
17 | });
18 | }));
19 |
20 | it('should ...', () => {
21 | expect(true).toBe(<%= testPassOnDefault %>);
22 | });
23 | });
--------------------------------------------------------------------------------
/templates/app/decorator.js:
--------------------------------------------------------------------------------
1 | /**
2 | * @ngdoc function
3 | * @name <%= scriptAppName %>.decorator:<%= classedName %><%= nameSuffix %>
4 | * @description
5 | * # <%= classedName %><%= nameSuffix %>
6 | * Decorator of the <%= scriptAppName %>
7 | */
8 |
9 | (() => {
10 | 'use strict';
11 |
12 | angular
13 | .module('<%= scriptAppName %>')
14 | .config(<%= classedName %><%= nameSuffix %>);
15 |
16 | function <%= classedName %><%= nameSuffix %>($provide) {
17 | $provide.decorator('<%= classedName %>', ($delegate) => {
18 | return $delegate;
19 | });
20 | }
21 | })();
22 |
--------------------------------------------------------------------------------
/templates/app/decorator.spec.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | describe('Decorator: <%= classedName %><%= nameSuffix %>', () => {
4 | // load the service's module
5 | beforeEach(module('<%= scriptAppName %>'));
6 |
7 | // instantiate service
8 | let <%= classedName %><%= nameSuffix %>;
9 | beforeEach(inject(function (_<%= classedName %><%= nameSuffix %>_) {
10 | <%= classedName %><%= nameSuffix %> = _<%= classedName %><%= nameSuffix %>_;
11 | }));
12 |
13 | it('should be defined', () => {
14 | expect(true).toBe(<%= testPassOnDefault %>);
15 | });
16 |
17 | });
--------------------------------------------------------------------------------
/templates/app/directive.html:
--------------------------------------------------------------------------------
1 | This is the <%= cameledName %> directive.
2 |
3 |
--------------------------------------------------------------------------------
/templates/app/directive.js:
--------------------------------------------------------------------------------
1 | /**
2 | * @ngdoc directive
3 | * @name <%= scriptAppName %>.directive:<%= cameledName %><%= nameSuffix %>
4 | * @description
5 | * # <%= cameledName %><%= nameSuffix %>
6 | */
7 |
8 | (() => {
9 | 'use strict';
10 |
11 | class <%= classedName %><%= nameSuffix %>Ctrl {
12 | /* @ngInject */
13 | constructor(<% if(createService) {%><%= svcName %><% } %>){
14 | }
15 | }
16 |
17 | angular
18 | .module('<%= scriptAppName %>')
19 | .directive('<%= cameledName %><%= nameSuffix %>', {<% if(tplUrl) {%>
20 | templateUrl: '<%= tplUrl %>',<% } %>
21 | bindToController: {
22 | },
23 | controller: <%= classedName %><%= nameSuffix %>Ctrl,
24 | controllerAs: '$ctrl',
25 | restrict: 'A',
26 | scope: true
27 | });
28 |
29 | // hacky fix for ff
30 | <%= classedName %><%= nameSuffix %>Ctrl.$$ngIsClass = true;
31 | })();
32 |
--------------------------------------------------------------------------------
/templates/app/directive.spec.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | describe('Directive: <%= cameledName %><%= nameSuffix %>', () => {
4 |
5 | // load the directive's module
6 | beforeEach(module('<%= scriptAppName %>'));
7 | beforeEach(module('templates'));
8 |
9 | let element;
10 | let scope;
11 |
12 | beforeEach(inject(($rootScope) => {
13 | scope = $rootScope.$new();
14 | }));
15 |
16 | it('should do something', inject(($compile) => {
17 | element = $compile('<<%= dashedName %>><%= dashedName %>>')(scope);
18 | scope.$digest();
19 | expect(true).toBe(<%= testPassOnDefault %>);
20 | }));
21 | });
--------------------------------------------------------------------------------
/templates/app/factory.js:
--------------------------------------------------------------------------------
1 | /**
2 | * @ngdoc factory
3 | * @name <%= scriptAppName %>.<%= classedName %><%= nameSuffix %>
4 | * @description
5 | * # <%= classedName %><%= nameSuffix %>
6 | * Factory in the <%= scriptAppName %>.
7 | */
8 |
9 | (() => {
10 | 'use strict';
11 |
12 | class <%= classedName %><%= nameSuffix %> {
13 | /* @ngInject */
14 | constructor(){
15 | }
16 | }
17 |
18 | angular
19 | .module('<%= scriptAppName %>')
20 | .factory('<%= classedName %><%= nameSuffix %>', <%= classedName %><%= nameSuffix %>);
21 |
22 | // hacky fix for ff
23 | <%= classedName %><%= nameSuffix %>.$$ngIsClass = true;
24 | })();
25 |
--------------------------------------------------------------------------------
/templates/app/factory.spec.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | describe('Factory: <%= classedName %><%= nameSuffix %>', () => {
4 | // load the service's module
5 | beforeEach(module('<%= scriptAppName %>'));
6 |
7 | // instantiate service
8 | let <%= classedName %><%= nameSuffix %>;
9 | beforeEach(inject((_<%= classedName %><%= nameSuffix %>_) => {
10 | <%= classedName %><%= nameSuffix %> = _<%= classedName %><%= nameSuffix %>_;
11 | }));
12 |
13 | it('should be defined', () => {
14 | expect(true).toBe(<%= testPassOnDefault %>);
15 | });
16 |
17 | });
--------------------------------------------------------------------------------
/templates/app/filter.js:
--------------------------------------------------------------------------------
1 | /**
2 | * @ngdoc filter
3 | * @name <%= scriptAppName %>.filter:<%= cameledName %><%= nameSuffix %>
4 | * @function
5 | * @description
6 | * # <%= cameledName %><%= nameSuffix %>
7 | * Filter in the <%= scriptAppName %>.
8 | */
9 |
10 | (() => {
11 | 'use strict';
12 |
13 | angular
14 | .module('<%= scriptAppName %>')
15 | .filter('<%= cameledName %><%= nameSuffix %>', <%= cameledName %><%= nameSuffix %>);
16 |
17 | function <%= cameledName %><%= nameSuffix %>() {
18 | return (parameters) => {
19 | return parameters;
20 | }
21 | }
22 | })();
23 |
--------------------------------------------------------------------------------
/templates/app/filter.spec.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | describe('Filter: <%= cameledName %><%= nameSuffix %>', () => {
4 |
5 | // load the filter's module
6 | beforeEach(module('<%= scriptAppName %>'));
7 |
8 | // initialize a new instance of the filter before each test
9 | let <%= cameledName %><%= nameSuffix %>;
10 | beforeEach(inject(($filter) => {
11 | <%= cameledName %><%= nameSuffix %> = $filter('<%= cameledName %><%= nameSuffix %>');
12 | }));
13 |
14 | it('should change some output:"', () => {
15 | // var text = 'angularjs';
16 | // expect(<%= cameledName %><%= nameSuffix %>(text)).toBe('something else');
17 | expect(true).toBe(<%= testPassOnDefault %>);
18 |
19 | });
20 |
21 | });
--------------------------------------------------------------------------------
/templates/app/provider.js:
--------------------------------------------------------------------------------
1 | /**
2 | * @ngdoc provider
3 | * @name <%= scriptAppName %>.<%= classedName %><%= nameSuffix %>
4 | * @description
5 | * # <%= classedName %><%= nameSuffix %>
6 | * Provider in the <%= scriptAppName %>.
7 | */
8 |
9 | (() => {
10 | 'use strict';
11 |
12 | let config;
13 |
14 | // Private constructor-function aka factory definition
15 | class <%= classedName %><%= nameSuffix %> {
16 | /* @ngInject */
17 | constructor() {
18 | }
19 |
20 | someServiceFunction() {
21 | };
22 | }
23 |
24 | class <%= classedName %><%= nameSuffix %>Provider {
25 | /* @ngInject */
26 | constructor() {
27 | config = {};
28 | }
29 |
30 | // PROVIDER-FUNCTIONS
31 | extendConfig(additionalConfig) {
32 | config = angular.extend(config, additionalConfig);
33 | }
34 |
35 | // return service definition
36 | $get() {
37 | return new <%= classedName %><%= nameSuffix %>();
38 | }
39 | }
40 |
41 | angular
42 | .module('<%= scriptAppName %>')
43 | .provider('<%= classedName %><%= nameSuffix %>', <%= classedName %><%= nameSuffix %>Provider);
44 |
45 | // hacky fix for ff
46 | <%= classedName %><%= nameSuffix %>Provider.$$ngIsClass = true;
47 | <%= classedName %><%= nameSuffix %>.$$ngIsClass = true;
48 | })();
--------------------------------------------------------------------------------
/templates/app/provider.spec.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | describe('Provider: <%= classedName %><%= nameSuffix %>', () => {
4 | // load the service's module
5 | let provider;
6 |
7 | beforeEach(module('<%= scriptAppName %>', (<%= classedName %><%= nameSuffix %>Provider) => {
8 | provider = <%= classedName %><%= nameSuffix %>Provider;
9 | }));
10 |
11 | // instantiate service-function
12 | let <%= classedName %><%= nameSuffix %>;
13 | beforeEach(inject(function (_<%= classedName %><%= nameSuffix %>_) {
14 | <%= classedName %><%= nameSuffix %> = _<%= classedName %><%= nameSuffix %>_;
15 | }));
16 |
17 | it('should be defined', () => {
18 | // provider.extendConfig({});
19 | expect(true).toBe(<%= testPassOnDefault %>);
20 | });
21 |
22 | });
--------------------------------------------------------------------------------
/templates/app/routes.js:
--------------------------------------------------------------------------------
1 | /**
2 | * @ngdoc overview
3 | * @name <%= scriptAppName %>.routes
4 | * @description
5 | * # <%= scriptAppName %>.routes
6 | *
7 | * Routes module. All app states are defined here.
8 | */
9 |
10 | (() => {
11 | 'use strict';
12 |
13 | angular
14 | .module('<%= scriptAppName %>')
15 | .config(routerHelperProvider);
16 |
17 | /* @ngInject */
18 | function routerHelperProvider($stateProvider, $urlRouterProvider) {
19 |
20 | $urlRouterProvider.otherwise('/');
21 |
22 | $stateProvider
23 | .state('home', {
24 | url: '/',
25 | template: 'Hello!
All clean here, as intended! Why not build some routes via "yo moda:r my-route"?
'
26 | })
27 | /* STATES-NEEDLE - DO NOT REMOVE THIS */;
28 | }
29 | })();
30 |
--------------------------------------------------------------------------------
/templates/app/routes.spec.js:
--------------------------------------------------------------------------------
1 | describe('<%= scriptAppName %>.routes', () => {
2 | 'use strict';
3 |
4 | beforeEach(module('<%= scriptAppName %>'));
5 |
6 | it('should be defined', () => {
7 | expect(true)
8 | .toBe(true);
9 | });
10 | });
--------------------------------------------------------------------------------
/templates/app/service.js:
--------------------------------------------------------------------------------
1 | /**
2 | * @ngdoc service
3 | * @name <%= scriptAppName %>.<%= classedName %><%= nameSuffix %>
4 | * @description
5 | * # <%= classedName %><%= nameSuffix %>
6 | * Service in the <%= scriptAppName %>.
7 | */
8 |
9 | (() => {
10 | 'use strict';
11 |
12 | class <%= classedName %><%= nameSuffix %> {
13 | /* @ngInject */
14 | constructor(){
15 | }
16 | }
17 |
18 | angular
19 | .module('<%= scriptAppName %>')
20 | .service('<%= classedName %><%= nameSuffix %>', <%= classedName %><%= nameSuffix %>);
21 |
22 | // hacky fix for ff
23 | <%= classedName %><%= nameSuffix %>.$$ngIsClass = true;
24 | })();
25 |
--------------------------------------------------------------------------------
/templates/app/service.spec.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | describe('Service: <%= classedName %><%= nameSuffix %>', () => {
4 | // load the service's module
5 | beforeEach(module('<%= scriptAppName %>'));
6 |
7 | // instantiate service
8 | let <%= classedName %><%= nameSuffix %>;
9 | beforeEach(inject((_<%= classedName %><%= nameSuffix %>_) => {
10 | <%= classedName %><%= nameSuffix %> = _<%= classedName %><%= nameSuffix %>_;
11 | }));
12 |
13 | it('should be defined', () => {
14 | expect(true).toBe(<%= testPassOnDefault %>);
15 | });
16 |
17 | });
--------------------------------------------------------------------------------
/templates/e2e-tests/example.e2e.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | describe('The home view', function ()
4 | {
5 | var page;
6 |
7 | beforeEach(function ()
8 | {
9 | browser.get('http://localhost:3000/index.html');
10 | page = require('./home.po');
11 | });
12 |
13 | it('runs e2e tests', function ()
14 | {
15 | expect(page.body.count()).toBeGreaterThan(1);
16 | });
17 |
18 | });
19 |
--------------------------------------------------------------------------------
/templates/e2e-tests/po/home.po.js:
--------------------------------------------------------------------------------
1 | /**
2 | * This file uses the Page Object pattern
3 | * @see https://docs.google.com/presentation/d/1B6manhG0zEXkC-H-tPo2vwU06JhL8w9-XCF9oehXzAQ
4 | */
5 |
6 | 'use strict';
7 |
8 | var MainPage = function ()
9 | {
10 | this.body = element(by.css('body'));
11 | };
12 |
13 | MainPage.prototype.goTo = function ()
14 | {
15 | return browser.get('/');
16 | };
17 |
18 | module.exports = new MainPage();
19 |
--------------------------------------------------------------------------------
/templates/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | <%= humanizedAppName %>
5 |
6 |
8 |
10 |
12 |
14 |
15 |
19 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
33 |
34 |
35 |
36 |
37 |
38 | <% if (ngRoute) {
39 | %><%
40 | } %><% if (uiRouter) {
41 | %><% } %>
42 |
43 |
44 |
48 |
49 |
50 |
51 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
--------------------------------------------------------------------------------
/templates/root/README.md:
--------------------------------------------------------------------------------
1 | # <%= appname %>
2 |
3 | This project was generated with [yo angular modular generator](https://github.com/johannesjo/generator-modular-angular)
4 | version <%= pkg.version %>.
5 |
6 | ## Build & development
7 |
8 | Run `gulp` for development, `gulp build` for building and `gulp buildCordova` for building the hybrid-app.
9 |
10 | ## Testing
11 |
12 | Unit tests are automatically run with the default task. End-to-End tests are run via `gulp e2e`.
13 |
14 | ## The gulp tasks
15 | As per default the following tasks are available at your convenience:
16 |
17 | * `gulp`: The development task. Runs all the injectors on file-change, file-creation or file-deletion. Unit-tests are run in parallel, as well as the sass-compilation.
18 | * `gulp injectAll`: Runs all the injectors once.
19 | * `gulp build`: Minifies your JavaScript via ng-annotate, your css, your images and your html files and copies everything to the www-folder.
20 | * `gulp test`: Runs your unit tests with the keep-alive option.
21 | * `gulp testSingle`: Runs your unit tests once.
22 | * `gulp e2e`: Runs your end to end tests once.
23 |
24 | The mobile tasks require a little preparation described in the next section.
25 |
26 | * `gulp cordovaDev`: Symlinks your app-folder to www and runs the emulator for easy live development.
27 | * `gulp cordovaRun`: Symlinks your app-folder to www and runs it on your device if connected.
28 |
29 | Of course there are also all the [standard cordova commands](https://cordova.apache.org/docs/en/4.0.0/guide_cli_index.md.html) available as well. If you want to build a release run:
30 | ```
31 | gulp build
32 | cordova build android --release
33 | ```
34 |
35 | For all cordova related commands there is an optional platform parameter you can use to specify the platform for the cordova task. E.g. `gulp cordovaDev --platform=android` to run the android emulator. Alternatively you can edit the config.js to change the default platform.
36 |
37 | All tasks can be edited freely and can be found in the /tasks folder.
38 |
39 | ## Setting up the hybrid build
40 | Compiling your app to a hybrid app requires a little bit of configuration and you need to have cordova installed. Fortunately [that is quite easy](http://cordova.apache.org/docs/en/4.0.0/guide_cli_index.md.html#The%20Command-Line%20Interface).
41 |
42 | If everything is in place, you need to add the platforms you want to build your app on. For Android you would run:
43 | ```
44 | cordova platform add android
45 | ```
46 | If you get the message `Current working directory is not a Cordova-based project` you need to create the www-folder first (e.g.: `mkdir www` from your projects root directory).
47 |
48 | After that you should build your current state via `gulp build` then you can run `gulp run` or `gulp emulate` to check out your app on your device or in the emulator.
--------------------------------------------------------------------------------
/templates/root/_bower.json:
--------------------------------------------------------------------------------
1 | {<% var ngVer = "1.6.6" %>
2 | "name": "<%= slugAppName %>",
3 | "version": "0.0.0",
4 | "authors": [
5 | ],
6 | "license": "none",
7 | "private": true,
8 | "ignore": [
9 | "**/.*",
10 | "node_modules",
11 | "bower_components",
12 | "test",
13 | "tests"
14 | ],
15 | "dependencies": {
16 | "json3": "latest",
17 | "es5-shim": "latest",
18 | "animate.css-scss": "latest",
19 | "angular": "^<%= ngVer %>"<% if (animateModule) { %>,
20 | "angular-animate": "^<%= ngVer %>"<% } %><% if (ariaModule) { %>,
21 | "angular-aria": "^<%= ngVer %>"<% } %><% if (cookiesModule) { %>,
22 | "angular-cookies": "^<%= ngVer %>"<% } %><% if (messagesModule) { %>,
23 | "angular-messages": "^<%= ngVer %>"<% } %><% if (resourceModule) { %>,
24 | "angular-resource": "^<%= ngVer %>"<% } %><% if (routeModule) { %>,
25 | "angular-route": "^<%= ngVer %>"<% } %><% if (sanitizeModule) { %>,
26 | "angular-sanitize": "^<%= ngVer %>"<% } %><% if (touchModule) { %>,
27 | "angular-touch": "^<%= ngVer %>"<% } %><% if (uiRouterModule) { %>,
28 | "angular-ui-router": "latest"<% } %><% if (ngMaterialModule) { %>,
29 | "angular-material": "latest"<% } %><% if (ngFabFormModule) { %>,
30 | "ng-fab-form": "latest"<% } %>
31 | },
32 | "devDependencies": {
33 | "angular-mocks": "^<%= ngVer %>"
34 | },
35 | "scripts":{
36 | "postinstall": "gulp wiredep"
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/templates/root/_bowerrc:
--------------------------------------------------------------------------------
1 | {
2 | "directory": "app/bower_components"
3 | }
4 |
--------------------------------------------------------------------------------
/templates/root/_config.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | <%= humanizedAppName %>
4 |
5 | <%= humanizedAppName %> is fabulous
6 |
7 |
8 | Your Name
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/templates/root/_editorconfig:
--------------------------------------------------------------------------------
1 | # EditorConfig helps developers define and maintain consistent
2 | # coding styles between different editors and IDEs
3 | # editorconfig.org
4 |
5 | root = true
6 |
7 |
8 | [*]
9 | charset = utf-8
10 | end_of_line = lf
11 | indent_size = 4
12 | indent_style = space
13 | insert_final_newline = true
14 | trim_trailing_whitespace = true
15 |
16 | [*.md]
17 | trim_trailing_whitespace = false
18 |
19 | [{package.json,bower.json,.travis.yml}]
20 | indent_size = 2
21 |
--------------------------------------------------------------------------------
/templates/root/_gitattributes:
--------------------------------------------------------------------------------
1 | # Automatically normalize line endings for all text-based files
2 | # http://git-scm.com/docs/gitattributes#_end_of_line_conversion
3 | * text=auto
4 |
5 | # For the following file types, normalize line endings to LF on
6 | # checkin and prevent conversion to CRLF when they are checked out
7 | # (this is required in order to prevent newline related issues like,
8 | # for example, after the build script is run)
9 | .* text eol=lf
10 | *.css text eol=lf
11 | *.html text eol=lf
12 | *.js text eol=lf
13 | *.json text eol=lf
14 | *.md text eol=lf
15 | *.sh text eol=lf
16 | *.txt text eol=lf
17 | *.xml text eol=lf
18 |
19 | # Exclude the `.htaccess` file from GitHub's language statistics
20 | # https://github.com/github/linguist#using-gitattributes
21 | dist/.htaccess linguist-vendored
--------------------------------------------------------------------------------
/templates/root/_gitignore:
--------------------------------------------------------------------------------
1 | node_modules
2 | dist
3 | www
4 | platforms
5 | release
6 | .tmp
7 | app/styles/**/*.css
8 | app/styles/**/*.css.map
9 | .sass-cache
10 | bower_components
11 | app/bower_components
12 | *.log
13 |
--------------------------------------------------------------------------------
/templates/root/_gulpfile.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 | // require all task files
3 | var requireDir = require('require-dir');
4 | requireDir('./tasks');
5 |
--------------------------------------------------------------------------------
/templates/root/_jshintrc:
--------------------------------------------------------------------------------
1 | {
2 | "node": true,
3 | "browser": true,
4 | "esnext": true,
5 | "bitwise": true,
6 | "camelcase": true,
7 | "curly": true,
8 | "eqeqeq": true,
9 | "indent": 4,
10 | "latedef": "nofunc",
11 | "noarg": true,
12 | "quotmark": "single",
13 | "undef": true,
14 | "unused": true,
15 | "strict": true,
16 | "trailing": true,
17 | "smarttabs": true,
18 | "globals": {
19 | "angular": false,
20 | "browser": false,
21 | "jasmine": false,
22 | "describe": false,
23 | "xdescribe": false,
24 | "before": false,
25 | "beforeEach": false,
26 | "after": false,
27 | "afterEach": false,
28 | "it": false,
29 | "xit": false,
30 | "it": false,
31 | "inject": false,
32 | "expect": false,
33 | "spyOn": false
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/templates/root/_karma-e2e.conf.js:
--------------------------------------------------------------------------------
1 | // An example configuration file.
2 | 'use strict';
3 |
4 | exports.config = {
5 | // The address of a running selenium server.
6 | seleniumAddress: 'http://localhost:4444/wd/hub',
7 |
8 | // Spec patterns are relative to the current working directly when
9 | // protractor is called.
10 | specs: ['e2e-tests/**/*.js'],
11 |
12 | // Options to be passed to Jasmine-node.
13 | jasmineNodeOpts: {
14 | showColors: true,
15 | defaultTimeoutInterval: 30000,
16 | isVerbose: true
17 | },
18 |
19 | onPrepare: function() {
20 | browser.manage()
21 | .window()
22 | .setSize(1360, 768);
23 | browser.manage()
24 | .timeouts()
25 | .setScriptTimeout(20000);
26 | }
27 | };
28 |
--------------------------------------------------------------------------------
/templates/root/_karma.conf.js:
--------------------------------------------------------------------------------
1 | // Karma configuration
2 | 'use strict';
3 |
4 | module.exports = function(config) {
5 | config.set({
6 | // base path that will be used to resolve all patterns (eg. files, exclude)
7 | basePath: '',
8 |
9 | // frameworks to use
10 | // available frameworks: https://npmjs.org/browse/keyword/karma-adapter
11 | frameworks: ['jasmine'],
12 |
13 |
14 | // list of files / patterns to load in the browser
15 | files: [
16 | // bower:js
17 | // endbower
18 |
19 | // modules first
20 | 'app/scripts/**/_*.js',
21 | // all the rest of the files
22 | 'app/scripts/**/*.js',
23 | // load html as well as required for karma-ng-html2js-preprocessor
24 | 'app/scripts/**/*.html'
25 | ],
26 |
27 |
28 | // list of files to exclude
29 | exclude: [],
30 |
31 |
32 | // web server port
33 | port: 9876,
34 |
35 |
36 | // enable / disable colors in the output (reporters and logs)
37 | colors: true,
38 |
39 |
40 | // level of logging
41 | // possible values: config.LOG_DISABLE || config.LOG_ERROR || config.LOG_WARN || config.LOG_INFO || config.LOG_DEBUG
42 | logLevel: config.LOG_INFO,
43 |
44 | plugins: [
45 | 'karma-jasmine',
46 | //'karma-coverage',
47 | 'karma-phantomjs-launcher',
48 | 'karma-ng-html2js-preprocessor'
49 | ],
50 |
51 | preprocessors: {
52 | //'**/app/scripts/**/!(*spec).js': 'coverage',
53 | '**/app/scripts/**/*.html': 'ng-html2js'
54 | },
55 |
56 | ngHtml2JsPreprocessor: {
57 | moduleName: 'templates',
58 | stripPrefix: 'app/'
59 | },
60 |
61 | // enable / disable watching file and executing tests whenever any file changes
62 | autoWatch: false,
63 |
64 |
65 | // start these browsers
66 | // available browser launchers: https://npmjs.org/browse/keyword/karma-launcher
67 | browsers: ['PhantomJS'],
68 |
69 |
70 | // Continuous Integration mode
71 | // if true, Karma captures browsers, runs the tests and exits
72 | singleRun: true
73 | });
74 | };
75 |
--------------------------------------------------------------------------------
/templates/root/_package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "<%= slugAppName %>",
3 | "version": "0.0.0",
4 | "description": "",
5 | "main": "gulpfile.js",
6 | "repository": {},
7 | "scripts": {
8 | "test": "echo \"Error: no test specified\" && exit 1"
9 | },
10 | "author": "",
11 | "license": "none",
12 | "devDependencies": {
13 | "autoprefixer-core": "latest",
14 | "browser-sync": "latest",
15 | "del": "latest",
16 | "ecstatic": "latest",
17 | "gulp": "latest",
18 | "gulp-autoprefixer": "latest",
19 | "gulp-clean-css": "latest",
20 | "gulp-if": "latest",
21 | "gulp-imagemin": "latest",
22 | "gulp-inject": "latest",
23 | "gulp-jscs": "latest",
24 | "gulp-jshint": "latest",
25 | "gulp-livereload": "latest",
26 | "gulp-minify-html": "latest",
27 | "gulp-natural-sort": "latest",
28 | "gulp-ng-annotate": "latest",
29 | "gulp-ng-config": "latest",
30 | "gulp-plumber": "latest",
31 | "gulp-protractor": "latest",
32 | "gulp-sass": "latest",
33 | "gulp-shell": "latest",
34 | "gulp-sourcemaps": "latest",
35 | "gulp-symlink": "latest",
36 | "gulp-uglify": "latest",
37 | "gulp-useref": "latest",
38 | "gulp-util": "latest",
39 | "gulp-watch": "latest",
40 | "jasmine-core": "latest",
41 | "jshint": "latest",
42 | "jshint-stylish": "latest",
43 | "karma": "latest",
44 | "karma-jasmine": "latest",
45 | "karma-ng-html2js-preprocessor": "latest",
46 | "karma-phantomjs-launcher": "latest",
47 | "lazypipe": "latest",
48 | "merge-stream": "latest",
49 | "node-sass": "latest",
50 | "protractor": "latest",
51 | "phantomjs-prebuilt": "latest",
52 | "require-dir": "latest",
53 | "run-sequence": "latest",
54 | "uglify-save-license": "^0.4.1",
55 | "wiredep": "latest",
56 | "yargs": "latest"
57 | },
58 | "dependencies": {
59 | "cordova-android": "latest"
60 | }
61 | }
62 |
--------------------------------------------------------------------------------
/templates/root/_travis.yml:
--------------------------------------------------------------------------------
1 | language: node_js
2 | node_js:
3 | - '0.10'
4 | before_script:
5 | - 'npm install -g bower grunt-cli'
6 | - 'bower install'
7 |
--------------------------------------------------------------------------------
/templates/styles/_functions/_some-function.scss:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/johannesjo/generator-modular-angular/06e3d19b171ab4beba97cdcfa5c60b9d827c7d7b/templates/styles/_functions/_some-function.scss
--------------------------------------------------------------------------------
/templates/styles/_mixins/_some-mixin.scss:
--------------------------------------------------------------------------------
1 | @mixin some-mixin() {
2 |
3 | }
4 |
--------------------------------------------------------------------------------
/templates/styles/_placeholders/_some-placeholder.scss:
--------------------------------------------------------------------------------
1 | %some-placeholder {
2 |
3 | }
4 |
--------------------------------------------------------------------------------
/templates/styles/_variables.scss:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/johannesjo/generator-modular-angular/06e3d19b171ab4beba97cdcfa5c60b9d827c7d7b/templates/styles/_variables.scss
--------------------------------------------------------------------------------
/templates/styles/base/_buttons.scss:
--------------------------------------------------------------------------------
1 | button {
2 | text-align: center;
3 |
4 | &:hover {
5 |
6 | }
7 | &:active {
8 |
9 | }
10 | &:focus {
11 |
12 | }
13 | }
14 |
--------------------------------------------------------------------------------
/templates/styles/base/_fonts.scss:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/johannesjo/generator-modular-angular/06e3d19b171ab4beba97cdcfa5c60b9d827c7d7b/templates/styles/base/_fonts.scss
--------------------------------------------------------------------------------
/templates/styles/base/_forms.scss:
--------------------------------------------------------------------------------
1 | form {
2 |
3 | }
4 |
5 | fieldset {
6 |
7 | }
8 |
9 | input {
10 | &[type="text"],
11 | &[type="password"],
12 | &[type="email"] {
13 |
14 | }
15 |
16 | &[type="radio"] {
17 |
18 | }
19 |
20 | &[type="checkbox"] {
21 |
22 | }
23 |
24 | &[type="number"] {
25 |
26 | }
27 | }
28 |
29 | select {
30 |
31 | }
32 |
33 | textarea {
34 |
35 | }
36 |
--------------------------------------------------------------------------------
/templates/styles/base/_icons.scss:
--------------------------------------------------------------------------------
1 | [class^="icon-"], [class*=" icon-"] {
2 | font-family: 'icon-font';
3 | speak: none;
4 | font-style: normal;
5 | font-weight: normal;
6 | font-variant: normal;
7 | text-transform: none;
8 | line-height: 1;
9 | /* Better Font Rendering =========== */
10 | -webkit-font-smoothing: antialiased;
11 | -moz-osx-font-smoothing: grayscale;
12 | }
13 |
--------------------------------------------------------------------------------
/templates/styles/base/_lists.scss:
--------------------------------------------------------------------------------
1 | ul {
2 | li {
3 |
4 | }
5 | }
6 |
7 | ol {
8 | li {
9 |
10 | }
11 | }
12 |
--------------------------------------------------------------------------------
/templates/styles/base/_page.scss:
--------------------------------------------------------------------------------
1 | * {
2 | // global reset and border-box
3 | &,
4 | &:after,
5 | &:before {
6 | -webkit-box-sizing: border-box;
7 | -moz-box-sizing: border-box;
8 | box-sizing: border-box;
9 | }
10 | }
11 |
12 | body,
13 | html {
14 | // prevent overflow
15 | width: 100%;
16 | max-width: 100%;
17 | overflow-x: hidden;
18 | }
19 |
20 | main {
21 |
22 | }
23 |
24 | article {
25 |
26 | }
27 |
--------------------------------------------------------------------------------
/templates/styles/base/_tables.scss:
--------------------------------------------------------------------------------
1 | table {
2 |
3 | }
4 |
5 | thead {
6 |
7 | }
8 |
9 | tbody {
10 |
11 | }
12 |
13 | tfoot {
14 |
15 | }
16 |
17 | tr {
18 |
19 | }
20 |
21 | td {
22 |
23 | }
24 |
--------------------------------------------------------------------------------
/templates/styles/base/_typography.scss:
--------------------------------------------------------------------------------
1 | h1,
2 | h2,
3 | h3,
4 | h4,
5 | h5,
6 | h6 {
7 |
8 | }
9 |
10 | p {
11 |
12 | }
13 |
--------------------------------------------------------------------------------
/templates/styles/main.scss:
--------------------------------------------------------------------------------
1 | /*
2 | IMPORTANT NOTE:
3 | This file SHOULD NOT BE EDITED MANUALLY, as its purpose
4 | is to be the point where all your stylesheet-files will
5 | be imported
6 | */
7 |
8 |
9 |
10 | // inject:sass
11 |
12 | @import '_variables.scss';
13 |
14 | @import 'base/_buttons.scss';
15 |
16 | @import 'base/_fonts.scss';
17 |
18 | @import 'base/_forms.scss';
19 |
20 | @import 'base/_icons.scss';
21 |
22 | @import 'base/_lists.scss';
23 |
24 | @import 'base/_page.scss';
25 |
26 | @import 'base/_tables.scss';
27 |
28 | @import 'base/_typography.scss';
29 |
30 | @import 'functions/_some-function.scss';
31 |
32 | @import 'mixins/_some-mixin.scss';
33 |
34 | @import 'placeholders/_some-placeholder.scss';
35 |
36 | // endinject
37 |
--------------------------------------------------------------------------------
/templates/tasks/build.js:
--------------------------------------------------------------------------------
1 | var config = require('./config');
2 | var gulp = require('gulp');
3 |
4 | /**
5 | * Build-Task Files
6 | *
7 | * NOTE: Depends on sme of the dev-tasks as well
8 | */
9 |
10 |
11 | var del = require('del');
12 | var gulpif = require('gulp-if');
13 | var minifyHtml = require('gulp-minify-html');
14 | var cleanCSS = require('gulp-clean-css');
15 | var useref = require('gulp-useref');
16 | var sourcemaps = require('gulp-sourcemaps');
17 | var ngAnnotate = require('gulp-ng-annotate');
18 | var uglify = require('gulp-uglify');
19 | var saveLicense = require('uglify-save-license');
20 | var imagemin = require('gulp-imagemin');
21 | var runSequence = require('run-sequence')
22 | .use(gulp);
23 | var wiredep = require('wiredep').stream;
24 |
25 | var merge = require('merge-stream');
26 | var lazypipe = require('lazypipe');
27 |
28 |
29 | // main task
30 | gulp.task('build', function(callback) {
31 | runSequence(
32 | 'cleanDist',
33 | 'wiredepBuild',
34 | 'injectAll',
35 | 'testSingle',
36 | 'lint',
37 | 'sass',
38 | 'minFiles',
39 | 'copy',
40 | // reset config
41 | //'ngConfig',
42 | callback);
43 | });
44 |
45 | gulp.task('wiredepBuild', function() {
46 | return gulp.src([config.karmaConf, config.mainFile], {base: './'})
47 | .pipe(wiredep({
48 | exclude: [
49 | // TODO inject excluded
50 | ],
51 | devDependencies: false
52 | }))
53 | .pipe(gulp.dest('./'));
54 | });
55 |
56 | gulp.task('cleanDist', function() {
57 | return del.sync(config.dist);
58 | });
59 |
60 |
61 | gulp.task('copy', function() {
62 | var html = gulp.src(config.htmlF, {base: config.base})
63 | .pipe(minifyHtml({
64 | conditionals: true,
65 | loose: true,
66 | empty: true,
67 | quotes: true
68 | }))
69 | .pipe(gulp.dest(config.dist));
70 |
71 | var fonts = gulp.src(config.fontsF, {base: config.base})
72 | .pipe(gulp.dest(config.dist));
73 |
74 | // TODO this ain't perfect
75 | var images = gulp.src(config.imagesF, {base: config.base})
76 | .pipe(imagemin({
77 | progressive: true,
78 | svgoPlugins: [{removeViewBox: false}]
79 | }))
80 | .pipe(gulp.dest(config.dist));
81 |
82 | return merge(html, fonts, images);
83 | });
84 |
85 |
86 | gulp.task('minFiles', function() {
87 | return gulp.src(config.mainFile)
88 | .pipe(useref({}, lazypipe()
89 | .pipe(sourcemaps.init, {loadMaps: true})))
90 | .pipe(gulpif('*.js', ngAnnotate()))
91 | .pipe(gulpif(/\.js$/, uglify({
92 | output: {
93 | comments: saveLicense
94 | }
95 | })))
96 | .pipe(gulpif('*.css', cleanCSS()))
97 | .pipe(gulp.dest(config.dist));
98 | });
99 |
--------------------------------------------------------------------------------
/templates/tasks/config.js:
--------------------------------------------------------------------------------
1 | module.exports = (function() {
2 | 'use strict';
3 |
4 | // config vars
5 | var base = './app';
6 | var scripts = base + '/scripts';
7 | var sass = base + '/styles';
8 |
9 | var data = {
10 | browserSyncPort: 3000,
11 | cordovaPath: 'cordova',
12 | defaultPlatform: 'ios',
13 | excludedBowerComponents: ['es5-shim', 'json3'],
14 | base: base,
15 | mainFile: base + '/index.html',
16 | mainSassFile: sass + '/main.scss',
17 | routesFiles: base + '/scripts/_routes.js',
18 | e2eBaseUrl: 'http://localhost:3000/',
19 | styles: base + '/styles/',
20 | stylesF: [
21 | base + '/styles/**/_*.{scss,sass,less}',
22 | scripts + '/**/*.{scss,sass,less}'
23 | ],
24 | stylesAllF: [
25 | base + '/styles/**/*.{scss,sass,less}',
26 | scripts + '/**/*.{scss,sass,less}'
27 | ],
28 | scripts: base + '/scripts/',
29 | scriptsF: [
30 | // modules first
31 | base + '/scripts/**/_*.js',
32 | base + '/scripts/**/*.js',
33 | '!' + base + '/scripts/**/*.spec.js'
34 | ],
35 | scriptsAllF: base + '/scripts/**/*.js',
36 | scriptTestsF: base + '/scripts/**/*.spec.js',
37 | html: base + '/scripts/',
38 | htmlF: [
39 | base + '/scripts/**/*.html'
40 | ],
41 | images: base + '/images/',
42 | imagesF: base + '/images/**/*.*',
43 | fonts: base + '/fonts/',
44 | fontsF: base + '/fonts/**/*.*',
45 | tmp: './.tmp',
46 | dist: 'www',
47 | wwwDestination: '',
48 | karmaConf: './karma.conf.js',
49 | karmaConfE2E: './karma-e2e.conf.js'
50 | };
51 |
52 | data.allHtmlF = data.htmlF.slice()
53 | data.allHtmlF.push(data.mainFile);
54 |
55 | return data;
56 | })();
57 |
--------------------------------------------------------------------------------
/templates/tasks/cordova.js:
--------------------------------------------------------------------------------
1 | var config = require('./config');
2 | var gulp = require('gulp');
3 |
4 | /**
5 | * Cordova-Build-Task Files
6 | *
7 | * NOTE: Depends on some of the build-tasks as well
8 | * inspired by:
9 | * @url https://github.com/kamrik/CordovaGulpTemplate
10 | */
11 |
12 | var plugins = ['org.apache.cordova.file'];
13 |
14 | var path = require('path');
15 | var shell = require('gulp-shell');
16 | var runSequence = require('run-sequence')
17 | .use(gulp);
18 | var symlink = require('gulp-symlink');
19 | var argv = require('yargs').argv;
20 |
21 | var watch = require('gulp-watch');
22 | var livereload = require('gulp-livereload');
23 | var http = require('http');
24 | var ecstatic = require('ecstatic');
25 | var gutil = require('gulp-util');
26 | var sass = require('gulp-sass');
27 |
28 | function platformArg() {
29 | return (argv.platform || config.defaultPlatform);
30 | }
31 |
32 | gulp.task('cordovaDev', function(cb) {
33 | //gulp.start('test');
34 |
35 | runSequence(
36 | 'cleanDist',
37 | 'symlinkApp',
38 | 'ngConfig',
39 | 'injectAll',
40 | 'buildStyles',
41 | 'browserSync',
42 | 'cordovaServer',
43 | 'cordovaEmulate',
44 | ['watchForCordova', 'watch'],
45 | cb
46 | );
47 | });
48 |
49 |
50 | gulp.task('cordovaRun', function(cb) {
51 | runSequence(
52 | 'cleanDist',
53 | 'symlinkApp',
54 | 'ngConfig',
55 | 'injectAll',
56 | 'buildStyles',
57 | 'browserSync',
58 | 'cordovaServer',
59 | 'cordovaRunOnDevice',
60 | ['watchForCordova', 'watch'],
61 | cb
62 | );
63 | });
64 |
65 |
66 | gulp.task('watchForCordova', function() {
67 | livereload.listen();
68 | var projectFiles = config.base + '/**/*.*';
69 | return gulp.src(projectFiles)
70 | .pipe(watch(projectFiles))
71 | .pipe(gulp.dest('./platforms/' + platformArg() + '/www/'))
72 | .pipe(livereload());
73 | });
74 |
75 |
76 | gulp.task('cordovaServer', function() {
77 | var port = 8000;
78 | var url = "http://localhost:" + port + "/";
79 | http.createServer(ecstatic({
80 | root: "platforms",
81 | cache: 0
82 | }))
83 | .listen(port);
84 |
85 | gutil.log(gutil.colors.blue("HTTP server listening on " + port));
86 | });
87 |
88 |
89 | gulp.task('cordovaEmulate', shell.task([
90 | config.cordovaPath + ' emulate ' + platformArg() + ' -l -s -c'
91 | ]));
92 |
93 |
94 | gulp.task('cordovaRunOnDevice', shell.task([
95 | config.cordovaPath + ' run ' + platformArg() + ' -l -s -c'
96 | ]));
97 |
98 |
99 | gulp.task('symlinkApp', function() {
100 | return gulp.src(config.base)
101 | .pipe(symlink(config.dist));
102 | });
103 |
104 |
105 | gulp.task('buildCordova', shell.task([
106 | config.cordovaPath + ' build ' + platformArg() + ''
107 | ]));
108 |
109 |
--------------------------------------------------------------------------------
/templates/tasks/deploy.js:
--------------------------------------------------------------------------------
1 | var config = require('./config');
2 | var gulp = require('gulp');
3 | //var rsync = require('rsyncwrapper').rsync;
4 |
5 | /**
6 | * Build-Task Files
7 | *
8 | * NOTE: Hard to make assumptions about this one
9 | * so be creative ;)
10 | */
11 |
12 | //gulp.task('deploy', function ()
13 | //{
14 | // rsync({
15 | // ssh: true,
16 | // src: config.dist,
17 | // recursive: true,
18 | // dest: config.wwwDestination,
19 | // syncDest: true,
20 | // args: ['--verbose']
21 | // }, function (error, stdout, stderr)
22 | // {
23 | // console.log(error);
24 | // console.log(stdout);
25 | // console.log(stderr);
26 | // });
27 | //});
--------------------------------------------------------------------------------
/templates/tasks/dev.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 | /* jshint camelcase: false */
3 |
4 | var config = require('./config');
5 | var gulp = require('gulp');
6 |
7 | /**
8 | * Dev Task File
9 | *
10 | */
11 |
12 |
13 | var sass = require('gulp-sass').sync;
14 | var autoprefixer = require('gulp-autoprefixer');
15 | var sourcemaps = require('gulp-sourcemaps');
16 | var wiredep = require('wiredep').stream;
17 | var inj = require('gulp-inject');
18 |
19 | var browserSync = require('browser-sync');
20 | var reload = browserSync.reload;
21 | var watch = require('gulp-watch');
22 | var runSequence = require('run-sequence')
23 | .use(gulp);
24 |
25 | var jshint = require('gulp-jshint');
26 | var jscs = require('gulp-jscs');
27 | var KarmaServer = require('karma').Server;
28 |
29 | // var gulpNgConfig = require('gulp-ng-config');
30 |
31 | var merge = require('merge-stream');
32 | var plumber = require('gulp-plumber');
33 | var sort = require('gulp-natural-sort');
34 |
35 | // main task
36 | gulp.task('default', function(cb) {
37 | runSequence(
38 | //'ngConfig',
39 | 'wiredep',
40 | 'lint',
41 | 'beautify',
42 | 'injectAll',
43 | 'buildStyles',
44 | 'browserSync',
45 | 'watch',
46 | function() {
47 | // run in parallel but afterwards
48 | gulp.start('test');
49 | cb();
50 | }
51 | );
52 | });
53 | gulp.task('serve', ['default']);
54 | gulp.task('server', ['default']);
55 |
56 |
57 | gulp.task('injectAll', function(callback) {
58 | runSequence(
59 | 'wiredep',
60 | 'injectScripts',
61 | 'injectStyles',
62 | 'beautify',
63 | callback
64 | );
65 | });
66 |
67 |
68 | gulp.task('watch', function(cb) {
69 | watch(config.stylesF, function() {
70 | gulp.start('buildStyles')
71 | .on('end', cb);
72 | });
73 | watch(config.scriptsF, function() {
74 | gulp.start('injectScripts')
75 | .on('end', cb);
76 | });
77 | watch(config.scriptsAllF, function() {
78 | gulp.start('lint')
79 | .on('end', cb);
80 | });
81 | watch(config.allHtmlF, function() {
82 | gulp.start('html')
83 | .on('end', cb);
84 | });
85 |
86 | //gulp.watch('bower.json', ['wiredep']);
87 |
88 | // enable at your convenience
89 | //watch(config.scripts + '*.json', function() {
90 | // gulp.start('ngConfig')
91 | // .on('end', cb);
92 | //});
93 | });
94 |
95 |
96 | gulp.task('buildStyles', function(cb) {
97 | runSequence(
98 | 'injectStyles',
99 | 'sass',
100 | cb
101 | );
102 | });
103 |
104 |
105 | gulp.task('injectStyles', function() {
106 | var sources = gulp.src(config.stylesF, {read: false})
107 | .pipe(sort());
108 | var target = gulp.src(config.mainSassFile);
109 | var outputFolder = gulp.dest(config.styles);
110 |
111 | return target
112 | .pipe(inj(sources,
113 | {
114 | starttag: '// inject:sass',
115 | endtag: '// endinject',
116 | ignorePath: [config.base.replace('./', ''), 'styles'],
117 | relative: true,
118 | addRootSlash: false,
119 | transform: function(filepath) {
120 | if (filepath) {
121 | return '@import \'' + filepath + '\';';
122 | }
123 | }
124 | }
125 | ))
126 | .pipe(outputFolder);
127 | });
128 |
129 |
130 | gulp.task('injectScripts', function() {
131 | var sources = gulp.src(config.scriptsF, {read: true})
132 | .pipe(sort());
133 | var target = gulp.src(config.mainFile);
134 | return target
135 | .pipe(inj(sources,
136 | {
137 | ignorePath: config.base.replace('./', ''),
138 | addRootSlash: false
139 | }
140 | ))
141 | .pipe(gulp.dest(config.base));
142 | });
143 |
144 |
145 | gulp.task('sass', function() {
146 | var sources = gulp.src(config.mainSassFile);
147 | var outputFolder = gulp.dest(config.styles);
148 |
149 | return sources
150 | .pipe(plumber({
151 | handleError: function(err) {
152 | console.log(err);
153 | this.emit('end');
154 | }
155 | }))
156 | .pipe(sourcemaps.init())
157 | .pipe(sass({errLogToConsole: true}))
158 | .pipe(autoprefixer({
159 | browsers: ['> 0.1%']
160 | }))
161 | .pipe(sourcemaps.write('.'))
162 | .pipe(gulp.dest(config.tmp))
163 | .pipe(gulp.dest(config.styles))
164 | .pipe(outputFolder)
165 | .pipe(browserSync.stream());
166 | });
167 |
168 |
169 | gulp.task('browserSync', function() {
170 | browserSync({
171 | port: config.browserSyncPort,
172 | server: {
173 | baseDir: config.base,
174 | livereload: true
175 | }
176 | });
177 | });
178 |
179 |
180 | gulp.task('html', function() {
181 | return gulp.src(config.allHtmlF)
182 | .pipe(reload({stream: true}));
183 | });
184 |
185 |
186 | gulp.task('wiredep', ['wirdepKarma', 'wiredepIndex']);
187 |
188 | gulp.task('wirdepKarma', function() {
189 | return gulp.src(config.karmaConf, {base: './'})
190 | .pipe(wiredep({
191 | devDependencies: true,
192 | exclude: config.excludedBowerComponents
193 | }))
194 | // required as weird workaround for not messing up the files
195 | .pipe(gulp.dest(config.tmp))
196 | .pipe(gulp.dest('./'));
197 | });
198 |
199 | gulp.task('wiredepIndex', function() {
200 | return gulp.src(config.mainFile, {base: './'})
201 | .pipe(wiredep({
202 | devDependencies: false,
203 | exclude: config.excludedBowerComponents
204 | }))
205 | // required as weird workaround for not messing up the files
206 | .pipe(gulp.dest(config.tmp))
207 | .pipe(gulp.dest('./'));
208 | });
209 |
210 |
211 | gulp.task('test', function(done) {
212 | new KarmaServer({
213 | configFile: __dirname + '/../karma.conf.js',
214 | action: 'watch',
215 | autoWatch: true,
216 | singleRun: false
217 | }, done).start();
218 | });
219 |
220 |
221 | gulp.task('testSingle', function(done) {
222 | new KarmaServer({
223 | configFile: __dirname + '/../karma.conf.js',
224 | action: 'run',
225 | autoWatch: false,
226 | singleRun: true
227 | }, done).start();
228 | });
229 |
230 |
231 | gulp.task('lint', function() {
232 | return gulp.src([
233 | config.scriptsAllF,
234 | './karma-e2e.conf.js',
235 | './karma.conf.js',
236 | './gulpfile.js'
237 | ], {base: './'})
238 | .pipe(jshint())
239 | .pipe(jshint.reporter('jshint-stylish'))
240 | .pipe(jscs());
241 | });
242 |
243 | gulp.task('beautify', function() {
244 | return gulp.src([
245 | config.scriptsAllF,
246 | './karma-e2e.conf.js',
247 | './karma.conf.js',
248 | './gulpfile.js'
249 | ], {base: './'})
250 | .pipe(jscs({fix: true}))
251 | .pipe(gulp.dest('./'));
252 | });
253 |
254 |
255 | //gulp.task('ngConfig', function () {
256 | // return gulp.src(config.scripts + 'constants.json')
257 | // .pipe(gulpNgConfig('config', {
258 | // wrap: '(function () {\n\'use strict\';\n/*jshint ignore:start*/\n return <%= ngConfModulePlaceholder %> /*jshint ignore:end*/\n})();',
259 | // environment: 'dev'
260 | // }))
261 | // .pipe(gulp.dest(config.scripts))
262 | //});
263 |
264 |
--------------------------------------------------------------------------------
/templates/tasks/e2e.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 | /* jshint camelcase: false */
3 |
4 | var config = require('./config');
5 | var gulp = require('gulp');
6 |
7 | var protractor = require('gulp-protractor');
8 | var browserSync = require('browser-sync');
9 |
10 |
11 | gulp.task('protractor', ['protractor:src']);
12 | gulp.task('e2e', [
13 | 'browserSync',
14 | 'webdriver-update'
15 | ], runProtractor);
16 |
17 |
18 | gulp.task('webdriver-update', protractor.webdriver_update);
19 | gulp.task('webdriver-standalone', protractor.webdriver_standalone);
20 |
21 | function runProtractor(done) {
22 | gulp.src('.nonononoNOTHING')
23 | .pipe(protractor.protractor({
24 | configFile: './karma-e2e.conf.js'
25 | }))
26 | .on('error', function(err) {
27 | // Make sure failed tests cause gulp to exit non-zero
28 | throw err;
29 | })
30 | .on('end', function() {
31 | // Close browser sync server
32 | browserSync.exit();
33 | done();
34 | });
35 | }
36 |
37 |
--------------------------------------------------------------------------------
/test-app/injections.spec.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 | var path = require('path');
3 | var helpers = require('yeoman-test');
4 | var assert = require('yeoman-assert');
5 | var exec = require('child_process').exec;
6 | var fs = require('fs');
7 |
8 |
9 | describe('gulp inject', function() {
10 | var instancePath = path.join(__dirname, '../.test-instance');
11 | var gulp = '$(which gulp)';
12 | this.timeout(20000);
13 |
14 |
15 | describe('styles', function() {
16 | var mainScss = path.join(instancePath, 'app/styles/main.scss');
17 | var injectStylesCmd = gulp + ' injectStyles';
18 |
19 | describe('scss partials in styles folder', function() {
20 | var expectedContent = [
21 | [mainScss, /_variables/],
22 | [mainScss, /base\/_buttons\.scss/],
23 | [mainScss, /base\/_fonts\.scss/],
24 | [mainScss, /base\/_forms\.scss/],
25 | [mainScss, /base\/_icons\.scss/],
26 | [mainScss, /base\/_lists\.scss/],
27 | [mainScss, /base\/_page\.scss/],
28 | [mainScss, /base\/_tables\.scss/],
29 | [mainScss, /base\/_typography\.scss/],
30 | [mainScss, /functions\/_some-function\.scss/],
31 | [mainScss, /mixins\/_some-mixin\.scss/],
32 | [mainScss, /placeholders\/_some-placeholder\.scss/]
33 | ];
34 | var expected = [
35 | mainScss
36 | ];
37 |
38 | beforeEach(function(done) {
39 | fs.truncateSync(mainScss);
40 | fs.writeFileSync(mainScss, '// inject:sass\n\n// endinject');
41 | exec(injectStylesCmd, {
42 | cwd: instancePath
43 | }, function() {
44 | done();
45 | });
46 | });
47 |
48 | it('adds imports for default files', function() {
49 | assert.file([].concat(
50 | expected
51 | ));
52 | assert.fileContent([].concat(
53 | expectedContent
54 | ));
55 | });
56 | });
57 | });
58 |
59 | describe('scripts', function() {
60 | var mainHtml = path.join(instancePath, 'app/index.html');
61 | var injectScriptsCmd = gulp + ' injectScripts';
62 | var cachedMainFileContent;
63 |
64 | describe('scripts into index.html', function() {
65 | var expectedContent = [
66 | [mainHtml, /_app\.js/]
67 | ];
68 | var expected = [
69 | mainHtml
70 | ];
71 |
72 | beforeEach(function(done) {
73 | cachedMainFileContent = fs.readFileSync(mainHtml, 'utf8');
74 | fs.truncateSync(mainHtml);
75 | fs.writeFileSync(mainHtml, '\n');
76 | exec(injectScriptsCmd, {
77 | cwd: instancePath
78 | }, function() {
79 | done();
80 | });
81 | });
82 |
83 | afterEach(function() {
84 | // restore old html
85 | fs.truncateSync(mainHtml);
86 | fs.writeFileSync(mainHtml, cachedMainFileContent);
87 | });
88 |
89 | it('adds imports for script files', function() {
90 | assert.file([].concat(
91 | expected
92 | ));
93 | assert.fileContent([].concat(
94 | expectedContent
95 | ));
96 | });
97 | });
98 | });
99 |
100 |
101 | describe('wiredep', function() {
102 | var mainHtml = path.join(instancePath, 'app/index.html');
103 | var wiredepCmd = gulp + ' wiredep';
104 | var cachedMainFileContent;
105 |
106 | describe('bower-components into index.html', function() {
107 | var expectedContent = [
108 | [mainHtml, /bower_components\/angular\/angular\.js/]
109 | ];
110 | var expected = [
111 | mainHtml
112 | ];
113 |
114 | beforeEach(function(done) {
115 | cachedMainFileContent = fs.readFileSync(mainHtml, 'utf8');
116 | fs.truncateSync(mainHtml);
117 | fs.writeFileSync(mainHtml, '\n');
118 | exec(wiredepCmd, {
119 | cwd: instancePath
120 | }, function() {
121 | done();
122 | });
123 | });
124 |
125 | afterEach(function() {
126 | // restore old html
127 | fs.truncateSync(mainHtml);
128 | fs.writeFileSync(mainHtml, cachedMainFileContent);
129 | });
130 |
131 | it('adds imports for bower-components', function() {
132 | assert.file([].concat(
133 | expected
134 | ));
135 | assert.fileContent([].concat(
136 | expectedContent
137 | ));
138 | });
139 | });
140 | });
141 | });
--------------------------------------------------------------------------------
/test-app/styles.spec.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 | var path = require('path');
3 | var helpers = require('yeoman-test');
4 | var assert = require('yeoman-assert');
5 | var exec = require('child_process').exec;
6 | var fs = require('fs');
7 |
8 |
9 | describe('gulp buildStyles', function() {
10 | var instancePath = path.join(__dirname, '../.test-instance');
11 | var gulp = '$(which gulp)';
12 | this.timeout(20000);
13 | var stylesDir = path.join(instancePath, 'app/styles');
14 | var testFileInStylesDir = path.join(stylesDir, 'base/_test.scss');
15 | var testFileInScritsDir = path.join(instancePath, 'app/scripts/_test.scss');
16 | var mainScss = path.join(stylesDir, 'main.scss');
17 | var mainCss = path.join(stylesDir, 'main.css');
18 | var injectStylesCmd = gulp + ' injectStyles';
19 | var sassCmd = gulp + ' sass';
20 |
21 |
22 | describe('autoprefixer, sourcemap as base 64 and general compilation', function() {
23 | var expectedContent = [
24 | [mainScss, /_variables/],
25 | [mainScss, /base\/_buttons\.scss/],
26 | [mainScss, /base\/_fonts\.scss/],
27 | [mainScss, /base\/_forms\.scss/],
28 | [mainScss, /base\/_icons\.scss/],
29 | [mainScss, /base\/_lists\.scss/],
30 | [mainScss, /base\/_page\.scss/],
31 | [mainScss, /base\/_tables\.scss/],
32 | [mainScss, /base\/_typography\.scss/],
33 | [mainScss, /functions\/_some-function\.scss/],
34 | [mainScss, /mixins\/_some-mixin\.scss/],
35 | [mainScss, /placeholders\/_some-placeholder\.scss/],
36 | [mainScss, /base\/_test\.scss/],
37 | [mainScss, /\.\.\/scripts\/_test\.scss/],
38 | [mainCss, /\.styles/],
39 | [mainCss, /\.scripts/],
40 | [mainCss, /color: blue;/],
41 | [mainCss, /sourceMappingURL=main\.css\.map/]
42 | ];
43 |
44 | beforeEach(function(done) {
45 | fs.truncateSync(mainScss);
46 | fs.writeFileSync(testFileInScritsDir, '.scripts-class{color:blue;}');
47 | fs.writeFileSync(testFileInStylesDir, '.styles-class{background: linear-gradient(to bottom right, yellow, green);}');
48 | fs.writeFileSync(mainScss, '// inject:sass\n\n// endinject');
49 | exec(injectStylesCmd, {
50 | cwd: instancePath
51 | }, function(err, stdout) {
52 | exec(sassCmd, {
53 | cwd: instancePath
54 | }, function(err, stdout) {
55 | done();
56 | });
57 | });
58 | });
59 |
60 | afterEach(function() {
61 | fs.unlinkSync(testFileInScritsDir);
62 | fs.unlinkSync(testFileInStylesDir);
63 | });
64 |
65 | it('creates expected files', function() {
66 | assert.file([
67 | mainCss,
68 | mainScss,
69 | testFileInScritsDir,
70 | testFileInStylesDir
71 | ]);
72 | assert.fileContent([].concat(
73 | expectedContent
74 | ));
75 | });
76 | });
77 | });
--------------------------------------------------------------------------------
/test/app.spec.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 | var path = require('path');
3 | var helpers = require('yeoman-test');
4 | var assert = require('yeoman-assert');
5 |
6 | describe('moda generator', function() {
7 | var alwaysExpected = [
8 | '.editorconfig',
9 | '.gitignore',
10 | '.gitattributes',
11 | 'package.json',
12 | 'bower.json',
13 | '.bowerrc',
14 | 'gulpfile.js',
15 | 'config.xml',
16 | '.jshintrc',
17 | '.jscsrc',
18 | '.travis.yml',
19 | 'karma.conf.js',
20 | 'karma-e2e.conf.js',
21 | 'app/index.html',
22 | 'app/scripts/_app.js',
23 | 'app/scripts/_app.spec.js',
24 | 'tasks/config.js',
25 | 'tasks/cordova.js',
26 | 'tasks/deploy.js',
27 | 'tasks/build.js',
28 | 'tasks/dev.js',
29 | 'tasks/e2e.js'
30 | ];
31 |
32 | var alwaysExpectedContent = [
33 | ['gulpfile.js', /tasks/],
34 | ['app/index.html', /main\.css/],
35 | ['bower.json', /angular/],
36 | ['package.json', /gulp/],
37 | ['app/styles/main.scss', /\/\/ inject:sass/],
38 | ['app/styles/main.scss', /\/\/ endinject/],
39 | ['app/index.html', //],
40 | ['app/index.html', //],
41 | ['app/index.html', //],
42 | ['app/index.html', //]
43 | ];
44 |
45 |
46 | it('can be required without throwing', function() {
47 | this.app = require('../app');
48 | });
49 |
50 | describe('basic file creation', function() {
51 |
52 | var expectedContent = alwaysExpectedContent
53 | .slice()
54 | .concat([]);
55 |
56 | var expected = alwaysExpected
57 | .slice()
58 | .concat([]);
59 |
60 | var options = {
61 | 'skip-install-message': true,
62 | 'skip-install': true,
63 | 'skip-welcome-message': true,
64 | 'skip-message': true
65 | };
66 |
67 | var runGen;
68 |
69 | beforeEach(function() {
70 | runGen = helpers
71 | .run(path.join(__dirname, '../app'))
72 | .inDir(path.join(__dirname, '.tmp'))
73 | });
74 |
75 | it('creates expected files', function(done) {
76 | runGen.withOptions(options)
77 | .on('end', function() {
78 | assert.file(expected);
79 | assert.noFile([
80 | 'app/styles/main.css'
81 | ]);
82 | assert.fileContent(expectedContent);
83 | done();
84 | });
85 | });
86 | });
87 |
88 |
89 | describe('module file creation and app.js injection', function() {
90 |
91 | var expectedContent = alwaysExpectedContent
92 | .slice()
93 | .concat([
94 | // cfg
95 | ['.yo-rc.json', /"uiRouter": true/],
96 |
97 | // module injection
98 | ['app/scripts/_app.js', /ngAnimate/],
99 | ['app/scripts/_app.js', /ngAria/],
100 | ['app/scripts/_app.js', /ngCookies/],
101 | ['app/scripts/_app.js', /ngMessages/],
102 | ['app/scripts/_app.js', /ngResource/],
103 | ['app/scripts/_app.js', /ngRoute/],
104 | ['app/scripts/_app.js', /ngSanitize/],
105 | ['app/scripts/_app.js', /ngTouch/],
106 | ['app/scripts/_app.js', /ui.router/],
107 | ['app/scripts/_app.js', /ngMaterial/],
108 | ['app/scripts/_app.js', /ngFabForm/],
109 |
110 | ['bower.json', /angular-animate/],
111 | ['bower.json', /angular-aria/],
112 | ['bower.json', /angular-cookies/],
113 | ['bower.json', /angular-messages/],
114 | ['bower.json', /angular-resource/],
115 | ['bower.json', /angular-route/],
116 | ['bower.json', /angular-sanitize/],
117 | ['bower.json', /angular-touch/],
118 | ['bower.json', /ui-router/],
119 | ['bower.json', /angular-material/],
120 | ['bower.json', /ng-fab-form/]
121 | ]);
122 |
123 | var expected = alwaysExpected
124 | .slice()
125 | .concat([]);
126 |
127 | var options = {
128 | 'skip-install-message': true,
129 | 'skip-install': true,
130 | 'skip-welcome-message': true,
131 | 'skip-message': true
132 | };
133 |
134 | var runGen;
135 |
136 | beforeEach(function() {
137 | runGen = helpers
138 | .run(path.join(__dirname, '../app'))
139 | .inDir(path.join(__dirname, '.tmp'))
140 | });
141 |
142 | it('creates expected files', function(done) {
143 | runGen
144 | .withOptions(options)
145 | .withPrompts({
146 | modules: [
147 | 'animateModule',
148 | 'ariaModule',
149 | 'cookiesModule',
150 | 'messagesModule',
151 | 'resourceModule',
152 | 'routeModule',
153 | 'uiRouterModule',
154 | 'ngFabFormModule',
155 | 'sanitizeModule',
156 | 'ngMaterialModule',
157 | 'touchModule'
158 | ]
159 | })
160 | .on('end', function() {
161 | assert.file([].concat(
162 | expected
163 | ));
164 | assert.noFile([
165 | 'app/styles/main.css'
166 | ]);
167 | assert.fileContent(expectedContent);
168 | done();
169 | });
170 | });
171 | });
172 |
173 |
174 | describe('route files with ui router', function() {
175 |
176 | var expectedContent = alwaysExpectedContent
177 | .slice()
178 | .concat([
179 | // module injection
180 | ['app/scripts/_app.js', /ui.router/],
181 | ['bower.json', /ui-router/],
182 | ['.yo-rc.json', /"uiRouter": true/],
183 | ['app/scripts/routes.js', '/* STATES-NEEDLE - DO NOT REMOVE THIS */']
184 | ]);
185 |
186 | var expected = alwaysExpected
187 | .slice()
188 | .concat([
189 | 'app/scripts/routes.js',
190 | 'app/scripts/routes.spec.js'
191 | ]);
192 |
193 | var options = {
194 | 'skip-install-message': true,
195 | 'skip-install': true,
196 | 'skip-welcome-message': true,
197 | 'skip-message': true
198 | };
199 |
200 | var runGen;
201 |
202 | beforeEach(function() {
203 | runGen = helpers
204 | .run(path.join(__dirname, '../app'))
205 | .inDir(path.join(__dirname, '.tmp'));
206 | });
207 |
208 | it('creates expected files', function(done) {
209 | runGen
210 | .withOptions(options)
211 | .withPrompts({
212 | modules: [
213 | 'uiRouterModule'
214 | ]
215 | })
216 | .on('end', function() {
217 | assert.file([].concat(
218 | expected
219 | ));
220 | assert.noFile([
221 | 'app/styles/main.css'
222 | ]);
223 | assert.fileContent(expectedContent);
224 | done();
225 | });
226 | });
227 | });
228 | });
229 |
230 |
231 |
--------------------------------------------------------------------------------
/test/component.spec.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 | var path = require('path');
3 | var helpers = require('yeoman-test');
4 | var assert = require('yeoman-assert');
5 |
6 | describe('moda Component generator', function() {
7 | var SUB_GEN_PATH = '../cp';
8 |
9 | // not testing the actual run of generators yet
10 | it('can be required without throwing', function() {
11 | this.app = require(SUB_GEN_PATH);
12 | });
13 |
14 | describe('basic file creation', function() {
15 | var testArguments = 'test-name';
16 | var expectedContent = [
17 | ['app/scripts/test-name/test-name-cp.js', /testName/],
18 | ['app/scripts/test-name/test-name-cp.js', /module\('tmp'\)/],
19 | ['app/scripts/test-name/test-name-cp.js', /scripts\/test-name\/test-name-cp\.html/],
20 | ['app/scripts/test-name/test-name-cp.spec.js', /\('<\/test-name>'\)/],
21 | ['app/scripts/test-name/test-name-cp.html', /testName/],
22 | ];
23 | var expected = [
24 | 'app/scripts/test-name/test-name-cp.js',
25 | 'app/scripts/test-name/test-name-cp.spec.js',
26 | 'app/scripts/test-name/test-name-cp.html',
27 | 'app/scripts/test-name/_test-name-cp.scss'
28 | ];
29 |
30 | var noFile = [
31 | 'app/scripts/test-name/test-name-s.js',
32 | 'app/scripts/test-name/test-name-f.js',
33 | 'app/scripts/test-name-cp.js'
34 | ];
35 |
36 | var nonExpected = [
37 | ['app/scripts/test-name/test-name-cp.js', /testNamea/]
38 | ];
39 |
40 | var options = {
41 | 'useDefaults': true,
42 | 'skipInject': true
43 | };
44 |
45 | var runGen;
46 |
47 | beforeEach(function() {
48 | runGen = helpers
49 | .run(path.join(__dirname, SUB_GEN_PATH))
50 | .inDir(path.join(__dirname, '.tmp'))
51 | });
52 |
53 | it('creates expected files', function(done) {
54 | runGen
55 | .withArguments(testArguments)
56 | .withOptions(options)
57 | .on('end', function() {
58 | assert.file([].concat(
59 | expected
60 | ));
61 | assert.noFile([].concat(
62 | noFile
63 | ));
64 | assert.fileContent([].concat(
65 | expectedContent
66 | ));
67 | assert.noFileContent([].concat(
68 | nonExpected
69 | ));
70 | done();
71 | });
72 | });
73 | });
74 |
75 |
76 | describe('file in sub folder creation', function() {
77 | var testArguments = 'test-name test-path';
78 | var expectedContent = [
79 | ['app/scripts/test-path/test-name/test-name-cp.js', /testName/],
80 | ['app/scripts/test-path/test-name/test-name-cp.js', /module\('tmp'\)/],
81 | ['app/scripts/test-path/test-name/test-name-cp.js', /scripts\/test-path\/test-name\/test-name-cp\.html/],
82 | ['app/scripts/test-path/test-name/test-name-cp.spec.js', /\('<\/test-name>'\)/],
83 | ['app/scripts/test-path/test-name/test-name-cp.html', /testName/],
84 | ];
85 | var expected = [
86 | 'app/scripts/test-path/test-name/test-name-cp.js',
87 | 'app/scripts/test-path/test-name/test-name-cp.spec.js',
88 | 'app/scripts/test-path/test-name/test-name-cp.html',
89 | 'app/scripts/test-path/test-name/_test-name-cp.scss'
90 | ];
91 |
92 | var noFile = [
93 | 'app/scripts/test-path/test-name/test-name-s.js',
94 | 'app/scripts/test-path/test-name/test-name-f.js',
95 | 'app/scripts/test-name-cp.js'
96 | ];
97 |
98 | var nonExpected = [
99 | ['app/scripts/test-path/test-name/test-name-cp.js', /testNamea/]
100 | ];
101 |
102 | var options = {
103 | 'useDefaults': true,
104 | 'skipInject': true
105 | };
106 |
107 | var runGen;
108 |
109 | beforeEach(function() {
110 | runGen = helpers
111 | .run(path.join(__dirname, SUB_GEN_PATH))
112 | .inDir(path.join(__dirname, '.tmp'))
113 | });
114 |
115 | it('creates expected files', function(done) {
116 | runGen
117 | .withArguments(testArguments)
118 | .withOptions(options)
119 | .on('end', function() {
120 | assert.file([].concat(
121 | expected
122 | ));
123 | assert.noFile([].concat(
124 | noFile
125 | ));
126 | assert.fileContent([].concat(
127 | expectedContent
128 | ));
129 | assert.noFileContent([].concat(
130 | nonExpected
131 | ));
132 | done();
133 | });
134 | });
135 | });
136 |
137 |
138 | describe('file with service creation and no template (in sub folder)', function() {
139 | var testArguments = 'test-name test-path';
140 | var expectedContent = [
141 | ['app/scripts/test-path/test-name/test-name-cp.js', /testName/],
142 | ['app/scripts/test-path/test-name/test-name-cp.js', /module\('tmp'\)/],
143 | ['app/scripts/test-path/test-name/test-name-s.js', /module\('tmp'\)/],
144 | ['app/scripts/test-path/test-name/test-name-s.js', /TestName/],
145 | ['app/scripts/test-path/test-name/test-name-s.spec.js', /TestName/],
146 | ['app/scripts/test-path/test-name/test-name-cp.spec.js', /\('<\/test-name>'\)/],
147 | ];
148 | var expected = [
149 | 'app/scripts/test-path/test-name/test-name-cp.js',
150 | 'app/scripts/test-path/test-name/test-name-cp.spec.js',
151 | 'app/scripts/test-path/test-name/test-name-s.js',
152 | 'app/scripts/test-path/test-name/test-name-s.spec.js'
153 | ];
154 |
155 | var noFile = [
156 | 'app/scripts/test-path/test-name/test-name-f.js',
157 | 'app/scripts/test-path/test-name/test-name-f.spec.js',
158 | 'app/scripts/test-name-cp.js',
159 | 'app/scripts/test-path/test-name/test-name-cp.html',
160 | 'app/scripts/test-path/test-name/_test-name-cp.scss'
161 | ];
162 |
163 | var nonExpected = [
164 | ['app/scripts/test-path/test-name/test-name-cp.js', /templateUrl/]
165 | ];
166 |
167 | var options = {
168 | 'skipInject': true
169 | };
170 |
171 | var runGen;
172 |
173 | beforeEach(function() {
174 | runGen = helpers
175 | .run(path.join(__dirname, SUB_GEN_PATH))
176 | .inDir(path.join(__dirname, '.tmp'))
177 |
178 | });
179 |
180 | it('creates expected files', function(done) {
181 | runGen
182 | .withArguments(testArguments)
183 | .withPrompts({
184 | createService: 'service',
185 | createTemplate: false
186 | })
187 | .withOptions(options)
188 | .on('end', function() {
189 | assert.file([].concat(
190 | expected
191 | ));
192 | assert.noFile([].concat(
193 | noFile
194 | ));
195 | assert.fileContent([].concat(
196 | expectedContent
197 | ));
198 | assert.noFileContent([].concat(
199 | nonExpected
200 | ));
201 | done();
202 | });
203 | });
204 | });
205 | });
--------------------------------------------------------------------------------
/test/controller.spec.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 | var path = require('path');
3 | var helpers = require('yeoman-test');
4 | var assert = require('yeoman-assert');
5 |
6 | describe('moda Controller generator', function() {
7 | var generatorPath = '../c';
8 | // not testing the actual run of generators yet
9 | it('can be required without throwing', function() {
10 | this.app = require(generatorPath);
11 | });
12 |
13 | describe('basic file creation', function() {
14 | var testArguments = 'test-name';
15 | var expectedContent = [
16 | ['app/scripts/test-name/test-name-c.js', /TestNameCtrl/],
17 | ['app/scripts/test-name/test-name-c.js', /module\('tmp'\)/],
18 | ['app/scripts/test-name/test-name-c.spec.js', /TestNameCtrl/],
19 | ['app/scripts/test-name/test-name-c.html', /class="page-test-name"/],
20 | ];
21 | var expected = [
22 | 'app/scripts/test-name/test-name-c.js',
23 | 'app/scripts/test-name/test-name-c.spec.js',
24 | 'app/scripts/test-name/test-name-c.html',
25 | 'app/scripts/test-name/_test-name-c.scss'
26 | ];
27 |
28 | var noFile = [
29 | 'app/scripts/test-name/test-name-s.js',
30 | 'app/scripts/test-name/test-name-f.js',
31 | 'app/scripts/test-name-c.js'
32 | ];
33 |
34 | var nonExpected = [
35 | ['app/scripts/test-name/test-name-c.js', /TestNamea/],
36 | ['app/scripts/test-name/test-name-c.js', /testName/],
37 | ];
38 |
39 | var options = {
40 | 'useDefaults': true,
41 | 'skipInject': true
42 | };
43 |
44 | var runGen;
45 |
46 | beforeEach(function() {
47 | runGen = helpers
48 | .run(path.join(__dirname, generatorPath))
49 | .inDir(path.join(__dirname, '.tmp'))
50 | });
51 |
52 | it('creates expected files', function(done) {
53 | runGen
54 | .withArguments(testArguments)
55 | .withOptions(options)
56 | .on('end', function() {
57 | assert.file([].concat(
58 | expected
59 | ));
60 | assert.noFile([].concat(
61 | noFile
62 | ));
63 | assert.fileContent([].concat(
64 | expectedContent
65 | ));
66 | assert.noFileContent([].concat(
67 | nonExpected
68 | ));
69 | done();
70 | });
71 | });
72 | });
73 |
74 |
75 | describe('files in sub folder creation', function() {
76 | var testArguments = 'test-name test-path';
77 | var expectedContent = [
78 | ['app/scripts/test-path/test-name/test-name-c.js', /TestNameCtrl/],
79 | ['app/scripts/test-path/test-name/test-name-c.js', /module\('tmp'\)/],
80 | ['app/scripts/test-path/test-name/test-name-c.spec.js', /TestNameCtrl/],
81 | ['app/scripts/test-path/test-name/test-name-c.html', /class="page-test-name"/],
82 | ];
83 | var expected = [
84 | 'app/scripts/test-path/test-name/test-name-c.js',
85 | 'app/scripts/test-path/test-name/test-name-c.spec.js',
86 | 'app/scripts/test-path/test-name/test-name-c.html',
87 | 'app/scripts/test-path/test-name/_test-name-c.scss'
88 | ];
89 |
90 | var noFile = [
91 | 'app/scripts/test-path/test-name/test-name-s.js',
92 | 'app/scripts/test-path/test-name/test-name-f.js',
93 | 'app/scripts/test-name-c.js'
94 | ];
95 |
96 | var nonExpected = [
97 | ['app/scripts/test-path/test-name/test-name-c.js', /testName/]
98 | ];
99 |
100 | var options = {
101 | 'useDefaults': true,
102 | 'skipInject': true
103 | };
104 |
105 | var runGen;
106 |
107 | beforeEach(function() {
108 | runGen = helpers
109 | .run(path.join(__dirname, generatorPath))
110 | .inDir(path.join(__dirname, '.tmp'))
111 | });
112 |
113 | it('creates expected files', function(done) {
114 | runGen
115 | .withArguments(testArguments)
116 | .withOptions(options)
117 | .on('end', function() {
118 | assert.file([].concat(
119 | expected
120 | ));
121 | assert.noFile([].concat(
122 | noFile
123 | ));
124 | assert.fileContent([].concat(
125 | expectedContent
126 | ));
127 | assert.noFileContent([].concat(
128 | nonExpected
129 | ));
130 | done();
131 | });
132 | });
133 | });
134 |
135 |
136 | describe('file with service creation and no template (in sub folder)', function() {
137 | var testArguments = 'test-name test-path';
138 | var expectedContent = [
139 | ['app/scripts/test-path/test-name/test-name-c.js', /TestNameCtrl/],
140 | ['app/scripts/test-path/test-name/test-name-c.js', /module\('tmp'\)/],
141 | ['app/scripts/test-path/test-name/test-name-s.js', /module\('tmp'\)/],
142 | ['app/scripts/test-path/test-name/test-name-s.js', /TestName/],
143 | ['app/scripts/test-path/test-name/test-name-s.spec.js', /TestName/]
144 | ];
145 | var expected = [
146 | 'app/scripts/test-path/test-name/test-name-c.js',
147 | 'app/scripts/test-path/test-name/test-name-c.spec.js',
148 | 'app/scripts/test-path/test-name/test-name-s.js',
149 | 'app/scripts/test-path/test-name/test-name-s.spec.js'
150 | ];
151 |
152 | var noFile = [
153 | 'app/scripts/test-path/test-name/test-name-f.js',
154 | 'app/scripts/test-path/test-name/test-name-f.spec.js',
155 | 'app/scripts/test-name-c.js',
156 | 'app/scripts/test-path/test-name/test-name-c.html',
157 | 'app/scripts/test-path/test-name/_test-name-c.scss'
158 | ];
159 |
160 | var nonExpected = [];
161 |
162 | var options = {
163 | 'skipInject': true
164 | };
165 |
166 | var runGen;
167 |
168 | beforeEach(function() {
169 | runGen = helpers
170 | .run(path.join(__dirname, generatorPath))
171 | .inDir(path.join(__dirname, '.tmp'))
172 |
173 | });
174 |
175 | it('creates expected files', function(done) {
176 | runGen
177 | .withArguments(testArguments)
178 | .withPrompts({
179 | createService: 'service',
180 | createTemplate: false
181 | })
182 | .withOptions(options)
183 | .on('end', function() {
184 | assert.file([].concat(
185 | expected
186 | ));
187 | assert.noFile([].concat(
188 | noFile
189 | ));
190 | assert.fileContent([].concat(
191 | expectedContent
192 | ));
193 | assert.noFileContent([].concat(
194 | nonExpected
195 | ));
196 | done();
197 | });
198 | });
199 | });
200 | });
--------------------------------------------------------------------------------
/test/custom-templates-from-file.spec.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 | var path = require('path');
3 | var helpers = require('yeoman-test');
4 | var assert = require('yeoman-assert');
5 | var fs = require('fs');
6 | describe('moda custom file templates from folder', function() {
7 | var generatorPath = '../s';
8 | var yoRc = path.join(__dirname, '.tmp', '.yo-rc.json');
9 | var templatePath = path.join(__dirname, '.tmp-templates');
10 | var serviceFile = path.join(templatePath, 'service.js');
11 | var serviceFileContent = 'SERVICE<%= classedName %><%= nameSuffix %>';
12 | var serviceSpecFile = path.join(templatePath, 'service.spec.js');
13 | var serviceSpecFileContent = 'SPEC<%= classedName %><%= nameSuffix %>';
14 |
15 |
16 | var testArguments = 'test-name';
17 | var expectedContent = [
18 | ['app/scripts/main/global-services/test-name-s.js', /SERVICE/],
19 | ['app/scripts/main/global-services/test-name-s.spec.js', /SPEC/],
20 | ['app/scripts/main/global-services/test-name-s.js', /TestName/],
21 | ['app/scripts/main/global-services/test-name-s.spec.js', /TestName/]
22 | ];
23 | var expected = [
24 | 'app/scripts/main/global-services/test-name-s.js',
25 | 'app/scripts/main/global-services/test-name-s.spec.js'
26 | ];
27 |
28 | var options = {
29 | 'useDefaults': true,
30 | 'skipInject': true
31 | };
32 |
33 | var runGen;
34 |
35 | describe('success', function() {
36 | beforeEach(function() {
37 | if (!fs.existsSync(templatePath)) {
38 | fs.mkdirSync(templatePath);
39 | }
40 | if (!fs.existsSync(serviceFile)) {
41 | fs.writeFileSync(serviceFile, serviceFileContent);
42 | }
43 | if (!fs.existsSync(serviceSpecFile)) {
44 | fs.writeFileSync(serviceSpecFile, serviceSpecFileContent);
45 | }
46 | runGen = helpers
47 | .run(path.join(__dirname, generatorPath))
48 | .inDir(path.join(__dirname, '.tmp'))
49 | });
50 |
51 | afterEach(function() {
52 | fs.unlinkSync(yoRc);
53 | fs.unlinkSync(serviceFile);
54 | fs.unlinkSync(serviceSpecFile);
55 | fs.rmdir(templatePath);
56 | });
57 |
58 | it('should use the custom service templates', function(done) {
59 | runGen
60 | .withArguments(testArguments)
61 | .withLocalConfig({
62 | customTemplatesPath: templatePath
63 | })
64 | .withOptions(options)
65 | .on('end', function() {
66 | assert.file([].concat(
67 | expected
68 | ));
69 | assert.fileContent([].concat(
70 | expectedContent
71 | ));
72 |
73 | done();
74 | });
75 | });
76 | });
77 |
78 | });
--------------------------------------------------------------------------------
/test/custom-templates-in-yo-rc.spec.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 | var path = require('path');
3 | var helpers = require('yeoman-test');
4 | var assert = require('yeoman-assert');
5 | var fs = require('fs');
6 | describe('moda custom file templates via .yo-rc.json', function() {
7 | var generatorPath = '../d';
8 |
9 | var testArguments = 'test-name';
10 | var expectedContent = [
11 | ['app/scripts/test-name/test-name-d.js', /testName/],
12 | ['app/scripts/test-name/test-name-d.js', /module\('tmp'\)/],
13 | ['app/scripts/test-name/test-name-d.js', /scripts\/test-name\/test-name-d\.html/],
14 | ['app/scripts/test-name/test-name-d.spec.js', /\('<\/test-name>'\)/],
15 | ['app/scripts/test-name/test-name-d.html', /class="XXXXXX"/]
16 | ];
17 | var expected = [
18 | 'app/scripts/test-name/test-name-d.js',
19 | 'app/scripts/test-name/test-name-d.spec.js',
20 | 'app/scripts/test-name/test-name-d.html',
21 | 'app/scripts/test-name/_test-name-d.scss'
22 | ];
23 |
24 |
25 | var options = {
26 | 'useDefaults': true,
27 | 'skipInject': true
28 | };
29 |
30 | var runGen;
31 |
32 | beforeEach(function() {
33 | runGen = helpers
34 | .run(path.join(__dirname, generatorPath))
35 | .inDir(path.join(__dirname, '.tmp'))
36 | });
37 |
38 | afterEach(function() {
39 | fs.unlinkSync(path.join(__dirname, '.tmp', '.yo-rc.json'));
40 | });
41 |
42 | it('works for html templates', function(done) {
43 | runGen
44 | .withArguments(testArguments)
45 | .withLocalConfig({
46 | subGenerators: {
47 | directive: {
48 | tpl: {
49 | tpl: ''
50 | }
51 | }
52 | }
53 | })
54 | .withOptions(options)
55 | .on('end', function() {
56 | assert.file([].concat(
57 | expected
58 | ));
59 | assert.fileContent([].concat(
60 | expectedContent
61 | ));
62 |
63 | done();
64 | });
65 | });
66 |
67 | it('has common variables available', function(done) {
68 | runGen
69 | .withArguments(testArguments)
70 | .withLocalConfig({
71 | subGenerators: {
72 | directive: {
73 | tpl: {
74 | tpl: '<%=cameledName %>|<%=classedName %>|<%=sluggedName %>|<%=dashedName %>|<%=humanizedName %>'
75 | }
76 | }
77 | }
78 | })
79 | .withOptions(options)
80 | .on('end', function() {
81 | assert.file([].concat(
82 | expected
83 | ));
84 | assert.fileContent([
85 | ['app/scripts/test-name/test-name-d.html', 'testName|TestName|test-name|test-name|Test name']
86 | ]);
87 | done();
88 | });
89 | });
90 |
91 |
92 | it('works with services created from directives', function(done) {
93 | runGen
94 | .withArguments(testArguments)
95 | .withOptions({
96 | 'skipInject': true
97 | })
98 | .withPrompts({
99 | createService: 'service'
100 | })
101 | .withLocalConfig({
102 | subGenerators: {
103 | directive: {
104 | tpl: {
105 | tpl: 'HTML',
106 | script: 'JS',
107 | style: 'SCSS',
108 | spec: 'SPEC',
109 | }
110 | },
111 | service: {
112 | tpl: {
113 | script: 'SERVICE_JS',
114 | spec: 'SERVICE_JS_SPEC'
115 | }
116 | }
117 | }
118 | })
119 | .on('end', function() {
120 | assert.file([].concat(
121 | expected
122 | ));
123 | assert.fileContent([
124 | ['app/scripts/test-name/test-name-d.js', 'JS'],
125 | ['app/scripts/test-name/test-name-d.spec.js', 'SPEC'],
126 | ['app/scripts/test-name/test-name-d.html', 'HTML'],
127 | ['app/scripts/test-name/_test-name-d.scss', 'SCSS'],
128 | ['app/scripts/test-name/test-name-s.js', 'SERVICE_JS'],
129 | ['app/scripts/test-name/test-name-s.spec.js', 'SERVICE_JS_SPEC'],
130 | ]);
131 |
132 | done();
133 | });
134 | });
135 | });
136 |
--------------------------------------------------------------------------------
/test/decorator.spec.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 | var path = require('path');
3 | var assert = require('assert');
4 | var helpers = require('yeoman-test');
5 | var assert = require('yeoman-assert');
6 |
7 | describe('moda Decorator generator', function() {
8 | var generatorPath = '../decorator';
9 | // not testing the actual run of generators yet
10 | it('can be required without throwing', function() {
11 | this.app = require(generatorPath);
12 | });
13 |
14 | describe('basic file creation', function() {
15 | var testArguments = 'test-name';
16 | var expectedContent = [
17 | ['app/scripts/main/global-services/test-name-decorator.js', /TestName/],
18 | ['app/scripts/main/global-services/test-name-decorator.js', /module\('tmp'\)/],
19 | ['app/scripts/main/global-services/test-name-decorator.spec.js', /TestName/]
20 | ];
21 | var expected = [
22 | 'app/scripts/main/global-services/test-name-decorator.js',
23 | 'app/scripts/main/global-services/test-name-decorator.spec.js'
24 | ];
25 |
26 | var noFile = [
27 | 'app/scripts/test-name/test-name-decorator.js',
28 | 'app/scripts/test-name-decorator.js',
29 | 'app/scripts/global-services/test-name-s.js'
30 | ];
31 |
32 | var nonExpected = [
33 | ['app/scripts/main/global-services/test-name-decorator.js', /testName/]
34 | ];
35 |
36 | var options = {
37 | 'skipInject': true
38 | };
39 |
40 | var runGen;
41 |
42 | beforeEach(function() {
43 | runGen = helpers
44 | .run(path.join(__dirname, generatorPath))
45 | .inDir(path.join(__dirname, '.tmp'))
46 | });
47 |
48 | it('creates expected files', function(done) {
49 | runGen
50 | .withArguments(testArguments)
51 | .withOptions(options)
52 | .on('end', function() {
53 | assert.file([].concat(
54 | expected
55 | ));
56 | assert.noFile([].concat(
57 | noFile
58 | ));
59 | assert.fileContent([].concat(
60 | expectedContent
61 | ));
62 | assert.noFileContent([].concat(
63 | nonExpected
64 | ));
65 | done();
66 | });
67 | });
68 | });
69 |
70 |
71 | describe('file in sub folder creation', function() {
72 | var testArguments = 'test-name test-path';
73 | var expectedContent = [
74 | ['app/scripts/test-path/test-name-decorator.js', /TestName/],
75 | ['app/scripts/test-path/test-name-decorator.js', /module\('tmp'\)/],
76 | ['app/scripts/test-path/test-name-decorator.spec.js', /TestName/]
77 | ];
78 | var expected = [
79 | 'app/scripts/test-path/test-name-decorator.js',
80 | 'app/scripts/test-path/test-name-decorator.spec.js'
81 |
82 | ];
83 | var noFile = [
84 | 'app/scripts/test-path/test-name-s.js',
85 | 'app/scripts/test-name-decorator.js',
86 | 'app/scripts/test-path/test-name-d.html',
87 | 'app/scripts/test-path/_test-name-d.scss'
88 | ];
89 |
90 | var nonExpected = [
91 | ['app/scripts/test-path/test-name-decorator.js', /testName/]
92 | ];
93 |
94 | var options = {
95 | 'skipInject': true
96 | };
97 |
98 | var runGen;
99 |
100 | beforeEach(function() {
101 | runGen = helpers
102 | .run(path.join(__dirname, generatorPath))
103 | .inDir(path.join(__dirname, '.tmp'))
104 | });
105 |
106 | it('creates expected files', function(done) {
107 | runGen
108 | .withArguments(testArguments)
109 | .withOptions(options)
110 | .on('end', function() {
111 | assert.file([].concat(
112 | expected
113 | ));
114 | assert.noFile([].concat(
115 | noFile
116 | ));
117 | assert.fileContent([].concat(
118 | expectedContent
119 | ));
120 | assert.noFileContent([].concat(
121 | nonExpected
122 | ));
123 | done();
124 | });
125 | });
126 | });
127 | });
--------------------------------------------------------------------------------
/test/directive.spec.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 | var path = require('path');
3 | var assert = require('assert');
4 | var helpers = require('yeoman-test');
5 | var assert = require('yeoman-assert');
6 |
7 | describe('moda Directive generator', function() {
8 | // not testing the actual run of generators yet
9 | it('can be required without throwing', function() {
10 | this.app = require('../d');
11 | });
12 |
13 | describe('basic file creation', function() {
14 | var testArguments = 'test-name';
15 | var expectedContent = [
16 | ['app/scripts/test-name/test-name-d.js', /testName/],
17 | ['app/scripts/test-name/test-name-d.js', /module\('tmp'\)/],
18 | ['app/scripts/test-name/test-name-d.js', /scripts\/test-name\/test-name-d\.html/],
19 | ['app/scripts/test-name/test-name-d.spec.js', /\('<\/test-name>'\)/],
20 | ['app/scripts/test-name/test-name-d.html', /testName/],
21 | ];
22 | var expected = [
23 | 'app/scripts/test-name/test-name-d.js',
24 | 'app/scripts/test-name/test-name-d.spec.js',
25 | 'app/scripts/test-name/test-name-d.html',
26 | 'app/scripts/test-name/_test-name-d.scss'
27 | ];
28 |
29 | var noFile = [
30 | 'app/scripts/test-name/test-name-s.js',
31 | 'app/scripts/test-name/test-name-f.js',
32 | 'app/scripts/test-name-d.js'
33 | ];
34 |
35 | var nonExpected = [
36 | ['app/scripts/test-name/test-name-d.js', /testNamea/]
37 | ];
38 |
39 | var options = {
40 | 'useDefaults': true,
41 | 'skipInject': true
42 | };
43 |
44 | var runGen;
45 |
46 | beforeEach(function() {
47 | runGen = helpers
48 | .run(path.join(__dirname, '../d'))
49 | .inDir(path.join(__dirname, '.tmp'))
50 | });
51 |
52 | it('creates expected files', function(done) {
53 | runGen
54 | .withArguments(testArguments)
55 | .withOptions(options)
56 | .on('end', function() {
57 | assert.file([].concat(
58 | expected
59 | ));
60 | assert.noFile([].concat(
61 | noFile
62 | ));
63 | assert.fileContent([].concat(
64 | expectedContent
65 | ));
66 | assert.noFileContent([].concat(
67 | nonExpected
68 | ));
69 | done();
70 | });
71 | });
72 | });
73 |
74 |
75 | describe('file in sub folder creation', function() {
76 | var testArguments = 'test-name test-path';
77 | var expectedContent = [
78 | ['app/scripts/test-path/test-name/test-name-d.js', /testName/],
79 | ['app/scripts/test-path/test-name/test-name-d.js', /module\('tmp'\)/],
80 | ['app/scripts/test-path/test-name/test-name-d.js', /scripts\/test-path\/test-name\/test-name-d\.html/],
81 | ['app/scripts/test-path/test-name/test-name-d.spec.js', /\('<\/test-name>'\)/],
82 | ['app/scripts/test-path/test-name/test-name-d.html', /testName/],
83 | ];
84 | var expected = [
85 | 'app/scripts/test-path/test-name/test-name-d.js',
86 | 'app/scripts/test-path/test-name/test-name-d.spec.js',
87 | 'app/scripts/test-path/test-name/test-name-d.html',
88 | 'app/scripts/test-path/test-name/_test-name-d.scss'
89 | ];
90 |
91 | var noFile = [
92 | 'app/scripts/test-path/test-name/test-name-s.js',
93 | 'app/scripts/test-path/test-name/test-name-f.js',
94 | 'app/scripts/test-name-d.js'
95 | ];
96 |
97 | var nonExpected = [
98 | ['app/scripts/test-path/test-name/test-name-d.js', /testNamea/]
99 | ];
100 |
101 | var options = {
102 | 'useDefaults': true,
103 | 'skipInject': true
104 | };
105 |
106 | var runGen;
107 |
108 | beforeEach(function() {
109 | runGen = helpers
110 | .run(path.join(__dirname, '../d'))
111 | .inDir(path.join(__dirname, '.tmp'))
112 | });
113 |
114 | it('creates expected files', function(done) {
115 | runGen
116 | .withArguments(testArguments)
117 | .withOptions(options)
118 | .on('end', function() {
119 | assert.file([].concat(
120 | expected
121 | ));
122 | assert.noFile([].concat(
123 | noFile
124 | ));
125 | assert.fileContent([].concat(
126 | expectedContent
127 | ));
128 | assert.noFileContent([].concat(
129 | nonExpected
130 | ));
131 | done();
132 | });
133 | });
134 | });
135 |
136 |
137 | describe('file with service creation and no template (in sub folder)', function() {
138 | var testArguments = 'test-name test-path';
139 | var expectedContent = [
140 | ['app/scripts/test-path/test-name/test-name-d.js', /testName/],
141 | ['app/scripts/test-path/test-name/test-name-d.js', /module\('tmp'\)/],
142 | ['app/scripts/test-path/test-name/test-name-s.js', /module\('tmp'\)/],
143 | ['app/scripts/test-path/test-name/test-name-s.js', /TestName/],
144 | ['app/scripts/test-path/test-name/test-name-s.spec.js', /TestName/],
145 | ['app/scripts/test-path/test-name/test-name-d.spec.js', /\('<\/test-name>'\)/],
146 | ];
147 | var expected = [
148 | 'app/scripts/test-path/test-name/test-name-d.js',
149 | 'app/scripts/test-path/test-name/test-name-d.spec.js',
150 | 'app/scripts/test-path/test-name/test-name-s.js',
151 | 'app/scripts/test-path/test-name/test-name-s.spec.js'
152 | ];
153 |
154 | var noFile = [
155 | 'app/scripts/test-path/test-name/test-name-f.js',
156 | 'app/scripts/test-path/test-name/test-name-f.spec.js',
157 | 'app/scripts/test-name-d.js',
158 | 'app/scripts/test-path/test-name/test-name-d.html',
159 | 'app/scripts/test-path/test-name/_test-name-d.scss'
160 | ];
161 |
162 | var nonExpected = [
163 | ['app/scripts/test-path/test-name/test-name-d.js', /templateUrl/]
164 | ];
165 |
166 | var options = {
167 | 'skipInject': true
168 | };
169 |
170 | var runGen;
171 |
172 | beforeEach(function() {
173 | runGen = helpers
174 | .run(path.join(__dirname, '../d'))
175 | .inDir(path.join(__dirname, '.tmp'))
176 |
177 | });
178 |
179 | it('creates expected files', function(done) {
180 | runGen
181 | .withArguments(testArguments)
182 | .withPrompts({
183 | createService: 'service',
184 | createTemplate: false
185 | })
186 | .withOptions(options)
187 | .on('end', function() {
188 | assert.file([].concat(
189 | expected
190 | ));
191 | assert.noFile([].concat(
192 | noFile
193 | ));
194 | assert.fileContent([].concat(
195 | expectedContent
196 | ));
197 | assert.noFileContent([].concat(
198 | nonExpected
199 | ));
200 | done();
201 | });
202 | });
203 | });
204 | });
--------------------------------------------------------------------------------
/test/factory.spec.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 | var path = require('path');
3 | var assert = require('assert');
4 | var helpers = require('yeoman-test');
5 | var assert = require('yeoman-assert');
6 |
7 | describe('moda Factory generator', function() {
8 | var generatorPath = '../f';
9 |
10 |
11 | // not testing the actual run of generators yet
12 | it('can be required without throwing', function() {
13 | this.app = require(generatorPath);
14 | });
15 |
16 | describe('basic file creation', function() {
17 | var testArguments = 'test-name';
18 | var expectedContent = [
19 | ['app/scripts/main/global-services/test-name-f.js', /TestName/],
20 | ['app/scripts/main/global-services/test-name-f.js', /module\('tmp'\)/],
21 | ['app/scripts/main/global-services/test-name-f.spec.js', /TestName/]
22 | ];
23 | var expected = [
24 | 'app/scripts/main/global-services/test-name-f.js',
25 | 'app/scripts/main/global-services/test-name-f.spec.js'
26 | ];
27 |
28 | var noFile = [
29 | 'app/scripts/test-name/test-name-f.js',
30 | 'app/scripts/test-name-f.js',
31 | 'app/scripts/global-services/test-name-s.js'
32 | ];
33 |
34 | var nonExpected = [
35 | ['app/scripts/main/global-services/test-name-f.js', /testName/]
36 | ];
37 |
38 | var options = {
39 | 'skipInject': true
40 | };
41 |
42 | var runGen;
43 |
44 | beforeEach(function() {
45 | runGen = helpers
46 | .run(path.join(__dirname, generatorPath))
47 | .inDir(path.join(__dirname, '.tmp'))
48 | });
49 |
50 | it('creates expected files', function(done) {
51 | runGen
52 | .withArguments(testArguments)
53 | .withOptions(options)
54 | .on('end', function() {
55 | assert.file([].concat(
56 | expected
57 | ));
58 | assert.noFile([].concat(
59 | noFile
60 | ));
61 | assert.fileContent([].concat(
62 | expectedContent
63 | ));
64 | assert.noFileContent([].concat(
65 | nonExpected
66 | ));
67 | done();
68 | });
69 | });
70 | });
71 |
72 |
73 | describe('file in sub folder creation', function() {
74 | var testArguments = 'test-name test-path';
75 | var expectedContent = [
76 | ['app/scripts/test-path/test-name-f.js', /TestName/],
77 | ['app/scripts/test-path/test-name-f.js', /module\('tmp'\)/],
78 | ['app/scripts/test-path/test-name-f.spec.js', /TestName/]
79 | ];
80 | var expected = [
81 | 'app/scripts/test-path/test-name-f.js',
82 | 'app/scripts/test-path/test-name-f.spec.js'
83 |
84 | ];
85 | var noFile = [
86 | 'app/scripts/test-path/test-name-s.js',
87 | 'app/scripts/test-name-f.js',
88 | 'app/scripts/test-path/test-name-d.html',
89 | 'app/scripts/test-path/_test-name-d.scss'
90 | ];
91 |
92 | var nonExpected = [
93 | ['app/scripts/test-path/test-name-f.js', /testName/]
94 | ];
95 |
96 | var options = {
97 | 'skipInject': true
98 | };
99 |
100 | var runGen;
101 |
102 | beforeEach(function() {
103 | runGen = helpers
104 | .run(path.join(__dirname, generatorPath))
105 | .inDir(path.join(__dirname, '.tmp'))
106 | });
107 |
108 | it('creates expected files', function(done) {
109 | runGen
110 | .withArguments(testArguments)
111 | .withOptions(options)
112 | .on('end', function() {
113 | assert.file([].concat(
114 | expected
115 | ));
116 | assert.noFile([].concat(
117 | noFile
118 | ));
119 | assert.fileContent([].concat(
120 | expectedContent
121 | ));
122 | assert.noFileContent([].concat(
123 | nonExpected
124 | ));
125 | done();
126 | });
127 | });
128 | });
129 |
130 | describe('with local config for file extension, global path and name-suffix', function() {
131 | var testArguments = 'test-name';
132 | var expectedContent = [
133 | ['app/scripts/factories/test-name-factory.js', /TestNameFactory/],
134 | ['app/scripts/factories/test-name-factory.js', /module\('tmp'\)/],
135 | ['app/scripts/factories/test-name-factory.spec.js', /TestNameFactory/]
136 | ];
137 | var expected = [
138 | 'app/scripts/factories/test-name-factory.js',
139 | 'app/scripts/factories/test-name-factory.spec.js'
140 |
141 | ];
142 | var noFile = [
143 | 'app/scripts/main/global-services/test-name-f.js',
144 | 'app/scripts/main/global-services/test-name-factory.js',
145 | 'app/scripts/test-name-factory.js',
146 | 'app/scripts/factories/test-name-d.html',
147 | 'app/scripts/factories/_test-name-d.scss'
148 | ];
149 |
150 | var nonExpected = [
151 | ['app/scripts/factories/test-name-factory.js', /testNameFactory/]
152 | ];
153 |
154 | var options = {
155 | 'skipInject': true
156 | };
157 |
158 | var runGen;
159 |
160 | beforeEach(function() {
161 | runGen = helpers
162 | .run(path.join(__dirname, generatorPath))
163 | .inDir(path.join(__dirname, '.tmp'))
164 | });
165 |
166 | it('creates expected files', function(done) {
167 | runGen
168 | .withLocalConfig({
169 | subGenerators: {
170 | factory: {
171 | nameSuffix: 'Factory',
172 | suffix: '-factory',
173 | globalDir: 'factories'
174 | }
175 | }
176 | })
177 | .withArguments(testArguments)
178 | .withOptions(options)
179 | .on('end', function() {
180 | assert.file([].concat(
181 | expected
182 | ));
183 | assert.noFile([].concat(
184 | noFile
185 | ));
186 | assert.fileContent([].concat(
187 | expectedContent
188 | ));
189 | assert.noFileContent([].concat(
190 | nonExpected
191 | ));
192 | done();
193 | });
194 | });
195 | });
196 | });
--------------------------------------------------------------------------------
/test/filter.spec.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 | var path = require('path');
3 | var assert = require('assert');
4 | var helpers = require('yeoman-test');
5 | var assert = require('yeoman-assert');
6 |
7 | describe('moda Filter generator', function() {
8 | var generatorPath = '../filter';
9 | // not testing the actual run of generators yet
10 | it('can be required without throwing', function() {
11 | this.app = require(generatorPath);
12 | });
13 |
14 | describe('basic file creation', function() {
15 | var testArguments = 'test-name';
16 | var expectedContent = [
17 | ['app/scripts/main/global-filters/test-name-filter.js', /testName/],
18 | ['app/scripts/main/global-filters/test-name-filter.js', /module\('tmp'\)/],
19 | ['app/scripts/main/global-filters/test-name-filter.spec.js', /testName/]
20 | ];
21 | var expected = [
22 | 'app/scripts/main/global-filters/test-name-filter.js',
23 | 'app/scripts/main/global-filters/test-name-filter.spec.js'
24 | ];
25 |
26 | var noFile = [
27 | 'app/scripts/test-name/test-name-filter.js',
28 | 'app/scripts/test-name-filter.js',
29 | 'app/scripts/global-filters/test-name-s.js'
30 | ];
31 |
32 | var nonExpected = [
33 | ['app/scripts/main/global-filters/test-name-filter.js', /TestName/]
34 | ];
35 |
36 | var options = {
37 | 'skipInject': true
38 | };
39 |
40 | var runGen;
41 |
42 | beforeEach(function() {
43 | runGen = helpers
44 | .run(path.join(__dirname, generatorPath))
45 | .inDir(path.join(__dirname, '.tmp'))
46 | });
47 |
48 | it('creates expected files', function(done) {
49 | runGen
50 | .withArguments(testArguments)
51 | .withOptions(options)
52 | .on('end', function() {
53 | assert.file([].concat(
54 | expected
55 | ));
56 | assert.noFile([].concat(
57 | noFile
58 | ));
59 | assert.fileContent([].concat(
60 | expectedContent
61 | ));
62 | assert.noFileContent([].concat(
63 | nonExpected
64 | ));
65 | done();
66 | });
67 | });
68 | });
69 |
70 |
71 | describe('file in sub folder creation', function() {
72 | var testArguments = 'test-name test-path';
73 | var expectedContent = [
74 | ['app/scripts/test-path/test-name-filter.js', /testName/],
75 | ['app/scripts/test-path/test-name-filter.js', /module\('tmp'\)/],
76 | ['app/scripts/test-path/test-name-filter.spec.js', /testName/]
77 | ];
78 | var expected = [
79 | 'app/scripts/test-path/test-name-filter.js',
80 | 'app/scripts/test-path/test-name-filter.spec.js'
81 |
82 | ];
83 | var noFile = [
84 | 'app/scripts/test-path/test-name-s.js',
85 | 'app/scripts/test-name-filter.js',
86 | 'app/scripts/test-path/test-name-d.html',
87 | 'app/scripts/test-path/test-name-filter.html',
88 | 'app/scripts/test-path/test-name-filter.scss',
89 | 'app/scripts/test-path/_test-name-d.scss'
90 | ];
91 |
92 | var nonExpected = [
93 | ['app/scripts/test-path/test-name-filter.js', /TestName/]
94 | ];
95 |
96 | var options = {
97 | 'skipInject': true
98 | };
99 |
100 | var runGen;
101 |
102 | beforeEach(function() {
103 | runGen = helpers
104 | .run(path.join(__dirname, generatorPath))
105 | .inDir(path.join(__dirname, '.tmp'))
106 | });
107 |
108 | it('creates expected files', function(done) {
109 | runGen
110 | .withArguments(testArguments)
111 | .withOptions(options)
112 | .on('end', function() {
113 | assert.file([].concat(
114 | expected
115 | ));
116 | assert.noFile([].concat(
117 | noFile
118 | ));
119 | assert.fileContent([].concat(
120 | expectedContent
121 | ));
122 | assert.noFileContent([].concat(
123 | nonExpected
124 | ));
125 | done();
126 | });
127 | });
128 | });
129 | });
--------------------------------------------------------------------------------
/test/helper.spec.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 | var path = require('path');
3 | var assert = require('yeoman-assert');
4 | var helperScripts = require('../helper.js');
5 | var fs = require('fs');
6 |
7 | describe('moda Helper-Scripts', function() {
8 | helperScripts.STATE_NEEDLE = '/* NEEEEEEDLE */';
9 |
10 | describe('addToFile', function() {
11 | var fn = helperScripts.addToFile;
12 | var code = 'alert("asd");';
13 | var needle = '/* NEEEEEEDLE */';
14 | var testFile = path.join(__dirname, '.tmp/test-file.js');
15 | var testFileContent = needle;
16 |
17 |
18 | beforeEach(function(done) {
19 | fs.writeFile(testFile, testFileContent, function(err) {
20 | if (err) {
21 | return console.log(err);
22 | }
23 | done();
24 | });
25 | });
26 |
27 | afterEach(function(done) {
28 | // remove files
29 | fs.unlink(testFile, function() {
30 | done();
31 | });
32 | });
33 |
34 | it('injects code above a needle', function() {
35 | fn(testFile, code, needle);
36 | assert.fileContent([
37 | [testFile, 'alert("asd");\n/* NEEEEEEDLE */']
38 | ]);
39 |
40 | // works multiple times
41 | fn(testFile, code, needle);
42 | assert.fileContent([
43 | [testFile, 'alert("asd");\nalert("asd");\n/* NEEEEEEDLE */']
44 | ]);
45 | });
46 | });
47 |
48 | describe('injectRoute', function() {
49 | var fn = helperScripts.injectRoute;
50 | var needle = '/* NEEEEEEDLE */';
51 | var routesFile = path.join(__dirname, '.tmp/test-route.js');
52 | var routesFileContent = needle;
53 | var url = '/some-url';
54 | var mockGen = {
55 | log: {
56 | writeln: function() {
57 |
58 | }
59 | }
60 | };
61 |
62 | beforeEach(function(done) {
63 | // create test routes file
64 | fs.writeFile(routesFile, routesFileContent, function(err) {
65 | if (err) {
66 | return console.log(err);
67 | }
68 | done();
69 | });
70 | });
71 |
72 | afterEach(function(done) {
73 | // remove files
74 | fs.unlink(routesFile, function() {
75 | done();
76 | });
77 | });
78 |
79 | it('injects state above a needle', function() {
80 | fn(routesFile, 'test.name', url, false, false, mockGen);
81 | assert.fileContent([
82 | [routesFile, /test\.name/],
83 | [routesFile, url],
84 | [routesFile, /test\.name/],
85 | [routesFile, /test\.name/],
86 | [routesFile, /\.state\('test\.name', \{\s*url:\s*'\/some-url'\s*}\)\s*\/\* NEEEEEEDLE \*\//]
87 | ]);
88 | });
89 |
90 | it('injects the controller and template if given', function() {
91 | fn(routesFile, 'test.name', url, 'some.html', 'SomeCtrl', mockGen);
92 | assert.fileContent([
93 | [routesFile, /test\.name/],
94 | [routesFile, url],
95 | [routesFile, 'SomeCtrl'],
96 | [routesFile, 'some.html'],
97 | [routesFile, /\.state\('test\.name', \{\s*url:\s*'\/some-url',\s*controller:\s*'SomeCtrl',\s*controllerAs:\s*'vm',\s*templateUrl:\s*'some.html'\s+}\)\s*\/\* NEEEEEEDLE \*\//]
98 | ]);
99 | });
100 |
101 | it('injects the a template if given', function() {
102 | fn(routesFile, 'test.name', url, 'some.html', false, mockGen);
103 | assert.fileContent([
104 | [routesFile, /test\.name/],
105 | [routesFile, url],
106 | [routesFile, 'some.html'],
107 | [routesFile, /\.state\('test\.name', \{\s*url:\s*'\/some-url',\s*templateUrl:\s*'some.html'\s+}\)\s*\/\* NEEEEEEDLE \*\//]
108 | ]);
109 | });
110 | });
111 | });
--------------------------------------------------------------------------------
/test/provider.spec.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 | var path = require('path');
3 | var assert = require('assert');
4 | var helpers = require('yeoman-test');
5 | var assert = require('yeoman-assert');
6 |
7 | describe('moda Provider generator', function() {
8 | var generatorPath = '../p';
9 | // not testing the actual run of generators yet
10 | it('can be required without throwing', function() {
11 | this.app = require(generatorPath);
12 | });
13 |
14 | describe('basic file creation', function() {
15 | var testArguments = 'test-name';
16 | var expectedContent = [
17 | ['app/scripts/main/global-services/test-name-p.js', /TestName/],
18 | ['app/scripts/main/global-services/test-name-p.js', /module\('tmp'\)/],
19 | ['app/scripts/main/global-services/test-name-p.spec.js', /TestName/]
20 | ];
21 | var expected = [
22 | 'app/scripts/main/global-services/test-name-p.js',
23 | 'app/scripts/main/global-services/test-name-p.spec.js'
24 | ];
25 |
26 | var noFile = [
27 | 'app/scripts/test-name/test-name-p.js',
28 | 'app/scripts/test-name-p.js',
29 | 'app/scripts/global-services/test-name-s.js'
30 | ];
31 |
32 | var nonExpected = [
33 | ['app/scripts/main/global-services/test-name-p.js', /testName/]
34 | ];
35 |
36 | var options = {
37 | 'skipInject': true
38 | };
39 |
40 | var runGen;
41 |
42 | beforeEach(function() {
43 | runGen = helpers
44 | .run(path.join(__dirname, generatorPath))
45 | .inDir(path.join(__dirname, '.tmp'))
46 | });
47 |
48 | it('creates expected files', function(done) {
49 | runGen
50 | .withArguments(testArguments)
51 | .withOptions(options)
52 | .on('end', function() {
53 | assert.file([].concat(
54 | expected
55 | ));
56 | assert.noFile([].concat(
57 | noFile
58 | ));
59 | assert.fileContent([].concat(
60 | expectedContent
61 | ));
62 | assert.noFileContent([].concat(
63 | nonExpected
64 | ));
65 | done();
66 | });
67 | });
68 | });
69 |
70 |
71 | describe('file in sub folder creation', function() {
72 | var testArguments = 'test-name test-path';
73 | var expectedContent = [
74 | ['app/scripts/test-path/test-name-p.js', /TestName/],
75 | ['app/scripts/test-path/test-name-p.js', /module\('tmp'\)/],
76 | ['app/scripts/test-path/test-name-p.spec.js', /TestName/]
77 | ];
78 | var expected = [
79 | 'app/scripts/test-path/test-name-p.js',
80 | 'app/scripts/test-path/test-name-p.spec.js'
81 |
82 | ];
83 | var noFile = [
84 | 'app/scripts/test-path/test-name-s.js',
85 | 'app/scripts/test-name-p.js',
86 | 'app/scripts/test-path/test-name-d.html',
87 | 'app/scripts/test-path/test-name-p.html',
88 | 'app/scripts/test-path/test-name-p.scss',
89 | 'app/scripts/test-path/_test-name-d.scss'
90 | ];
91 |
92 | var nonExpected = [
93 | ['app/scripts/test-path/test-name-p.js', /testName/]
94 | ];
95 |
96 | var options = {
97 | 'skipInject': true
98 | };
99 |
100 | var runGen;
101 |
102 | beforeEach(function() {
103 | runGen = helpers
104 | .run(path.join(__dirname, generatorPath))
105 | .inDir(path.join(__dirname, '.tmp'))
106 | });
107 |
108 | it('creates expected files', function(done) {
109 | runGen
110 | .withArguments(testArguments)
111 | .withOptions(options)
112 | .on('end', function() {
113 | assert.file([].concat(
114 | expected
115 | ));
116 | assert.noFile([].concat(
117 | noFile
118 | ));
119 | assert.fileContent([].concat(
120 | expectedContent
121 | ));
122 | assert.noFileContent([].concat(
123 | nonExpected
124 | ));
125 | done();
126 | });
127 | });
128 | });
129 | });
--------------------------------------------------------------------------------
/test/route.spec.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 | var path = require('path');
3 | var helpers = require('yeoman-test');
4 | var assert = require('yeoman-assert');
5 | var fs = require('fs');
6 |
7 |
8 | describe('moda Route generator', function() {
9 | var generatorPath = '../r',
10 | routesDir = 'app/scripts/routes/';
11 |
12 |
13 | // not testing the actual run of generators yet
14 | it('can be required without throwing', function() {
15 | this.app = require(generatorPath);
16 | });
17 |
18 | describe('basic file creation', function() {
19 | var testArguments = 'test-name';
20 | var expectedContent = [
21 | [routesDir + 'test-name/test-name-c.js', /TestNameCtrl/],
22 | [routesDir + 'test-name/test-name-c.js', /module\('tmp'\)/],
23 | [routesDir + 'test-name/test-name-c.spec.js', /TestNameCtrl/],
24 | [routesDir + 'test-name/test-name-c.html', /class="page-test-name"/],
25 | ];
26 | var expected = [
27 | routesDir + 'test-name/test-name-c.js',
28 | routesDir + 'test-name/test-name-c.spec.js',
29 | routesDir + 'test-name/test-name-c.html',
30 | routesDir + 'test-name/_test-name-c.scss'
31 | ];
32 |
33 | var noFile = [
34 | routesDir + 'test-name/test-name-s.js',
35 | routesDir + 'test-name/test-name-f.js',
36 | routesDir + 'test-name-c.js'
37 | ];
38 |
39 | var nonExpected = [
40 | [routesDir + 'test-name/test-name-c.js', /TestNamea/],
41 | [routesDir + 'test-name/test-name-c.js', /testName/],
42 | ];
43 |
44 | var options = {
45 | 'useDefaults': true,
46 | 'skipInject': true
47 | };
48 |
49 | var runGen;
50 |
51 | beforeEach(function() {
52 | runGen = helpers
53 | .run(path.join(__dirname, generatorPath))
54 | .inDir(path.join(__dirname, '.tmp'));
55 | });
56 |
57 | it('creates expected files', function(done) {
58 | runGen
59 | .withArguments(testArguments)
60 | .withOptions(options)
61 | .on('end', function() {
62 | assert.file([].concat(
63 | expected
64 | ));
65 | assert.noFile([].concat(
66 | noFile
67 | ));
68 | assert.fileContent([].concat(
69 | expectedContent
70 | ));
71 | assert.noFileContent([].concat(
72 | nonExpected
73 | ));
74 | done();
75 | });
76 | });
77 | });
78 |
79 |
80 | describe('files in sub folder creation', function() {
81 | var testArguments = 'parState.subState';
82 | var expectedContent = [
83 | [routesDir + 'par-state/sub-state/sub-state-c.js', /SubStateCtrl/],
84 | [routesDir + 'par-state/sub-state/sub-state-c.js', /module\('tmp'\)/],
85 | [routesDir + 'par-state/sub-state/sub-state-c.spec.js', /SubStateCtrl/],
86 | [routesDir + 'par-state/sub-state/sub-state-c.html', /class="page-sub-state"/],
87 | ];
88 | var expected = [
89 | routesDir + 'par-state/sub-state/sub-state-c.js',
90 | routesDir + 'par-state/sub-state/sub-state-c.spec.js',
91 | routesDir + 'par-state/sub-state/sub-state-c.html',
92 | routesDir + 'par-state/sub-state/_sub-state-c.scss'
93 | ];
94 |
95 | var noFile = [
96 | routesDir + 'par-state/sub-state/sub-state-s.js',
97 | routesDir + 'par-state/sub-state/sub-state-f.js',
98 | routesDir + 'sub-state-c.js'
99 | ];
100 |
101 | var nonExpected = [
102 | // is classified
103 | [routesDir + 'par-state/sub-state/sub-state-c.js', /subStateCtrl/]
104 | ];
105 |
106 | var options = {
107 | 'useDefaults': true,
108 | 'skipInject': true
109 | };
110 |
111 | var runGen;
112 |
113 | beforeEach(function() {
114 | runGen = helpers
115 | .run(path.join(__dirname, generatorPath))
116 | .inDir(path.join(__dirname, '.tmp'));
117 | });
118 |
119 | it('creates expected files', function(done) {
120 | runGen
121 | .withArguments(testArguments)
122 | .withOptions(options)
123 | .on('end', function() {
124 | assert.file([].concat(
125 | expected
126 | ));
127 | assert.noFile([].concat(
128 | noFile
129 | ));
130 | assert.fileContent([].concat(
131 | expectedContent
132 | ));
133 | assert.noFileContent([].concat(
134 | nonExpected
135 | ));
136 | done();
137 | });
138 | });
139 | });
140 |
141 |
142 | describe('files with service creation and no template (in sub folder)', function() {
143 | var testArguments = 'parState.subState';
144 | var expectedContent = [
145 | [routesDir + 'par-state/sub-state/sub-state-c.js', /SubStateCtrl/],
146 | [routesDir + 'par-state/sub-state/sub-state-c.js', /module\('tmp'\)/],
147 | [routesDir + 'par-state/sub-state/sub-state-s.js', /module\('tmp'\)/],
148 | [routesDir + 'par-state/sub-state/sub-state-s.js', /SubState/],
149 | [routesDir + 'par-state/sub-state/sub-state-s.spec.js', /SubState/]
150 | ];
151 | var expected = [
152 | routesDir + 'par-state/sub-state/sub-state-c.js',
153 | routesDir + 'par-state/sub-state/sub-state-c.spec.js',
154 | routesDir + 'par-state/sub-state/sub-state-s.js',
155 | routesDir + 'par-state/sub-state/sub-state-s.spec.js'
156 | ];
157 |
158 | var noFile = [
159 | routesDir + 'par-state/sub-state/sub-state-f.js',
160 | routesDir + 'par-state/sub-state/sub-state-f.spec.js',
161 | routesDir + 'sub-state-c.js',
162 | routesDir + 'par-state/sub-state/sub-state-c.html',
163 | routesDir + 'par-state/sub-state/_sub-state-c.scss'
164 | ];
165 |
166 | var nonExpected = [
167 | [routesDir + 'par-state/sub-state/sub-state-s.js', /SubStateCtrl/],
168 | [routesDir + 'par-state/sub-state/sub-state-s.spec.js', /SubStateCtrl/],
169 | ];
170 |
171 | var options = {
172 | 'skipInject': true
173 | };
174 |
175 | var runGen;
176 |
177 | beforeEach(function() {
178 | runGen = helpers
179 | .run(path.join(__dirname, generatorPath))
180 | .inDir(path.join(__dirname, '.tmp'));
181 | });
182 |
183 | it('creates expected files', function(done) {
184 | runGen
185 | .withArguments(testArguments)
186 | .withPrompts({
187 | createService: 'service',
188 | createTemplate: false
189 | })
190 |
191 | .withOptions(options)
192 | .on('end', function() {
193 | assert.file([].concat(
194 | expected
195 | ));
196 | assert.noFile([].concat(
197 | noFile
198 | ));
199 | assert.fileContent([].concat(
200 | expectedContent
201 | ));
202 | assert.noFileContent([].concat(
203 | nonExpected
204 | ));
205 | done();
206 | });
207 | });
208 | });
209 |
210 | // TODO withLocalConfig is not working yet correctly
211 | describe('the routes directory should be configurable', function() {
212 |
213 | var otherRoutesDir = 'app/scripts/other-routes/';
214 | var testArguments = 'parState.subState';
215 | var expectedContent = [
216 | [otherRoutesDir + 'par-state/sub-state/sub-state-c.js', /SubStateCtrl/],
217 | [otherRoutesDir + 'par-state/sub-state/sub-state-c.js', /module\('tmp'\)/],
218 | [otherRoutesDir + 'par-state/sub-state/sub-state-s.js', /module\('tmp'\)/],
219 | [otherRoutesDir + 'par-state/sub-state/sub-state-s.js', /SubState/],
220 | [otherRoutesDir + 'par-state/sub-state/sub-state-s.spec.js', /SubState/]
221 | ];
222 | var expected = [
223 | otherRoutesDir + 'par-state/sub-state/sub-state-c.js',
224 | otherRoutesDir + 'par-state/sub-state/sub-state-c.spec.js',
225 | otherRoutesDir + 'par-state/sub-state/sub-state-s.js',
226 | otherRoutesDir + 'par-state/sub-state/sub-state-s.spec.js'
227 | ];
228 |
229 | var noFile = [
230 | otherRoutesDir + 'par-state/sub-state/sub-state-f.js',
231 | otherRoutesDir + 'par-state/sub-state/sub-state-f.spec.js',
232 | otherRoutesDir + 'sub-state-c.js',
233 | otherRoutesDir + 'par-state/sub-state/sub-state-c.html',
234 | otherRoutesDir + 'par-state/sub-state/_sub-state-c.scss'
235 | ];
236 |
237 | var nonExpected = [];
238 |
239 | var options = {
240 | 'skipInject': true
241 | };
242 |
243 | var runGen;
244 |
245 | beforeEach(function() {
246 | runGen = helpers
247 | .run(path.join(__dirname, generatorPath))
248 | .inDir(path.join(__dirname, '.tmp'));
249 | });
250 |
251 | it('creates expected files', function(done) {
252 | runGen
253 | .withArguments(testArguments)
254 | .withPrompts({
255 | createService: 'service',
256 | createTemplate: false
257 | })
258 | .withLocalConfig({
259 | dirs: {routes: 'other-routes'}
260 | })
261 | .withOptions(options)
262 | .on('end', function() {
263 | assert.file([].concat(
264 | expected
265 | ));
266 | assert.noFile([].concat(
267 | noFile
268 | ));
269 | assert.fileContent([].concat(
270 | expectedContent
271 | ));
272 | assert.noFileContent([].concat(
273 | nonExpected
274 | ));
275 | done();
276 | });
277 | });
278 | });
279 |
280 |
281 | describe('route injection with ui-router', function() {
282 | var testArguments = 'parState.subState';
283 | var routesFile = 'app/scripts/routes.js';
284 |
285 | var expectedContent = [
286 | [routesDir + 'par-state/sub-state/sub-state-c.js', /SubStateCtrl/],
287 | [routesDir + 'par-state/sub-state/sub-state-c.js', /module\('tmp'\)/],
288 | [routesFile, /subState/]
289 | ];
290 | var expected = [
291 | routesDir + 'par-state/sub-state/sub-state-c.js',
292 | routesDir + 'par-state/sub-state/sub-state-c.spec.js',
293 | routesDir + 'par-state/sub-state/sub-state-c.html',
294 | routesDir + 'par-state/sub-state/_sub-state-c.scss',
295 | routesFile
296 | ];
297 |
298 | var noFile = [
299 | routesDir + 'par-state/sub-state/sub-state-f.js',
300 | routesDir + 'par-state/sub-state/sub-state-f.spec.js',
301 | routesDir + 'sub-state-c.js'
302 | ];
303 |
304 | var nonExpected = [];
305 |
306 | var options = {
307 | 'skipInject': true
308 | };
309 |
310 | var runGen;
311 |
312 | beforeEach(function() {
313 | runGen = helpers
314 | .run(path.join(__dirname, generatorPath))
315 | .inDir(path.join(__dirname, '.tmp'));
316 | });
317 |
318 | it('injects routes into the router.js', function(done) {
319 | runGen
320 | .withArguments(testArguments)
321 | .withLocalConfig({
322 | uiRouter: true,
323 | routesFile: routesFile,
324 | dirs: {routes: 'routes'}
325 | })
326 | .withPrompts({
327 | createTemplate: true,
328 | createCtrl: true
329 | })
330 | .withOptions(options)
331 | .on('end', function() {
332 | assert.file([].concat(
333 | expected
334 | ));
335 | assert.noFile([].concat(
336 | noFile
337 | ));
338 | assert.fileContent([].concat(
339 | expectedContent
340 | ));
341 | assert.noFileContent([].concat(
342 | nonExpected
343 | ));
344 | done();
345 | });
346 | });
347 | });
348 | });
--------------------------------------------------------------------------------
/test/service.spec.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 | var path = require('path');
3 | var assert = require('assert');
4 | var helpers = require('yeoman-test');
5 | var assert = require('yeoman-assert');
6 |
7 | describe('moda Service generator', function() {
8 | // not testing the actual run of generators yet
9 | it('can be required without throwing', function() {
10 | this.app = require('../s');
11 | });
12 |
13 | describe('basic file creation', function() {
14 | var testArguments = 'test-name';
15 | var expectedContent = [
16 | ['app/scripts/main/global-services/test-name-s.js', /TestName/],
17 | ['app/scripts/main/global-services/test-name-s.js', /module\('tmp'\)/],
18 | ['app/scripts/main/global-services/test-name-s.spec.js', /TestName/]
19 | ];
20 | var expected = [
21 | 'app/scripts/main/global-services/test-name-s.js',
22 | 'app/scripts/main/global-services/test-name-s.spec.js'
23 | ];
24 |
25 | var noFile = [
26 | 'app/scripts/test-name/test-name-s.js',
27 | 'app/scripts/test-name-s.js',
28 | 'app/scripts/global-services/test-name-f.js'
29 | ];
30 |
31 | var nonExpected = [
32 | ['app/scripts/main/global-services/test-name-s.js', /testName/]
33 | ];
34 |
35 | var options = {
36 | 'skipInject': true
37 | };
38 |
39 | var runGen;
40 |
41 | beforeEach(function() {
42 | runGen = helpers
43 | .run(path.join(__dirname, '../s'))
44 | .inDir(path.join(__dirname, '.tmp'))
45 | });
46 |
47 | it('creates expected files', function(done) {
48 | runGen
49 | .withArguments(testArguments)
50 | .withOptions(options)
51 | .on('end', function() {
52 | assert.file([].concat(
53 | expected
54 | ));
55 | assert.noFile([].concat(
56 | noFile
57 | ));
58 | assert.fileContent([].concat(
59 | expectedContent
60 | ));
61 | assert.noFileContent([].concat(
62 | nonExpected
63 | ));
64 | done();
65 | });
66 | });
67 | });
68 |
69 |
70 | describe('files in sub folder creation', function() {
71 | var testArguments = 'test-name test-path';
72 | var expectedContent = [
73 | ['app/scripts/test-path/test-name-s.js', /TestName/],
74 | ['app/scripts/test-path/test-name-s.js', /module\('tmp'\)/],
75 | ['app/scripts/test-path/test-name-s.spec.js', /TestName/]
76 | ];
77 | var expected = [
78 | 'app/scripts/test-path/test-name-s.js',
79 | 'app/scripts/test-path/test-name-s.spec.js'
80 |
81 | ];
82 | var noFile = [
83 | 'app/scripts/test-path/test-name-f.js',
84 | 'app/scripts/test-name-s.js',
85 | 'app/scripts/test-path/test-name-d.html',
86 | 'app/scripts/test-path/_test-name-d.scss'
87 | ];
88 |
89 | var nonExpected = [
90 | ['app/scripts/test-path/test-name-s.js', /testName/]
91 | ];
92 |
93 | var options = {
94 | 'skipInject': true
95 | };
96 |
97 | var runGen;
98 |
99 | beforeEach(function() {
100 | runGen = helpers
101 | .run(path.join(__dirname, '../s'))
102 | .inDir(path.join(__dirname, '.tmp'))
103 | });
104 |
105 | it('creates expected files', function(done) {
106 | runGen
107 | .withArguments(testArguments)
108 | .withOptions(options)
109 | .on('end', function() {
110 | assert.file([].concat(
111 | expected
112 | ));
113 | assert.noFile([].concat(
114 | noFile
115 | ));
116 | assert.fileContent([].concat(
117 | expectedContent
118 | ));
119 | assert.noFileContent([].concat(
120 | nonExpected
121 | ));
122 | done();
123 | });
124 | });
125 | });
126 |
127 | describe('with local config for file extension, global path and name-suffix', function() {
128 | var testArguments = 'test-name';
129 | var expectedContent = [
130 | ['app/scripts/services/test-name-service.js', /TestNameService/],
131 | ['app/scripts/services/test-name-service.js', /module\('tmp'\)/],
132 | ['app/scripts/services/test-name-service.spec.js', /TestNameService/]
133 | ];
134 | var expected = [
135 | 'app/scripts/services/test-name-service.js',
136 | 'app/scripts/services/test-name-service.spec.js'
137 |
138 | ];
139 | var noFile = [
140 | 'app/scripts/services/test-name-f.js',
141 | 'app/scripts/test-name-service.js',
142 | 'app/scripts/services/test-name-d.html',
143 | 'app/scripts/services/_test-name-d.scss'
144 | ];
145 |
146 | var nonExpected = [
147 | ['app/scripts/services/test-name-service.js', /testNameService/]
148 | ];
149 |
150 | var options = {
151 | 'skipInject': true
152 | };
153 |
154 | var runGen;
155 |
156 | beforeEach(function() {
157 | runGen = helpers
158 | .run(path.join(__dirname, '../s'))
159 | .inDir(path.join(__dirname, '.tmp'))
160 | });
161 |
162 | it('creates expected files', function(done) {
163 | runGen
164 | .withLocalConfig({
165 | subGenerators: {
166 | service: {
167 | nameSuffix: 'Service',
168 | suffix: '-service',
169 | globalDir: 'services'
170 | }
171 | }
172 | })
173 | .withArguments(testArguments)
174 | .withOptions(options)
175 | .on('end', function() {
176 | assert.file([].concat(
177 | expected
178 | ));
179 | assert.noFile([].concat(
180 | noFile
181 | ));
182 | assert.fileContent([].concat(
183 | expectedContent
184 | ));
185 | assert.noFileContent([].concat(
186 | nonExpected
187 | ));
188 | done();
189 | });
190 | });
191 | });
192 | });
--------------------------------------------------------------------------------