bricks-cli
Version:
Command line tool for developing ambitious ember.js apps
878 lines (805 loc) • 26.6 kB
JavaScript
/*jshint quotmark: false*/
;
var Promise = require('../../lib/ext/promise');
var assertFile = require('../helpers/assert-file');
var assertFileEquals = require('../helpers/assert-file-equals');
var conf = require('../helpers/conf');
var ember = require('../helpers/ember');
var fs = require('fs-extra');
var outputFile = Promise.denodeify(fs.outputFile);
var path = require('path');
var rimraf = require('rimraf');
var root = process.cwd();
var tmp = require('tmp-sync');
var tmproot = path.join(root, 'tmp');
describe('Acceptance: ember generate', function() {
var tmpdir;
before(function() {
conf.setup();
});
after(function() {
conf.restore();
});
beforeEach(function() {
tmpdir = tmp.in(tmproot);
process.chdir(tmpdir);
});
afterEach(function() {
process.chdir(root);
rimraf.sync(tmproot);
});
function initApp() {
return ember(['init', 'my-app', '--skip-npm', '--skip-bower']);
}
function generate(args) {
var generateArgs = ['generate'].concat(args);
return initApp().then(function() {
return ember(generateArgs);
});
}
it('controller foo', function() {
return generate(['controller', 'foo']).then(function() {
assertFile('app/controllers/foo.js', {
contains: [
"import Ember from 'ember';",
"export default Ember.Controller.extend({\n});"
]
});
assertFile('tests/unit/controllers/foo-test.js', {
contains: [
"import { test, moduleFor } from 'ember-qunit';",
"moduleFor('controller:foo', 'FooController'"
]
});
});
});
it('controller foo type:object', function() {
return generate(['controller', 'foo', 'type:object']).then(function() {
assertFile('app/controllers/foo.js', {
contains: [
"import Ember from 'ember';",
"export default Ember.ObjectController.extend({\n});"
]
});
});
});
it('controller foo type:array', function() {
return generate(['controller', 'foo', 'type:array']).then(function() {
assertFile('app/controllers/foo.js', {
contains: [
"import Ember from 'ember';",
"export default Ember.ArrayController.extend({\n});"
]
});
});
});
it('controller foo/bar', function() {
return generate(['controller', 'foo/bar']).then(function() {
assertFile('app/controllers/foo/bar.js', {
contains: [
"import Ember from 'ember';",
"export default Ember.Controller.extend({\n});"
]
});
assertFile('tests/unit/controllers/foo/bar-test.js', {
contains: [
"import { test, moduleFor } from 'ember-qunit';",
"moduleFor('controller:foo/bar', 'FooBarController'"
]
});
});
});
it('component x-foo', function() {
return generate(['component', 'x-foo']).then(function() {
assertFile('app/components/x-foo.js', {
contains: [
"import Ember from 'ember';",
"export default Ember.Component.extend({\n});"
]
});
assertFile('app/templates/components/x-foo.hbs', {
contains: "{{yield}}"
});
assertFile('tests/unit/components/x-foo-test.js', {
contains: [
"import { test, moduleForComponent } from 'ember-qunit';",
"moduleForComponent('x-foo', 'XFooComponent'"
]
});
});
});
it('helper foo-bar', function() {
return generate(['helper', 'foo-bar']).then(function() {
assertFile('app/helpers/foo-bar.js', {
contains: "import Ember from 'ember';\n\n" +
"export default Ember.Handlebars.makeBoundHelper(function(value) {\n" +
" return value;\n" +
"});"
});
});
});
it('helper foo/bar-baz', function() {
return generate(['helper', 'foo/bar-baz']).then(function() {
assertFile('app/helpers/foo/bar-baz.js', {
contains: "import Ember from 'ember';\n\n" +
"export default Ember.Handlebars.makeBoundHelper(function(value) {\n" +
" return value;\n" +
"});"
});
});
});
it('model foo', function() {
return generate(['model', 'foo']).then(function() {
assertFile('app/models/foo.js', {
contains: [
"import DS from 'ember-data';",
"export default DS.Model.extend"
]
});
assertFile('tests/unit/models/foo-test.js', {
contains: [
"import { test, moduleForModel } from 'ember-qunit';",
"moduleForModel('foo', 'Foo'"
]
});
});
});
it('model foo with attributes', function() {
return generate([
'model',
'foo',
'noType',
'firstName:string',
'created_at:date',
'is-published:boolean',
'rating:number',
'bars:has-many',
'baz:belongs-to',
'echo:hasMany',
'bravo:belongs_to'
]).then(function() {
assertFile('app/models/foo.js', {
contains: [
"noType: DS.attr()",
"firstName: DS.attr('string')",
"createdAt: DS.attr('date')",
"isPublished: DS.attr('boolean')",
"rating: DS.attr('number')",
"bars: DS.hasMany('bar')",
"baz: DS.belongsTo('baz')",
"echos: DS.hasMany('echo')",
"bravo: DS.belongsTo('bravo')"
]
});
assertFile('tests/unit/models/foo-test.js', {
contains: "needs: ['model:bar', 'model:baz', 'model:echo', 'model:bravo']"
});
});
});
it('model foo/bar', function() {
return generate(['model', 'foo/bar']).then(function() {
assertFile('app/models/foo/bar.js', {
contains: [
"import DS from 'ember-data';",
"export default DS.Model.extend"
]
});
assertFile('tests/unit/models/foo/bar-test.js', {
contains: [
"import { test, moduleForModel } from 'ember-qunit';",
"moduleForModel('foo/bar', 'FooBar'"
]
});
});
});
it('route foo', function() {
return generate(['route', 'foo']).then(function() {
assertFile('app/router.js', {
contains: "this.route('foo')"
});
assertFile('app/routes/foo.js', {
contains: [
"import Ember from 'ember';",
"export default Ember.Route.extend({\n});"
]
});
assertFile('app/templates/foo.hbs');
assertFile('tests/unit/routes/foo-test.js', {
contains: [
"import { test, moduleFor } from 'ember-qunit';",
"moduleFor('route:foo', 'FooRoute'"
]
});
});
});
it('route foo type:resource', function() {
return generate(['route', 'foo', 'type:resource']).then(function() {
assertFile('app/router.js', {
contains: "this.resource('foo', { path: 'foos/:foo_id' });"
});
});
});
it('route foos type:resource', function() {
return generate(['route', 'foos', 'type:resource']).then(function() {
assertFile('app/router.js', {
contains: "this.resource('foos');"
});
});
});
it('route index', function() {
return generate(['route', 'index']).then(function() {
assertFile('app/router.js', {
doesNotContain: "this.route('index');"
});
});
});
it('route basic isn\'t added to router', function() {
return generate(['route', 'basic']).then(function() {
assertFile('app/router.js', {
doesNotContain: "this.route('basic');"
});
assertFile('app/routes/basic.js');
});
});
it('route bar does not create duplicates in router.js', function() {
function checkRoute(testString) {
var routerDefinition = (
"Router.map(function() {\n" +
" this.resource('foo', function() {\n" +
" " + testString + "\n" +
" });\n" +
"});\n"
);
return outputFile('app/router.js', routerDefinition)
.then(function() {
return ember(['generate', 'route', 'bar']);
})
.then(function() {
return assertFile('app/router.js', {
contains: routerDefinition
});
});
}
return initApp()
.then(function() {
return checkRoute("this.route('bar');");
})
.then(function() {
return checkRoute("this.route ('bar');");
})
.then(function() {
return checkRoute("this.route ( 'bar' );");
})
.then(function() {
return checkRoute('this.route("bar");');
});
});
it('template foo', function() {
return generate(['template', 'foo']).then(function() {
assertFile('app/templates/foo.hbs');
});
});
it('template foo/bar', function() {
return generate(['template', 'foo/bar']).then(function() {
assertFile('app/templates/foo/bar.hbs');
});
});
it('view foo', function() {
return generate(['view', 'foo']).then(function() {
assertFile('app/views/foo.js', {
contains: [
"import Ember from 'ember';",
'export default Ember.View.extend({\n})'
]
});
assertFile('tests/unit/views/foo-test.js', {
contains: [
"import { test, moduleFor } from 'ember-qunit';",
"moduleFor('view:foo', 'FooView'"
]
});
});
});
it('view foo/bar', function() {
return generate(['view', 'foo/bar']).then(function() {
assertFile('app/views/foo/bar.js', {
contains: [
"import Ember from 'ember';",
'export default Ember.View.extend({\n})'
]
});
assertFile('tests/unit/views/foo/bar-test.js', {
contains: [
"import { test, moduleFor } from 'ember-qunit';",
"moduleFor('view:foo/bar', 'FooBarView'"
]
});
});
});
it('resource foo', function() {
return generate(['resource', 'foo']).then(function() {
assertFile('app/router.js', {
contains: "this.resource('foo', { path: 'foos/:foo_id' });"
});
assertFile('app/models/foo.js', {
contains: 'export default DS.Model.extend'
});
assertFile('app/routes/foo.js', {
contains: 'export default Ember.Route.extend({\n});'
});
assertFile('app/templates/foo.hbs');
assertFile('tests/unit/models/foo-test.js', {
contains: "moduleForModel('foo', 'Foo'"
});
assertFile('tests/unit/routes/foo-test.js', {
contains: "moduleFor('route:foo', 'FooRoute'"
});
});
});
it('resource foos', function() {
return generate(['resource', 'foos']).then(function() {
assertFile('app/router.js', {
contains: "this.resource('foos');"
});
assertFile('app/models/foo.js', {
contains: 'export default DS.Model.extend'
});
assertFile('app/routes/foos.js', {
contains: 'export default Ember.Route.extend({\n});'
});
assertFile('app/templates/foos.hbs');
assertFile('tests/unit/models/foo-test.js', {
contains: "moduleForModel('foo', 'Foo'"
});
assertFile('tests/unit/routes/foos-test.js', {
contains: "moduleFor('route:foos', 'FoosRoute'"
});
});
});
it('initializer foo', function() {
return generate(['initializer', 'foo']).then(function() {
assertFile('app/initializers/foo.js', {
contains: "export default {\n" +
" name: 'foo',\n\n" +
" initialize: function(/* container, app */) {\n" +
" // app.register('route', 'foo', 'service:foo');\n" +
" }\n" +
"};"
});
});
});
it('initializer foo/bar', function() {
return generate(['initializer', 'foo/bar']).then(function() {
assertFile('app/initializers/foo/bar.js', {
contains: "export default {\n" +
" name: 'foo/bar',\n\n" +
" initialize: function(/* container, app */) {\n" +
" // app.register('route', 'foo', 'service:foo');\n" +
" }\n" +
"};"
});
});
});
it('mixin foo', function() {
return generate(['mixin', 'foo']).then(function() {
assertFile('app/mixins/foo.js', {
contains: [
"import Ember from 'ember';",
'export default Ember.Mixin.create({\n});'
]
});
assertFile('tests/unit/mixins/foo-test.js', {
contains: [
"import FooMixin from 'my-app/mixins/foo';"
]
});
});
});
it('mixin foo/bar', function() {
return generate(['mixin', 'foo/bar']).then(function() {
assertFile('app/mixins/foo/bar.js', {
contains: [
"import Ember from 'ember';",
'export default Ember.Mixin.create({\n});'
]
});
assertFile('tests/unit/mixins/foo/bar-test.js', {
contains: [
"import FooBarMixin from 'my-app/mixins/foo/bar';"
]
});
});
});
it('adapter foo', function() {
return generate(['adapter', 'foo']).then(function() {
assertFile('app/adapters/foo.js', {
contains: [
"import DS from 'ember-data';",
"export default DS.RESTAdapter.extend({\n});"
]
});
});
});
it('adapter foo/bar', function() {
return generate(['adapter', 'foo/bar']).then(function() {
assertFile('app/adapters/foo/bar.js', {
contains: [
"import DS from 'ember-data';",
"export default DS.RESTAdapter.extend({\n});"
]
});
});
});
it('serializer foo', function() {
return generate(['serializer', 'foo']).then(function() {
assertFile('app/serializers/foo.js', {
contains: [
"import DS from 'ember-data';",
'export default DS.RESTSerializer.extend({\n});'
]
});
assertFile('tests/unit/serializers/foo-test.js', {
contains: [
"import { test, moduleFor } from 'ember-qunit';",
"moduleFor('serializer:foo', 'FooSerializer'"
]
});
});
});
it('serializer foo/bar', function() {
return generate(['serializer', 'foo/bar']).then(function() {
assertFile('app/serializers/foo/bar.js', {
contains: [
"import DS from 'ember-data';",
'export default DS.RESTSerializer.extend({\n});'
]
});
assertFile('tests/unit/serializers/foo/bar-test.js', {
contains: [
"import { test, moduleFor } from 'ember-qunit';",
"moduleFor('serializer:foo/bar', 'FooBarSerializer'"
]
});
});
});
it('transform foo', function() {
return generate(['transform', 'foo']).then(function() {
assertFile('app/transforms/foo.js', {
contains: [
"import DS from 'ember-data';",
'export default DS.Transform.extend({\n' +
' deserialize: function(serialized) {\n' +
' return serialized;\n' +
' },\n' +
'\n' +
' serialize: function(deserialized) {\n' +
' return deserialized;\n' +
' }\n' +
'});'
]
});
assertFile('tests/unit/transforms/foo-test.js', {
contains: [
"import { test, moduleFor } from 'ember-qunit';",
"moduleFor('transform:foo', 'FooTransform'"
]
});
});
});
it('transform foo/bar', function() {
return generate(['transform', 'foo/bar']).then(function() {
assertFile('app/transforms/foo/bar.js', {
contains: [
"import DS from 'ember-data';",
'export default DS.Transform.extend({\n' +
' deserialize: function(serialized) {\n' +
' return serialized;\n' +
' },\n' +
'\n' +
' serialize: function(deserialized) {\n' +
' return deserialized;\n' +
' }\n' +
'});'
]
});
assertFile('tests/unit/transforms/foo/bar-test.js', {
contains: [
"import { test, moduleFor } from 'ember-qunit';",
"moduleFor('transform:foo/bar', 'FooBarTransform'"
]
});
});
});
it('util foo-bar', function() {
return generate(['util', 'foo-bar']).then(function() {
assertFile('app/utils/foo-bar.js', {
contains: 'export default function fooBar() {\n' +
' return true;\n' +
'}'
});
assertFile('tests/unit/utils/foo-bar-test.js', {
contains: [
"import fooBar from 'my-app/utils/foo-bar';"
]
});
});
});
it('util foo-bar/baz', function() {
return generate(['util', 'foo/bar-baz']).then(function() {
assertFile('app/utils/foo/bar-baz.js', {
contains: 'export default function fooBarBaz() {\n' +
' return true;\n' +
'}'
});
assertFile('tests/unit/utils/foo/bar-baz-test.js', {
contains: [
"import fooBarBaz from 'my-app/utils/foo/bar-baz';"
]
});
});
});
it('service foo', function() {
return generate(['service', 'foo']).then(function() {
assertFile('app/services/foo.js', {
contains: [
"import Ember from 'ember';",
'export default Ember.Object.extend({\n});'
]
});
assertFile('app/initializers/foo.js', {
contains: "export default {\n" +
" name: 'foo',\n" +
" initialize: function(container, app) {\n" +
" app.inject('route', 'foo', 'service:foo');\n" +
" }\n" +
"};"
});
assertFile('tests/unit/services/foo-test.js', {
contains: [
"import { test, moduleFor } from 'ember-qunit';",
"moduleFor('service:foo', 'FooService'"
]
});
});
});
it('service foo/bar', function() {
return generate(['service', 'foo/bar']).then(function() {
assertFile('app/services/foo/bar.js', {
contains: [
"import Ember from 'ember';",
'export default Ember.Object.extend({\n});'
]
});
assertFile('app/initializers/foo/bar.js', {
contains: "export default {\n" +
" name: 'foo/bar',\n" +
" initialize: function(container, app) {\n" +
" app.inject('route', 'fooBar', 'service:fooBar');\n" +
" }\n" +
"};"
});
assertFile('tests/unit/services/foo/bar-test.js', {
contains: [
"import { test, moduleFor } from 'ember-qunit';",
"moduleFor('service:foo/bar', 'FooBarService'"
]
});
});
});
it('blueprint foo', function() {
return generate(['blueprint', 'foo']).then(function() {
assertFile('blueprints/foo/index.js', {
contains: "module.exports = {\n" +
" // locals: function(options) {\n" +
" // // Return custom template variables here.\n" +
" // return {\n" +
" // foo: options.entity.options.foo\n" +
" // };\n" +
" // }\n" +
"\n" +
" // afterInstall: function(options) {\n" +
" // // Perform extra work here.\n" +
" // }\n" +
"};"
});
});
});
it('blueprint foo/bar', function() {
return generate(['blueprint', 'foo/bar']).then(function() {
assertFile('blueprints/foo/bar/index.js', {
contains: "module.exports = {\n" +
" // locals: function(options) {\n" +
" // // Return custom template variables here.\n" +
" // return {\n" +
" // foo: options.entity.options.foo\n" +
" // };\n" +
" // }\n" +
"\n" +
" // afterInstall: function(options) {\n" +
" // // Perform extra work here.\n" +
" // }\n" +
"};"
});
});
});
it('api-stub foo', function() {
return generate(['api-stub', 'foo']).then(function() {
assertFile('server/index.js', {
contains: "var bodyParser = require('body-parser');\n" +
"var globSync = require('glob').sync;\n" +
"var routes = globSync('./routes/**/*.js', { cwd: __dirname }).map(require);\n" +
"\n" +
"module.exports = function(app) {\n" +
" app.use(bodyParser.json());\n" +
" app.use(bodyParser.urlencoded({\n" +
" extended: true\n" +
" }));\n" +
"\n" +
" routes.forEach(function(route) { route(app); });\n" +
"};"
});
assertFile('server/routes/foo.js', {
contains: "module.exports = function(app) {\n" +
" var express = require('express');\n" +
" var fooRouter = express.Router();\n" +
" fooRouter.get('/', function(req, res) {\n" +
" res.send({foo:[]});\n" +
" });\n" +
" app.use('/api/foo', fooRouter);\n" +
"};"
});
assertFile('server/.jshintrc', {
contains: '{\n "node": true\n}'
});
});
});
it('uses blueprints from the project directory', function() {
return initApp()
.then(function() {
return outputFile(
'blueprints/foo/files/app/foos/__name__.js',
"import Ember from 'ember';\n\n" +
'export default Ember.Object.extend({ foo: true });\n'
);
})
.then(function() {
return ember(['generate', 'foo', 'bar']);
})
.then(function() {
assertFile('app/foos/bar.js', {
contains: 'foo: true'
});
});
});
it('allows custom blueprints to override built-ins', function() {
return initApp()
.then(function() {
return outputFile(
'blueprints/controller/files/app/controllers/__name__.js',
"import Ember from 'ember';\n\n" +
"export default Ember.Controller.extend({ custom: true });\n"
);
})
.then(function() {
return ember(['generate', 'controller', 'foo']);
})
.then(function() {
assertFile('app/controllers/foo.js', {
contains: 'custom: true'
});
});
});
it('passes custom cli arguments to blueprint options', function() {
return initApp()
.then(function() {
outputFile(
'blueprints/customblue/files/app/__name__.js',
"Q: Can I has custom command? A: <%= hasCustomCommand %>"
);
return outputFile(
'blueprints/customblue/index.js',
"module.exports = {\n" +
" locals: function(options) {\n" +
" var loc = {};\n" +
" loc.hasCustomCommand = (options.customCommand) ? 'Yes!' : 'No. :C';\n" +
" return loc;\n" +
" },\n" +
"};\n"
);
})
.then(function() {
return ember(['generate', 'customblue', 'foo', '--custom-command']);
})
.then(function() {
assertFile('app/foo.js', {
contains: 'A: Yes!'
});
});
});
it('acceptance-test foo', function() {
return generate(['acceptance-test', 'foo']).then(function() {
var expected = path.join(__dirname, '../fixtures/generate/acceptance-test-expected.js');
assertFileEquals('tests/acceptance/foo-test.js', expected);
});
});
it('correctly identifies the root of the project', function() {
return initApp()
.then(function() {
return outputFile(
'blueprints/controller/files/app/controllers/__name__.js',
"import Ember from 'ember';\n\n" +
"export default Ember.Controller.extend({ custom: true });\n"
);
})
.then(function() {
process.chdir(path.join(tmpdir, 'app'));
})
.then(function() {
return ember(['generate', 'controller', 'foo']);
})
.then(function() {
process.chdir(tmpdir);
})
.then(function() {
assertFile('app/controllers/foo.js', {
contains: 'custom: true'
});
});
});
it('scaffold foo', function() {
return generate(['scaffold', 'foo']).then(function() {
assertFile('app/router.js', {
contains: "this.resource('foo', { path: 'foos/:foo_id' });"
});
assertFile('app/models/foo.js', {
contains: 'export default DS.Model.extend'
});
assertFile('app/routes/foo.js', {
contains: 'export default Ember.Route.extend({\n});'
});
assertFile('app/templates/foo.hbs');
assertFile('app/views/foo.js');
assertFile('app/controllers/foo.js');
assertFile('tests/unit/models/foo-test.js', {
contains: "moduleForModel('foo', 'Foo'"
});
assertFile('tests/unit/routes/foo-test.js', {
contains: "moduleFor('route:foo', 'FooRoute'"
});
assertFile('tests/unit/controllers/foo-test.js', {
contains: "moduleFor('controller:foo', 'FooController'"
});
assertFile('tests/unit/views/foo-test.js', {
contains: "moduleFor('view:foo', 'FooView'"
});
});
});
it('scaffold foos', function() {
return generate(['scaffold', 'foos']).then(function() {
assertFile('app/router.js', {
contains: "this.resource('foos');"
});
assertFile('app/models/foo.js', {
contains: 'export default DS.Model.extend'
});
assertFile('app/routes/foos.js', {
contains: 'export default Ember.Route.extend({\n});'
});
assertFile('app/templates/foos.hbs');
assertFile('app/views/foos.js');
assertFile('app/controllers/foos.js');
assertFile('tests/unit/models/foo-test.js', {
contains: "moduleForModel('foo', 'Foo'"
});
assertFile('tests/unit/routes/foos-test.js', {
contains: "moduleFor('route:foos', 'FoosRoute'"
});
assertFile('tests/unit/controllers/foos-test.js', {
contains: "moduleFor('controller:foos', 'FoosController'"
});
assertFile('tests/unit/views/foos-test.js', {
contains: "moduleFor('view:foos', 'FoosView'"
});
});
});
});