Skip to content
This repository has been archived by the owner on Jul 12, 2020. It is now read-only.

Commit

Permalink
For 348: expands on Collection tests, fixes to models example, some o…
Browse files Browse the repository at this point in the history
…ther changes
  • Loading branch information
addyosmani committed Mar 23, 2013
1 parent 1c017d0 commit 94bb6a1
Show file tree
Hide file tree
Showing 6 changed files with 252 additions and 226 deletions.
Binary file modified backbone-fundamentals.epub
Binary file not shown.
120 changes: 63 additions & 57 deletions backbone-fundamentals.md
Original file line number Diff line number Diff line change
Expand Up @@ -9644,12 +9644,12 @@ and finally, here are our test cases:
module('jQuery#enumerate');

test( 'No arguments passed', 5, function() {
var items = $('#qunit-fixture li').enumerate();
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' );
var items = $('#qunit-fixture li').enumerate(); // 0
equal( items.eq(0).text(), '0. hello', 'first item should have index 0' );
equal( items.eq(1).text(), '1. world', 'second item should have index 1' );
equal( items.eq(2).text(), '2. i', 'third item should have index 2' );
equal( items.eq(3).text(), '3. am', 'fourth item should have index 3' );
equal( items.eq(4).text(), '4. foo', 'fifth item should have index 4' );
});

test( '0 passed as an argument', 5, function() {
Expand Down Expand Up @@ -9692,6 +9692,7 @@ test('An async test', function(){
topic: 'hello',
message: 'hi there!''
});
ok(true, 'Asynchronous test passed!');
start();
}
});
Expand Down Expand Up @@ -9972,18 +9973,17 @@ test('Can be created with default values for its attributes.', function() {
expect( 1 );

var todo = new Todo();

equal( todo.get('text'), '' );
equal( todo.get('done'), false );
equal( todo.get('order'), 0 );
});

test('Will set attributes on the model instance when created.', function() {
expect( 3 );

var todo = new Todo( { text: 'Get oil change for car.' } );

equal( todo.get('text'), 'Get oil change for car.' );
equal( todo.get('done'), false );
equal( todo.get('order'), 0 );

});

test('Will call a custom initialize function on the model instance when created.', function() {
Expand All @@ -10001,7 +10001,6 @@ test('Fires a custom event when the state changes.', function() {

todo.on( 'change', spy );
// How would you update a property on the todo here?
// Hint: http://documentcloud.github.com/backbone/#Model-set
todo.set( { text: 'new text' } );

ok( spy.calledOnce, 'A change event callback was correctly triggered' );
Expand Down Expand Up @@ -10030,57 +10029,69 @@ test('Can contain custom validation rules, and will trigger an invalid event on
For our collection we'll want to test that:
* New model instances can be added as both objects and arrays
* Changes to models result in any necessary custom events being fired
* A `url` property for defining the URL structure for models is correctly defined
* The Collection has a Todo Model
* Uses localStorage for syncing
* That done(), remaining() and clear() work as expected
* The order for Todos is numerically correct
```javascript
module( 'About Backbone.Collection');

test( 'Can add Model instances as objects and arrays.', function() {
expect( 3 );
describe('Test Collection', function() {

var todos = new TodoList();
equal( todos.length, 0 );

todos.add( { text: 'Clean the kitchen' } );
equal( todos.length, 1 );
beforeEach(function() {

todos.add([
{ text: 'Do the laundry', done: true },
{ text: 'Go to the gym' }
]);
// Define new todos
this.todoOne = new Todo;
this.todoTwo = new Todo({
title: "Buy some milk"
});

equal( todos.length, 3 );
});
// Create a new collection of todos for testing
return this.todos = new TodoList([this.todoOne, this.todoTwo]);
});

test( 'Can have a url property to define the basic url structure for all contained models.', function() {
expect( 1 );
var todos = new TodoList();
equal( todos.url, '/todos/' );
});
it('Has the Todo model', function() {
return expect(this.todos.model).toBe(Todo);
});

test('Fires custom named events when the models change.', function() {
expect(2);
it('Uses local storage', function() {
return expect(this.todos.localStorage).toEqual(new Store('todos-backbone'));
});

var todos = new TodoList();
var addModelCallback = this.spy();
var removeModelCallback = this.spy();
describe('done', function() {
return it('returns an array of the todos that are done', function() {
this.todoTwo.done = true;
return expect(this.todos.done()).toEqual([this.todoTwo]);
});
});

todos.on( 'add', addModelCallback );
todos.on( 'remove', removeModelCallback );
describe('remaining', function() {
return it('returns an array of the todos that are not done', function() {
this.todoTwo.done = true;
return expect(this.todos.remaining()).toEqual([this.todoOne]);
});
});

// How would you get the 'add' event to trigger?
todos.add( {text:'New todo'} );
describe('clear', function() {
return it('destroys the current todo from local storage', function() {
expect(this.todos.models).toEqual([this.todoOne, this.todoTwo]);
this.todos.clear(this.todoOne);
return expect(this.todos.models).toEqual([this.todoTwo]);
});
});

ok( addModelCallback.called );
return describe('Order sets the order on todos ascending numerically', function() {
it('defaults to one when there arent any items in the collection', function() {
this.emptyTodos = new TodoApp.Collections.TodoList;
return expect(this.emptyTodos.order()).toEqual(0);
});

// How would you get the 'remove' callback to trigger?
todos.remove( todos.last() );
return it('Increments the order by one each time', function() {
expect(this.todos.order(this.todoOne)).toEqual(1);
return expect(this.todos.order(this.todoTwo)).toEqual(2);
});
});

ok( removeModelCallback.called );
});
});
```
Expand Down Expand Up @@ -10123,10 +10134,8 @@ test('Can render, after which the DOM representation of the view will be visible
this.todoView.render();

// Hint: render() just builds the DOM representation of the view, but doesn't insert it into the DOM.
// How would you append it to the ul#todoList?
// How do you access the view's DOM representation?
//
// Hint: http://documentcloud.github.com/backbone/#View-el
// How would you append it to the ul#todoList?
// How do you access the view's DOM representation?

$('ul#todoList').append(this.todoView.el);
equal($('#todoList').find('li').length, 1);
Expand All @@ -10149,9 +10158,7 @@ asyncTest('Can wire up view methods to DOM elements.', function() {


// Hint: How would you trigger the view, via a DOM Event, to toggle the 'done' status.
// (See todos.js line 70, where the events hash is defined.)
//
// Hint: http://api.jquery.com/click
// (See todos.js line 70, where the events hash is defined.)

$('#todoList li input.check').click();
equal( this.todoView.model.get('done'), true );
Expand Down Expand Up @@ -10185,7 +10192,6 @@ test('Can extend JavaScript objects to support custom events.', function() {
var basicObject = {};

// How would you give basicObject these functions?
// Hint: http://documentcloud.github.com/backbone/#Events
_.extend( basicObject, Backbone.Events );

equal( typeof basicObject.on, 'function' );
Expand Down
119 changes: 63 additions & 56 deletions backbone-fundamentals.rtf
Original file line number Diff line number Diff line change
Expand Up @@ -7480,12 +7480,12 @@ here
{\pard \ql \f0 \sa180 \li0 \fi0 \f1 module('jQuery#enumerate');\line
\line
test( 'No arguments passed', 5, function() \{\line
var items = $('#qunit-fixture li').enumerate();\line
equal( items.eq(0).text(), '1. hello', 'first item should have index 1' );\line
equal( items.eq(1).text(), '2. world', 'second item should have index 2' );\line
equal( items.eq(2).text(), '3. i', 'third item should have index 3' );\line
equal( items.eq(3).text(), '4. am', 'fourth item should have index 4' );\line
equal( items.eq(4).text(), '5. foo', 'fifth item should have index 5' );\line
var items = $('#qunit-fixture li').enumerate(); // 0\line
equal( items.eq(0).text(), '0. hello', 'first item should have index 0' );\line
equal( items.eq(1).text(), '1. world', 'second item should have index 1' );\line
equal( items.eq(2).text(), '2. i', 'third item should have index 2' );\line
equal( items.eq(3).text(), '3. am', 'fourth item should have index 3' );\line
equal( items.eq(4).text(), '4. foo', 'fifth item should have index 4' );\line
\});\line
\line
test( '0 passed as an argument', 5, function() \{\line
Expand Down Expand Up @@ -7520,6 +7520,7 @@ test( '1 passed as an argument', 3, function() \{\line
topic: 'hello',\line
message: 'hi there!''\line
\});\line
ok(true, 'Asynchronous test passed!');\line
start();\line
\}\line
\});\line
Expand Down Expand Up @@ -7720,18 +7721,17 @@ test('Can be created with default values for its attributes.', function() \{\lin
expect( 1 );\line
\line
var todo = new Todo();\line
\line
equal( todo.get('text'), '' );\line
equal( todo.get('done'), false );\line
equal( todo.get('order'), 0 );\line
\});\line
\line
test('Will set attributes on the model instance when created.', function() \{\line
expect( 3 );\line
\line
var todo = new Todo( \{ text: 'Get oil change for car.' \} );\line
\line
equal( todo.get('text'), 'Get oil change for car.' );\line
equal( todo.get('done'), false );\line
equal( todo.get('order'), 0 );\line
\line
\});\line
\line
test('Will call a custom initialize function on the model instance when created.', function() \{\line
Expand All @@ -7749,7 +7749,6 @@ test('Fires a custom event when the state changes.', function() \{\line
\line
todo.on( 'change', spy );\line
// How would you update a property on the todo here?\line
// Hint: http://documentcloud.github.com/backbone/#Model-set\line
todo.set( \{ text: 'new text' \} );\line
\line
ok( spy.calledOnce, 'A change event callback was correctly triggered' );\line
Expand All @@ -7773,54 +7772,67 @@ test('Can contain custom validation rules, and will trigger an invalid event on
\});\par}
{\pard \ql \f0 \sa180 \li0 \fi0 \b \fs28 Collections\par}
{\pard \ql \f0 \sa180 \li0 \fi0 For our collection we\u8217'll want to test that:\par}
{\pard \ql \f0 \sa0 \li360 \fi-360 \bullet \tx360\tab New model instances can be added as both objects and arrays\par}
{\pard \ql \f0 \sa0 \li360 \fi-360 \bullet \tx360\tab Changes to models result in any necessary custom events being fired\par}
{\pard \ql \f0 \sa0 \li360 \fi-360 \bullet \tx360\tab A {\f1 url} property for defining the URL structure for models is correctly defined\sa180\par}
{\pard \ql \f0 \sa180 \li0 \fi0 \f1 module( 'About Backbone.Collection');\line
\line
test( 'Can add Model instances as objects and arrays.', function() \{\line
expect( 3 );\line
\line
var todos = new TodoList();\line
equal( todos.length, 0 );\line
{\pard \ql \f0 \sa0 \li360 \fi-360 \bullet \tx360\tab The Collection has a Todo Model\par}
{\pard \ql \f0 \sa0 \li360 \fi-360 \bullet \tx360\tab Uses localStorage for syncing\par}
{\pard \ql \f0 \sa0 \li360 \fi-360 \bullet \tx360\tab That done(), remaining() and clear() work as expected\par}
{\pard \ql \f0 \sa0 \li360 \fi-360 \bullet \tx360\tab The order for Todos is numerically correct\sa180\par}
{\pard \ql \f0 \sa180 \li0 \fi0 \f1 describe('Test Collection', function() \{\line
\line
todos.add( \{ text: 'Clean the kitchen' \} );\line
equal( todos.length, 1 );\line
beforeEach(function() \{\line
\line
todos.add([\line
\{ text: 'Do the laundry', done: true \},\line
\{ text: 'Go to the gym' \}\line
]);\line
// Define new todos\line
this.todoOne = new Todo;\line
this.todoTwo = new Todo(\{\line
title: "Buy some milk"\line
\});\line
\line
equal( todos.length, 3 );\line
\});\line
// Create a new collection of todos for testing\line
return this.todos = new TodoList([this.todoOne, this.todoTwo]);\line
\});\line
\line
test( 'Can have a url property to define the basic url structure for all contained models.', function() \{\line
expect( 1 );\line
var todos = new TodoList();\line
equal( todos.url, '/todos/' );\line
\});\line
it('Has the Todo model', function() \{\line
return expect(this.todos.model).toBe(Todo);\line
\});\line
\line
test('Fires custom named events when the models change.', function() \{\line
expect(2);\line
it('Uses local storage', function() \{\line
return expect(this.todos.localStorage).toEqual(new Store('todos-backbone'));\line
\});\line
\line
var todos = new TodoList();\line
var addModelCallback = this.spy();\line
var removeModelCallback = this.spy();\line
describe('done', function() \{\line
return it('returns an array of the todos that are done', function() \{\line
this.todoTwo.done = true;\line
return expect(this.todos.done()).toEqual([this.todoTwo]);\line
\});\line
\});\line
\line
todos.on( 'add', addModelCallback );\line
todos.on( 'remove', removeModelCallback );\line
describe('remaining', function() \{\line
return it('returns an array of the todos that are not done', function() \{\line
this.todoTwo.done = true;\line
return expect(this.todos.remaining()).toEqual([this.todoOne]);\line
\});\line
\});\line
\line
// How would you get the 'add' event to trigger?\line
todos.add( \{text:'New todo'\} );\line
describe('clear', function() \{\line
return it('destroys the current todo from local storage', function() \{\line
expect(this.todos.models).toEqual([this.todoOne, this.todoTwo]);\line
this.todos.clear(this.todoOne);\line
return expect(this.todos.models).toEqual([this.todoTwo]);\line
\});\line
\});\line
\line
ok( addModelCallback.called );\line
return describe('Order sets the order on todos ascending numerically', function() \{\line
it('defaults to one when there arent any items in the collection', function() \{\line
this.emptyTodos = new TodoApp.Collections.TodoList;\line
return expect(this.emptyTodos.order()).toEqual(0);\line
\});\line
\line
// How would you get the 'remove' callback to trigger?\line
todos.remove( todos.last() );\line
return it('Increments the order by one each time', function() \{\line
expect(this.todos.order(this.todoOne)).toEqual(1);\line
return expect(this.todos.order(this.todoTwo)).toEqual(2);\line
\});\line
\});\line
\line
ok( removeModelCallback.called );\line
\});\par}
\});\par}
{\pard \ql \f0 \sa180 \li0 \fi0 \b \fs28 Views\par}
{\pard \ql \f0 \sa180 \li0 \fi0 For our views we want to ensure:\par}
{\pard \ql \f0 \sa0 \li360 \fi-360 \bullet \tx360\tab They are being correctly tied to a DOM element when created\par}
Expand Down Expand Up @@ -7853,10 +7865,8 @@ test('Can render, after which the DOM representation of the view will be visible
this.todoView.render();\line
\line
// Hint: render() just builds the DOM representation of the view, but doesn't insert it into the DOM.\line
// How would you append it to the ul#todoList?\line
// How do you access the view's DOM representation?\line
//\line
// Hint: http://documentcloud.github.com/backbone/#View-el\line
// How would you append it to the ul#todoList?\line
// How do you access the view's DOM representation?\line
\line
$('ul#todoList').append(this.todoView.el);\line
equal($('#todoList').find('li').length, 1);\line
Expand All @@ -7879,9 +7889,7 @@ asyncTest('Can wire up view methods to DOM elements.', function() \{\line
\line
\line
// Hint: How would you trigger the view, via a DOM Event, to toggle the 'done' status.\line
// (See todos.js line 70, where the events hash is defined.)\line
//\line
// Hint: http://api.jquery.com/click\line
// (See todos.js line 70, where the events hash is defined.)\line
\line
$('#todoList li input.check').click();\line
equal( this.todoView.model.get('done'), true );\line
Expand All @@ -7908,7 +7916,6 @@ test('Can extend JavaScript objects to support custom events.', function() \{\li
var basicObject = \{\};\line
\line
// How would you give basicObject these functions?\line
// Hint: http://documentcloud.github.com/backbone/#Events\line
_.extend( basicObject, Backbone.Events );\line
\line
equal( typeof basicObject.on, 'function' );\line
Expand Down
Loading

1 comment on commit 94bb6a1

@addyosmani
Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Incorrectly labelled: this was for #348

Please sign in to comment.