add coffeescript
This commit is contained in:
parent
3b1f15f9ab
commit
a37de3c20c
|
@ -7,11 +7,28 @@ require 'thor/group'
|
|||
class BackboneGenerator < Thor
|
||||
include Thor::Actions
|
||||
|
||||
class_option :coffee, :type => :boolean, :desc => 'Generate CoffeeScript instead of JavaScript'
|
||||
def self.source_root
|
||||
File.expand_path('../../templates', __FILE__)
|
||||
end
|
||||
|
||||
no_tasks do
|
||||
def extension
|
||||
options[:coffee] ? 'coffee' : 'js'
|
||||
end
|
||||
|
||||
def script_target
|
||||
options[:coffee] ? 'app/coffeescripts' : 'public/javascripts'
|
||||
end
|
||||
|
||||
def view_target
|
||||
'app/views'
|
||||
end
|
||||
|
||||
def test_target
|
||||
'spec/javascripts'
|
||||
end
|
||||
|
||||
def underscore_name
|
||||
singularize(Thor::Util.snake_case(@name.gsub("::", "/")))
|
||||
end
|
||||
|
@ -29,25 +46,25 @@ class BackboneGenerator < Thor
|
|||
end
|
||||
|
||||
def generate_model
|
||||
template('model.js.erb', "public/javascripts/models/#{underscore_name}.js")
|
||||
template('model_spec.js.erb', "spec/javascripts/models/#{underscore_name}_spec.js")
|
||||
template("model.#{extension}.erb", File.join(script_target, "models", "#{underscore_name}.#{extension}"))
|
||||
template("model_spec.#{extension}.erb", File.join(test_target, "models", "#{underscore_name}_spec.#{extension}"))
|
||||
end
|
||||
|
||||
def generate_view
|
||||
template('view.js.erb', "public/javascripts/views/#{underscore_name}_view.js")
|
||||
template('view.jst.erb', "app/views/#{underscore_name}s/view.jst")
|
||||
template('view_spec.js.erb', "spec/javascripts/views/#{underscore_name}_view_spec.js")
|
||||
template("view.#{extension}.erb", File.join(script_target, "views", "#{underscore_name}_view.#{extension}"))
|
||||
template("view.jst.erb", File.join(view_target, "#{underscore_name}s/view.jst"))
|
||||
template("view_spec.#{extension}.erb", File.join(test_target, "views", "#{underscore_name}_view_spec.#{extension}"))
|
||||
end
|
||||
|
||||
def generate_collection
|
||||
template('collection.js.erb', "public/javascripts/collections/#{plural_underscore_name}.js")
|
||||
template('collection_spec.js.erb', "spec/javascripts/collections/#{plural_underscore_name}_spec.js")
|
||||
template("collection.#{extension}.erb", File.join(script_target, "collections", "#{plural_underscore_name}.#{extension}"))
|
||||
template("collection_spec.#{extension}.erb", File.join(test_target, "collections", "#{plural_underscore_name}_spec.#{extension}"))
|
||||
end
|
||||
|
||||
def generate_collection_view
|
||||
template('collection_view.js.erb', "public/javascripts/views/#{plural_underscore_name}_view.js")
|
||||
template('collection_view.jst.erb', "app/views/#{plural_underscore_name}/list.jst")
|
||||
template('collection_view_spec.js.erb', "spec/javascripts/views/#{plural_underscore_name}_view_spec.js")
|
||||
template("collection_view.#{extension}.erb", File.join(script_target, 'views', "#{plural_underscore_name}_view.#{extension}"))
|
||||
template("collection_view.jst.erb", File.join(view_target, "#{plural_underscore_name}/list.jst"))
|
||||
template("collection_view_spec.#{extension}.erb", File.join(test_target, "views", "#{plural_underscore_name}_view_spec.#{extension}"))
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -83,20 +100,20 @@ class BackboneGenerator < Thor
|
|||
|
||||
desc 'spec-helper', "Generate a spec helper for Backbone things"
|
||||
def spec_helper
|
||||
template('spec_helper.js.erb', 'spec/javascripts/helpers/backbone_spec_helper.js')
|
||||
template("spec_helper.#{extension}.erb", File.join(test_target, "helpers", "backbone_spec_helper.#{extension}"))
|
||||
end
|
||||
|
||||
desc 'app-helper', "Generate an application helper for useful Backbone things"
|
||||
desc "app-helper", "Generate an application helper for useful Backbone things"
|
||||
def app_helper
|
||||
template('app_helper.js.erb', 'public/javascripts/applications/backbone_helper.js')
|
||||
template("app_helper.#{extension}.erb", File.join(script_target, "applications", "backbone_helper.#{extension}"))
|
||||
end
|
||||
|
||||
desc 'app-scaffold', "Generate an application scaffold"
|
||||
desc "app-scaffold", "Generate an application scaffold"
|
||||
def app_scaffold
|
||||
template('app_view.js.erb', 'public/javascripts/application/app_view.js')
|
||||
template('app_view.jst.erb', 'app/views/application/app_view.jst')
|
||||
template('controller.js.erb', 'public/javascripts/application/controller.js')
|
||||
template('app_view_spec.js.erb', 'spec/javascripts/application/app_view_spec.js')
|
||||
template("app_view.#{extension}.erb", File.join(script_target, "application", "app_view.#{extension}"))
|
||||
template("app_view.jst.erb", File.join(view_target, "application", "app_view.jst"))
|
||||
template("controller.#{extension}.erb", File.join(script_target, "application", "controller.#{extension}"))
|
||||
template("app_view_spec.#{extension}.erb", File.join(test_target, "application", "app_view_spec.#{extension}"))
|
||||
end
|
||||
|
||||
private
|
||||
|
|
|
@ -16,8 +16,116 @@ describe 'backbone-generator' do
|
|||
after { clean! }
|
||||
|
||||
describe 'coffeescript' do
|
||||
describe 'model' do
|
||||
def should_generate_model
|
||||
File.file?(model = 'app/coffeescripts/models/section/model.coffee').should be_true
|
||||
File.file?(spec = 'spec/javascripts/models/section/model_spec.coffee').should be_true
|
||||
|
||||
File.read(model).should match(/SectionModel/)
|
||||
File.read(spec).should match(/SectionModel/)
|
||||
end
|
||||
|
||||
def should_generate_view
|
||||
File.file?(view = 'app/coffeescripts/views/section/model_view.coffee').should be_true
|
||||
File.file?(spec = 'spec/javascripts/views/section/model_view_spec.coffee').should be_true
|
||||
File.file?(template = 'app/views/section/models/view.jst').should be_true
|
||||
|
||||
File.read(view).should match(/SectionModel/)
|
||||
File.read(view).should match(%r{template: JST\['section/models/view'\]})
|
||||
File.read(spec).should match(/SectionModel/)
|
||||
end
|
||||
|
||||
def should_generate_collection
|
||||
File.file?(collection = 'app/coffeescripts/collections/section/models.coffee').should be_true
|
||||
File.file?(spec = 'spec/javascripts/collections/section/models_spec.coffee').should be_true
|
||||
|
||||
File.read(collection).should match(/SectionModels/)
|
||||
File.read(collection).should_not match(/SectionModelss/)
|
||||
File.read(collection).should match(%r{section/model})
|
||||
File.read(spec).should match(/SectionModels/)
|
||||
File.read(spec).should_not match(/SectionModelss/)
|
||||
end
|
||||
|
||||
def should_generate_collection_view
|
||||
File.file?(view = 'app/coffeescripts/views/section/models_view.coffee').should be_true
|
||||
File.file?(spec = 'spec/javascripts/views/section/models_view_spec.coffee').should be_true
|
||||
File.file?(template = 'app/views/section/models/list.jst').should be_true
|
||||
|
||||
File.read(view).should match(/SectionModelsView/)
|
||||
File.read(view).should_not match(/SectionModelssView/)
|
||||
File.read(view).should match(/SectionModelView/)
|
||||
File.read(view).should match(%r{template: JST\['section/models/list'\]})
|
||||
File.read(spec).should match(/SectionModelsView/)
|
||||
File.read(spec).should_not match(/SectionModelssView/)
|
||||
end
|
||||
|
||||
describe 'model' do
|
||||
it "should generate the model files" do
|
||||
run "model", "Section::Model", '--coffee'
|
||||
|
||||
should_generate_model
|
||||
end
|
||||
end
|
||||
|
||||
describe 'view' do
|
||||
it "should generate the model files" do
|
||||
run "view", "Section::Model", '--coffee'
|
||||
|
||||
should_generate_view
|
||||
end
|
||||
end
|
||||
|
||||
describe 'collection view' do
|
||||
it "should generate the collection view files" do
|
||||
run "collection-view", "Section::Model", '--coffee'
|
||||
|
||||
should_generate_collection_view
|
||||
end
|
||||
end
|
||||
|
||||
describe 'collection' do
|
||||
it "should generate the collection files" do
|
||||
run "collection", "Section::Model", '--coffee'
|
||||
|
||||
should_generate_collection
|
||||
end
|
||||
end
|
||||
|
||||
describe 'scaffold' do
|
||||
it "should generate everything!" do
|
||||
run "scaffold", "Section::Model", '--coffee'
|
||||
|
||||
should_generate_model
|
||||
should_generate_view
|
||||
should_generate_collection
|
||||
should_generate_collection_view
|
||||
end
|
||||
end
|
||||
|
||||
describe 'spec helper' do
|
||||
it "should generate a spec helper" do
|
||||
run "spec-helper", '--coffee'
|
||||
|
||||
File.file?(collection = 'spec/javascripts/helpers/backbone_spec_helper.coffee').should be_true
|
||||
end
|
||||
end
|
||||
|
||||
describe 'app helper' do
|
||||
it "should generate an app helper" do
|
||||
run "app-helper", '--coffee'
|
||||
|
||||
File.file?(collection = 'app/coffeescripts/applications/backbone_helper.coffee').should be_true
|
||||
end
|
||||
end
|
||||
|
||||
describe 'application scaffold' do
|
||||
it "should generate an application scaffold" do
|
||||
run "app-scaffold", '--coffee'
|
||||
|
||||
File.file?(app = 'app/coffeescripts/application/app_view.coffee').should be_true
|
||||
File.file?(app_view = 'app/views/application/app_view.jst').should be_true
|
||||
File.file?(controller = 'app/coffeescripts/application/controller.coffee').should be_true
|
||||
File.file?(spec = 'spec/javascripts/application/app_view_spec.coffee').should be_true
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
@ -0,0 +1,18 @@
|
|||
Backbone.Collection.prototype.ensureFetched = (callback) ->
|
||||
if (@_alreadyEnsureFetched)
|
||||
_refresher =>
|
||||
this.unbind('refresh', _refresher)
|
||||
callback.apply(this)
|
||||
@_alreadyEnsureFetched = true
|
||||
@bind('refresh', _refresher)
|
||||
@fetch()
|
||||
else
|
||||
callback.apply(this)
|
||||
|
||||
Backbone.View.prototype.attributes = ->
|
||||
attrs = {}
|
||||
for field in @attributeFields
|
||||
do (field) =>
|
||||
attrs[field] = this.$("input[name='#{field}']").val()
|
||||
attrs
|
||||
|
|
@ -0,0 +1,10 @@
|
|||
class window.AppView extends Backbone.View
|
||||
el: '#application'
|
||||
template: JST['application/app_view']
|
||||
initialize: ->
|
||||
controller = new Controller({app: this})
|
||||
Backbone.history.start()
|
||||
render: =>
|
||||
$(@el).html(@template())
|
||||
this
|
||||
|
|
@ -0,0 +1,9 @@
|
|||
describe 'AppView', ->
|
||||
appView = null
|
||||
|
||||
beforeEach, ->
|
||||
appView = new AppView()
|
||||
|
||||
it 'should render', ->
|
||||
expect($(appView.render().el)).toContain('.something')
|
||||
|
|
@ -0,0 +1,4 @@
|
|||
class window.<%= plural_object_name %> extends Backbone.Collection
|
||||
url: '/<%= plural_underscore_name %>'
|
||||
model: <%= object_name %>
|
||||
|
|
@ -0,0 +1,7 @@
|
|||
describe '<%= plural_object_name %>', ->
|
||||
collection = null
|
||||
|
||||
withServer()
|
||||
|
||||
it 'should fetch records from the API', ->
|
||||
|
|
@ -0,0 +1,23 @@
|
|||
class window.<%= plural_object_name %>View extends Backbone.View
|
||||
events: {
|
||||
'click button.new': 'addNew'
|
||||
}
|
||||
template: JST['<%= plural_underscore_name %>/list']
|
||||
initialize: ->
|
||||
@collection.bind('refresh', @addAll)
|
||||
|
||||
@render
|
||||
@collection.fetch
|
||||
render: =>
|
||||
$(this.el).html(@template())
|
||||
this
|
||||
addOne: (model) =>
|
||||
view = new <%= object_name %>View({model: model})
|
||||
this.$('.list').append(view.render().el)
|
||||
addAll: =>
|
||||
@collection.each(@addOne)
|
||||
addNew: =>
|
||||
facility = new <%= object_name %>()
|
||||
@collection.add(facility)
|
||||
@addOne(facility)
|
||||
|
|
@ -0,0 +1,19 @@
|
|||
describe '<%= plural_object_name %>View', ->
|
||||
view = collection = null
|
||||
|
||||
beforeEach ->
|
||||
collection = new <%= plural_object_name %>()
|
||||
|
||||
it 'should render', ->
|
||||
view = new <%= plural_object_name %>View({collection: collectioon})
|
||||
view.render
|
||||
|
||||
expect($(view.el)).toContain('.list')
|
||||
expect($(view.el)).toContail('button.new')
|
||||
|
||||
it 'should add a new model when new is clicked', ->
|
||||
view.$('button.new').trigger('click')
|
||||
|
||||
expect(view.$('.list').toContain('.<%= underscore_name %>')
|
||||
expect(collection.length).toEqual(1)
|
||||
|
|
@ -0,0 +1,2 @@
|
|||
class window.Controller extends Backbone.Controller
|
||||
routes: {}
|
|
@ -0,0 +1 @@
|
|||
class window.<%= object_name %> extends Backbone.Model
|
|
@ -0,0 +1,8 @@
|
|||
describe '<%= object_name %>', ->
|
||||
model = null
|
||||
|
||||
it 'should have some tests', ->
|
||||
model = new <%= object_name %>()
|
||||
|
||||
expect(true).toEqual(false)
|
||||
|
|
@ -0,0 +1,14 @@
|
|||
window.withServer ->
|
||||
jasmine.getEnv().withServer()
|
||||
|
||||
jasmine.Env.prototype.withServer ->
|
||||
@currentSuite.beforeEach ->
|
||||
@server = sinon.fakeServer.create()
|
||||
|
||||
@currentSuite.afterEach ->
|
||||
@server.restore()
|
||||
|
||||
beforeEach ->
|
||||
@validJSONResponse = (data) ->
|
||||
[ 200, { 'Content-type': 'application/json' }, JSON.stringify(data) ]
|
||||
|
|
@ -0,0 +1,22 @@
|
|||
class window.<%= object_name %>View extends Backbone.View
|
||||
events: {
|
||||
'click button.save': 'save',
|
||||
'click button.delete': 'destroy'
|
||||
}
|
||||
attributeFields: []
|
||||
template: JST['<%= underscore_name %>s/view']
|
||||
className: '<%= underscore_name %>'
|
||||
initialize: ->
|
||||
@model.bind('change', @render)
|
||||
@model.bind('remove', @remove)
|
||||
@model.view = this
|
||||
render: =>
|
||||
$(@el).html(@template(@model.toJSON))
|
||||
this.$('button.save').text(@model.isNew() ? 'Create' : 'Update')
|
||||
this
|
||||
save: =>
|
||||
@model.save(@attributes)
|
||||
destroy: =>
|
||||
if confirm("Are you sure?")
|
||||
@model.destroy
|
||||
|
|
@ -0,0 +1,42 @@
|
|||
describe '<%= object_name %>View', ->
|
||||
view = model = null
|
||||
|
||||
describe 'new record', ->
|
||||
beforeEach ->
|
||||
model = new <%= object_name %>
|
||||
|
||||
it 'should render with a create button', ->
|
||||
view = new <%= object_name %>View({model: model})
|
||||
view.render
|
||||
|
||||
expect(view.$('button.save')).toHaveText('Create')
|
||||
|
||||
describe 'existing record', ->
|
||||
beforeEach ->
|
||||
model = new <%= object_name %>({id: 1})
|
||||
setFixtures('<div id="container" />')
|
||||
|
||||
view = new <%= object_name %>View({model: model})
|
||||
|
||||
it 'should render with an update button', ->
|
||||
view.render
|
||||
|
||||
expect(view.$('button.save')).toHaveText('Update')
|
||||
|
||||
it 'should destroy the model', ->
|
||||
spyOn(window, 'confirm').andReturn(true)
|
||||
spyOn(model, 'destory')
|
||||
|
||||
$('#container').append(view.el)
|
||||
view.$('button.delete').trigger('click')
|
||||
|
||||
expect(model.destroy).toHaveBeenCalled
|
||||
expect(window.confirm).toHaveBeenCalled
|
||||
|
||||
it 'should remove the view when the model is destroyed', ->
|
||||
$('#container').append(view.render().el)
|
||||
|
||||
expect($('button.save')).toExist
|
||||
model.trigger('remove')
|
||||
expect($('button.save')).not.toExist
|
||||
|
Loading…
Reference in New Issue