Developing Backbone - Js Applications 2
Developing Backbone - Js Applications 2
DOCTYPE html>
<html>
<head>
<title>QUnit Test</title>
<link rel="stylesheet" href="qunit.css">
<script src="qunit.js"></script>
<script src="app.js"></script>
<script src="tests.js"></script>
</head>
<body>
<h1 id="qunit-header">QUnit Test</h1>
<h2 id="qunit-banner"></h2>
<div id="qunit-testrunner-toolbar"></div>
<h2 id="qunit-userAgent"></h2>
<ol id="qunit-tests"></ol>
<div id="qunit-fixture"></div>
</body>
</html>
return this.each(function(i){
$(this).prepend( '<b>' + ( i + start ) + '</b> ' );
});
} else {
// Since no `start` value was provided, function as a
// getter, returning the appropriate value from the first
// selected element.
1
return Number( val );
}
};
/*
<ul>
<li>1. hello</li>
<li>2. world</li>
<li>3. i</li>
<li>4. am</li>
<li>5. foo</li>
</ul>
*/
return this.each(function(i){
$(this).prepend( '<b>' + ( i + start ) + '</b> ' );
});
} else {
// Since no `start` value was provided, function as a
// getter, returning the appropriate value from the first
// selected element.
/*
<ul>
<li>1. hello</li>
<li>2. world</li>
<li>3. i</li>
<li>4. am</li>
<li>5. foo</li>
</ul>
2
*/
<div id="qunit-fixture">
<ul>
<li>hello</li>
<li>world</li>
<li>i</li>
<li>am</li>
<li>foo</li>
</ul>
</div>
module('jQuery#enumerate');
3
var items = $('#qunit-fixture li').enumerate( 1 );
equal( items.eq(0).text(), '1. hello', 'first item should have index 1' );
equal( items.eq(1).text(), '2. world', 'second item should have index 2' );
equal( items.eq(2).text(), '3. i', 'third item should have index 3' );
equal( items.eq(3).text(), '4. am', 'fourth item should have index 4' );
equal( items.eq(4).text(), '5. foo', 'fifth item should have index 5' );
});
4
test( 'should inspect the jQuery.getJSON usage of jQuery.ajax', function () {
this.spy( jQuery, 'ajax' );
jQuery.getJSON( '/todos/completed' );
ok( jQuery.ajax.calledOnce );
equals( jQuery.ajax.getCall(0).args[0].url, '/todos/completed' );
equals( jQuery.ajax.getCall(0).args[0].dataType, 'json' );
});
// This passes
assertTrue( spy.calledWith('many') );
5
// This however, fails
assertTrue( spy.calledWithExactly( 'many' ) );
});
PubSub.subscribe( 'message', a );
PubSub.subscribe( 'event', b );
assertTrue( a.calledBefore(b) );
assertTrue( b.calledAfter(a) );
});
6
// Directly checking the arguments of the call
equals( spy.getCall(0).args[0], message );
});
this.todoStub.restore();
setup: function() {
this.model = new Backbone.Model({
id: 2,
title: 'Hello world'
});
this.todoStub.returns( this.model );
});
this.todoList.model = Todo;
7
module( 'Should function when instantiated with model literals', {
setup:function() {
this.todoStub.returns(this.model);
this.todos = new TodoList();
// add a model
this.todos.add({
id: 2,
title: 'Hello world'
});
},
teardown: function() {
this.todoStub.restore();
}
});
8
var spy = this.spy();
var mock = this.mock( myAPI );
mock.expects( 'clearTodo' ).once().throws();
mock.verify();
ok( spy.calledOnce );
});
var todo = new Todo( { text: 'Get oil change for car.' } );
equal( todo.get('text'), 'Get oil change for car.' );
});
test('Will call a custom initialize function on the model instance when created.',
function() {
expect( 1 );
var toot = new Todo({ text: 'Stop monkeys from throwing their own crap!' });
equal( toot.get('text'), 'Stop monkeys from throwing their own rainbows!' );
});
9
test('Fires a custom event when the state changes.', function() {
expect( 1 );
test('Can contain custom validation rules, and will trigger an invalid event on failed
validation.', function() {
expect( 3 );
todo.on('invalid', errorCallback);
// Change the model state in such a way that validation will fail
todo.set( { done: 'not a boolean' } );
});
module('Test Collection', {
setup: function() {
10
});
// done
test('returns an array of the todos that are done', function() {
expect( 1 );
this.todoTwo.done = true;
deepEqual(this.todos.done(), [this.todoTwo]);
});
// remaining
test('returns an array of the todos that are not done', function() {
expect( 1 );
this.todoTwo.done = true;
deepEqual(this.todos.remaining(), [this.todoOne]);
});
// clear
test('destroys the current todo from local storage', function() {
expect( 2 );
deepEqual(this.todos.models, [this.todoOne, this.todoTwo]);
this.todos.clear(this.todoOne);
deepEqual(this.todos.models, [this.todoTwo]);
});
11
this.emptyTodos = new TodoApp.Collections.TodoList;
equal(this.emptyTodos.order(), 0);
});
test('Should be tied to a DOM element when created, based off the property provided.',
function() {
expect( 1 );
equal( this.todoView.el.tagName.toLowerCase(), 'li' );
});
test('Can render, after which the DOM representation of the view will be visible.',
function() {
this.todoView.render();
12
// Append the DOM representation of the view to ul#todoList
$('ul#todoList').append(this.todoView.el);
$('#todoList').append( this.todoView.render().el );
setTimeout(function() {
viewElt = $('#todoList li input.check').filter(':first');
teardown: function() {
this.App.todos.reset();
13
$('#app').remove();
}
});
// Set the value of a brand new todo within the input box
$('#new-todo').val( 'Buy some milk' );
// cranium.js - Cranium.Events
14
// Counter
eventNumber: 0,
// cranium.js - Cranium.Model
15
// so that it can identify itself (e.g. on chage
// announcements)
var Model = Cranium.Model = function (attributes) {
this.id = _.uniqueId('model');
this.attributes = attributes || {};
};
16
// DOM View
var View = Cranium.View = function (options) {
// Mix in options object (e.g extending functionality)
_.extend(this, options);
this.id = _.uniqueId('view');
};
// cranium.js - Cranium.Controller
<!doctype html>
<html lang="en">
17
<head>
<meta charset="utf-8">
<title></title>
<meta name="description" content="">
</head>
<body>
<div id="todo">
</div>
<script type="text/template" class="todo-template">
<div>
<input id="todo_complete" type="checkbox" <%= completed %>>
<%= title %>
</div>
</script>
<script src="underscore-min.js"></script>
<script src="cranium.js"></script>
<script src="example.js"></script>
</body>
</html>
18
init: function (model) {
this.render( model.attributes );
events: {
"#todo.click" : "toggleComplete"
},
// Initialize everything
initialize: function () {
this.view.init(this.model);
return this;
},
// Toggles the value of the todo in the Model
toggleComplete: function () {
var completed = todoController.model.get('completed');
console.log("Todo old 'completed' value?", completed);
todoController.model.set({ completed: (!completed) ? 'checked': '' });
console.log("Todo new 'completed' value?", todoController.model.get('completed'));
return this;
}
});
19
todo1.set({ title: "Due to this change Model will notify View and it will re-render"})
// The TodoView listens for changes to its model, re-rendering. Since there's
// a one-to-one correspondence between a **Todo** and a **TodoView** in this
// app, we set a direct reference on the model for convenience.
initialize: function() {
this.listenTo( this.model, 'change', this.render );
this.listenTo( this.model, 'destroy', this.remove );
},
20
var myApplication = (function(){
function(){
// ...
},
return {
// ...
}
})();
/*
Does check for existence. If already defined, we use that instance.
Option 1: if(!myApplication) myApplication = {};
21
Option 2: var myApplication = myApplication || {};
We can then populate our object literal to support models, views and collections (or any
data, really):
*/
var myApplication = {
models : {},
views : {
pages : {}
},
collections : {}
};
var myConfig = {
language: 'english',
defaults: {
enableDelegation: true,
maxTodos: 40
},
theme: {
skin: 'a',
toolbars: {
index: 'ui-navigation-toolbar',
pages: 'ui-custom-toolbar'
}
}
}
YAHOO.util.Dom.getElementsByClassName('test');
22
var todoApp = todoApp || {};
// routers
todoApp.routers.Workspace = Backbone.Router.extend({});
todoApp.routers.TodoSearch = Backbone.Router.extend({});
// models
todoApp.model.Todo = Backbone.Model.extend({});
todoApp.model.Notes = Backbone.Model.extend({});
// special models
todoApp.model.special.Admin = Backbone.Model.extend({});
23
// the `$` variable.
Backbone.$ = root.jQuery || root.Zepto || root.ender || root.$;
var methodMap = {
'create': 'POST',
'update': 'PUT',
'patch': 'PATCH',
'delete': 'DELETE',
'read': 'GET'
};
24
// Make the request, allowing the user to override any Ajax options.
var xhr = options.xhr = Backbone.ajax(_.extend(params, options));
model.trigger('request', model, xhr, options);
return xhr;
25