Browse files

Switch to mocha testing framework.

  • Loading branch information...
1 parent 7c0e34a commit ecdea6c1c1ac05aa803c0d974c63393bea25ebe4 @miccolis miccolis committed Jul 23, 2012
View
2 README.md
@@ -17,6 +17,8 @@ and on the [concepts](https://github.com/developmentseed/bones/wiki/Plugin-Archi
To run the test suite, type `npm test`. **Note**: bones has to be in a folder named `node_modules` for tests to work correctly.
+Code coverages tests require [jscoverage](https://github.com/visionmedia/node-jscoverage). To generate a report run `npm run-script coverage`.
+
## License
Bones is [BSD licensed](https://github.com/developmentseed/bones/raw/master/LICENSE).
View
22 bones.js
@@ -3,22 +3,24 @@ if (global.__BonesPlugin__) {
process.exit(4);
}
+var path = require('path');
+
exports.$ = require('jquery');
exports._ = require('underscore');
exports.mirror = require('mirror');
-exports.utils = require('bones/server/utils');
-exports.middleware = require('bones/server/middleware');
+exports.utils = require(path.join(__dirname, 'server/utils'));
+exports.middleware = require(path.join(__dirname, 'server/middleware'));
exports.server = true;
-exports.Backbone = require('bones/server/backbone');
-exports.Router = require('bones/server/router');
-exports.Model = require('bones/server/model');
-exports.Collection = require('bones/server/collection');
-exports.View = require('bones/server/view');
-exports.Server = require('bones/server/server');
-exports.Command = require('bones/server/command');
+exports.Backbone = require(path.join(__dirname, 'server/backbone'));
+exports.Router = require(path.join(__dirname, 'server/router'));
+exports.Model = require(path.join(__dirname, 'server/model'));
+exports.Collection = require(path.join(__dirname, 'server/collection'));
+exports.View = require(path.join(__dirname, 'server/view'));
+exports.Server = require(path.join(__dirname, 'server/server'));
+exports.Command = require(path.join(__dirname, 'server/command'));
exports.load = function(dir) {
return exports.plugin.load(dir);
@@ -29,6 +31,6 @@ exports.start = function(callback) {
};
var Plugin = require('./server/plugin');
-global.__BonesPath__ = require.resolve('bones');
+global.__BonesPath__ = require.resolve(__dirname);
exports.plugin = global.__BonesPlugin__ = new Plugin();
exports.plugin.load(__dirname);
View
2 package.json
@@ -21,7 +21,7 @@
},
"scripts": {
- "test": "expresso -I ..",
+ "test": "mocha -R spec",
"coverage": "./test/coverage.sh"
},
"engines": {
View
2 server/plugin.js
@@ -4,7 +4,7 @@ var util = require('util');
var assert = require('assert');
var Module = require('module');
var _ = require('underscore');
-var Bones = require('bones');
+var Bones = require(path.join(__dirname, '../'));
var utils = Bones.utils;
View
13 servers/Route.bones
@@ -1,3 +1,4 @@
+var path = require('path');
var env = process.env.NODE_ENV || 'development';
var headers = { 'Content-Type': 'application/json' };
@@ -12,15 +13,15 @@ var options = {
// TODO: This should be moved to the initialize method!
server.prototype.assets = {
vendor: new mirror([
- require.resolve('bones/assets/jquery'),
+ require.resolve(path.join(__dirname, '../assets/jquery')),
require.resolve('underscore'),
require.resolve('backbone')
], { type: '.js' }),
core: new mirror([
- require.resolve('bones/shared/utils'),
- require.resolve('bones/client/utils'),
- require.resolve('bones/shared/backbone'),
- require.resolve('bones/client/backbone')
+ require.resolve(path.join(__dirname, '../shared/utils')),
+ require.resolve(path.join(__dirname, '../client/utils')),
+ require.resolve(path.join(__dirname, '../shared/backbone')),
+ require.resolve(path.join(__dirname, '../client/backbone'))
], { type: '.js' }),
models: new mirror([], options),
views: new mirror([], options),
@@ -29,7 +30,7 @@ server.prototype.assets = {
};
if (env === 'development') {
- server.prototype.assets.core.unshift(require.resolve('bones/assets/debug'));
+ server.prototype.assets.core.unshift(require.resolve(path.join(__dirname, '../assets/debug')));
}
// TODO: This should be moved to the initialize method!
View
118 test/assets.test.js
@@ -1,57 +1,87 @@
process.env.NODE_ENV = 'test';
var assert = require('assert');
var fs = require('fs');
+var path = require('path');
var server = require('./fixture/start').servers.Core;
-exports['assets'] = function(beforeExit) {
+function checkAsset(res, fixture) {
+ var contents = fs.readFileSync(require.resolve(path.join(
+ __dirname, '..', fixture)));
+ assert.ok(res.body.indexOf(contents) >= 0, 'Missing '+fixture);
+}
+
+function excludesAsset(res, fixture) {
+ var contents = fs.readFileSync(require.resolve(path.join(
+ __dirname, '..', fixture)));
+ assert.ok(res.body.indexOf(contents) === -1, 'Includes '+fixture);
+}
+
+function checkTemplate(res, fixture) {
+ var contents = require(path.join( __dirname, '..', fixture)).toString();
+ assert.ok(res.body.indexOf(contents) >= 0, 'Missing '+fixture);
+}
+
+function excludesTemplate(res, fixture) {
+ var contents = require(path.join( __dirname, '..', fixture)).toString();
+ assert.ok(res.body.indexOf(contents) === -1, 'Includes '+fixture);
+}
+
+describe('assets', function() {
+
+it('should return 404', function(done) {
assert.response(server, {
url: '/assets/fixture/does-not-exist',
method: 'GET'
}, {
body: 'Not Found',
status: 404
- });
+ }, done);
+});
+it('should return 200', function(done) {
assert.response(server, {
url: '/assets/fixture/foo',
method: 'GET'
}, {
body: 'lorem ipsum',
status: 200
- });
-};
+ }, done);
+});
-exports['/assets/bones/core.js'] = function() {
+
+it('/assets/bones/core.js', function(done) {
assert.response(server, {
url: '/assets/bones/core.js',
method: 'GET'
- }, { status: 200 }, function(res) {
- assert.ok(res.body.indexOf(fs.readFileSync(require.resolve('bones/client/backbone.js'))) >= 0);
- assert.ok(res.body.indexOf(fs.readFileSync(require.resolve('bones/client/utils.js'))) >= 0);
- assert.ok(res.body.indexOf(fs.readFileSync(require.resolve('bones/shared/backbone.js'))) >= 0);
- assert.ok(res.body.indexOf(fs.readFileSync(require.resolve('bones/shared/utils.js'))) >= 0);
+ }, { status: 200 }, function(err, res) {
+ checkAsset(res, 'client/backbone.js');
+ checkAsset(res, 'client/utils.js');
+ checkAsset(res, 'shared/backbone.js');
+ checkAsset(res, 'client/utils.js');
+ done()
});
-};
+});
-exports['/assets/bones/core.js'] = function() {
+it('/assets/bones/core.js', function(done) {
assert.response(server, {
url: '/assets/bones/vendor.js',
method: 'GET'
- }, { status: 200 }, function(res) {
- assert.ok(res.body.indexOf(fs.readFileSync(require.resolve('bones/assets/jquery.js'))) >= 0);
+ }, { status: 200 }, function(err, res) {
+ checkAsset(res, 'assets/jquery.js');
assert.ok(res.body.indexOf(fs.readFileSync(require.resolve('backbone'))) >= 0);
assert.ok(res.body.indexOf(fs.readFileSync(require.resolve('underscore'))) >= 0);
+ done();
});
-};
+});
-exports['/assets/bones/routers.js'] = function() {
+it('/assets/bones/routers.js', function(done) {
assert.response(server, {
url: '/assets/bones/routers.js',
method: 'GET'
- }, { status: 200 }, function(res) {
- assert.ok(res.body.indexOf(fs.readFileSync(require.resolve('bones/test/fixture/node_modules/submodule/routers/Foo'))) >= 0);
- assert.ok(res.body.indexOf(fs.readFileSync(require.resolve('bones/test/fixture/routers/Page'))) >= 0);
+ }, { status: 200 }, function(err, res) {
+ checkAsset(res, 'test/fixture/node_modules/submodule/routers/Foo');
+ checkAsset(res, 'test/fixture/routers/Page');
// Correct order.
assert.ok(res.body.indexOf('// ---- start test/fixture/node_modules/submodule/routers/Foo.bones ----') >= 0);
@@ -61,22 +91,23 @@ exports['/assets/bones/routers.js'] = function() {
assert.ok(res.body.indexOf('// ---- end test/fixture/node_modules/submodule/routers/Foo.bones ----') >= 0);
assert.ok(res.body.indexOf('// ---- end test/fixture/node_modules/submodule/routers/Foo.bones ----') <
res.body.indexOf('// ---- start test/fixture/routers/Page.bones ----'));
+ done();
});
-};
+});
-exports['/assets/bones/models.js'] = function() {
+it('/assets/bones/models.js', function(done) {
assert.response(server, {
url: '/assets/bones/models.js',
method: 'GET'
- }, { status: 200 }, function(res) {
- assert.ok(res.body.indexOf(fs.readFileSync(require.resolve('bones/test/fixture/models/Failure'))) >= 0);
- assert.ok(res.body.indexOf(fs.readFileSync(require.resolve('bones/test/fixture/models/Failures'))) >= 0);
- assert.ok(res.body.indexOf(fs.readFileSync(require.resolve('bones/test/fixture/models/House'))) >= 0);
- assert.ok(res.body.indexOf(fs.readFileSync(require.resolve('bones/test/fixture/models/Houses'))) >= 0);
- assert.ok(res.body.indexOf(fs.readFileSync(require.resolve('bones/test/fixture/models/Page'))) >= 0);
+ }, { status: 200 }, function(err, res) {
+ checkAsset(res, 'test/fixture/models/Failure');
+ checkAsset(res, 'test/fixture/models/Failures');
+ checkAsset(res, 'test/fixture/models/House');
+ checkAsset(res, 'test/fixture/models/Houses');
+ checkAsset(res, 'test/fixture/models/Page');
// Doesn't include server files.
- assert.ok(res.body.indexOf(fs.readFileSync(require.resolve('bones/test/fixture/models/Page.server'))) < 0);
+ excludesAsset(res, 'test/fixture/models/Page.server');
// Correct order.
assert.ok(res.body.indexOf('// ---- start test/fixture/models/Failure.bones ----') >= 0);
@@ -88,42 +119,47 @@ exports['/assets/bones/models.js'] = function() {
res.body.indexOf('// ---- start test/fixture/models/Houses.bones ----'));
assert.ok(res.body.indexOf('// ---- start test/fixture/models/Houses.bones ----') <
res.body.indexOf('// ---- start test/fixture/models/Page.bones ----'));
+ done();
});
-};
+});
-exports['/assets/bones/views.js'] = function() {
+it('/assets/bones/views.js', function(done) {
assert.response(server, {
url: '/assets/bones/views.js',
method: 'GET'
- }, { status: 200 }, function(res) {
- assert.ok(res.body.indexOf(fs.readFileSync(require.resolve('bones/test/fixture/views/Error'))) >= 0);
- assert.ok(res.body.indexOf(fs.readFileSync(require.resolve('bones/test/fixture/views/App'))) >= 0);
+ }, { status: 200 }, function(err, res) {
+ checkAsset(res, 'test/fixture/views/Error');
+ checkAsset(res, 'test/fixture/views/App');
// Doesn't include server files.
- assert.ok(res.body.indexOf(fs.readFileSync(require.resolve('bones/test/fixture/views/App.server'))) < 0);
+ excludesAsset(res, 'test/fixture/views/App.server');
// Correct order.
assert.ok(res.body.indexOf('// ---- start test/fixture/views/Error.bones ----') >= 0);
assert.ok(res.body.indexOf('// ---- start test/fixture/views/Error.bones ----') <
res.body.indexOf('// ---- start test/fixture/views/App.bones ----'));
+ done();
});
-};
+});
-exports['/assets/bones/templates.js'] = function() {
+it('/assets/bones/templates.js', function(done) {
assert.response(server, {
url: '/assets/bones/templates.js',
method: 'GET'
- }, { status: 200 }, function(res) {
- assert.ok(res.body.indexOf(require('bones/test/fixture/templates/Error._').toString()) >= 0);
- assert.ok(res.body.indexOf(require('bones/test/fixture/node_modules/othermodule/templates/Other._').toString()) >= 0);
+ }, { status: 200 }, function(err, res) {
+ checkTemplate(res, 'test/fixture/templates/Error._');
+ checkTemplate(res, 'test/fixture/node_modules/othermodule/templates/Other._');
// Doesn't include server files.
- assert.ok(res.body.indexOf(require('bones/test/fixture/templates/ServerSide.server._').toString()) < 0);
+ excludesTemplate(res, 'test/fixture/templates/ServerSide.server._');
// Correct order.
assert.ok(res.body.indexOf('// ---- start test/fixture/templates/Error._ ----') >= 0);
assert.ok(res.body.indexOf('// ---- start test/fixture/templates/Error._ ----') >
res.body.indexOf('// ---- start test/fixture/node_modules/othermodule/templates/Other._ ----'));
+ done();
});
-};
+});
+
+});
View
96 test/cli-coverage.test.js
@@ -1,6 +1,7 @@
var assert = require('assert');
var os = require('os');
var exec = require('child_process').exec;
+var path = require('path');
var hostnameDescription = 'Hostnames allowed for requests. Wildcards are allowed. (Default: ["127.0.0.1","localhost","' + os.hostname() + '","other","*.third"])';
@@ -9,32 +10,28 @@ function makePlain(json) {
return JSON.parse(JSON.stringify(json));
}
+var bones = require(path.join(__dirname, '../'));
+
require('./fixture');
-exports['test --help'] = function(beforeExit) {
- var completed = false;
+describe('cli code coverage', function() {
+it('test --help', function(done) {
require('optimist').argv = { _: [], '$0': 'node ./test/fixture', help: true };
- require('bones').start(function(output) {
- completed = true;
-
+ bones.start(function(output) {
assert.deepEqual(output, [
[ 'Usage: %s for a list of options.', '\u001b[0;32mnode ./test/fixture [command] --help\u001b[0m' ],
[ 'Available commands are:' ],
[ ' start: start application' ],
[ ' foo: demo command' ]
]);
+ done();
});
+});
- beforeExit(function() { assert.ok(completed); });
-};
-
-exports['test start --help'] = function(beforeExit) {
- var completed = false;
-
+it('test start --help', function(done) {
require('optimist').argv = { _: ['start'], '$0': 'node ./test/fixture', help: true };
- require('bones').start(function(output) {
- completed = true;
+ bones.start(function(output) {
assert.deepEqual(output, [
[ 'Usage: %s', '\u001b[0;32mnode ./test/fixture <command> [options...]\u001b[0m' ],
[ 'Commands: start application' ],
@@ -44,18 +41,14 @@ exports['test start --help'] = function(beforeExit) {
[ ' --adminParty Celebrate with administrators! (Default: false)' ],
[ ' --config=[path] Path to JSON configuration file.' ]
]);
+ done();
});
+});
- beforeExit(function() { assert.ok(completed); });
-};
-
-
-exports['test foo --help'] = function(beforeExit) {
- var completed = false;
+it('test foo --help', function(done) {
require('optimist').argv = { _: ['foo'], '$0': 'node ./test/fixture', help: true };
- require('bones').start(function(output) {
- completed = true;
+ bones.start(function(output) {
assert.deepEqual(output, [
[ 'Usage: %s', '\u001b[0;32mnode ./test/fixture <command> [options...]\u001b[0m' ],
[ 'Commands: demo command' ],
@@ -67,79 +60,64 @@ exports['test foo --help'] = function(beforeExit) {
[ ' --adminParty Celebrate with administrators! (Default: false)' ],
[ ' --config=[path] Path to JSON configuration file.' ]
]);
+ done();
});
-
- beforeExit(function() { assert.ok(completed); });
-};
+});
-exports['test foo'] = function(beforeExit) {
- var completed = false;
-
+it('test foo', function(done) {
require('optimist').argv = { _: ['foo'], '$0': 'node ./test/fixture' };
- require('bones').start(function(output) {
- completed = true;
+ bones.start(function(output) {
assert.equal(output, 'successfully started!');
+ done();
});
-
- beforeExit(function() { assert.ok(completed); });
-};
+});
-exports['test foo --config=test/fixture/config.json'] = function(beforeExit) {
- var completed = false;
-
+it('test foo --config=test/fixture/config.json', function(done) {
require('optimist').argv = { _: ['foo'], '$0': 'node ./test/fixture', config: 'test/fixture/config.json' };
- require('bones').start(function(output) {
- completed = true;
- assert.deepEqual(makePlain(require('bones').plugin.config), {
+ bones.start(function(output) {
+ assert.deepEqual(makePlain(bones.plugin.config), {
lorem: 'ipsum',
dolor: __dirname + '/fixture/commands',
host: [ '127.0.0.1', 'localhost', os.hostname(), 'other', '*.third' ],
adminParty: true,
unknownOption: 42
});
assert.equal(output, 'successfully started!');
+ done();
});
-
- beforeExit(function() { assert.ok(completed); });
-};
+});
-exports['test foo --dolor=pain'] = function(beforeExit) {
- var completed = false;
-
+it('test foo --dolor=pain', function(done) {
require('optimist').argv = { _: ['foo'], '$0': 'node ./test/fixture', dolor: 'pain' };
- require('bones').plugin.config = {};
- require('bones').start(function(output) {
- completed = true;
- assert.deepEqual(makePlain(require('bones').plugin.config), {
+ bones.plugin.config = {};
+ bones.start(function(output) {
+ assert.deepEqual(makePlain(bones.plugin.config), {
lorem: 'ipsum',
dolor: 'pain',
host: [ '127.0.0.1', 'localhost', os.hostname(), 'other', '*.third' ],
adminParty: false
});
assert.equal(output, 'successfully started!');
+ done();
});
+});
- beforeExit(function() { assert.ok(completed); });
-};
-
-exports['test foo --config=test/fixture/config.json --show-config'] = function(beforeExit) {
- var completed = false;
-
+it('test foo --config=test/fixture/config.json --show-config', function(done) {
require('optimist').argv = { _: ['foo'], '$0': 'node ./test/fixture', config: 'test/fixture/config.json', 'show-config': true };
- require('bones').start(function(output) {
- completed = true;
+ bones.start(function(output) {
assert.equal(output, undefined);
- assert.deepEqual(makePlain(require('bones').plugin.config), {
+ assert.deepEqual(makePlain(bones.plugin.config), {
lorem: 'ipsum',
dolor: 'pain',
host: [ '127.0.0.1', 'localhost', os.hostname(), 'other', '*.third' ],
adminParty: true,
unknownOption: 42
});
+ done();
});
+});
- beforeExit(function() { assert.ok(completed); });
-};
+});
View
33 test/cli.test.js
@@ -4,7 +4,9 @@ var exec = require('child_process').exec;
var hostnameDescription = 'Hostnames allowed for requests. Wildcards are allowed. (Default: ["127.0.0.1","localhost","' + os.hostname() + '","other","*.third"])';
-exports['test --help'] = function() {
+describe('cli tests', function() {
+
+it('test --help', function(done) {
exec('node test/fixture --help', function(err, stdout, stderr) {
assert.equal(err.code, 1);
assert.equal(stderr,
@@ -13,10 +15,11 @@ exports['test --help'] = function() {
' start: start application\n' +
' foo: demo command\n');
assert.equal(stdout, '');
+ done();
});
-};
+});
-exports['test start --help'] = function() {
+it('test start --help', function(done) {
exec('node test/fixture start --help', function(err, stdout, stderr) {
assert.equal(err.code, 1);
assert.equal(stderr,
@@ -29,10 +32,11 @@ exports['test start --help'] = function() {
' --adminParty Celebrate with administrators! (Default: false)\n' +
' --config=[path] Path to JSON configuration file.\n');
assert.equal(stdout, '');
+ done();
});
-};
+});
-exports['test foo --help'] = function() {
+it('test foo --help', function(done) {
exec('node test/fixture foo --help', function(err, stdout, stderr) {
assert.equal(err.code, 1);
assert.equal(stderr,
@@ -47,10 +51,11 @@ exports['test foo --help'] = function() {
' --adminParty Celebrate with administrators! (Default: false)\n' +
' --config=[path] Path to JSON configuration file.\n');
assert.equal(stdout, '');
+ done();
});
-};
+});
-exports['test foo --config=test/fixture/config.json'] = function() {
+it('test foo --config=test/fixture/config.json', function(done) {
exec('node test/fixture foo --config=test/fixture/config.json', function(err, stdout, stderr) {
assert.ok(!err);
assert.deepEqual(JSON.parse(stdout), {
@@ -61,10 +66,11 @@ exports['test foo --config=test/fixture/config.json'] = function() {
host: [ '127.0.0.1', 'localhost', os.hostname(), 'other', '*.third' ]
});
assert.equal(stderr, 'Note: Unknown option "unknownOption" in config file.\n');
+ done();
});
-};
+});
-exports['test foo --dolor=pain'] = function() {
+it('test foo --dolor=pain', function(done) {
exec('node test/fixture foo --dolor=pain', function(err, stdout, stderr) {
assert.ok(!err);
assert.deepEqual(JSON.parse(stdout), {
@@ -74,11 +80,12 @@ exports['test foo --dolor=pain'] = function() {
host: [ '127.0.0.1', 'localhost', os.hostname(), 'other', '*.third' ]
});
assert.equal(stderr, '');
+ done();
});
-};
+});
-exports['test foo --config=test/fixture/config.json --show-config'] = function() {
+it('test foo --config=test/fixture/config.json --show-config', function(done) {
exec('node test/fixture foo --config=test/fixture/config.json --show-config', function(err, stdout, stderr) {
assert.ok(!err);
assert.equal(stdout, '');
@@ -98,5 +105,7 @@ exports['test foo --config=test/fixture/config.json --show-config'] = function()
' "*.third"\n' +
' ]\n' +
'}\n');
+ done();
});
-};
+});
+});
View
26 test/collections.test.js
@@ -3,46 +3,58 @@ var assert = require('assert');
var server = require('./fixture/start').servers.Core;
-exports['api endpoints'] = function() {
+describe('api endpoints', function() {
+
+it('should load collection', function(done) {
assert.response(server, {
url: '/api/House',
method: 'GET'
}, {
body: '[{"foo":"bar"},{"foo":"baz"},{"foo":"blah"}]',
status: 200
- });
+ }, done);
+});
+it('should return 500', function(done) {
assert.response(server, {
url: '/api/Failure',
method: 'GET'
}, {
body: 'Internal Server Error',
status: 500
- });
+ }, done);
+});
+it('should return 500', function(done) {
assert.response(server, {
url: '/api/Failure',
method: 'GET',
headers: { accept: 'application/json' }
}, {
body: '{"message":"Internal Server Error"}',
status: 500
- });
+ }, done);
+});
+it('should return 404', function(done) {
assert.response(server, {
url: '/api/DoesNotExist',
method: 'GET'
}, {
body: 'Not Found',
status: 404
- });
+ }, done);
+});
+it('should return 404', function(done) {
assert.response(server, {
url: '/api/DoesNotExist',
method: 'GET',
headers: { accept: 'application/json' }
}, {
body: '{"message":"Not Found"}',
status: 404
- });
-};
+ }, done);
+});
+
+});
View
16 test/coverage.sh
@@ -1,8 +1,8 @@
#!/usr/bin/env sh
cd ..
-rm -rf coverage/node_modules
-mkdir -p coverage/node_modules
+rm -rf bones-cov
+mkdir bones-cov
jscoverage --no-instrument=test \
--no-instrument=node_modules \
--no-instrument=assets \
@@ -19,6 +19,12 @@ jscoverage --no-instrument=test \
--no-instrument=server/view.suffix.js \
--exclude=examples \
bones \
- coverage/node_modules/bones
-cd coverage/node_modules/bones
-expresso
+ bones-cov
+cd bones-cov
+
+mocha -R html-cov > coverage.html
+
+VIEWER=$(which open);
+if [ -x $VIEWER ]; then
+ $VIEWER coverage.html
+fi
View
36 test/demo.test.js
@@ -4,66 +4,84 @@ var os = require('os');
var server = require('./fixture/start').servers.Core;
-exports['routes'] = function(beforeExit) {
+describe('routes', function() {
+
+it('should load submodule page', function(done) {
assert.response(server, {
url: '/submodule-page',
method: 'GET'
}, {
body: 'submodule page',
status: 200
- });
+ }, done);
+});
+it('should load foo page', function(done) {
assert.response(server, {
url: '/page/foo',
method: 'GET'
}, {
body: 'page foo',
status: 200
- });
+ }, done);
+});
+it('should load bar page', function(done) {
assert.response(server, {
url: '/page/bar',
method: 'GET'
}, {
body: 'page bar',
status: 200
- });
+ }, done);
+});
+it('should load special page', function(done) {
assert.response(server, {
url: '/page/special',
method: 'GET'
}, {
body: 'special page',
status: 200
- });
+ }, done);
+});
+it('should redirect fragment querystring', function(done) {
assert.response(server, {
url: '/?_escaped_fragment_=/page/special',
method: 'GET',
headers: { host: os.hostname() }
}, {
body: '<p>Moved Permanently. Redirecting to <a href="http://' + os.hostname() + '/page/special">http://' + os.hostname() + '/page/special</a></p>',
status: 301
- }, function(res) {
+ }, function(err, res) {
+ assert.ifError(err);
assert.equal(res.headers.location, 'http://' + os.hostname() + '/page/special');
+ done();
});
+});
+it('should load baz page', function(done) {
assert.response(server, {
url: '/page/baz',
method: 'GET'
}, {
body: 'bones router special page',
status: 200
- });
+ }, done);
+});
+it('should deny POST', function() {
assert.response(server, {
url: '/page/foo',
method: 'POST'
}, {
body: 'Forbidden',
status: 403
});
+});
+it('should not find page', function() {
assert.response(server, {
url: '/page/foo',
method: 'POST',
@@ -76,4 +94,6 @@ exports['routes'] = function(beforeExit) {
body: 'Not Found',
status: 404
});
-};
+});
+
+});
View
58 test/error.test.js
@@ -3,33 +3,41 @@ var assert = require('assert');
var server = require('./fixture/start').servers.Core;
-exports['error 404'] = function(beforeExit) {
+describe('errors', function() {
+
+it('should return 404', function(done) {
assert.response(server, {
url: '/does-not-exist',
method: 'GET'
}, {
body: 'Not Found',
status: 404
- });
+ }, done);
+});
+it('should return JSON 404 message', function(done) {
assert.response(server, {
url: '/does-not-exist',
method: 'GET',
headers: { 'accept': 'application/json' }
}, {
body: '{"message":"Not Found"}',
status: 404
- });
+ }, done);
+});
+it('should return 403', function(done) {
assert.response(server, {
url: '/does-not-exist',
method: 'POST',
headers: { 'accept': 'application/json' }
}, {
body: '{"message":"Forbidden"}',
status: 403
- });
+ }, done);
+});
+it('should return 404', function(done) {
assert.response(server, {
url: '/does-not-exist',
method: 'POST',
@@ -41,8 +49,10 @@ exports['error 404'] = function(beforeExit) {
}, {
body: 'Not Found',
status: 404
- });
+ }, done);
+});
+it('should return JSON 404 message', function(done) {
assert.response(server, {
url: '/does-not-exist',
method: 'POST',
@@ -55,42 +65,52 @@ exports['error 404'] = function(beforeExit) {
}, {
body: '{"message":"Not Found"}',
status: 404
- });
+ }, done);
+});
+it('should return 404', function(done) {
assert.response(server, {
url: '/api/DoesNotExit/asdf',
method: 'GET'
}, {
body: 'Not Found',
status: 404
- });
+ }, done);
+});
+it('should return JSON 404 message', function(done) {
assert.response(server, {
url: '/api/DoesNotExit/asdf',
method: 'GET',
headers: { 'accept': 'application/json' }
}, {
body: '{"message":"Not Found"}',
status: 404
- });
+ }, done);
+});
+it('should return 404', function(done) {
assert.response(server, {
url: '/api/Page/asdf',
method: 'GET'
}, {
body: 'Not Found',
status: 404
- });
+ }, done);
+});
+it('should return JSON 404 message', function(done) {
assert.response(server, {
url: '/api/Page/asdf',
method: 'GET',
headers: { 'accept': 'application/json' }
}, {
body: '{"message":"Not Found"}',
status: 404
- });
+ }, done);
+});
+it('should return 409', function(done) {
assert.response(server, {
url: '/api/Page/asdf',
method: 'PUT',
@@ -102,8 +122,10 @@ exports['error 404'] = function(beforeExit) {
}, {
body: 'Conflict',
status: 409
- });
+ }, done);
+});
+it('should return JSON 409 message', function(done) {
assert.response(server, {
url: '/api/Page/asdf',
method: 'PUT',
@@ -116,8 +138,10 @@ exports['error 404'] = function(beforeExit) {
}, {
body: '{"message":"Conflict"}',
status: 409
- });
+ }, done);
+});
+it('should return 409', function(done) {
assert.response(server, {
url: '/api/Page/asdf',
method: 'DELETE',
@@ -129,8 +153,10 @@ exports['error 404'] = function(beforeExit) {
}, {
body: 'Conflict',
status: 409
- });
+ }, done);
+});
+it('should return JSON 409 message', function(done) {
assert.response(server, {
url: '/api/Page/asdf',
method: 'DELETE',
@@ -143,5 +169,7 @@ exports['error 404'] = function(beforeExit) {
}, {
body: '{"message":"Conflict"}',
status: 409
- });
-};
+ }, done);
+});
+
+});
View
7 test/fixture/index.js
@@ -4,8 +4,11 @@ require('submodule');
// Explicit order
require('./views/Error');
-require('bones').load(__dirname);
+var path = require('path');
+var bones = require(path.join(__dirname, '../../'));
+
+bones.load(__dirname);
if (!module.parent) {
- require('bones').start();
+ bones.start();
}
View
3 test/fixture/node_modules/othermodule/index.js
@@ -1 +1,2 @@
-require('bones').load(__dirname);
+var path = require('path');
+require(path.join(__dirname, '../../../../')).load(__dirname);
View
3 test/fixture/node_modules/submodule/index.js
@@ -1 +1,2 @@
-require('bones').load(__dirname);
+var path = require('path');
+require(path.join(__dirname, '../../../../')).load(__dirname);
View
126 test/fixture/start.js
@@ -1,6 +1,130 @@
// Load application.
require('./');
+var path = require('path');
process.env.NODE_ENV = 'test';
process.argv[2] = 'start';
-module.exports = require('bones').start();
+module.exports = require(path.join(__dirname, '../../')).start();
+
+
+// Augment assert for now...
+var assert = require('assert');
+var http = require('http');
+var util = require('util');
+/**
+ * Assert response from `server` with
+ * the given `req` object and `res` assertions object.
+ *
+ * @param {Server} server
+ * @param {Object} req
+ * @param {Object|Function} res
+ * @param {String} msg
+ */
+assert.response = function(server, req, res, msg) {
+ // Callback as third or fourth arg
+ var callback = typeof res === 'function'
+ ? res
+ : typeof msg === 'function'
+ ? msg
+ : function() {};
+
+ // Default messate to test title
+ if (typeof msg === 'function') msg = null;
+ msg = msg || '';
+
+ // Issue request
+ var timer,
+ method = req.method || 'GET',
+ status = res.status || res.statusCode,
+ data = req.data || req.body,
+ requestTimeout = req.timeout || 0,
+ encoding = req.encoding || 'utf8';
+
+ var request = http.request({
+ host: '127.0.0.1',
+ port: server.port,
+ path: req.url,
+ method: method,
+ headers: req.headers
+ });
+
+ var check = function() {
+ if (--server.__pending === 0) {
+ server.close();
+ server.__listening = false;
+ }
+ };
+
+ // Timeout
+ if (requestTimeout) {
+ timer = setTimeout(function() {
+ check();
+ delete req.timeout;
+ throw new Error(msg + 'Request timed out after ' + requestTimeout + 'ms.');
+ }, requestTimeout);
+ }
+
+ if (data) request.write(data);
+
+ request.on('response', function(response) {
+ response.body = '';
+ response.setEncoding(encoding);
+ response.on('data', function(chunk) { response.body += chunk; });
+ response.on('end', function() {
+ if (timer) clearTimeout(timer);
+ var err = null;
+ try {
+ // Assert response body
+ if (res.body !== undefined) {
+ var eql = res.body instanceof RegExp
+ ? res.body.test(response.body)
+ : res.body === response.body;
+ assert.ok(
+ eql,
+ msg + 'Invalid response body.\n'
+ + ' Expected: ' + util.inspect(res.body) + '\n'
+ + ' Got: ' + util.inspect(response.body)
+ );
+ }
+
+ // Assert response status
+ if (typeof status === 'number') {
+ assert.equal(
+ response.statusCode,
+ status,
+ msg + 'Invalid response status code.\n'
+ + ' Expected: ' + status + '\n'
+ + ' Got: ' + response.statusCode + ''
+ );
+ }
+
+ // Assert response headers
+ if (res.headers) {
+ var keys = Object.keys(res.headers);
+ for (var i = 0, len = keys.length; i < len; ++i) {
+ var name = keys[i],
+ actual = response.headers[name.toLowerCase()],
+ expected = res.headers[name],
+ eql = expected instanceof RegExp
+ ? expected.test(actual)
+ : expected == actual;
+ assert.ok(
+ eql,
+ msg + 'Invalid response header ' + name + '.\n'
+ + ' Expected: ' + expected + '\n'
+ + ' Got: ' + actual
+ );
+ }
+ }
+ }
+ catch (e) {
+ err = e;
+ }
+ callback(err, response);
+ });
+ });
+
+ request.end();
+
+};
+
View
21 test/hostname.test.js
@@ -4,64 +4,81 @@ var os = require('os');
var server = require('./fixture/start').servers.Core;
-exports['hostname'] = function() {
+describe('hostname', function() {
+
+it('should get 200', function() {
assert.response(server, {
url: '/hostname'
}, {
status: 200
});
+});
+it('should have hostname', function() {
assert.response(server, {
url: '/hostname',
headers: { host: os.hostname() }
}, {
body: os.hostname(),
status: 200
});
+});
+it('should have port', function() {
assert.response(server, {
url: '/hostname',
headers: { host: os.hostname() + ':3000' }
}, {
body: os.hostname() + ':3000',
status: 200
});
+});
+it('should have other', function() {
assert.response(server, {
url: '/hostname',
headers: { host: 'other' }
}, {
body: 'other',
status: 200
});
+});
+it('should have subdomain', function() {
assert.response(server, {
url: '/hostname',
headers: { host: 'foo.third' }
}, {
body: 'foo.third',
status: 200
});
+});
+it('should have subdomain and port', function() {
assert.response(server, {
url: '/hostname',
headers: { host: 'foo.third:3000' }
}, {
body: 'foo.third:3000',
status: 200
});
+});
+it('should reply with 400', function() {
assert.response(server, {
url: '/hostname',
headers: { host: 'other.foo.third' }
}, {
status: 400
});
+});
+it('should reply 400 again', function() {
assert.response(server, {
url: '/hostname',
headers: { host: 'asdf' }
}, {
status: 400
});
-};
+});
+});
View
16 test/models.test.js
@@ -3,23 +3,28 @@ var assert = require('assert');
var server = require('./fixture/start').servers.Core;
-exports['api endpoints'] = function() {
+describe('models', function() {
+it('should load model', function(done) {
assert.response(server, {
url: '/api/Page/foo',
method: 'GET'
}, {
body: '{"id":"foo","method":"read"}',
status: 200
- });
+ }, done);
+});
+it('should return 404', function(done) {
assert.response(server, {
url: '/api/page/foo',
method: 'GET'
}, {
body: 'Not Found',
status: 404
- });
+ }, done);
+});
+it('should update model', function(done) {
assert.response(server, {
url: '/api/Page/foo',
method: 'PUT',
@@ -31,5 +36,6 @@ exports['api endpoints'] = function() {
}, {
body: '{"id":"foo","key":"value","method":"update"}',
status: 200
- });
-};
+ }, done);
+});
+});
View
95 test/pluralize.test.js
@@ -1,50 +1,51 @@
var assert = require('assert');
-var utils = require('bones').utils;
+var path = require('path');
+var utils = require(path.join(__dirname, '../')).utils;
-module.exports = {
- 'test .pluralize()': function() {
- assert.equal('ids', utils.pluralize('id'));
- assert.equal('friends', utils.pluralize('friend'));
- assert.equal('buses', utils.pluralize('bus'));
- assert.equal('misses', utils.pluralize('miss'));
- assert.equal('wishes', utils.pluralize('wish'));
- assert.equal('watches', utils.pluralize('watch'));
- assert.equal('foxes', utils.pluralize('fox'));
- assert.equal('potatoes', utils.pluralize('potato'));
- assert.equal('parties', utils.pluralize('party'));
- assert.equal('quizzes', utils.pluralize('quiz'));
- assert.equal('things', utils.pluralize('thing'));
- assert.equal('men', utils.pluralize('man'));
- assert.equal('kisses', utils.pluralize('kiss'));
- assert.equal('dishes', utils.pluralize('dish'));
- assert.equal('judges', utils.pluralize('judge'));
- assert.equal('massages', utils.pluralize('massage'));
- assert.equal('monkeys', utils.pluralize('monkey'));
- assert.equal('keys', utils.pluralize('key'));
- assert.equal('dogs', utils.pluralize('dog'));
- assert.equal('boys', utils.pluralize('boy'));
- assert.equal('oxen', utils.pluralize('ox'));
- assert.equal('indices', utils.pluralize('index'));
- assert.equal('indices', utils.pluralize('indice'));
- },
+describe('pluralization', function() {
+ it('should .pluralize()', function() {
+ assert.equal('ids', utils.pluralize('id'));
+ assert.equal('friends', utils.pluralize('friend'));
+ assert.equal('buses', utils.pluralize('bus'));
+ assert.equal('misses', utils.pluralize('miss'));
+ assert.equal('wishes', utils.pluralize('wish'));
+ assert.equal('watches', utils.pluralize('watch'));
+ assert.equal('foxes', utils.pluralize('fox'));
+ assert.equal('potatoes', utils.pluralize('potato'));
+ assert.equal('parties', utils.pluralize('party'));
+ assert.equal('quizzes', utils.pluralize('quiz'));
+ assert.equal('things', utils.pluralize('thing'));
+ assert.equal('men', utils.pluralize('man'));
+ assert.equal('kisses', utils.pluralize('kiss'));
+ assert.equal('dishes', utils.pluralize('dish'));
+ assert.equal('judges', utils.pluralize('judge'));
+ assert.equal('massages', utils.pluralize('massage'));
+ assert.equal('monkeys', utils.pluralize('monkey'));
+ assert.equal('keys', utils.pluralize('key'));
+ assert.equal('dogs', utils.pluralize('dog'));
+ assert.equal('boys', utils.pluralize('boy'));
+ assert.equal('oxen', utils.pluralize('ox'));
+ assert.equal('indices', utils.pluralize('index'));
+ assert.equal('indices', utils.pluralize('indice'));
+ });
- 'test .singularize()': function() {
- assert.equal('paper', utils.singularize('papers'));
- assert.equal('ox', utils.singularize('oxen'));
- assert.equal('shoe', utils.singularize('shoes'));
- assert.equal('thing', utils.singularize('things'));
- assert.equal('thing', utils.singularize('thing'));
- assert.equal('man', utils.singularize('men'));
- assert.equal('parenthesi', utils.singularize('parenthesis'));
- assert.equal('bus', utils.singularize('bus'));
- assert.equal('miss', utils.singularize('miss'));
- assert.equal('kiss', utils.singularize('kiss'));
- assert.equal('man', utils.singularize('man'));
- assert.equal('monkey', utils.singularize('monkeys'));
- assert.equal('key', utils.singularize('keys'));
- assert.equal('boy', utils.singularize('boys'));
- assert.equal('movie', utils.singularize('movies'));
- assert.equal('series', utils.singularize('series'));
- assert.equal('index', utils.singularize('indices'));
- }
-};
+ it('should .singularize()', function() {
+ assert.equal('paper', utils.singularize('papers'));
+ assert.equal('ox', utils.singularize('oxen'));
+ assert.equal('shoe', utils.singularize('shoes'));
+ assert.equal('thing', utils.singularize('things'));
+ assert.equal('thing', utils.singularize('thing'));
+ assert.equal('man', utils.singularize('men'));
+ assert.equal('parenthesi', utils.singularize('parenthesis'));
+ assert.equal('bus', utils.singularize('bus'));
+ assert.equal('miss', utils.singularize('miss'));
+ assert.equal('kiss', utils.singularize('kiss'));
+ assert.equal('man', utils.singularize('man'));
+ assert.equal('monkey', utils.singularize('monkeys'));
+ assert.equal('key', utils.singularize('keys'));
+ assert.equal('boy', utils.singularize('boys'));
+ assert.equal('movie', utils.singularize('movies'));
+ assert.equal('series', utils.singularize('series'));
+ assert.equal('index', utils.singularize('indices'));
+ });
+});
View
9 test/router.test.js
@@ -1,11 +1,14 @@
process.env.NODE_ENV = 'test';
var assert = require('assert');
var fs = require('fs');
+var path = require('path');
-var fixture = require('bones').plugin;
+var fixture = require(path.join(__dirname, '../')).plugin;
-exports['router behavior'] = function() {
+describe('router', function() {
+it('router behavior', function() {
assert['throws'](function() {
new fixture.routers.Page;
}, "Can't initialize router without server.");
-};
+});
+});
View
11 test/stringify.test.js
@@ -1,14 +1,16 @@
process.env.NODE_ENV = 'test';
var assert = require('assert');
var fs = require('fs');
+var path = require('path');
require('./fixture')
-var fixture = require('bones').plugin;
+var fixture = require(path.join(__dirname, '../')).plugin;
-exports['stringify'] = function() {
+describe('stringify', function() {
+it('should stringify', function() {
assert.equal(fixture.routers.Foo + '', '<Router Foo>');
assert.equal(fixture.routers.Page + '', '<Router Page>');
- var srv = new (require('bones').Server.extend({}, { title: 'Demo' }));
+ var srv = new (require(path.join(__dirname, '../')).Server.extend({}, { title: 'Demo' }));
assert.equal(new fixture.routers.Page({ server: srv }) + '', '[Router Page]');
assert.equal(fixture.models.Failure + '', '<Model Failure>');
@@ -30,4 +32,5 @@ exports['stringify'] = function() {
assert.equal(fixture.views.App + '', '<View App>');
assert.equal(fixture.views.Error + '', '<View Error>');
assert.equal(new fixture.views.Error({ error: 'test' }) + '', '[View Error]');
-};
+});
+});
View
22 test/urls.test.js
@@ -3,32 +3,36 @@ var assert = require('assert');
var server = require('./fixture/start').servers.Core;
-exports['_escaped_fragment_ redirect'] = function() {
+describe('URL handling', function() {
+
+it('should redirect _escaped_fragment_',function(done) {
assert.response(server, {
url: '/page/special?_escaped_fragment_=/something/different',
method: 'GET'
}, {
body: '<p>Moved Permanently. Redirecting to <a href="http://127.0.0.1:3000/something/different">http://127.0.0.1:3000/something/different</a></p>',
status: 301
- });
-}
+ }, done);
+});
-exports['hash request'] = function() {
+it('should serve home for hash requests', function(done) {
assert.response(server, {
url: '/#!/map/devseed-hq',
method: 'GET'
}, {
body: 'home',
status: 200
- });
-}
+ }, done);
+});
-exports['query request'] = function() {
+it('should ignore query strings', function(done) {
assert.response(server, {
url: '/?foo',
method: 'GET'
}, {
body: 'home',
status: 200
- });
-}
+ }, done);
+});
+
+});

0 comments on commit ecdea6c

Please sign in to comment.