diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..4b90444
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1 @@
+./node_modules
diff --git a/.gitmodules b/.gitmodules
index e69de29..8d4fef4 100644
--- a/.gitmodules
+++ b/.gitmodules
@@ -0,0 +1,3 @@
+[submodule "deps/jade-html5-boilerplate"]
+ path = deps/jade-html5-boilerplate
+ url = git://github.com/dmotz/jade-html5-boilerplate.git
diff --git a/deps/jade-html5-boilerplate b/deps/jade-html5-boilerplate
new file mode 160000
index 0000000..e0d69d4
--- /dev/null
+++ b/deps/jade-html5-boilerplate
@@ -0,0 +1 @@
+Subproject commit e0d69d474b61f2777b8edb0b91c4e44a31a8e31c
diff --git a/node_modules/.bin/express b/node_modules/.bin/express
new file mode 120000
index 0000000..b741d99
--- /dev/null
+++ b/node_modules/.bin/express
@@ -0,0 +1 @@
+../express/bin/express
\ No newline at end of file
diff --git a/node_modules/.bin/jade b/node_modules/.bin/jade
new file mode 120000
index 0000000..571fae7
--- /dev/null
+++ b/node_modules/.bin/jade
@@ -0,0 +1 @@
+../jade/bin/jade
\ No newline at end of file
diff --git a/node_modules/express/.npmignore b/node_modules/express/.npmignore
new file mode 100644
index 0000000..74bd365
--- /dev/null
+++ b/node_modules/express/.npmignore
@@ -0,0 +1,7 @@
+.git*
+docs/
+examples/
+support/
+test/
+testing.js
+.DS_Store
diff --git a/node_modules/express/History.md b/node_modules/express/History.md
new file mode 100644
index 0000000..1ba6588
--- /dev/null
+++ b/node_modules/express/History.md
@@ -0,0 +1,775 @@
+
+2.5.2 / 2011-12-10
+==================
+
+ * Fixed: express(1) LF -> CRLF for windows
+
+2.5.1 / 2011-11-17
+==================
+
+ * Changed: updated connect to 1.8.x
+ * Removed sass.js support from express(1)
+
+2.5.0 / 2011-10-24
+==================
+
+ * Added ./routes dir for generated app by default
+ * Added npm install reminder to express(1) app gen
+ * Added 0.5.x support
+ * Removed `make test-cov` since it wont work with node 0.5.x
+ * Fixed express(1) public dir for windows. Closes #866
+
+2.4.7 / 2011-10-05
+==================
+
+ * Added mkdirp to express(1). Closes #795
+ * Added simple _json-config_ example
+ * Added shorthand for the parsed request's pathname via `req.path`
+ * Changed connect dep to 1.7.x to fix npm issue...
+ * Fixed `res.redirect()` __HEAD__ support. [reported by xerox]
+ * Fixed `req.flash()`, only escape args
+ * Fixed absolute path checking on windows. Closes #829 [reported by andrewpmckenzie]
+
+2.4.6 / 2011-08-22
+==================
+
+ * Fixed multiple param callback regression. Closes #824 [reported by TroyGoode]
+
+2.4.5 / 2011-08-19
+==================
+
+ * Added support for routes to handle errors. Closes #809
+ * Added `app.routes.all()`. Closes #803
+ * Added "basepath" setting to work in conjunction with reverse proxies etc.
+ * Refactored `Route` to use a single array of callbacks
+ * Added support for multiple callbacks for `app.param()`. Closes #801
+Closes #805
+ * Changed: removed .call(self) for route callbacks
+ * Dependency: `qs >= 0.3.1`
+ * Fixed `res.redirect()` on windows due to `join()` usage. Closes #808
+
+2.4.4 / 2011-08-05
+==================
+
+ * Fixed `res.header()` intention of a set, even when `undefined`
+ * Fixed `*`, value no longer required
+ * Fixed `res.send(204)` support. Closes #771
+
+2.4.3 / 2011-07-14
+==================
+
+ * Added docs for `status` option special-case. Closes #739
+ * Fixed `options.filename`, exposing the view path to template engines
+
+2.4.2. / 2011-07-06
+==================
+
+ * Revert "removed jsonp stripping" for XSS
+
+2.4.1 / 2011-07-06
+==================
+
+ * Added `res.json()` JSONP support. Closes #737
+ * Added _extending-templates_ example. Closes #730
+ * Added "strict routing" setting for trailing slashes
+ * Added support for multiple envs in `app.configure()` calls. Closes #735
+ * Changed: `res.send()` using `res.json()`
+ * Changed: when cookie `path === null` don't default it
+ * Changed; default cookie path to "home" setting. Closes #731
+ * Removed _pids/logs_ creation from express(1)
+
+2.4.0 / 2011-06-28
+==================
+
+ * Added chainable `res.status(code)`
+ * Added `res.json()`, an explicit version of `res.send(obj)`
+ * Added simple web-service example
+
+2.3.12 / 2011-06-22
+==================
+
+ * \#express is now on freenode! come join!
+ * Added `req.get(field, param)`
+ * Added links to Japanese documentation, thanks @hideyukisaito!
+ * Added; the `express(1)` generated app outputs the env
+ * Added `content-negotiation` example
+ * Dependency: connect >= 1.5.1 < 2.0.0
+ * Fixed view layout bug. Closes #720
+ * Fixed; ignore body on 304. Closes #701
+
+2.3.11 / 2011-06-04
+==================
+
+ * Added `npm test`
+ * Removed generation of dummy test file from `express(1)`
+ * Fixed; `express(1)` adds express as a dep
+ * Fixed; prune on `prepublish`
+
+2.3.10 / 2011-05-27
+==================
+
+ * Added `req.route`, exposing the current route
+ * Added _package.json_ generation support to `express(1)`
+ * Fixed call to `app.param()` function for optional params. Closes #682
+
+2.3.9 / 2011-05-25
+==================
+
+ * Fixed bug-ish with `../' in `res.partial()` calls
+
+2.3.8 / 2011-05-24
+==================
+
+ * Fixed `app.options()`
+
+2.3.7 / 2011-05-23
+==================
+
+ * Added route `Collection`, ex: `app.get('/user/:id').remove();`
+ * Added support for `app.param(fn)` to define param logic
+ * Removed `app.param()` support for callback with return value
+ * Removed module.parent check from express(1) generated app. Closes #670
+ * Refactored router. Closes #639
+
+2.3.6 / 2011-05-20
+==================
+
+ * Changed; using devDependencies instead of git submodules
+ * Fixed redis session example
+ * Fixed markdown example
+ * Fixed view caching, should not be enabled in development
+
+2.3.5 / 2011-05-20
+==================
+
+ * Added export `.view` as alias for `.View`
+
+2.3.4 / 2011-05-08
+==================
+
+ * Added `./examples/say`
+ * Fixed `res.sendfile()` bug preventing the transfer of files with spaces
+
+2.3.3 / 2011-05-03
+==================
+
+ * Added "case sensitive routes" option.
+ * Changed; split methods supported per rfc [slaskis]
+ * Fixed route-specific middleware when using the same callback function several times
+
+2.3.2 / 2011-04-27
+==================
+
+ * Fixed view hints
+
+2.3.1 / 2011-04-26
+==================
+
+ * Added `app.match()` as `app.match.all()`
+ * Added `app.lookup()` as `app.lookup.all()`
+ * Added `app.remove()` for `app.remove.all()`
+ * Added `app.remove.VERB()`
+ * Fixed template caching collision issue. Closes #644
+ * Moved router over from connect and started refactor
+
+2.3.0 / 2011-04-25
+==================
+
+ * Added options support to `res.clearCookie()`
+ * Added `res.helpers()` as alias of `res.locals()`
+ * Added; json defaults to UTF-8 with `res.send()`. Closes #632. [Daniel * Dependency `connect >= 1.4.0`
+ * Changed; auto set Content-Type in res.attachement [Aaron Heckmann]
+ * Renamed "cache views" to "view cache". Closes #628
+ * Fixed caching of views when using several apps. Closes #637
+ * Fixed gotcha invoking `app.param()` callbacks once per route middleware.
+Closes #638
+ * Fixed partial lookup precedence. Closes #631
+Shaw]
+
+2.2.2 / 2011-04-12
+==================
+
+ * Added second callback support for `res.download()` connection errors
+ * Fixed `filename` option passing to template engine
+
+2.2.1 / 2011-04-04
+==================
+
+ * Added `layout(path)` helper to change the layout within a view. Closes #610
+ * Fixed `partial()` collection object support.
+ Previously only anything with `.length` would work.
+ When `.length` is present one must still be aware of holes,
+ however now `{ collection: {foo: 'bar'}}` is valid, exposes
+ `keyInCollection` and `keysInCollection`.
+
+ * Performance improved with better view caching
+ * Removed `request` and `response` locals
+ * Changed; errorHandler page title is now `Express` instead of `Connect`
+
+2.2.0 / 2011-03-30
+==================
+
+ * Added `app.lookup.VERB()`, ex `app.lookup.put('/user/:id')`. Closes #606
+ * Added `app.match.VERB()`, ex `app.match.put('/user/12')`. Closes #606
+ * Added `app.VERB(path)` as alias of `app.lookup.VERB()`.
+ * Dependency `connect >= 1.2.0`
+
+2.1.1 / 2011-03-29
+==================
+
+ * Added; expose `err.view` object when failing to locate a view
+ * Fixed `res.partial()` call `next(err)` when no callback is given [reported by aheckmann]
+ * Fixed; `res.send(undefined)` responds with 204 [aheckmann]
+
+2.1.0 / 2011-03-24
+==================
+
+ * Added ` Welcome to <%= title %> some html ' + http.STATUS_CODES[status] + '. Redirecting to ' + url + ' views: ' + sess.views + ' expires in: ' + (sess.cookie.maxAge / 1000) + 's Hello ' + escape((interp = name) == null ? '' : interp) + '\n Hello ' + escape((interp = name) == null ? '' : interp) + '\n wahoo! foo bar baz rawr..... #{something} foo asdf
+ asdf
+ asdfasdfaf
+ asdf
+ asd.
+ .<%= title %>
'
+ , '' + files.map(function(file){
+ var icon = ''
+ , classes = [];
+
+ if (useIcons && '..' != file) {
+ icon = icons[extname(file)] || icons.default;
+ icon = '';
+ classes.push('icon');
+ }
+
+ return '
';
+}
+
+/**
+ * Load and cache the given `icon`.
+ *
+ * @param {String} icon
+ * @return {String}
+ * @api private
+ */
+
+function load(icon) {
+ if (cache[icon]) return cache[icon];
+ return cache[icon] = fs.readFileSync(__dirname + '/../public/icons/' + icon, 'base64');
+}
+
+/**
+ * Filter "hidden" `files`, aka files
+ * beginning with a `.`.
+ *
+ * @param {Array} files
+ * @return {Array}
+ * @api private
+ */
+
+function removeHidden(files) {
+ return files.filter(function(file){
+ return '.' != file[0];
+ });
+}
+
+/**
+ * Icon map.
+ */
+
+var icons = {
+ '.js': 'page_white_code_red.png'
+ , '.c': 'page_white_c.png'
+ , '.h': 'page_white_h.png'
+ , '.cc': 'page_white_cplusplus.png'
+ , '.php': 'page_white_php.png'
+ , '.rb': 'page_white_ruby.png'
+ , '.cpp': 'page_white_cplusplus.png'
+ , '.swf': 'page_white_flash.png'
+ , '.pdf': 'page_white_acrobat.png'
+ , 'default': 'page_white.png'
+};
diff --git a/node_modules/express/node_modules/connect/lib/middleware/errorHandler.js b/node_modules/express/node_modules/connect/lib/middleware/errorHandler.js
new file mode 100644
index 0000000..f2fc44f
--- /dev/null
+++ b/node_modules/express/node_modules/connect/lib/middleware/errorHandler.js
@@ -0,0 +1,100 @@
+/*!
+ * Connect - errorHandler
+ * Copyright(c) 2010 Sencha Inc.
+ * Copyright(c) 2011 TJ Holowaychuk
+ * MIT Licensed
+ */
+
+/**
+ * Module dependencies.
+ */
+
+var utils = require('../utils')
+ , url = require('url')
+ , fs = require('fs');
+
+/**
+ * Flexible error handler, providing (_optional_) stack traces
+ * and error message responses for requests accepting text, html,
+ * or json.
+ *
+ * Options:
+ *
+ * - `showStack`, `stack` respond with both the error message and stack trace. Defaults to `false`
+ * - `showMessage`, `message`, respond with the exception message only. Defaults to `false`
+ * - `dumpExceptions`, `dump`, dump exceptions to stderr (without terminating the process). Defaults to `false`
+ *
+ * Text:
+ *
+ * By default, and when _text/plain_ is accepted a simple stack trace
+ * or error message will be returned.
+ *
+ * JSON:
+ *
+ * When _application/json_ is accepted, connect will respond with
+ * an object in the form of `{ "error": error }`.
+ *
+ * HTML:
+ *
+ * When accepted connect will output a nice html stack trace.
+ *
+ * @param {Object} options
+ * @return {Function}
+ * @api public
+ */
+
+exports = module.exports = function errorHandler(options){
+ options = options || {};
+
+ // defaults
+ var showStack = options.showStack || options.stack
+ , showMessage = options.showMessage || options.message
+ , dumpExceptions = options.dumpExceptions || options.dump
+ , formatUrl = options.formatUrl;
+
+ return function errorHandler(err, req, res, next){
+ res.statusCode = 500;
+ if (dumpExceptions) console.error(err.stack);
+ if (showStack) {
+ var accept = req.headers.accept || '';
+ // html
+ if (~accept.indexOf('html')) {
+ fs.readFile(__dirname + '/../public/style.css', 'utf8', function(e, style){
+ fs.readFile(__dirname + '/../public/error.html', 'utf8', function(e, html){
+ var stack = (err.stack || '')
+ .split('\n').slice(1)
+ .map(function(v){ return '{linked-path}
+ {files}
+ {title}
+ 500 {error}
+ {stack}
+
foo
+bar
+ +Jade also supports unbuffered comments, by simply adding a hyphen: + + //- will not output within markup + p foo + p bar + +outputting + +foo
+bar
+ +### Block Comments + + A block comment is legal as well: + + body + // + #content + h1 Example + +outputting + + + + + +Jade supports conditional-comments as well, for example: + + head + //if lt IE 8 + script(src='/ie-sucks.js') + +outputs: + + + + + + +### Nesting + + Jade supports nesting to define the tags in a natural way: + + ul + li.first + a(href='#') foo + li + a(href='#') bar + li.last + a(href='#') baz + +### Block Expansion + + Block expansion allows you to create terse single-line nested tags, + the following example is equivalent to the nesting example above. + + ul + li.first: a(href='#') foo + li: a(href='#') bar + li.last: a(href='#') baz + +### Case + + The case statement takes the following form: + + html + body + friends = 10 + case friends + when 0 + p you have no friends + when 1 + p you have a friend + default + p you have #{friends} friends + + Block expansion may also be used: + + friends = 5 + + html + body + case friends + when 0: p you have no friends + when 1: p you have a friend + default: p you have #{friends} friends + +### Attributes + +Jade currently supports '(' and ')' as attribute delimiters. + + a(href='/login', title='View login page') Login + +When a value is `undefined` or `null` the attribute is _not_ added, +so this is fine, it will not compile 'something="null"'. + + div(something=null) + +Boolean attributes are also supported: + + input(type="checkbox", checked) + +Boolean attributes with code will only output the attribute when `true`: + + input(type="checkbox", checked=someValue) + +Multiple lines work too: + + input(type='checkbox', + name='agreement', + checked) + +Multiple lines without the comma work fine: + + input(type='checkbox' + name='agreement' + checked) + +Funky whitespace? fine: + + + input( + type='checkbox' + name='agreement' + checked) + +Colons work: + + rss(xmlns:atom="atom") + +Suppose we have the `user` local `{ id: 12, name: 'tobi' }` +and we wish to create an anchor tag with `href` pointing to "/user/12" +we could use regular javascript concatenation: + + a(href='/user/' + user.id)= user.name + +or we could use jade's interpolation, which I added because everyone +using Ruby or CoffeeScript seems to think this is legal js..: + + a(href='/user/#{user.id}')= user.name + +The `class` attribute is special-cased when an array is given, +allowing you to pass an array such as `bodyClasses = ['user', 'authenticated']` directly: + + body(class=bodyClasses) + +### HTML + + Inline html is fine, we can use the pipe syntax to + write arbitrary text, in this case some html: + +``` +html + body + |foo bar baz
+``` + + Or we can use the trailing `.` to indicate to Jade that we + only want text in this block, allowing us to omit the pipes: + +``` +html + body. +foo bar baz
+``` + + Both of these examples yield the same result: + +``` +foo bar baz
+ +``` + + The same rule applies for anywhere you can have text + in jade, raw html is fine: + +``` +html + body + h1 User #{name} +``` + +### Doctypes + +To add a doctype simply use `!!!`, or `doctype` followed by an optional value: + + !!! + +Will output the _transitional_ doctype, however: + + !!! 5 + +or + + !!! html + +or + + doctype html + +doctypes are case-insensitive, so the following are equivalent: + + doctype Basic + doctype basic + +it's also possible to simply pass a doctype literal: + + doctype html PUBLIC "-//W3C//DTD XHTML Basic 1.1//EN + +yielding: + + ', + 'default': '', + 'transitional': '', + 'strict': '', + 'frameset': '', + '1.1': '', + 'basic': '', + 'mobile': '' + }; +``` + +To alter the default simply change: + +```javascript + jade.doctypes.default = 'whatever you want'; +``` + +## Filters + +Filters are prefixed with `:`, for example `:markdown` and +pass the following block of text to an arbitrary function for processing. View the _features_ +at the top of this document for available filters. + + body + :markdown + Woah! jade _and_ markdown, very **cool** + we can even link to [stuff](http://google.com) + +Renders: + +Woah! jade and markdown, very cool we can even link to stuff
+ +## Code + +Jade currently supports three classifications of executable code. The first +is prefixed by `-`, and is not buffered: + + - var foo = 'bar'; + +This can be used for conditionals, or iteration: + + - for (var key in obj) + p= obj[key] + +Due to Jade's buffering techniques the following is valid as well: + + - if (foo) + ul + li yay + li foo + li worked + - else + p oh no! didnt work + +Hell, even verbose iteration: + + - if (items.length) + ul + - items.forEach(function(item){ + li= item + - }) + +Anything you want! + +Next up we have _escaped_ buffered code, which is used to +buffer a return value, which is prefixed by `=`: + + - var foo = 'bar' + = foo + h1= foo + +Which outputs `barWelcome to my super lame site.
+ + + +``` + + As mentioned `include` can be used to include other content + such as html or css. By providing an extension Jade will not + assume that the file is Jade source and will include it as + a literal: + +``` +html + body + include content.html +``` + + Include directives may also accept a block, in which case the + the given block will be appended to the _last_ block defined + in the file. For example if `head.jade` contains: + +``` +head + script(src='/jquery.js') +``` + + We may append values by providing a block to `include head` + as shown below, adding the two scripts. + +``` +html + include head + script(src='/foo.js') + script(src='/bar.js') + body + h1 test +``` + + You may also `yield` within an included template, allowing you to explicitly mark where the block given to `include` will be placed. Suppose for example you wish to prepend scripts rather than append, you might do the following: + +``` +head + yield + script(src='/jquery.js') + script(src='/jquery.ui.js') +``` + + Since included Jade is parsed and literally merges the AST, lexically scoped variables function as if the included Jade was written right in the same file. This means `include` may be used as sort of partial, for example support we have `user.jade` which utilizes a `user` variable. + +``` +h1= user.name +p= user.occupation +``` + +We could then simply `include user` while iterating users, and since the `user` variable is already defined within the loop the included template will have access to it. + +``` +users = [{ name: 'Tobi', occupation: 'Ferret' }] + +each user in users + .user + include user +``` + +yielding: + +```html +Ferret
+'); + buf.push('Just an example'); + buf.push('
'); + } + return buf.join(""); + } catch (err) { + rethrow(err, __.input, __.filename, __.lineno); + } +} +``` + +When the `compileDebug` option _is_ explicitly `false`, this instrumentation +is stripped, which is very helpful for light-weight client-side templates. Combining Jade's options with the `./runtime.js` file in this repo allows you +to toString() compiled templates and avoid running the entire Jade library on +the client, increasing performance, and decreasing the amount of JavaScript +required. + +```js +function anonymous(locals) { + var attrs = jade.attrs, escape = jade.escape; + var buf = []; + with (locals || {}) { + var interp; + var title = 'yay' + buf.push(''); + buf.push('Just an example'); + buf.push('
'); + } + return buf.join(""); +} +``` + +## Example Makefile + + Below is an example Makefile used to compile _pages/*.jade_ + into _pages/*.html_ files by simply executing `make`. + +```make +JADE = $(shell find pages/*.jade) +HTML = $(JADE:.jade=.html) + +all: $(HTML) + +%.html: %.jade + jade < $< --path $< > $@ + +clean: + rm -f $(HTML) + +.PHONY: clean +``` + +this can be combined with the `watch(1)` command to produce +a watcher-like behaviour: + + $ watch make + +## jade(1) + +``` + +Usage: jade [options] [dir|file ...] + +Options: + + -h, --help output usage information + -v, --version output the version number + -o, --objExpressoInsanely fast TDD framework for node featuring code coverage reporting. | |
expresso | bin/expresso |
+!/usr/bin/env node+ |
+
+
+ |
+
+ Module dependencies. + + |
+
+
+ |
+
+ Expresso version. + + |
+
+
+ |
+
+ Failure count. + + |
+
+
+ |
+
+ Number of tests executed. + + |
+
+
+ |
+
+ Whitelist of tests to run. + + |
+
+
+ |
+
+ Boring output. + + |
+
+
+ |
+
+ Growl notifications. + + |
+
+
+ |
+
+ Server port. + + |
+
+
+ |
+
+ Watch mode. + + |
+
+
+ |
+
+ Execute serially. + + |
+
+
+ |
+
+ Default timeout. + + |
+
+
+ |
+
+ Usage documentation. + + |
+
+
+ |
+
+ Colorized sys.error(). + + + +
|
+
+
+ |
+
+ Colorize the given string using ansi-escape sequences. +Disabled when --boring is set. + + + +
|
+
+
+ |
+
+ Assert that
|
+
+
+ |
+
+ Assert that
|
+
+
+ |
+
+ Assert that
|
+
+
+ |
+
+ Assert that
|
+
+
+ |
+
+ Assert that
|
+
+
+ |
+
+ Assert that
|
+
+
+ |
+
+ Assert that Examples+ +assert.includes('foobar', 'bar'); + assert.includes(['foo', 'bar'], 'foo'); + + + +
|
+
+
+ |
+
+ Assert length of
|
+
+
+ |
+
+ Assert response from
|
+
+
+ |
+
+ Pad the given string to the maximum width provided. + + + +
|
+
+
+ |
+
+ Pad the given string to the maximum width provided. + + + +
|
+
+
+ |
+
+ Report test coverage. + + + +
|
+
+
+ |
+
+ Populate code coverage data. + + + +
|
+
+
+ |
+
+ Total coverage for the given file data. + + + +
|
+
+
+ |
+
+ Run the given test
|
+
+
+ |
+
+ Show the cursor when
|
+
+
+ |
+
+ Run the given test
|
+
+
+ |
+
+ Run tests for the given
|
+
+
+ |
+
+ Clear the module cache for the given
|
+
+
+ |
+
+ Watch the given
|
+
+
+ |
+
+ Report
|
+
+
+ |
+
+ Run the given tests, callback
|
+
+
+ |
+
+ Report exceptions. + + |
+
+
+ |
+
+ Growl notify the given
|
+
+
+ |
+
+ index
+
Expresso is a JavaScript TDD framework written for nodejs. Expresso is extremely fast, and is packed with features such as additional assertion methods, code coverage reporting, CI support, and more.
+ +assert.eql()
alias of assert.deepEqual()
assert.response()
http response utilityassert.includes()
assert.isNull()
assert.isUndefined()
assert.isNotNull()
assert.isDefined()
assert.match()
assert.length()
To install both expresso and node-jscoverage run +the command below, which will first compile node-jscoverage:
+ +$ make install
+
+
+To install expresso alone without coverage reporting run:
+ +$ make install-expresso
+
+
+Install via npm:
+ +$ npm install expresso
+
+
+To define tests we simply export several functions:
+ +exports['test String#length'] = function(){
+ assert.equal(6, 'foobar'.length);
+};
+
+
+Alternatively for large numbers of tests you may want to +export your own object containing the tests, however this +is essentially the as above:
+ +module.exports = {
+ 'test String#length': function(){
+ assert.equal(6, 'foobar'.length);
+ }
+};
+
+
+If you prefer not to use quoted keys:
+ +exports.testsStringLength = function(){
+ assert.equal(6, 'foobar'.length);
+};
+
+
+The argument passed to each callback is beforeExit, +which is typically used to assert that callbacks have been +invoked.
+ +exports.testAsync = function(beforeExit){
+ var n = 0;
+ setTimeout(function(){
+ ++n;
+ assert.ok(true);
+ }, 200);
+ setTimeout(function(){
+ ++n;
+ assert.ok(true);
+ }, 200);
+ beforeExit(function(){
+ assert.equal(2, n, 'Ensure both timeouts are called');
+ });
+};
+
+
+Asserts that the given val is null.
+ +assert.isNull(null);
+
+
+Asserts that the given val is not null.
+ +assert.isNotNull(undefined);
+assert.isNotNull(false);
+
+
+Asserts that the given val is undefined.
+ +assert.isUndefined(undefined);
+
+
+Asserts that the given val is not undefined.
+ +assert.isDefined(null);
+assert.isDefined(false);
+
+
+Asserts that the given str matches regexp.
+ +assert.match('foobar', /^foo(bar)?/);
+assert.match('foo', /^foo(bar)?/);
+
+
+Assert that the given val has a length of n.
+ +assert.length([1,2,3], 3);
+assert.length('foo', 3);
+
+
+Assert that the given obj is typeof type.
+ +assert.type(3, 'number');
+
+
+Assert that object b is equal to object a. This is an +alias for the core assert.deepEqual() method which does complex +comparisons, opposed to assert.equal() which uses ==.
+ +assert.eql('foo', 'foo');
+assert.eql([1,2], [1,2]);
+assert.eql({ foo: 'bar' }, { foo: 'bar' });
+
+
+Assert that obj is within val. This method supports Array_s +and Strings_s.
+ +assert.includes([1,2,3], 3);
+assert.includes('foobar', 'foo');
+assert.includes('foobar', 'bar');
+
+
+Performs assertions on the given server, which should not call +listen(), as this is handled internally by expresso and the server +is killed after all responses have completed. This method works with +any http.Server instance, so Connect and Express servers will work +as well.
+ +The req object may contain:
+ +The res object may be a callback function which +receives the response for assertions, or an object +which is then used to perform several assertions +on the response with the following properties:
+ +When providing res you may then also pass a callback function +as the fourth argument for additional assertions.
+ +Below are some examples:
+ +assert.response(server, {
+ url: '/', timeout: 500
+}, {
+ body: 'foobar'
+});
+
+assert.response(server, {
+ url: '/',
+ method: 'GET'
+},{
+ body: '{"name":"tj"}',
+ status: 200,
+ headers: {
+ 'Content-Type': 'application/json; charset=utf8',
+ 'X-Foo': 'bar'
+ }
+});
+
+assert.response(server, {
+ url: '/foo',
+ method: 'POST',
+ data: 'bar baz'
+},{
+ body: '/foo bar baz',
+ status: 200
+}, 'Test POST');
+
+assert.response(server, {
+ url: '/foo',
+ method: 'POST',
+ data: 'bar baz'
+},{
+ body: '/foo bar baz',
+ status: 200
+}, function(res){
+ // All done, do some more tests if needed
+});
+
+assert.response(server, {
+ url: '/'
+}, function(res){
+ assert.ok(res.body.indexOf('tj') >= 0, 'Test assert.response() callback');
+});
+
+
+To run a single test suite (file) run:
+ +$ expresso test/a.test.js
+
+
+To run several suites we may simply append another:
+ +$ expresso test/a.test.js test/b.test.js
+
+
+We can also pass a whitelist of tests to run within all suites:
+ +$ expresso --only "foo()" --only "bar()"
+
+
+Or several with one call:
+ +$ expresso --only "foo(), bar()"
+
+
+Globbing is of course possible as well:
+ +$ expresso test/*
+
+
+When expresso is called without any files, test/* is the default, +so the following is equivalent to the command above:
+ +$ expresso
+
+
+If you wish to unshift a path to require.paths
before
+running tests, you may use the -I
or --include
flag.
$ expresso --include lib test/*
+
+
+The previous example is typically what I would recommend, since expresso +supports test coverage via node-jscoverage (bundled with expresso), +so you will need to expose an instrumented version of you library.
+ +To instrument your library, simply run node-jscoverage, +passing the src and dest directories:
+ +$ node-jscoverage lib lib-cov
+
+
+Now we can run our tests again, using the lib-cov directory that has been +instrumented with coverage statements:
+ +$ expresso -I lib-cov test/*
+
+
+The output will look similar to below, depending on your test coverage of course :)
+ + + +To make this process easier expresso has the -c or --cov which essentially +does the same as the two commands above. The following two commands will +run the same tests, however one will auto-instrument, and unshift lib-cov, +and the other will run tests normally:
+ +$ expresso -I lib test/*
+$ expresso -I lib --cov test/*
+
+
+Currently coverage is bound to the lib directory, however in the
+future --cov
will most likely accept a path.
Sometimes it is useful to postpone running of tests until a callback or event has fired, currently the exports.foo = function(){}; syntax is supported for this:
+ +setTimeout(function(){
+ exports['test async exports'] = function(){
+ assert.ok('wahoo');
+ };
+}, 100);
+
+
+