├── .gitattributes ├── app ├── templates │ ├── gitattributes │ ├── bowerrc │ ├── hbs │ │ ├── index.hbs │ │ └── application.hbs │ ├── scripts │ │ ├── store.js │ │ ├── store.coffee │ │ ├── router.coffee │ │ ├── router.js │ │ ├── routes │ │ │ ├── application_route.coffee │ │ │ └── application_route.js │ │ ├── app.coffee │ │ └── app.js │ ├── styles │ │ ├── style.css │ │ ├── style_bootstrap.scss │ │ └── normalize.css │ ├── gitignore │ ├── index.html │ ├── _bower.json │ ├── editorconfig │ ├── _jshintrc │ ├── test │ │ ├── integration │ │ │ ├── _index.coffee │ │ │ └── _index.js │ │ ├── _initializer.coffee │ │ └── _initializer.js │ ├── _package.json │ ├── karma.conf.js │ └── Gruntfile.js └── index.js ├── .gitignore ├── .travis.yml ├── contributing.md ├── view ├── templates │ ├── single.js │ ├── single.coffee │ ├── single_edit.coffee │ ├── single_edit.js │ ├── plural.coffee │ ├── plural.js │ ├── plural.hbs │ ├── single_edit.hbs │ └── single.hbs └── index.js ├── component ├── templates │ ├── component.coffee │ ├── component.js │ └── component.hbs └── index.js ├── controller ├── templates │ ├── base.coffee │ ├── plural.coffee │ ├── base.js │ ├── plural.js │ ├── plural_route.coffee │ ├── plural_route.js │ ├── single_route.coffee │ ├── single_route.js │ ├── base_edit.coffee │ ├── single_edit_route.coffee │ ├── base_edit.js │ └── single_edit_route.js └── index.js ├── project └── img │ └── screenshots │ └── 2013_07_17.png ├── script └── reset_dev_env.sh ├── utils └── js_path.js ├── .editorconfig ├── router ├── templates │ ├── base.coffee │ └── base.js └── index.js ├── .jshintrc ├── test ├── helpers │ ├── expected_component_files.js │ ├── expected_model_files.js │ ├── expected_view_files.js │ └── expected_controller_files.js ├── test-router.js ├── test-view.js ├── test-component.js ├── test-karma.js ├── test-controller.js ├── test-model.js ├── test-compass.js └── test-file-creation.js ├── model ├── templates │ ├── base.coffee │ └── base.js └── index.js ├── package.json ├── changelog.md └── readme.md /.gitattributes: -------------------------------------------------------------------------------- 1 | * text=auto 2 | -------------------------------------------------------------------------------- /app/templates/gitattributes: -------------------------------------------------------------------------------- 1 | * text=auto -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | test/temp 3 | temp/ 4 | npm-debug.log 5 | -------------------------------------------------------------------------------- /app/templates/bowerrc: -------------------------------------------------------------------------------- 1 | { 2 | "directory": "app/bower_components" 3 | } 4 | -------------------------------------------------------------------------------- /app/templates/hbs/index.hbs: -------------------------------------------------------------------------------- 1 |
2 | Welcome to Yeoman and Ember.js! 3 |
4 | -------------------------------------------------------------------------------- /app/templates/scripts/store.js: -------------------------------------------------------------------------------- 1 | <%= _.classify(appname) %>.ApplicationAdapter = DS.FixtureAdapter; 2 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | sudo: false 2 | language: node_js 3 | node_js: 4 | - 'iojs' 5 | - '0.12' 6 | - '0.10' 7 | -------------------------------------------------------------------------------- /app/templates/scripts/store.coffee: -------------------------------------------------------------------------------- 1 | <%= _.classify(appname) %>.ApplicationAdapter = DS.FixtureAdapter 2 | -------------------------------------------------------------------------------- /app/templates/styles/style.css: -------------------------------------------------------------------------------- 1 | /* Put your CSS here */ 2 | html, body { 3 | margin: 30px 0; 4 | } 5 | -------------------------------------------------------------------------------- /app/templates/scripts/router.coffee: -------------------------------------------------------------------------------- 1 | <%= _.classify(appname) %>.Router.map -> 2 | # Add your routes here 3 | -------------------------------------------------------------------------------- /contributing.md: -------------------------------------------------------------------------------- 1 | See the [contributing docs](https://github.com/yeoman/yeoman/blob/master/contributing.md) 2 | -------------------------------------------------------------------------------- /view/templates/single.js: -------------------------------------------------------------------------------- 1 | <%= _.classify(appname) %>.<%= _.classify(name) %>View = Ember.View.extend({ 2 | }); 3 | -------------------------------------------------------------------------------- /view/templates/single.coffee: -------------------------------------------------------------------------------- 1 | <%= _.classify(appname) %>.<%= _.classify(name) %>View = Ember.View.extend( 2 | ) 3 | -------------------------------------------------------------------------------- /view/templates/single_edit.coffee: -------------------------------------------------------------------------------- 1 | <%= _.classify(appname) %>.<%= _.classify(name) %>EditView = Ember.View.extend( 2 | ) 3 | -------------------------------------------------------------------------------- /view/templates/single_edit.js: -------------------------------------------------------------------------------- 1 | <%= _.classify(appname) %>.<%= _.classify(name) %>EditView = Ember.View.extend({ 2 | }); 3 | -------------------------------------------------------------------------------- /app/templates/scripts/router.js: -------------------------------------------------------------------------------- 1 | <%= _.classify(appname) %>.Router.map(function () { 2 | // Add your routes here 3 | }); 4 | -------------------------------------------------------------------------------- /view/templates/plural.coffee: -------------------------------------------------------------------------------- 1 | <%= _.classify(appname) %>.<%= _.classify(pluralized_name) %>View = Ember.View.extend( 2 | ) 3 | -------------------------------------------------------------------------------- /view/templates/plural.js: -------------------------------------------------------------------------------- 1 | <%= _.classify(appname) %>.<%= _.classify(pluralized_name) %>View = Ember.View.extend({ 2 | }); 3 | -------------------------------------------------------------------------------- /app/templates/gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | temp 3 | dist 4 | .sass-cache 5 | .tmp 6 | app/bower_components 7 | test/bower_components -------------------------------------------------------------------------------- /component/templates/component.coffee: -------------------------------------------------------------------------------- 1 | <%= _.classify(appname) %>.<%= componetized_name %>Component = Ember.Component.extend( 2 | ) 3 | -------------------------------------------------------------------------------- /component/templates/component.js: -------------------------------------------------------------------------------- 1 | <%= _.classify(appname) %>.<%= componetized_name %>Component = Ember.Component.extend({ 2 | }); 3 | -------------------------------------------------------------------------------- /controller/templates/base.coffee: -------------------------------------------------------------------------------- 1 | <%= _.classify(appname) %>.<%= _.classify(name) %>Controller = Ember.ObjectController.extend() 2 | -------------------------------------------------------------------------------- /project/img/screenshots/2013_07_17.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/deprecate/generator-ember/HEAD/project/img/screenshots/2013_07_17.png -------------------------------------------------------------------------------- /script/reset_dev_env.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | `rm -rf libpeerconnection.log bower.json Gruntfile.js karma.conf.js package.json test/ app/` 3 | -------------------------------------------------------------------------------- /utils/js_path.js: -------------------------------------------------------------------------------- 1 | module.exports = function getJSPath (file) { 2 | return file + (this.options.coffee ? '.coffee' : '.js'); 3 | }; 4 | -------------------------------------------------------------------------------- /controller/templates/plural.coffee: -------------------------------------------------------------------------------- 1 | <%= _.classify(appname) %>.<%= _.classify(pluralized_name) %>Controller = Ember.ObjectController.extend() 2 | -------------------------------------------------------------------------------- /component/templates/component.hbs: -------------------------------------------------------------------------------- 1 |

I'm a component, customize me please!

2 | -------------------------------------------------------------------------------- /controller/templates/base.js: -------------------------------------------------------------------------------- 1 | <%= _.classify(appname) %>.<%= _.classify(name) %>Controller = Ember.ObjectController.extend({ 2 | // Implement your controller here. 3 | }); 4 | 5 | -------------------------------------------------------------------------------- /controller/templates/plural.js: -------------------------------------------------------------------------------- 1 | <%= _.classify(appname) %>.<%= _.classify(pluralized_name) %>Controller = Ember.ObjectController.extend({ 2 | // Implement your controller here. 3 | }); 4 | 5 | -------------------------------------------------------------------------------- /app/templates/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Yeoman Ember Starter Kit 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /controller/templates/plural_route.coffee: -------------------------------------------------------------------------------- 1 | <%= _.classify(appname) %>.<%= _.classify(pluralized_name) %>Route = Ember.Route.extend( 2 | model: -> 3 | @get('store').find('<%= _.slugify(name) %>') 4 | ) 5 | 6 | -------------------------------------------------------------------------------- /view/templates/plural.hbs: -------------------------------------------------------------------------------- 1 |

<%= pluralized_name %>

2 | 3 | 8 | 9 | {{outlet}} 10 | -------------------------------------------------------------------------------- /controller/templates/plural_route.js: -------------------------------------------------------------------------------- 1 | <%= _.classify(appname) %>.<%= _.classify(pluralized_name) %>Route = Ember.Route.extend({ 2 | model: function() { 3 | return this.get('store').find('<%= _.slugify(name) %>'); 4 | } 5 | }); 6 | 7 | -------------------------------------------------------------------------------- /controller/templates/single_route.coffee: -------------------------------------------------------------------------------- 1 | <%= _.classify(appname) %>.<%= _.classify(name) %>Route = Ember.Route.extend( 2 | model: (params) -> 3 | @get('store').find('<%= _.slugify(name) %>', params.<%= _.slugify(name) %>_id) 4 | ) 5 | 6 | -------------------------------------------------------------------------------- /app/templates/styles/style_bootstrap.scss: -------------------------------------------------------------------------------- 1 | $icon-font-path: "../styles/fonts/"; // Change the path to the fonts 2 | @import "bootstrap-sass-official/vendor/assets/stylesheets/bootstrap"; 3 | 4 | /* Put your CSS here */ 5 | html, body { 6 | margin: 30px 0; 7 | } 8 | -------------------------------------------------------------------------------- /controller/templates/single_route.js: -------------------------------------------------------------------------------- 1 | <%= _.classify(appname) %>.<%= _.classify(name) %>Route = Ember.Route.extend({ 2 | model: function(params) { 3 | return this.get('store').find('<%= _.slugify(name) %>', params.<%= _.slugify(name) %>_id); 4 | } 5 | }); 6 | 7 | -------------------------------------------------------------------------------- /.editorconfig: -------------------------------------------------------------------------------- 1 | # editorconfig.org 2 | root = true 3 | 4 | [*] 5 | indent_style = space 6 | indent_size = 2 7 | end_of_line = lf 8 | charset = utf-8 9 | trim_trailing_whitespace = true 10 | insert_final_newline = true 11 | 12 | [*.md] 13 | trim_trailing_whitespace = false 14 | -------------------------------------------------------------------------------- /app/templates/scripts/routes/application_route.coffee: -------------------------------------------------------------------------------- 1 | <%= _.classify(appname) %>.ApplicationRoute = Ember.Route.extend 2 | # admittedly, this should be in IndexRoute and not in the 3 | # top level ApplicationRoute; we're in transition... :-) 4 | model: -> ['red', 'yellow', 'blue'] 5 | -------------------------------------------------------------------------------- /router/templates/base.coffee: -------------------------------------------------------------------------------- 1 | <%= _.classify(appname) %>.Router.map( -> 2 | <% _.each(models, function(model, i) { %> 3 | @resource('<%= model.plural %>', -> 4 | @resource('<%= model.single %>', path: '/:<%= model.single %>_id', -> 5 | @route('edit') 6 | ) 7 | @route('create') 8 | ) 9 | <% }); %> 10 | ) 11 | -------------------------------------------------------------------------------- /.jshintrc: -------------------------------------------------------------------------------- 1 | { 2 | "node": true, 3 | "esnext": true, 4 | "bitwise": false, 5 | "curly": false, 6 | "eqeqeq": true, 7 | "eqnull": true, 8 | "immed": true, 9 | "latedef": true, 10 | "newcap": true, 11 | "noarg": true, 12 | "undef": true, 13 | "strict": false, 14 | "camelcase": true, 15 | "indent": 2 16 | } 17 | -------------------------------------------------------------------------------- /app/templates/scripts/routes/application_route.js: -------------------------------------------------------------------------------- 1 | <%= _.classify(appname) %>.ApplicationRoute = Ember.Route.extend({ 2 | // admittedly, this should be in IndexRoute and not in the 3 | // top level ApplicationRoute; we're in transition... :-) 4 | model: function () { 5 | return ['red', 'yellow', 'blue']; 6 | } 7 | }); 8 | -------------------------------------------------------------------------------- /view/templates/single_edit.hbs: -------------------------------------------------------------------------------- 1 |

<%= name %>

2 | 3 | 4 | {{#each buffer}} 5 | 6 | 9 | 12 | 13 | {{/each}} 14 |
7 | {{key}}: 8 | 10 | {{input value=value}} 11 |
15 | 16 | 17 | 18 | {{outlet}} 19 | -------------------------------------------------------------------------------- /test/helpers/expected_component_files.js: -------------------------------------------------------------------------------- 1 | JS_FILES_GENERATED_BY_COMPONENT_SUBGEN = [ 2 | 'app/scripts/components/x_player_component.js', 3 | 'app/templates/components/x-player.hbs' 4 | ]; 5 | 6 | COFFEE_FILES_GENERATED_BY_COMPONENT_SUBGEN = [ 7 | 'app/scripts/components/x_player_component.coffee', 8 | 'app/templates/components/x-player.hbs' 9 | ]; 10 | -------------------------------------------------------------------------------- /view/templates/single.hbs: -------------------------------------------------------------------------------- 1 |

<%= name %>

2 | 3 | 4 | {{#each model.attributes}} 5 | 6 | 9 | 12 | 13 | {{/each}} 14 |
7 | {{this.key}}: 8 | 10 | {{this.value}} 11 |
15 | 16 | {{#link-to '<%= slugified_name %>.edit' model}}Change{{/link-to}} 17 | 18 | {{outlet}} 19 | -------------------------------------------------------------------------------- /router/templates/base.js: -------------------------------------------------------------------------------- 1 | <%= _.classify(appname) %>.Router.map(function () { 2 | <% _.each(models, function(model, i) { %> 3 | this.resource('<%= model.plural %>', function(){ 4 | this.resource('<%= model.single %>', { path: '/:<%= model.single %>_id' }, function(){ 5 | this.route('edit'); 6 | }); 7 | this.route('create'); 8 | }); 9 | <% }); %> 10 | }); 11 | -------------------------------------------------------------------------------- /app/templates/scripts/app.coffee: -------------------------------------------------------------------------------- 1 | <%= _.classify(appname) %> = window.<%= _.classify(appname) %> = Ember.Application.create() 2 | 3 | # Order and include as you please. 4 | require 'scripts/controllers/*' 5 | require 'scripts/store' 6 | require 'scripts/models/*' 7 | require 'scripts/routes/*' 8 | require 'scripts/components/*' 9 | require 'scripts/views/*' 10 | require 'scripts/router' 11 | -------------------------------------------------------------------------------- /app/templates/scripts/app.js: -------------------------------------------------------------------------------- 1 | var <%= _.classify(appname) %> = window.<%= _.classify(appname) %> = Ember.Application.create(); 2 | 3 | /* Order and include as you please. */ 4 | require('scripts/controllers/*'); 5 | require('scripts/store'); 6 | require('scripts/models/*'); 7 | require('scripts/routes/*'); 8 | require('scripts/components/*'); 9 | require('scripts/views/*'); 10 | require('scripts/router'); 11 | -------------------------------------------------------------------------------- /controller/templates/base_edit.coffee: -------------------------------------------------------------------------------- 1 | <%= _.classify(appname) %>.<%= _.classify(name) %>EditController = Ember.ObjectController.extend( 2 | needs: '<%=name.toLowerCase()%>' 3 | actions: 4 | save: -> 5 | self = this 6 | @get('buffer').forEach (attr)-> 7 | self.get('controllers.<%=name.toLowerCase()%>.model').set(attr.key, attr.value) 8 | @transitionToRoute '<%= name.toLowerCase() %>', @get('model') 9 | ) 10 | -------------------------------------------------------------------------------- /controller/templates/single_edit_route.coffee: -------------------------------------------------------------------------------- 1 | <%= _.classify(appname) %>.<%= _.classify(name) %>EditRoute = Ember.Route.extend( 2 | model: (params) -> 3 | @get('store').find('<%= _.slugify(name) %>', @modelFor('<%= _.slugify(name) %>').id) 4 | setupController: (controller, model) -> 5 | controller.set 'model', model 6 | buffer = model.get('attributes').map (attr)-> 7 | { key: attr.get('key'), value: attr.get('value') } 8 | controller.set 'buffer', buffer 9 | ) 10 | 11 | -------------------------------------------------------------------------------- /app/templates/_bower.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "<%= _.slugify(appname) %>", 3 | "version": "0.0.0", 4 | "dependencies": { 5 | "ember": "1.7.0", 6 | "handlebars": "1.3.0", 7 | "ember-data": "1.0.0-beta.10"<% if (compassBootstrap) { %>, 8 | "bootstrap-sass-official": "3.1.1" 9 | <% } %> 10 | }, 11 | "resolutions": { 12 | "ember": "1.6.1" 13 | }, 14 | "devDependencies": {<% if (testFramework === 'mocha') { %> 15 | "ember-mocha-adapter": "0.2.1"<% } %> 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /test/helpers/expected_model_files.js: -------------------------------------------------------------------------------- 1 | require('./expected_controller_files'); 2 | require('./expected_view_files'); 3 | 4 | JS_FILES_GENERATED_BY_MODEL_SUBGEN = [ 5 | 'app/scripts/models/user_model.js' 6 | ].concat(JS_FILES_GENERATED_BY_CONTROLLER_SUBGEN).concat(JS_FILES_GENERATED_BY_VIEW_SUBGEN); 7 | 8 | COFFEE_FILES_GENERATED_BY_MODEL_SUBGEN = [ 9 | 'app/scripts/models/user_model.coffee' 10 | ].concat(COFFEE_FILES_GENERATED_BY_CONTROLLER_SUBGEN).concat(COFFEE_FILES_GENERATED_BY_VIEW_SUBGEN); 11 | -------------------------------------------------------------------------------- /controller/templates/base_edit.js: -------------------------------------------------------------------------------- 1 | <%= _.classify(appname) %>.<%= _.classify(name) %>EditController = Ember.ObjectController.extend({ 2 | needs: '<%= name.toLowerCase() %>', 3 | actions: { 4 | save: function(){ 5 | self = this 6 | this.get('buffer').forEach(function(attr){ 7 | self.get('controllers.<%=name.toLowerCase()%>.model').set(attr.key, attr.value); 8 | }); 9 | this.transitionToRoute('<%=name.toLowerCase()%>',this.get('model')); 10 | } 11 | } 12 | }); 13 | 14 | -------------------------------------------------------------------------------- /app/templates/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 | 10 | # Change these settings to your own preference 11 | indent_style = space 12 | indent_size = 4 13 | 14 | # We recommend you to keep these unchanged 15 | end_of_line = lf 16 | charset = utf-8 17 | trim_trailing_whitespace = true 18 | insert_final_newline = true 19 | 20 | [*.md] 21 | trim_trailing_whitespace = false 22 | -------------------------------------------------------------------------------- /app/templates/_jshintrc: -------------------------------------------------------------------------------- 1 | { 2 | "node": true, 3 | "browser": true, 4 | "esnext": true, 5 | "bitwise": false, 6 | "curly": false, 7 | "eqeqeq": true, 8 | "eqnull": true, 9 | "immed": true, 10 | "latedef": true, 11 | "newcap": true, 12 | "noarg": true, 13 | "undef": true, 14 | "strict": false, 15 | "globals": { 16 | "<%= _.classify(appname) %>": true, 17 | "jQuery": true, 18 | "Ember": true, 19 | "Handlebars": true, 20 | "DS": true 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /app/templates/test/integration/_index.coffee: -------------------------------------------------------------------------------- 1 | describe "Index page", -> 2 | it "displays a welcome message", -> 3 | visit('/').then -> 4 | find('div.well').text().should.contain 'Welcome to Yeoman and Ember.js' 5 | 6 | describe "ApplicationRoute", -> 7 | describe "model property", -> 8 | applicationRoute = <%= _.classify(appname) %>.ApplicationRoute.create() 9 | 10 | it "should have the right number of items", -> 11 | model = applicationRoute.model() 12 | model.should.have.length 3 13 | -------------------------------------------------------------------------------- /controller/templates/single_edit_route.js: -------------------------------------------------------------------------------- 1 | <%= _.classify(appname) %>.<%= _.classify(name) %>EditRoute = Ember.Route.extend({ 2 | model: function(params) { 3 | return this.get('store').find('<%= _.slugify(name) %>', this.modelFor('<%= _.slugify(name)%>').id); 4 | }, 5 | setupController: function(controller, model){ 6 | controller.set('model', model); 7 | buffer = model.get('attributes').map(function(attr){ 8 | return { key: attr.get('key'), value: attr.get('value') } 9 | }); 10 | controller.set('buffer', buffer) 11 | } 12 | }); 13 | 14 | -------------------------------------------------------------------------------- /test/helpers/expected_view_files.js: -------------------------------------------------------------------------------- 1 | JS_FILES_GENERATED_BY_VIEW_SUBGEN = [ 2 | 'app/scripts/views/user_view.js', 3 | 'app/scripts/views/user_edit_view.js', 4 | 'app/scripts/views/users_view.js', 5 | 'app/templates/user.hbs', 6 | 'app/templates/user/edit.hbs', 7 | 'app/templates/users.hbs' 8 | ]; 9 | 10 | COFFEE_FILES_GENERATED_BY_VIEW_SUBGEN = [ 11 | 'app/scripts/views/user_view.coffee', 12 | 'app/scripts/views/user_edit_view.coffee', 13 | 'app/scripts/views/users_view.coffee', 14 | 'app/templates/user.hbs', 15 | 'app/templates/user/edit.hbs', 16 | 'app/templates/users.hbs' 17 | ]; 18 | -------------------------------------------------------------------------------- /app/templates/test/integration/_index.js: -------------------------------------------------------------------------------- 1 | describe("Index page", function () { 2 | it("displays a welcome message", function () { 3 | visit('/').then(function () { 4 | find('div.well').text().should.contain('Welcome to Yeoman and Ember.js'); 5 | }); 6 | }); 7 | }); 8 | 9 | describe("ApplicationRoute", function () { 10 | describe("model property", function () { 11 | var applicationRoute = <%= _.classify(appname) %>.ApplicationRoute.create(); 12 | it("should have the right number of items", function () { 13 | var model = applicationRoute.model(); 14 | model.should.have.length(3); 15 | }); 16 | }); 17 | }); 18 | 19 | -------------------------------------------------------------------------------- /app/templates/test/_initializer.coffee: -------------------------------------------------------------------------------- 1 | document.write('
'); 2 | document.write(''); 3 | 4 | expect = chai.expect 5 | assert = chai.assert 6 | should = chai.should() 7 | 8 | chai.Assertion.includeStack = true 9 | 10 | <%= _.classify(appname) %>.rootElement = "#ember-testing" 11 | Ember.Test.adapter = Ember.Test.MochaAdapter.create() 12 | 13 | <%= _.classify(appname) %>.setupForTesting() 14 | <%= _.classify(appname) %>.injectTestHelpers() 15 | 16 | window.start = -> 17 | window.stop = -> 18 | -------------------------------------------------------------------------------- /app/templates/test/_initializer.js: -------------------------------------------------------------------------------- 1 | /*jshint undef:false */ 2 | 3 | document.write('
'); 4 | document.write(''); 5 | 6 | var expect = chai.expect; 7 | var assert = chai.assert; 8 | var should = chai.should(); 9 | 10 | chai.Assertion.includeStack = true; 11 | 12 | <%= _.classify(appname) %>.rootElement = "#ember-testing"; 13 | Ember.Test.adapter = Ember.Test.MochaAdapter.create(); 14 | 15 | <%= _.classify(appname) %>.setupForTesting(); 16 | <%= _.classify(appname) %>.injectTestHelpers(); 17 | 18 | window.start = function () {}; 19 | window.stop = function () {}; 20 | 21 | -------------------------------------------------------------------------------- /model/templates/base.coffee: -------------------------------------------------------------------------------- 1 | <%= _.classify(appname) %>.<%= _.classify(name) %> = DS.Model.extend 2 | <% _.each(attrs, function(attr, i) { %> 3 | <%= _.camelize(attr.name) %>: DS.attr('<%= attr.type %>') 4 | <%})%> 5 | 6 | # probably should be mixed-in... 7 | <%= _.classify(appname) %>.<%= _.classify(name) %>.reopen 8 | # certainly I'm duplicating something that exists elsewhere... 9 | attributes: ( -> 10 | model = this 11 | Em.keys(@get('data')).map (key)-> 12 | Em.Object.create(model: model, key: key, valueBinding: 'model.' + key) 13 | ).property() 14 | 15 | # delete below here if you do not want fixtures 16 | <%= _.classify(appname) %>.<%= _.classify(name) %>.FIXTURES = [ 17 | <% var ids = [1,2]; _.each(ids, function(idx, id) { %> 18 | { id: <%= id %>, <% _.each(attrs, function(attr, i) { %> <%= attr.name %>: 'foo',<%});%> }, 19 | <% }); %> 20 | ] 21 | -------------------------------------------------------------------------------- /test/helpers/expected_controller_files.js: -------------------------------------------------------------------------------- 1 | require('./expected_view_files'); 2 | 3 | JS_FILES_GENERATED_BY_CONTROLLER_SUBGEN = [ 4 | 'app/scripts/controllers/user_controller.js', 5 | 'app/scripts/controllers/users_controller.js', 6 | 'app/scripts/controllers/user_edit_controller.js', 7 | 'app/scripts/routes/user_route.js', 8 | 'app/scripts/routes/user_edit_route.js', 9 | 'app/scripts/routes/users_route.js' 10 | ].concat(JS_FILES_GENERATED_BY_VIEW_SUBGEN); 11 | 12 | 13 | COFFEE_FILES_GENERATED_BY_CONTROLLER_SUBGEN = [ 14 | 'app/scripts/controllers/user_controller.coffee', 15 | 'app/scripts/controllers/users_controller.coffee', 16 | 'app/scripts/controllers/user_edit_controller.coffee', 17 | 'app/scripts/routes/user_route.coffee', 18 | 'app/scripts/routes/user_edit_route.coffee', 19 | 'app/scripts/routes/users_route.coffee' 20 | ].concat(COFFEE_FILES_GENERATED_BY_VIEW_SUBGEN); 21 | -------------------------------------------------------------------------------- /model/templates/base.js: -------------------------------------------------------------------------------- 1 | /*global Ember*/ 2 | <%= _.classify(appname) %>.<%= _.classify(name) %> = DS.Model.extend({<% _.each(attrs, function(attr, i) { %> 3 | <%= _.camelize(attr.name) %>: DS.attr('<%= attr.type %>')<% if(i < (attributes.length - 1)) { %>,<% } %> 4 | <% }); %>}); 5 | 6 | // probably should be mixed-in... 7 | <%= _.classify(appname) %>.<%= _.classify(name) %>.reopen({ 8 | attributes: function(){ 9 | var model = this; 10 | return Ember.keys(this.get('data')).map(function(key){ 11 | return Em.Object.create({ model: model, key: key, valueBinding: 'model.' + key }); 12 | }); 13 | }.property() 14 | }); 15 | 16 | // delete below here if you do not want fixtures 17 | <%= _.classify(appname) %>.<%= _.classify(name) %>.FIXTURES = [ 18 | <% var ids = [1,2]; _.each(ids, function(idx, id) { %> 19 | { 20 | id: <%= id %>, 21 | <% _.each(attrs, function(attr, i) { %> 22 | <%= attr.name %>: 'foo'<% if(i < (attrs.length - 1)) { %>,<% } %> 23 | <% }); %> 24 | }<% if(id < (ids.length - 1)) { %>,<% } %> 25 | <% }); %> 26 | ]; 27 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "generator-ember", 3 | "version": "0.8.6", 4 | "description": "Yeoman generator for Ember", 5 | "keywords": [ 6 | "yeoman-generator", 7 | "scaffold", 8 | "generator", 9 | "framework", 10 | "mvc", 11 | "ember" 12 | ], 13 | "homepage": "https://github.com/yeoman/generator-ember", 14 | "bugs": "https://github.com/yeoman/generator-ember/issues", 15 | "author": "The Yeoman Team", 16 | "main": "app/index.js", 17 | "repository": { 18 | "type": "git", 19 | "url": "git://github.com/yeoman/generator-ember.git" 20 | }, 21 | "scripts": { 22 | "test": "mocha --reporter spec" 23 | }, 24 | "dependencies": { 25 | "yeoman-generator": "~0.16.0", 26 | "fleck": "~0.5.1" 27 | }, 28 | "devDependencies": { 29 | "mocha": "*" 30 | }, 31 | "peerDependencies": { 32 | "generator-mocha": ">=0.1.1", 33 | "yo": ">=1.0.0" 34 | }, 35 | "engines": { 36 | "node": ">=0.10.0", 37 | "npm": ">=1.2.10" 38 | }, 39 | "licenses": [ 40 | { 41 | "type": "BSD" 42 | } 43 | ] 44 | } 45 | -------------------------------------------------------------------------------- /model/index.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | var util = require('util'); 4 | var yeoman = require('yeoman-generator'); 5 | var getJSPath = require('../utils/js_path'); 6 | 7 | var ModelGenerator = module.exports = function ModelGenerator(args, options, config) { 8 | yeoman.generators.NamedBase.apply(this, arguments); 9 | 10 | this.hookFor('ember:controller', { 11 | args: args 12 | }); 13 | 14 | this.options.coffee = options.coffee; 15 | // XXX default and banner to be implemented 16 | this.argument('attributes', { type: Array, defaults: [], banner: 'field[:type] field[:type]' }); 17 | 18 | // parse back the attributes provided, build an array of attr 19 | this.attrs = this.attributes.map(function (attr) { 20 | var parts = attr.split(':'); 21 | return { 22 | name: parts[0], 23 | type: parts[1] || 'string' 24 | }; 25 | }); 26 | }; 27 | 28 | util.inherits(ModelGenerator, yeoman.generators.NamedBase); 29 | 30 | ModelGenerator.prototype._getJSPath = getJSPath; 31 | 32 | ModelGenerator.prototype.files = function files() { 33 | this.template(this._getJSPath('base'), 'app/scripts/models/' + this._.slugify(this.name) + this._getJSPath('_model')); 34 | }; 35 | -------------------------------------------------------------------------------- /app/templates/hbs/application.hbs: -------------------------------------------------------------------------------- 1 |
2 | 15 |
16 |
17 |
18 |
19 | 27 |
28 |
29 | {{outlet}} 30 |
31 |
32 |
33 |
34 |
35 | -------------------------------------------------------------------------------- /test/test-router.js: -------------------------------------------------------------------------------- 1 | /*global describe:true, beforeEach:true, it:true */ 2 | 'use strict'; 3 | var path = require('path'); 4 | var helpers = require('yeoman-generator').test; 5 | var assert = require('assert'); 6 | var fs = require('fs'); 7 | 8 | describe('Router', function () { 9 | 10 | beforeEach(function (done) { 11 | helpers.testDirectory(path.join(__dirname, './temp'), function (err) { 12 | done(); 13 | }.bind(this)); 14 | }); 15 | 16 | var filesDoNotExist = function (files) { 17 | for (var i = 0; i < files.length; i++) { 18 | assert(!fs.existsSync(files[i]), files[i] + ' should not exist'); 19 | } 20 | }; 21 | 22 | it('with javascript', function (done) { 23 | var router = helpers.createGenerator('ember:router', ['../../router']); 24 | 25 | filesDoNotExist([router.router_file]); 26 | 27 | router.controller_files = ['user_controller.js']; 28 | router.run({}, function () { 29 | helpers.assertFiles([router.options.router_file]); 30 | done(); 31 | }); 32 | }); 33 | 34 | it('with coffee-script', function (done) { 35 | var router = helpers.createGenerator('ember:router', ['../../router']); 36 | 37 | filesDoNotExist([router.router_file]); 38 | 39 | router.controllerFiles = ['user_controller.coffee']; 40 | router.run({}, function () { 41 | helpers.assertFiles([router.options.router_file]); 42 | done(); 43 | }); 44 | }); 45 | }); 46 | -------------------------------------------------------------------------------- /view/index.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | var util = require('util'); 4 | var yeoman = require('yeoman-generator'); 5 | var fleck = require('fleck'); 6 | var getJSPath = require('../utils/js_path'); 7 | 8 | var ViewGenerator = module.exports = function ViewGenerator(args, options, config) { 9 | yeoman.generators.NamedBase.apply(this, arguments); 10 | this.pluralized_name = fleck.pluralize(this.name); 11 | this.slugified_name = this._.slugify(this.name); 12 | 13 | // TODO Find a better way to do this. Passing `coffee` via options from controller seems to be a futile effort 14 | this.options.coffee = options.coffee; 15 | if (!this.options.coffee && this.expandFiles('app/scripts/**/*.coffee', {}).length > 0) { 16 | this.options.coffee = true; 17 | } 18 | }; 19 | 20 | util.inherits(ViewGenerator, yeoman.generators.NamedBase); 21 | 22 | ViewGenerator.prototype._getJSPath = getJSPath; 23 | 24 | ViewGenerator.prototype.files = function files() { 25 | this.copy(this._getJSPath('single'), 'app/scripts/views/' + this.slugified_name + this._getJSPath('_view')); 26 | this.copy(this._getJSPath('single_edit'), 'app/scripts/views/' + this.slugified_name + this._getJSPath('_edit_view')); 27 | this.copy(this._getJSPath('plural'), 'app/scripts/views/' + this._.slugify(this.pluralized_name) + this._getJSPath('_view')); 28 | this.copy('single.hbs', 'app/templates/' + this.slugified_name + '.hbs'); 29 | this.copy('single_edit.hbs', 'app/templates/' + this.slugified_name + '/edit.hbs'); 30 | this.copy('plural.hbs', 'app/templates/' + this._.slugify(this.pluralized_name) + '.hbs'); 31 | }; 32 | -------------------------------------------------------------------------------- /app/templates/_package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "<%= _.slugify(appname) %>", 3 | "version": "0.0.0", 4 | "dependencies": {}, 5 | "devDependencies": { 6 | "grunt": "~0.4.1", 7 | "grunt-contrib-copy": "~0.4.1", 8 | "grunt-contrib-concat": "~0.3.0",<% if (options.coffee) { %> 9 | "grunt-contrib-coffee": "~0.7.0",<% } %> 10 | "grunt-contrib-uglify": "~0.2.0",<% if (compassBootstrap) { %> 11 | "grunt-contrib-compass": "~0.5.0",<% } %> 12 | "grunt-contrib-jshint": "~0.6.3", 13 | "grunt-contrib-cssmin": "~0.6.0", 14 | "grunt-contrib-connect": "~0.3.0", 15 | "grunt-contrib-clean": "~0.5.0", 16 | "grunt-contrib-htmlmin": "~0.1.3", 17 | "grunt-contrib-imagemin": "~0.8.1", 18 | "grunt-contrib-watch": "~0.5.2",<% if (testFramework === 'jasmine') { %> 19 | "grunt-contrib-jasmine": "~0.5.1",<% } %> 20 | "grunt-rev": "~0.1.0", 21 | "grunt-usemin": "~0.1.12",<% if (testFramework === 'mocha') { %> 22 | "grunt-mocha": "~0.4.1",<% } %> 23 | "grunt-open": "~0.2.0", 24 | "grunt-svgmin": "~0.2.0", 25 | "grunt-concurrent": "~0.3.0", 26 | "load-grunt-tasks": "~0.1.0", 27 | "connect-livereload": "~0.2.0", 28 | "grunt-ember-templates": "0.4.14", 29 | "time-grunt": "~0.1.1", 30 | "grunt-replace": "~0.4.4", 31 | "jshint-stylish": "~0.1.3", 32 | "grunt-neuter": "~0.6.0"<% if (options.karma) { %>, 33 | "grunt-karma": "~0.8.2", 34 | "karma-chrome-launcher": "~0.1.2", <% if (testFramework === 'mocha') { %> 35 | "karma-mocha": "~0.1.3"<% } else { %> 36 | "karma-jasmine": "~0.1" <% } } %> 37 | }, 38 | "engines": { 39 | "node": ">=0.8.0" 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /component/index.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | var util = require('util'); 4 | var yeoman = require('yeoman-generator'); 5 | var fleck = require('fleck'); 6 | var getJSPath = require('../utils/js_path'); 7 | 8 | var ComponentGenerator = module.exports = function ComponentGenerator(args, options, config) { 9 | yeoman.generators.NamedBase.apply(this, arguments); 10 | this.dasherized_name = this._.dasherize(this.name); 11 | this.componetized_name = this._.classify(this.dasherized_name); 12 | this.slugified_name = this._.slugify(this.componetized_name); 13 | this.underscorized_name = this._.underscored(this.name); 14 | 15 | if (this.dasherized_name.indexOf('-') === 0) { 16 | this.dasherized_name = this.dasherized_name.slice(1); 17 | } 18 | 19 | if (!this.componetized_name.match(/.*[A-Z].*[A-Z].*/)) { 20 | throw 'Component name must be made of two or more words, e.g. x-player, UserProfile, my_big_gravatar'; 21 | 22 | } 23 | 24 | // TODO Find a better way to do this. Passing `coffee` via options from controller seems to be a futile effort 25 | this.options.coffee = options.coffee; 26 | if (!this.options.coffee && this.expandFiles('app/scripts/**/*.coffee', {}).length > 0) { 27 | this.options.coffee = true; 28 | } 29 | }; 30 | 31 | util.inherits(ComponentGenerator, yeoman.generators.NamedBase); 32 | 33 | ComponentGenerator.prototype._getJSPath = getJSPath; 34 | 35 | ComponentGenerator.prototype.files = function files() { 36 | this.copy(this._getJSPath('component'), 'app/scripts/components/' + this.underscorized_name + this._getJSPath('_component')); 37 | this.copy('component.hbs', 'app/templates/components/' + this.dasherized_name + '.hbs'); 38 | }; 39 | -------------------------------------------------------------------------------- /router/index.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | var util = require('util'); 4 | var yeoman = require('yeoman-generator'); 5 | var fs = require('fs'); 6 | var fleck = require('fleck'); 7 | var getJSPath = require('../utils/js_path'); 8 | 9 | var RouterGenerator = module.exports = function RouterGenerator(args, options, config) { 10 | // NamedBase needs a name, which is usually the first param passed in the script 11 | // https://github.com/yeoman/generator/pull/231 12 | args.push('ember:router'); 13 | yeoman.generators.NamedBase.apply(this, arguments); 14 | 15 | this.options.model_files = []; 16 | this.options.model_dir = 'app/scripts/models'; 17 | 18 | if (fs.existsSync(this.options.model_dir)) { 19 | this.model_files = fs.readdirSync(this.options.model_dir); 20 | } 21 | 22 | this.options.coffee = options.coffee; 23 | // TODO Find a better way to do this. Passing `coffee` via options from model seems to be a futile effort 24 | this.options.coffee = options.coffee; 25 | if (!this.options.coffee && this.expandFiles('app/scripts/**/*.coffee', {}).length > 0) { 26 | this.options.coffee = true; 27 | } 28 | 29 | this.options.router_file = this._getJSPath('app/scripts/router'); 30 | }; 31 | 32 | util.inherits(RouterGenerator, yeoman.generators.NamedBase); 33 | 34 | RouterGenerator.prototype._getJSPath = getJSPath; 35 | 36 | RouterGenerator.prototype.generateFiles = function generateFiles() { 37 | this.models = []; 38 | var models = this.model_files; 39 | for (var i in models) { 40 | var extension = this._getJSPath('_model'); 41 | var stripped = models[i].replace(extension, ''); 42 | this.models.push({ 43 | single: fleck.singularize(stripped), 44 | plural: fleck.pluralize(stripped) 45 | }); 46 | } 47 | this.copy(this._getJSPath('base'), this.options.router_file); 48 | }; 49 | -------------------------------------------------------------------------------- /test/test-view.js: -------------------------------------------------------------------------------- 1 | /*global describe:true, beforeEach:true, it:true */ 2 | 'use strict'; 3 | var path = require('path'); 4 | var helpers = require('yeoman-generator').test; 5 | var assert = require('assert'); 6 | var fs = require('fs'); 7 | 8 | require('./helpers/expected_view_files'); 9 | 10 | describe('View', function () { 11 | 12 | beforeEach(function (done) { 13 | helpers.testDirectory(path.join(__dirname, './temp'), function (err) { 14 | done(); 15 | }.bind(this)); 16 | }); 17 | 18 | var filesDoNotExist = function(list_of_files){ 19 | for (var i = 0; i < list_of_files.length; i++) { 20 | assert(!fs.existsSync(list_of_files[i]), list_of_files[i]); 21 | } 22 | }; 23 | 24 | it('with javascript', function (done) { 25 | this.view = {}; 26 | this.view = helpers.createGenerator('ember:view', ['../../view'], 'user'); 27 | 28 | filesDoNotExist(JS_FILES_GENERATED_BY_VIEW_SUBGEN); 29 | 30 | var view = this.view; 31 | this.view.run({}, function () { 32 | helpers.assertFiles( JS_FILES_GENERATED_BY_VIEW_SUBGEN ); 33 | helpers.assertFile('app/scripts/views/users_view.js', /UsersView/); 34 | helpers.assertFile('app/templates/users.hbs', /link-to.*this/); 35 | done(); 36 | }); 37 | }); 38 | 39 | it('with coffee-script', function (done) { 40 | this.view = {}; 41 | this.view = helpers.createGenerator('ember:view', ['../../view'], 'user'); 42 | 43 | filesDoNotExist(COFFEE_FILES_GENERATED_BY_VIEW_SUBGEN); 44 | 45 | var view = this.view; 46 | this.view.options['coffee'] = true; 47 | this.view.run({}, function () { 48 | helpers.assertFiles( COFFEE_FILES_GENERATED_BY_VIEW_SUBGEN ); 49 | helpers.assertFile('app/scripts/views/users_view.coffee', /UsersView/); 50 | helpers.assertFile('app/templates/users.hbs', /link-to.*this/); 51 | done(); 52 | }); 53 | }); 54 | }); 55 | -------------------------------------------------------------------------------- /test/test-component.js: -------------------------------------------------------------------------------- 1 | /*global describe:true, beforeEach:true, it:true */ 2 | 'use strict'; 3 | var path = require('path'); 4 | var helpers = require('yeoman-generator').test; 5 | var assert = require('assert'); 6 | var fs = require('fs'); 7 | 8 | require('./helpers/expected_component_files'); 9 | 10 | describe('Component', function () { 11 | 12 | beforeEach(function (done) { 13 | helpers.testDirectory(path.join(__dirname, './temp'), function (err) { 14 | done(); 15 | }.bind(this)); 16 | }); 17 | 18 | var filesDoNotExist = function(list_of_files){ 19 | for (var i = 0; i < list_of_files.length; i++) { 20 | assert(!fs.existsSync(list_of_files[i]), list_of_files[i]); 21 | } 22 | }; 23 | 24 | it('with javascript', function (done) { 25 | this.view = {}; 26 | this.view = helpers.createGenerator('ember:component', ['../../component'], 'x-player'); 27 | 28 | filesDoNotExist(JS_FILES_GENERATED_BY_COMPONENT_SUBGEN); 29 | 30 | var view = this.view; 31 | this.view.run({}, function () { 32 | helpers.assertFiles( JS_FILES_GENERATED_BY_COMPONENT_SUBGEN ); 33 | helpers.assertFile('app/scripts/components/x_player_component.js', /XPlayerComponent/); 34 | helpers.assertFile('app/templates/components/x-player.hbs', /component/); 35 | done(); 36 | }); 37 | }); 38 | 39 | it('with coffee-script', function (done) { 40 | this.view = {}; 41 | this.view = helpers.createGenerator('ember:component', ['../../component'], 'x-player'); 42 | 43 | filesDoNotExist(COFFEE_FILES_GENERATED_BY_COMPONENT_SUBGEN); 44 | 45 | var view = this.view; 46 | this.view.options['coffee'] = true; 47 | this.view.run({}, function () { 48 | helpers.assertFiles( COFFEE_FILES_GENERATED_BY_COMPONENT_SUBGEN ); 49 | helpers.assertFile('app/scripts/components/x_player_component.coffee', /XPlayerComponent/); 50 | helpers.assertFile('app/templates/components/x-player.hbs', /component/); 51 | done(); 52 | }); 53 | }); 54 | }); 55 | -------------------------------------------------------------------------------- /test/test-karma.js: -------------------------------------------------------------------------------- 1 | /*global describe:true, beforeEach:true, it:true */ 2 | 'use strict'; 3 | var path = require('path'); 4 | var helpers = require('yeoman-generator').test; 5 | var assert = require('assert'); 6 | var fs = require('fs'); 7 | 8 | var EXPECTED_FILES = [ 9 | '.gitignore', 10 | '.gitattributes', 11 | '.bowerrc', 12 | 'bower.json', 13 | 'package.json', 14 | '.jshintrc', 15 | '.editorconfig', 16 | 'Gruntfile.js', 17 | 'app/scripts/app.js', 18 | 'app/scripts/router.js', 19 | 'app/scripts/routes/application_route.js', 20 | 'app/templates/application.hbs', 21 | 'app/templates/index.hbs', 22 | 'app/index.html' 23 | ]; 24 | 25 | describe('Karma', function () { 26 | beforeEach(function (done) { 27 | 28 | helpers.testDirectory(path.join(__dirname, './temp'), function (err) { 29 | if (err) { 30 | return done(err); 31 | } 32 | this.ember = {}; 33 | this.ember.app = helpers.createGenerator('ember:app', [ 34 | '../../router', 35 | '../../app', [ 36 | helpers.createDummyGenerator(), 37 | 'mocha:app' 38 | ] 39 | ]); 40 | helpers.mockPrompt(this.ember.app, { 41 | 'compassBootstrap': true 42 | }); 43 | this.ember.app.options['coffee'] = false; 44 | this.ember.app.options['skip-install'] = true; 45 | done(); 46 | }.bind(this)); 47 | }); 48 | 49 | it('creates files with correct syntax', function (done) { 50 | this.ember.app.options['karma'] = true; 51 | EXPECTED_FILES = [ 52 | 'karma.conf.js', 53 | 'test/integration/index.js', 54 | 'test/support/initializer.js' 55 | ]; 56 | this.ember.app.run({}, function () { 57 | helpers.assertFiles(EXPECTED_FILES); 58 | 59 | var content = fs.readFileSync(EXPECTED_FILES[1]); 60 | assert(content.toString().match(/Temp.ApplicationRoute/)); 61 | 62 | var content = fs.readFileSync(EXPECTED_FILES[2]); 63 | assert(content.toString().match(/Temp.rootElement/)); 64 | 65 | done(); 66 | }); 67 | }); 68 | }); 69 | -------------------------------------------------------------------------------- /controller/index.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | var util = require('util'); 4 | var yeoman = require('yeoman-generator'); 5 | var fs = require('fs'); 6 | var fleck = require('fleck'); 7 | var getJSPath = require('../utils/js_path'); 8 | 9 | var ControllerGenerator = module.exports = function ControllerGenerator(args, options, config) { 10 | yeoman.generators.NamedBase.apply(this, arguments); 11 | this.pluralized_name = fleck.pluralize(this.name); 12 | 13 | this.options.coffee = options.coffee; 14 | // TODO Find a better way to do this. Passing `coffee` via options from controller seems to be a futile effort 15 | this.options.coffee = options.coffee; 16 | if (!this.options.coffee && this.expandFiles('app/scripts/**/*.coffee', {}).length > 0) { 17 | this.options.coffee = true; 18 | } 19 | 20 | this.hookFor('ember:view', { 21 | args: args, 22 | // this doesn't seem to be working yet 23 | options: { 24 | coffee: this.options.coffee 25 | } 26 | }); 27 | 28 | this.hookFor('ember:router'); 29 | }; 30 | 31 | // TODO: add option for Array or Object controller 32 | 33 | util.inherits(ControllerGenerator, yeoman.generators.NamedBase); 34 | 35 | ControllerGenerator.prototype._getJSPath = getJSPath; 36 | 37 | ControllerGenerator.prototype.files = function files() { 38 | this.template(this._getJSPath('base'), 'app/scripts/controllers/' + this._.slugify(this.name) + this._getJSPath('_controller')); 39 | this.template(this._getJSPath('plural'), 'app/scripts/controllers/' + this._.slugify(this.pluralized_name) + this._getJSPath('_controller')); 40 | this.template(this._getJSPath('base_edit'), 'app/scripts/controllers/' + this._.slugify(this.name) + this._getJSPath('_edit_controller')); 41 | this.template(this._getJSPath('plural_route'), 'app/scripts/routes/' + this._.slugify(this.pluralized_name) + this._getJSPath('_route')); 42 | this.template(this._getJSPath('single_route'), 'app/scripts/routes/' + this._.slugify(this.name) + this._getJSPath('_route')); 43 | this.template(this._getJSPath('single_edit_route'), 'app/scripts/routes/' + this._.slugify(this.name) + this._getJSPath('_edit_route')); 44 | }; 45 | -------------------------------------------------------------------------------- /test/test-controller.js: -------------------------------------------------------------------------------- 1 | /*global describe:true, beforeEach:true, it:true */ 2 | 'use strict'; 3 | var path = require('path'); 4 | var helpers = require('yeoman-generator').test; 5 | var assert = require('assert'); 6 | var fs = require('fs'); 7 | 8 | require('./helpers/expected_controller_files'); 9 | require('./helpers/expected_view_files'); 10 | 11 | describe('Controller', function () { 12 | 13 | beforeEach(function (done) { 14 | helpers.testDirectory(path.join(__dirname, './temp'), function (err) { 15 | done(); 16 | }.bind(this)); 17 | }); 18 | 19 | var filesDoNotExist = function(list_of_files){ 20 | for (var i = 0; i < list_of_files.length; i++) { 21 | assert(!fs.existsSync(list_of_files[i]), list_of_files[i]); 22 | } 23 | }; 24 | 25 | it('with javascript', function (done) { 26 | this.controller = {}; 27 | this.controller = helpers.createGenerator('ember:controller', ['../../controller','../../view','../../router'], 'user'); 28 | 29 | filesDoNotExist(JS_FILES_GENERATED_BY_CONTROLLER_SUBGEN); 30 | 31 | var controller = this.controller; 32 | this.controller.run({}, function () { 33 | helpers.assertFiles( JS_FILES_GENERATED_BY_CONTROLLER_SUBGEN ); 34 | helpers.assertFile('app/scripts/controllers/users_controller.js', /UsersController/); 35 | helpers.assertFile('app/scripts/routes/users_route.js', /UsersRoute/); 36 | done(); 37 | }); 38 | }); 39 | 40 | it('with coffee-script', function (done) { 41 | this.controller = {}; 42 | this.controller = helpers.createGenerator('ember:controller', ['../../controller','../../view','../../router'], 'user'); 43 | 44 | filesDoNotExist(COFFEE_FILES_GENERATED_BY_CONTROLLER_SUBGEN); 45 | 46 | var controller = this.controller; 47 | this.controller.options['coffee'] = true; 48 | this.controller.run({}, function () { 49 | helpers.assertFiles( COFFEE_FILES_GENERATED_BY_CONTROLLER_SUBGEN ); 50 | helpers.assertFile('app/scripts/controllers/users_controller.coffee', /UsersController/); 51 | helpers.assertFile('app/scripts/routes/users_route.coffee', /UsersRoute/); 52 | done(); 53 | }); 54 | }); 55 | 56 | }); 57 | -------------------------------------------------------------------------------- /app/templates/karma.conf.js: -------------------------------------------------------------------------------- 1 | /*jshint undef:false */ 2 | 3 | // Karma configuration 4 | module.exports = function(config) { 5 | 6 | config.set({ 7 | 8 | // Base path that will be used to resolve files and exclude. 9 | basePath : '', 10 | 11 | // Testing framework to be used, default is `jasmine`. 12 | frameworks : [ 13 | <% if (testFramework === 'mocha') { %>'mocha' 14 | <% } else { %>'jasmine' 15 | <% } %> 16 | ], 17 | 18 | 19 | // List of files / patterns to load in the browser. 20 | files : [ 21 | 'app/bower_components/jquery/dist/jquery.min.js', 22 | 'app/bower_components/handlebars/handlebars.runtime.js', 23 | 'app/bower_components/ember/ember.js', 24 | 'app/bower_components/ember-data/ember-data.js', 25 | <% if (testFramework === 'mocha') { %> 26 | 'test/bower_components/chai/chai.js', 27 | 'app/bower_components/ember-mocha-adapter/adapter.js', 28 | <% } %> 29 | '.tmp/scripts/combined-scripts.js', 30 | '.tmp/scripts/compiled-templates.js',<% if (options.coffee) { %> 31 | '.tmp/test/support/*.js', 32 | '.tmp/test/spec/*.js', 33 | '.tmp/test/integration/*.js'<% } else { %> 34 | 'test/support/*.js', 35 | 'test/spec/*.js', 36 | 'test/integration/*.js'<% } %> 37 | ], 38 | 39 | 40 | // List of files to exclude. 41 | exclude : [], 42 | 43 | 44 | // Test results reporter to use. 45 | // Possible values: 'dots', 'progress', 'junit' 46 | reporters : ['progress'], 47 | 48 | 49 | // Web server port. 50 | port : 9876, 51 | 52 | 53 | // Cli runner port. 54 | runnerPort : 9100, 55 | 56 | 57 | // Enable / disable colors in the output (reporters and logs). 58 | colors : true, 59 | 60 | 61 | // Level of logging. Possible values are: 62 | // 63 | // * LOG_DISABLE 64 | // * LOG_ERROR 65 | // * LOG_WARN 66 | // * LOG_INFO 67 | // * LOG_DEBUG 68 | logLevel : config.LOG_INFO, 69 | 70 | 71 | // Enable / disable watching files and executing tests whenever any of them 72 | // changes. 73 | autoWatch : true, 74 | 75 | 76 | // Start these browsers, currently available: 77 | // - Chrome 78 | // - ChromeCanary 79 | // - Firefox 80 | // - Opera 81 | // - Safari (only Mac) 82 | // - PhantomJS 83 | // - IE (only Windows) 84 | browsers : ['Chrome'], 85 | 86 | 87 | // If the browser does not capture in the given timeout [ms], then kill it. 88 | captureTimeout : 60000, 89 | 90 | 91 | // Continuous Integration mode. 92 | // If it's `true`, then it captures browsers, runs the tests and exits. 93 | singleRun : false 94 | 95 | }); 96 | 97 | }; 98 | -------------------------------------------------------------------------------- /test/test-model.js: -------------------------------------------------------------------------------- 1 | /*global describe:true, beforeEach:true, it:true */ 2 | 'use strict'; 3 | var path = require('path'); 4 | var helpers = require('yeoman-generator').test; 5 | var assert = require('assert'); 6 | var fs = require('fs'); 7 | 8 | require('fleck'); 9 | 10 | require('./helpers/expected_model_files'); 11 | 12 | describe('Model', function () { 13 | 14 | beforeEach(function (done) { 15 | helpers.testDirectory(path.join(__dirname, './temp'), function (err) { 16 | done(); 17 | }.bind(this)); 18 | }); 19 | 20 | var filesDoNotExist = function(list_of_files){ 21 | for (var i = 0; i < list_of_files.length; i++) { 22 | assert(!fs.existsSync(list_of_files[i])); 23 | } 24 | }; 25 | 26 | //it('takes singular noun and creates singular route, controller, template for edit') 27 | //it('takes singular noun and registers singular and plural routes with router') 28 | //it('takes singular noun and creates plural route, template for read of all') 29 | //it('takes singular noun and creates singular controller, template for read') 30 | it('with javascript', function (done) { 31 | this.model = {}; 32 | var cmd_line_args = ['User', 'name:string', 'zipcode:number']; 33 | this.model = helpers.createGenerator('ember:model', 34 | ['../../model','../../controller','../../view','../../router'], 35 | cmd_line_args); 36 | 37 | filesDoNotExist(JS_FILES_GENERATED_BY_MODEL_SUBGEN); 38 | 39 | var model = this.model; 40 | this.model.run({}, function () { 41 | helpers.assertFiles( JS_FILES_GENERATED_BY_MODEL_SUBGEN ); 42 | helpers.assertFile('app/scripts/models/user_model.js', /User = DS.Model/); 43 | helpers.assertFile('app/scripts/models/user_model.js', /name: DS.attr\('string'\)/); 44 | helpers.assertFile('app/scripts/models/user_model.js', /zipcode: DS.attr\('number'\)/); 45 | helpers.assertFile('app/scripts/models/user_model.js', /User.FIXTURES/); 46 | done(); 47 | }); 48 | }); 49 | 50 | it('with coffeescript', function (done) { 51 | this.model = {}; 52 | var cmd_line_args = ['User', 'name:string', 'zipcode:number']; 53 | this.model = helpers.createGenerator('ember:model', 54 | ['../../model','../../controller','../../view','../../router'], 55 | cmd_line_args); 56 | 57 | filesDoNotExist(COFFEE_FILES_GENERATED_BY_MODEL_SUBGEN); 58 | 59 | var model = this.model; 60 | this.model.options.coffee = true; 61 | this.model.run({}, function () { 62 | helpers.assertFiles( COFFEE_FILES_GENERATED_BY_MODEL_SUBGEN ); 63 | helpers.assertFile('app/scripts/models/user_model.coffee', /User = DS.Model/); 64 | helpers.assertFile('app/scripts/models/user_model.coffee', /name: DS.attr\('string'\)/); 65 | helpers.assertFile('app/scripts/models/user_model.coffee', /zipcode: DS.attr\('number'\)/); 66 | helpers.assertFile('app/scripts/models/user_model.coffee', /User.FIXTURES/); 67 | done(); 68 | }); 69 | }); 70 | }); 71 | -------------------------------------------------------------------------------- /test/test-compass.js: -------------------------------------------------------------------------------- 1 | /*global describe:true, beforeEach:true, it:true */ 2 | 'use strict'; 3 | var path = require('path'); 4 | var helpers = require('yeoman-generator').test; 5 | var assert = require('assert'); 6 | var fs = require('fs'); 7 | 8 | var EXPECTED_FILES = [ 9 | '.gitignore', 10 | '.gitattributes', 11 | '.bowerrc', 12 | 'bower.json', 13 | 'package.json', 14 | '.jshintrc', 15 | '.editorconfig', 16 | 'Gruntfile.js', 17 | 'app/scripts/app.js', 18 | 'app/templates/application.hbs', 19 | 'app/templates/index.hbs', 20 | 'app/index.html' 21 | ]; 22 | 23 | describe('compassBootstrap', function () { 24 | 25 | beforeEach(function (done) { 26 | helpers.testDirectory(path.join(__dirname, './temp'), function (err) { 27 | if (err) { 28 | return done(err); 29 | } 30 | this.ember = {}; 31 | this.ember.app = helpers.createGenerator('ember:app', [ 32 | '../../router', 33 | '../../app', [ 34 | helpers.createDummyGenerator(), 35 | 'mocha:app' 36 | ] 37 | ]); 38 | this.ember.app.options['coffee'] = false; 39 | this.ember.app.options['skip-install'] = true; 40 | done(); 41 | }.bind(this)); 42 | }); 43 | 44 | describe('true', function () { 45 | 46 | beforeEach(function () { 47 | helpers.mockPrompt(this.ember.app, { 48 | compassBootstrap: true 49 | }); 50 | }); 51 | 52 | it('create expected files', function (done) { 53 | this.ember.app.run({}, function () { 54 | helpers.assertFile(EXPECTED_FILES); 55 | done(); 56 | }); 57 | }); 58 | 59 | it('add compass as an npm dependency', function (done) { 60 | this.ember.app.run({}, function () { 61 | helpers.assertFileContent('package.json', /grunt-contrib-compass/); 62 | done(); 63 | }); 64 | }); 65 | 66 | it('add compass configuration to Gruntfile', function (done) { 67 | this.ember.app.run({}, function () { 68 | helpers.assertFileContent('Gruntfile.js', /compass:/); 69 | done(); 70 | }); 71 | }); 72 | 73 | }); 74 | 75 | describe('false', function () { 76 | 77 | beforeEach(function () { 78 | helpers.mockPrompt(this.ember.app, { 79 | compassBootstrap: false 80 | }); 81 | }); 82 | 83 | it('create expected files', function (done) { 84 | this.ember.app.run({}, function () { 85 | helpers.assertFile(EXPECTED_FILES); 86 | helpers.assertFile( ['app/styles/normalize.css', 'app/styles/style.css'] ); 87 | done(); 88 | }); 89 | }); 90 | 91 | it('do not add compass as an npm dependency', function (done) { 92 | this.ember.app.run({}, function () { 93 | helpers.assertNoFileContent('package.json', /grunt-contrib-compass/); 94 | done(); 95 | }); 96 | }); 97 | 98 | it('do not add compass configuration to Gruntfile', function (done) { 99 | this.ember.app.run({}, function () { 100 | helpers.assertNoFileContent('Gruntfile.js', /compass:/); 101 | done(); 102 | }); 103 | }); 104 | 105 | }); 106 | }); 107 | -------------------------------------------------------------------------------- /test/test-file-creation.js: -------------------------------------------------------------------------------- 1 | /*global describe:true, beforeEach:true, it:true, afterEach:true */ 2 | 'use strict'; 3 | var path = require('path'); 4 | var helpers = require('yeoman-generator').test; 5 | var assert = require('assert'); 6 | var fs = require('fs'); 7 | 8 | var EXPECTED_FILES = [ 9 | '.gitignore', 10 | '.gitattributes', 11 | '.bowerrc', 12 | 'bower.json', 13 | 'package.json', 14 | '.jshintrc', 15 | '.editorconfig', 16 | 'Gruntfile.js', 17 | 'app/scripts/app.js', 18 | 'app/scripts/store.js', 19 | 'app/scripts/routes/application_route.js', 20 | 'app/templates/application.hbs', 21 | 'app/templates/index.hbs', 22 | 'app/index.html' 23 | ]; 24 | 25 | describe('File Creation', function () { 26 | 27 | beforeEach(function (done) { 28 | 29 | helpers.testDirectory(path.join(__dirname, './temp'), function (err) { 30 | if (err) { 31 | return done(err); 32 | } 33 | 34 | this.ember = helpers.createGenerator('ember:app', [ 35 | '../../router', 36 | '../../app', [ 37 | helpers.createDummyGenerator(), 38 | 'mocha:app' 39 | ] 40 | ]); 41 | helpers.mockPrompt(this.ember, { 42 | compassBootstrap: true 43 | }); 44 | this.ember.options.coffee = false; 45 | this.ember.options['skip-install'] = true; 46 | 47 | done(); 48 | }.bind(this)); 49 | }); 50 | 51 | it('every generator can be required without throwing', function () { 52 | // not testing the actual run of generators yet 53 | require('../app'); 54 | require('../router'); 55 | require('../controller'); 56 | require('../view'); 57 | require('../model'); 58 | }); 59 | 60 | it('creates the expected files', function (done) { 61 | this.ember.run({}, function () { 62 | helpers.assertFiles(EXPECTED_FILES); 63 | done(); 64 | }); 65 | }); 66 | 67 | it('properly links ember data', function (done) { 68 | var expected = [ 69 | [ 70 | 'app/index.html', 71 | /