Dr Nic

newjs = newgem for JavaScript projects; free TDD suite

Want to start a new JavaScript project for a library or widget/badge for your website?

You know you should do TDD but wouldn’t know how to get started, what support libraries you need and where to get them from?

You need tools to deploy your library, your website etc?

You’d like a consistent structure to your project so that IDEs could provide support (toggle btw src/person.js and test/unit/person_test.html) [I haven’t done this bit yet, I’m sure I’ll add it to the JavaScipt Unit testing textmate bundle one day soon].

I couldn’t find anything helpful like this, so I created newjs – the JavaScript Project Generator.

Why?

But first, an brief history of everything…

I fell instantly in love with Rails for a couple reasons:

  • rails & script/generate commands – they teach you what files you need
    and where they should go
  • Ajax support – the marketing phrase “its as easy to use Ajax as not to” took me
    away from ASP.NET where the new Ajax.NET library was non-trivial to use; RJS
    didn’t exist at this stage, but Rails’ JavaScript support was still awesome
  • TextMate – though I didn’t get to use it for 18 mths til I bought a Mac

Later I fell in love with Ruby, for its meta-programming, syntactical possibilities
and free TDD support within Rails.

Then I fell out of love with JavaScript. Partly because Rails started generating JavaScript for me, and ultimately because I didn’t have test support. Whether you use Rails JavaScript helpers, or write your own unobtrusive JavaScript libraries you’re still living in an unhappy world without tests; let alone without TDD.

I still wrote JavaScript because it still needed writing. But a lot of my JavaScript
became “write-once, modify-never” affairs. Not just because I had no tests,
but each project had a different structure, different deployment processes, etc.

Finally, this year I figured out “TDD for JavaScript”. For every 1000 blog articles about Rails or Ruby, there is 0-1 article on unit testing JavaScript. Or perhaps I just don’t know how to use Google. Soon, the “JavaScript Unit Testing” PeepCode will be finished, so hopefully it will add to this lacking body of knowledge.

What I needed now was one-line starter-kit for new JavaScript projects that included:

  • A standard structure for JavaScript libraries/projects
  • In-built testing support, with rake tasks and script/generate unit_test
    generators
  • Tasks for deploying distribution files (via version numbers)
  • Tasks for managing the project website

I don’t think there is one already, thus my hand was forced: newjs.

Installation & Getting Started

Installation and maintenance of generated JavaScript projects requires the installation of Ruby and RubyGems.

The command-line application newjs is installed as below, for any operating system (except the ‘sudo’ part – use as necessary):

sudo gem install newjs

You’ll note it uses RubiGen because I like to cheat when it comes to generating things.

To kick-off your new project/library, run the command-line app newjs:

$ newjs mylib -a "Dr Nic" -e "drnicwilliams@gmail.com" -u "http://mylib.rubyforge.org"
      create  config
      create  lib
      create  src
      create  script
      create  tasks
      create  test/assets
      create  test/assets/unittest.css
      create  test/assets/unittest.js
      create  test/assets/prototype.js
      create  tasks/javascript_test_autotest_tasks.rake
      create  tasks/environment.rake
      create  tasks/deploy.rake
      create  config/javascript_test_autotest.yml.sample
      create  lib/protodoc.rb
      create  lib/jstest.rb
      create  Rakefile
      create  README.txt
      create  History.txt
      create  License.txt
      create  src/HEADER
      create  src/mylib.js
      create  script/rstakeout
      create  script/js_autotest
  dependency  install_rubigen_scripts
      exists    script
      create    script/generate
      create    script/destroy

And you thought you wanted to create all that by hand…

TDD for JavaScript

Personally, I can never remember what basic HTML + JavaScript goes in the test HTML files. I quite like the javascript_test plugin for Rails, which allows you to generate a test HTML stub. So I’ve included a version of it
here.

Two actually: one for unit tests and one for functional tests.

$ script/generate unit_test some_lib
  create  test/unit
  create  test/unit/some_lib_test.html

For functional tests, use functional_test generator. See the newjs site for more details.

Lifecycle of JavaScript files

You create JavaScript files in src/ and then when you run rake dist
they can compressed into dist/project_name.js.

To make this work, add new src/ files into src/project_name.js via
<%= include "file_name.js" %>.

This is the build mechanism used by prototypejs and I stole it. Actually, I stole nearly everything from the prototypejs source structure.

Other stuff

Like newgem you can create a simple website (via textile files):

script/generate install_website

BONUS: instead of the crap purple default theme for newgem, newjs websites have a nice yellow theme – see example.

Source for newjs

Get it via git: master branch

Credits

The generated structure, the unittest.js test suite, and its included help files mostly come from prototypejs and newgem.

The generator mechanism is from RubiGem which comes from the Rails Generator created by Jeremy “I made someone leave Rails for PHP” Kemper.

Actually, I stole nearly everything from the prototypejs source structure. They are much cleverer than I am.

Related posts:

  1. Using CoffeeScript in Rails and even on Heroku I’m pretty excited about CoffeeScript as a clean-syntax replacement for...
  2. newgem 1.0.0 all thanks to Cucumber The New Gem Generator (newgem) was exciting, moderately revolutionary, and...
  3. One-stop JavaScript Unit Testing for Rails 2.0 Previously, I mentioned a multi-step/multi-project solution to doing JavaScript Unit...
  4. Autotesting Javascript in Rails I used to love Javascript so much that it would...
  5. NewGem Generator – now with script/generate The New Gem Generator (0.13.0)’s newgem command now behaves like...

10 Responses to “newjs = newgem for JavaScript projects; free TDD suite”

  1. Phil says:

    I wonder if we couldn’t see a JSpec version of this at some point. (http://github.com/wycats/jspec/tree/master)

  2. Dr Nic says:

    @Phil [via] – initially I suggest forking newjs, adding in the alternate test suite and updating the generators + templates to use this suite. If people like it, then I could merge it in, provide newjs command-line options to select which one (like newgem has a -t option to chose rspec).

    I don’t mean to offload work, but I’m sure Yehuda Katz (wycats) is the right man to help with this – he’s worked with RubiGen before thru Merb.

  3. Dr Nic says:

    Also, I’m working on a version of unittest.js that has no dependencies on prototype.js. It will have the same API as prototypejs’s version (it uses prototypejs’ unit_tests.html as one of its functional tests), so the TM bundle will still work.

    Note: as far as I’m aware, for BDDers, JSpec (above) also has no dependencies on any other library.

  4. Dr Nic says:

    I’ve finished the rewrite of unittest – http://drnicjavascript.rubyforge.org/jsunittest/ Its a drop-in replacement for prototypejs’ unittest.js that has no dependencies on prototype.

    newjs 1.2.0 uses this now; so run ‘newjs .’ in your project to get this new asset. The generators are updated too.

  5. [...] newjs = newgem for JavaScript projects; free TDD suite – Dr. Nic adds some structure to quick and dirty JavaScript projects. [...]

  6. Sounds awesome, Nic. I can’t wait to start trying it out this weekend.

  7. ash says:

    i have used this to test my JavaScript files and it worked but when i run sphinx search engine and run “rake test:javascripts” it says –
    =============================
    rake aborted!
    Address already in use – bind(2)
    =============================
    i am trying to load the content through JavaScript. my rails version is 2.2

  8. Dr Nic says:

    @ash when you run “rake test:javascripts” it starts a webrick server on port 4711 or thereabouts. Perhaps sphinx is using that port too? Try changing the port number to something else. If it still has the bind(2) error, it might be that two webricks are running at the same time.

  9. My vote is on http://visionmedia.github.com/jspec/
    To initialize a project just run `jspec init myproject` with –template to switch usage of the Rack server, Rhino terminal usage, or default DOM reporting