Compare commits

...

24 Commits

Author SHA1 Message Date
John Bintz 7ff9dc5ff9 remove a thing 2011-05-19 22:31:27 -04:00
John Bintz 0ba8019c64 fix the helper 2011-05-19 22:23:48 -04:00
John Bintz 134f93be86 oops 2011-05-19 20:58:34 -04:00
John Bintz 81bd5c176c better routes to trigger history 2011-05-19 20:56:04 -04:00
John Bintz 1ab4d353fa tyop and history fix 2011-05-19 20:53:39 -04:00
John Bintz b7d0e181d8 match rails 3.1 asset structure 2011-05-19 18:38:30 -04:00
John Bintz b0a8425617 more fixes 2011-05-13 10:22:13 -04:00
John Bintz 6b31491da7 another fix 2011-05-13 10:11:03 -04:00
John Bintz 8aea97569e view cleanup 2011-05-13 10:06:44 -04:00
John Bintz 755ffdb6c0 fix up collection view 2011-05-13 10:04:42 -04:00
John Bintz d7a77e672b update some templates 2011-05-09 21:47:00 -04:00
John Bintz 429549027f clean up mistakes 2011-05-09 07:35:37 -04:00
John Bintz a37de3c20c add coffeescript 2011-05-08 22:44:21 -04:00
John Bintz 3b1f15f9ab clean up test 2011-05-07 12:50:06 -04:00
John Bintz 5c2e078c02 fix bugs in the view templates 2011-05-03 16:10:26 -04:00
John Bintz ed9a824c37 tyop 2011-05-03 15:57:57 -04:00
John Bintz 97efc633de more template work, more fun defaults 2011-05-03 15:53:36 -04:00
John Bintz 14a2f3f714 more javascript updates 2011-05-03 15:43:19 -04:00
John Bintz 2919235390 make views more useful when created 2011-04-29 15:05:54 -04:00
John Bintz 8fbe5628ff merge 2011-04-23 19:09:03 -04:00
John Bintz b9c2f64d95 app scaffold 2011-04-23 19:02:33 -04:00
John Bintz adf18ae119 add app helper 2011-04-23 19:02:33 -04:00
John Bintz a22177ba54 Merge branch 'app-helper' into develop 2011-04-23 11:15:10 -04:00
John Bintz 1e9213f653 add app helper 2011-04-23 11:13:54 -04:00
27 changed files with 625 additions and 105 deletions

View File

@ -2,4 +2,12 @@ Autotest.add_hook(:initialize) do |at|
at.add_mapping(%r{bin/(.*)}, true) do |filename, matches| at.add_mapping(%r{bin/(.*)}, true) do |filename, matches|
at.files_matching(%r{spec/bin/#{matches[1]}_spec\.rb}) at.files_matching(%r{spec/bin/#{matches[1]}_spec\.rb})
end end
at.add_mapping(%r{spec/(.*)}, true) do |filename, matches|
at.files_matching(%r{#{filename}})
end
at.add_mapping(%r{templates/.*}, true) do |filename, matches|
at.files_matching(%r{spec/bin/.*_spec\.rb})
end
end end

View File

@ -7,15 +7,36 @@ require 'thor/group'
class BackboneGenerator < Thor class BackboneGenerator < Thor
include Thor::Actions include Thor::Actions
class_option :coffee, :type => :boolean, :desc => 'Generate CoffeeScript instead of JavaScript'
def self.source_root def self.source_root
File.expand_path('../../templates', __FILE__) File.expand_path('../../templates', __FILE__)
end end
no_tasks do no_tasks do
def extension
options[:coffee] ? 'coffee' : 'js'
end
def script_target
options[:coffee] ? 'app/assets/javascripts' : 'public/javascripts'
end
def view_target
'app/views'
end
def test_target
'spec/javascripts'
end
def underscore_name def underscore_name
singularize(Thor::Util.snake_case(@name.gsub("::", "/"))) singularize(Thor::Util.snake_case(@name.gsub("::", "/")))
end end
def css_class_name
underscore_name.gsub(%r{[^a-z0-9_]}, '-')
end
def plural_underscore_name def plural_underscore_name
pluralize(underscore_name) pluralize(underscore_name)
end end
@ -29,25 +50,25 @@ class BackboneGenerator < Thor
end end
def generate_model def generate_model
template('model.js.erb', "public/javascripts/models/#{underscore_name}.js") template("model.#{extension}.erb", File.join(script_target, "models", "#{underscore_name}.#{extension}"))
template('model_spec.js.erb', "spec/javascripts/models/#{underscore_name}_spec.js") template("model_spec.#{extension}.erb", File.join(test_target, "models", "#{underscore_name}_spec.#{extension}"))
end end
def generate_view def generate_view
template('view.js.erb', "public/javascripts/views/#{underscore_name}_view.js") template("view.#{extension}.erb", File.join(script_target, "views", "#{underscore_name}_view.#{extension}"))
template('view.jst.erb', "app/views/#{underscore_name}s/view.jst") template("view.jst.erb", File.join(view_target, "#{underscore_name}s/view.jst"))
template('view_spec.js.erb', "spec/javascripts/views/#{underscore_name}_view_spec.js") template("view_spec.#{extension}.erb", File.join(test_target, "views", "#{underscore_name}_view_spec.#{extension}"))
end end
def generate_collection def generate_collection
template('collection.js.erb', "public/javascripts/collections/#{plural_underscore_name}.js") template("collection.#{extension}.erb", File.join(script_target, "collections", "#{plural_underscore_name}.#{extension}"))
template('collection_spec.js.erb', "spec/javascripts/collections/#{plural_underscore_name}_spec.js") template("collection_spec.#{extension}.erb", File.join(test_target, "collections", "#{plural_underscore_name}_spec.#{extension}"))
end end
def generate_collection_view def generate_collection_view
template('collection_view.js.erb', "public/javascripts/views/#{plural_underscore_name}_view.js") template("collection_view.#{extension}.erb", File.join(script_target, 'views', "#{plural_underscore_name}_view.#{extension}"))
template('collection_view.jst.erb', "app/views/#{plural_underscore_name}/list.jst") template("collection_view.jst.erb", File.join(view_target, "#{plural_underscore_name}/list.jst"))
template('collection_view_spec.js.erb', "spec/javascripts/views/#{plural_underscore_name}_view_spec.js") template("collection_view_spec.#{extension}.erb", File.join(test_target, "views", "#{plural_underscore_name}_view_spec.#{extension}"))
end end
end end
@ -83,7 +104,20 @@ class BackboneGenerator < Thor
desc 'spec-helper', "Generate a spec helper for Backbone things" desc 'spec-helper', "Generate a spec helper for Backbone things"
def spec_helper 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"
def app_helper
template("app_helper.#{extension}.erb", File.join(script_target, "application", "backbone_helper.#{extension}"))
end
desc "app-scaffold", "Generate an application scaffold"
def app_scaffold
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 end
private private

View File

@ -8,9 +8,128 @@ describe 'backbone-generator' do
FileUtils.rm_rf 'app' FileUtils.rm_rf 'app'
end end
def run(*opts)
system %{bin/backbone-generator #{opts.join(' ')}}
end
before { clean! } before { clean! }
after { clean! } after { clean! }
describe 'coffeescript' do
def should_generate_model
File.file?(model = 'app/assets/javascripts/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/assets/javascripts/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/assets/javascripts/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/assets/javascripts/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/assets/javascripts/application/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/assets/javascripts/application/app_view.coffee').should be_true
File.file?(app_view = 'app/views/application/app_view.jst').should be_true
File.file?(controller = 'app/assets/javascripts/application/controller.coffee').should be_true
File.file?(spec = 'spec/javascripts/application/app_view_spec.coffee').should be_true
end
end
end
describe 'javascript' do
def should_generate_model def should_generate_model
File.file?(model = 'public/javascripts/models/section/model.js').should be_true File.file?(model = 'public/javascripts/models/section/model.js').should be_true
File.file?(spec = 'spec/javascripts/models/section/model_spec.js').should be_true File.file?(spec = 'spec/javascripts/models/section/model_spec.js').should be_true
@ -57,7 +176,7 @@ describe 'backbone-generator' do
describe 'model' do describe 'model' do
it "should generate the model files" do it "should generate the model files" do
system %{bin/backbone-generator model Section::Model} run "model", "Section::Model"
should_generate_model should_generate_model
end end
@ -65,7 +184,7 @@ describe 'backbone-generator' do
describe 'view' do describe 'view' do
it "should generate the view files" do it "should generate the view files" do
system %{bin/backbone-generator view Section::Model} run "view", "Section::Model"
should_generate_view should_generate_view
end end
@ -74,7 +193,7 @@ describe 'backbone-generator' do
describe 'collection view' do describe 'collection view' do
context 'without trailing s' do context 'without trailing s' do
it "should generate the collection view files" do it "should generate the collection view files" do
system %{bin/backbone-generator collection-view Section::Model} run "collection-view", "Section::Model"
should_generate_collection_view should_generate_collection_view
end end
@ -82,7 +201,7 @@ describe 'backbone-generator' do
context 'with trailing s' do context 'with trailing s' do
it "should generate the collection view files" do it "should generate the collection view files" do
system %{bin/backbone-generator collection-view Section::Models} run "collection-view", "Section::Models"
should_generate_collection_view should_generate_collection_view
end end
@ -92,7 +211,7 @@ describe 'backbone-generator' do
describe 'collection' do describe 'collection' do
context 'without trailing s' do context 'without trailing s' do
it "should generate the collection files" do it "should generate the collection files" do
system %{bin/backbone-generator collection Section::Model} run "collection", "Section::Model"
should_generate_collection should_generate_collection
end end
@ -100,7 +219,7 @@ describe 'backbone-generator' do
context 'with trailing s' do context 'with trailing s' do
it "should generate the collection files" do it "should generate the collection files" do
system %{bin/backbone-generator collection Section::Models} run "collection", "Section::Models"
should_generate_collection should_generate_collection
end end
@ -109,7 +228,7 @@ describe 'backbone-generator' do
describe 'scaffold' do describe 'scaffold' do
it "should generate everything!" do it "should generate everything!" do
system %{bin/backbone-generator scaffold Section::Model} run "scaffold", "Section::Model"
should_generate_model should_generate_model
should_generate_view should_generate_view
@ -120,9 +239,29 @@ describe 'backbone-generator' do
describe 'spec helper' do describe 'spec helper' do
it "should generate a spec helper" do it "should generate a spec helper" do
system %{bin/backbone-generator spec-helper} run "spec-helper"
File.file?(collection = 'spec/javascripts/helpers/backbone_spec_helper.js').should be_true File.file?(collection = 'spec/javascripts/helpers/backbone_spec_helper.js').should be_true
end end
end end
describe 'app helper' do
it "should generate an app helper" do
run "app-helper"
File.file?(collection = 'public/javascripts/application/backbone_helper.js').should be_true
end
end
describe 'application scaffold' do
it "should generate an application scaffold" do
run "app-scaffold"
File.file?(app = 'public/javascripts/application/app_view.js').should be_true
File.file?(app_view = 'app/views/application/app_view.jst').should be_true
File.file?(controller = 'public/javascripts/application/controller.js').should be_true
File.file?(spec = 'spec/javascripts/application/app_view_spec.js').should be_true
end
end
end
end end

View File

@ -0,0 +1,19 @@
Backbone.Collection.prototype.ensureFetched = (callback) ->
if !@_alreadyEnsureFetched
_refresher = null
_refresher =>
this.unbind('refresh', _refresher)
callback.apply(this)
@_alreadyEnsureFetched = true
this.bind('refresh', _refresher)
this.fetch()
else
callback.apply(this)
Backbone.View.prototype.attributes = ->
attrs = {}
for field in @attributeFields
do (field) =>
attrs[field] = this.$("input[name='#{field}']").val()
attrs

View File

@ -0,0 +1,29 @@
/* Ensure a Collection is fetched and has entries before running a block of code. */
_.extend(Backbone.Collection.prototype, {
ensureFetched: function(callback) {
if (this._alreadyEnsureFetched) {
var _this = this;
var _refresher = function() {
_this.unbind('refresh', _refresher);
callback.apply(_this);
_this._alreadyEnsureFetched = true;
};
this.bind('refresh', _refresher);
this.fetch();
} else {
callback.apply(this);
}
}
});
_.extend(Backbone.View.prototype, {
attributes: function() {
var attrs = {};
var _this = this;
_.each(this.attributeFields, function(field) {
attrs[field] = _this.$('input[name="' + field + '"]').val();
});
return attrs;
}
});

View File

@ -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

16
templates/app_view.js.erb Normal file
View File

@ -0,0 +1,16 @@
var AppView = Backbone.View.extend({
el: '#application',
template: JST['application/app_view'],
initialize: function() {
_.bindAll(this, 'render');
var controller = new Controller({app: this});
Backbone.history.start();
},
render: function() {
$(this.el).html(this.template());
return this;
},
});

View File

@ -0,0 +1 @@
<!-- application view goes here -->

View File

@ -0,0 +1,9 @@
describe 'AppView', ->
appView = null
beforeEach, ->
appView = new AppView()
it 'should render', ->
expect($(appView.render().el)).toContain('.something')

View File

@ -0,0 +1,12 @@
describe('AppView', function() {
var app_view;
beforeEach(function() {
app_view = new AppView();
});
it('should render', function() {
expect($(app_view.render().el)).toContain('.something');
});
});

View File

@ -0,0 +1,4 @@
class window.<%= plural_object_name %> extends Backbone.Collection
url: '/<%= plural_underscore_name %>'
model: <%= object_name %>

View File

@ -0,0 +1,14 @@
describe '<%= plural_object_name %>', ->
collection = null
withServer()
it 'should fetch records from the API', ->
collection = new <%= plural_object_name %>()
@server.respondWith('GET', '/<%= plural_underscore_name %>', @validJSONResponse([{id: 1}]))
collection.fetch()
@server.respond()
expect(collection.length).toEqual(1)

View File

@ -0,0 +1,21 @@
class window.<%= plural_object_name %>View extends Backbone.View
events: {
'click button.new': 'addNew'
}
template: JST['<%= plural_underscore_name %>/list']
initialize: ->
@collection.bind('refresh', this.addAll)
render: =>
$(this.el).html(this.template())
this.addAll()
this
addOne: (model) =>
view = new <%= object_name %>View({model: model})
this.$('.list').append(view.render().el)
addAll: =>
@collection.each(this.addOne)
addNew: =>
object = new <%= object_name %>()
@collection.add(object)
this.addOne(object)

View File

@ -1,9 +1,11 @@
var <%= plural_object_name %>View = Backbone.View.extend({ var <%= plural_object_name %>View = Backbone.View.extend({
events: {
'click button.new': 'addNew'
},
template: JST['<%= plural_underscore_name %>/list'], template: JST['<%= plural_underscore_name %>/list'],
initialize: function(collection) { initialize: function() {
_.bindAll(this, 'render', 'addOne', 'addAll'); _.bindAll(this, 'render', 'addOne', 'addAll', 'addNew');
this.collection = collection;
this.collection.bind('refresh', this.addAll); this.collection.bind('refresh', this.addAll);
this.render(); this.render();
@ -19,5 +21,11 @@ var <%= plural_object_name %>View = Backbone.View.extend({
}, },
addAll: function() { addAll: function() {
this.collection.each(this.addOne); this.collection.each(this.addOne);
},
addNew: function() {
var object = new <%= object_name %>();
this.collection.add(object);
this.addOne(object);
} }
}); });

View File

@ -1 +1,3 @@
<div class="list"></div> <div class="list"></div>
<button class="new">Create</button>

View File

@ -0,0 +1,26 @@
describe '<%= plural_object_name %>View', ->
view = collection = null
beforeEach ->
collection = new <%= plural_object_name %>()
view = new <%= plural_object_name %>View({collection: collection})
view.render()
it 'should render', ->
expect($(view.el)).toContain('.list')
expect($(view.el)).toContain('button.new')
it 'should add a new model when new is clicked', ->
view.$('button.new').trigger('click')
expect(view.$('.list')).toContain('.<%= css_class_name %>')
expect(collection.length).toEqual(1)
it 'should render the models when re-rendered', ->
expect(view.$('.list')).not.toContain('.<%= css_class_name %>')
model = new <%= object_name %>({id: 1})
collection.add(model)
view.render()
expect(view.$('.list')).toContain('.<%= css_class_name %>')

View File

@ -6,9 +6,17 @@ describe('<%= plural_object_name %>View', function() {
}); });
it('should render', function() { it('should render', function() {
view = new <%= plural_object_name %>View(collection); view = new <%= plural_object_name %>View({collection: collection});
view.render(); view.render();
expect($(view.el)).toContain('.list'); expect($(view.el)).toContain('.list');
expect($(view.el)).toContain('button.new');
});
it('should add a new model when new is clicked', function() {
view.$('button.new').trigger('click');
expect(view.$('.list')).toContain('.<%= underscore_name %>');
expect(collection.length).toEqual(1);
}); });
}); });

View File

@ -0,0 +1,4 @@
class window.Controller extends Backbone.Controller
routes: {
'index': 'index'
}

View File

@ -0,0 +1,6 @@
var Controller = Backbone.Controller.extend({
routes: {
'index': 'index'
}
});

View File

@ -0,0 +1 @@
class window.<%= object_name %> extends Backbone.Model

View File

@ -0,0 +1,8 @@
describe '<%= object_name %>', ->
model = null
it 'should have some tests', ->
model = new <%= object_name %>()
expect(true).toEqual(false)

View File

@ -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) ]

25
templates/view.coffee.erb Normal file
View File

@ -0,0 +1,25 @@
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: '<%= css_class_name %>'
initialize: ->
_.bindAll(this, 'remove')
@model.bind('change', this.render)
@model.bind('remove', this.remove)
@model.view = this
render: =>
$(@el).html(this.template(@model.toJSON()))
this.$('button.save').text(if @model.isNew() then 'Create' else 'Update')
this.$('button.delete')[if @model.isNew() then 'hide' else 'show']();
this
save: =>
@model.save(this.attributes())
destroy: =>
if confirm("Are you sure?")
@model.destroy()

View File

@ -1,11 +1,31 @@
var <%= object_name %>View = Backbone.View.extend({ var <%= object_name %>View = Backbone.View.extend({
events: {
'click button.save': 'save',
'click button.delete': 'destroy'
},
attributeFields: [],
template: JST['<%= underscore_name %>s/view'], template: JST['<%= underscore_name %>s/view'],
className: '<%= underscore_name %>',
initialize: function() { initialize: function() {
_.bindAll(this, 'render'); _.bindAll(this, 'render', 'save', 'destroy', 'remove');
this.model.bind('change', this.render);
this.model.bind('remove', this.remove);
this.model.view = this;
}, },
render: function() { render: function() {
$(this.el).html(this.template()); $(this.el).html(this.template(this.model.toJSON()));
this.$('button.save').text(this.model.isNew() ? 'Create' : 'Update');
this.$('button.delete')[this.model.isNew() ? 'hide' : 'show']();
return this; return this;
},
save: function() {
this.model.save(this.attributes(), { success: function(model) { model.view.render(); } });
},
destroy: function() {
if (confirm("Are you sure?")) {
this.model.destroy();
}
} }
}); });

View File

@ -1 +1,2 @@
<!-- your <%= object_name %>View template goes here --> <!-- your <%= object_name %>View template fields go here -->
<button class="save" /><button class="delete">Delete</button>

View File

@ -0,0 +1,41 @@
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})
view.render()
it 'should render with an update button', ->
expect(view.$('button.save')).toHaveText('Update')
it 'should destroy the model', ->
spyOn(window, 'confirm').andReturn(true)
spyOn(model, 'destroy')
$('#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()

View File

@ -1,10 +1,50 @@
describe('<%= object_name %>View', function() { describe('<%= object_name %>View', function() {
var view; var view, model;
it('should render', function() { describe('new record', function() {
view = new <%= object_name %>View(); beforeEach(function() {
model = new <%= object_name %>();
});
it('should render with a create button', function() {
view = new <%= object_name %>View({model: model});
view.render(); view.render();
expect($(view.el)).toContain('.something'); expect(view.$('button.save')).toHaveText('Create');
});
});
describe('existing record', function() {
beforeEach(function() {
model = new <%= object_name %>({id: 1});
setFixtures('<div id="container" />');
view = new <%= object_name %>View({model: model});
});
it('should render with an update button', function() {
view.render();
expect(view.$('button.save')).toHaveText('Update');
});
it('should destroy the model', function() {
spyOn(window, 'confirm').andReturn(true);
spyOn(model, 'destroy');
$('#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', function() {
$('#container').append(view.render().el);
expect($('button.save')).toExist();
model.trigger('remove');
expect($('button.save')).not.toExist();
});
}); });
}); });