All the todo list applications I've seen have the purpose of showing the "easy to use" a framework are. In this case I simply don't want to proof that a framework is better than other.
Since I teach TDD/BDD, Javascript and OO, I'd like to show to my students best practices to develop rich internet applications, and the todo list application is simple enough to show key concepts. So I think it's a good idea publishing a full sample project showing this concepts.
Of course I'm not perfect, the application can have errors or something could have been done in a better way. This is my second motivation, to learn. I expect to get some feedback to enhance this sample application ! I can lear too new ideas and techniches.
Finally I'd like to explore some frameworks and how to use them in an efective way.
A well designed architecture should give you the freedom of switching the framework used without impacting most of your code. In this project I'd tried to decouple most of the code from any framework.
The DOM Access Layer decouple the core of the application from the specifics of DOM manipulation. In this case I use "view models" to implement this layer. There is an implementation of these "view models" using knockout.js, and other using Zepto/jQuery. Switching from one framework to another is only matter of switching the "view model" library used. If in the future we wish to change the presentation framework we only need to implement a new "view model" library.
It's interesting comparing both implementations of the DOM Access Layer. Clearly knockout.js seems more powerful, the view layer is very simple to code. With Zepto/jQuery the view layer is more complex, but I don't need to modify the HTML and I can use the same document as provided by the web designer. Another advantage of Zepto/jQuery is that the final result has less footprint and less start up time, specially in the case of Zepto.
The Data Access Layer decouples the models from the specifics storage mechanism used. Currently there is only support for local storage. I plan to add more storage systems (AJAX, WebSockets...) only need to implement a new storage library. The rest of the code won't need to be changed.
The core of the application code is fully unit tested. Furthermore there exists end to end integration tests for most of the use cases scenarios of the application. I didn't use any fancy BDD framework, but just Jasmine and PhantomJS.
The tests are integrated in a build script and generate JUnit XML report files, so I hope it will be easy to integrate with a CI server in the future.
If you have never seen TDD in practice in a full rich internet application, I hope this project helps you to illustrate how to apply TDD in a web application based in javascript and HTML5.
To build this project follow these steps:
- If not on your system, install Node.js. It has already installed NPM.
- If you plan to run the BDD integration tests install [PhantomJS]
(http://phantomjs.org/download.html)
3 Uninstall old version of grunt
npm uninstall -g grunt
- Install grunt-cli:
npm install -g grunt-cli
- Download this project to your computer
- Install all the packages needed to build this application, it's easy,
simply run the command
npm install
in the root of the project - Execute the following command
npm test
from the root folder of this project.
This project is now integrated with travis CI. Have a look at the .travis.yml
file and the package.json
file at the root of the project
After building the project, simply open in your browser either
todo_with_knockout.html
or todo_with_zepto.html
or todo_with_jquery .html
. Do this from the dist/
directory.
The project is structured in the following directories:
package.json
The node information used by npm and Travis-CI when you want to build this project with them.travis.yml
The Travis-CI configuration file for this projectkarma.conf.js
The karma configuration file (for BDD test suite)Gruntfile.js
The grunt configuration filedist/
The output directorysrc/
The source code for the applicationcss/
Simple CSS for the applicationsimg/
Some images (the ajax loader)lib/
The source code for the runtimecommon/
The source code of the core of the application, decoupled from the DOM/Presentation framework used. The unit tests cover this files, except store.js.utils.js
Event & observable fields (whenever I do not have knockout)model.js
A Task & Tasks (task list) model. Decoupled of the specific persistence/storage mechanismcontroller.js
The high level application controllerwidgets.js
Reusable controllers/widgets. Decoupled from the specific presentation frameworkstore.js
A simple in memory storage.
knockout/
The view models implemented with Knockout.jszepto_jquery/
The view models implemented with Zepto/[jQuery](http://docs.jquery .com/Downloading_jQuery)
tests/
The source code for the testsbdd/
End to end tests of the application (BDD test suite)vendor/
Third party libs used for testing (jQuery, jQuery-simulate & jQuery-simulate.key-sequence)main.js
The entry point for the tddadding-tasks.js
The BDD test suite about creating new tasks in the applicationconsulting-tasks.js
The BDD test suite about consulting the existing tasks in the applicationdoing-tasks.js
The BDD test suite about marking tasks as done or undone.page-objects.js
A wrapper around the application's UI using jQuery, jQuery simulate and jQuery simulate key-sequece
unit/
Unit teststest-doubles.js
A test double (mocks/spies/stubs) library for the application*-tests.js
The unit test suites
There are a lot of things left to do !
- Use bower for client-side dependencies
- Use application cache manifest
- Edit the description of the task (click to edit)
- Task filters (view only done/todo)
- Task filters (matching description)
- A better web design (somebody help me with those damned CSS!)
- Responsive design
- An storage based in a remote REST service using AJAX
- An storage based in a remote service using WebSockets
- An robust storage able to switch to local storage when there is no connectivity and resync with the server when it is online again
- Explore other presentation frameworks (ember.js, jquerymobile...?)
If you are learning JavaScript and about building a rich web application, this is your project. Feel free to read the code, modify it and experiment! This is the main purpose of this project !