Skip to content
Browse files

switch testing frameworks

  • Loading branch information...
1 parent c51fe8b commit 55893c6709f4e3715bba6fa62f0bb75391aac0fc @joshbuddy committed
View
100 spec/minitest.js/README.md
@@ -0,0 +1,100 @@
+# About
+
+Simple test framework for asynchronous testing in [Node.js](http://nodejs.org/). It's trying to be as simple and explicit as possible. No magic, no wheel reinventing. Just use minitest for building your tests and the [assert library](http://nodejs.org/api.html#assert-212) for the actual helpers for testing equality etc.
+
+This is how the output looks like:
+
+![Minitest.js output](http://github.com/botanicus/minitest.js/raw/master/minitest.png)
+
+# Setup
+
+* `require()` minitest
+* Use `minitest.setupListeners()` for listening on the `uncaughtException` and `exit` events.
+* Use `minitest.context(description, block)` for defining your contexts. Context will be usually a function or object name.
+* Use `#<a Context>.assertion(description, block)` for defining your assertions.
+* Use `#<a Test>.finished()` to mark test as finished. All the tests has to have it. Without this you won't be able to write solid asynchronous tests, because you can't ask only "is a and b the same?", but also "did the callback run?".
+* Run `node foo_test.js` to get the results.
+
+# Example
+
+ var minitest = require("minitest");
+ var assert = require("assert");
+
+ minitest.setupListeners();
+
+ minitest.context("Context#setup()", function () {
+ this.setup(function () {
+ this.user = {name: "Jakub"};
+ });
+
+ this.assertion("it should setup listeners", function (test) {
+ // test something via the standard assert module
+ assert.ok(this.user)
+
+ // mark test as finished
+ test.finished();
+ });
+
+ this.assertion("it should be able to count", function (test) {
+ if (2 !== 4) {
+ // manually fail the test
+ throw new Error("You can't count, can you?");
+ };
+ });
+ });
+
+## Formatters
+
+If you don't like minitest output, you can simply override following methods:
+
+* `Context.prototype.contextHeader()`
+* `Test.prototype.reportSuccess()`
+* `Test.prototype.reportError(error)`
+* `Test.prototype.reportNotRun()`
+
+All this methods are supposed to return a string and all these methods have access to `this.description`.
+
+# Common Problems in Testing Asynchronous Code
+
+## Exceptions in Callbacks
+
+Obviously you can't catch errors which occured in callbacks. Consider following:
+
+ try {
+ db.get("botanicus", function (user) {
+ throw new Error("You can't catch me!");
+ });
+ } catch(error) {
+ // you'll never get in here
+ };
+
+## Testing Exceptions
+
+ this.assertion("should throw an error", function (test) {
+ assert.throws(function () {
+ throw new Error("Error occured!");
+ test.finished();
+ });
+ });
+
+This obviously can't work, because exception interrupts the anonymous function we are passing as an argument for `assert.throws()`.
+
+ this.assertion("should throw an error", function (test) {
+ assert.throws(function () {
+ throw new Error("Error occured!");
+ });
+ test.finished();
+ });
+
+This is better, it will at least work, but what if there will be an error in the `assert.throws()` function and it doesn't call the anonymous function?
+
+ this.assertion("should throw an error", function (test) {
+ assert.throws(function () {
+ test.finished();
+ throw new Error("Error occured!");
+ });
+ });
+
+OK, this is better, `test.finished()` doesn't jump out of the test, so in case that the assertion will fail, we will get the proper result. However it's not perfect, because I can change `test.finished()` in future to actually jump out of the function (I probably won't do that but you can't know) plus if there would be a bug, so `test.finished()` would cause an exception, it would satisfy `assert.throws()` without actually testing the code. Well, you'd probably noticed in other tests, but still.
+
+Fortunatelly you can specify error class and expected message for `assert.throws()` in this order: `assert.throws(block, error, message)`.
View
9 spec/minitest.js/TODO.txt
@@ -0,0 +1,9 @@
+- Fix the unicode issues with Node.js 0.1.90. It does work with Node.js 0.1.33, but in 0.1.90 it just prints first two lines (context description and first successful message) and then don't output anything (but the code is still running and we are even able to inspect these messages which should be outputted via sys.p()).
+
+Fix this:
+context("foo", function () {
+ var test = true;
+ this.assertion("bar", function (test) {
+ sys.p(test); // undefined, which is because of the magic with call
+ });
+});
View
35 spec/minitest.js/colours.js
@@ -0,0 +1,35 @@
+/*
+ Simple module for coloured output for POSIX shells.
+
+ @example
+ colours.bold.green + "OK: " + colours.reset + description
+*/
+
+colours = {
+ reset: "\x1B[0m",
+
+ grey: "\x1B[0;30m",
+ red: "\x1B[0;31m",
+ green: "\x1B[0;32m",
+ yellow: "\x1B[0;33m",
+ blue: "\x1B[0;34m",
+ magenta: "\x1B[0;35m",
+ cyan: "\x1B[0;36m",
+ white: "\x1B[0;37m",
+
+ bold: {
+ grey: "\x1B[1;30m",
+ red: "\x1B[1;31m",
+ green: "\x1B[1;32m",
+ yellow: "\x1B[1;33m",
+ blue: "\x1B[1;34m",
+ magenta: "\x1B[1;35m",
+ cyan: "\x1B[1;36m",
+ white: "\x1B[1;37m",
+ }
+};
+
+// exports
+for (colour in colours) {
+ exports[colour] = colours[colour];
+};
View
24 spec/minitest.js/example_test.js
@@ -0,0 +1,24 @@
+#!/usr/bin/env node
+
+var assert = require("assert");
+var minitest = require("./minitest");
+
+// setup listeners
+minitest.setupListeners();
+
+// tests
+minitest.context("Minitest.js", function () {
+ this.assertion("it should succeed", function (test) {
+ assert.ok(true);
+ test.finished();
+ });
+
+ this.assertion("it should fail", function (test) {
+ assert.ok(null);
+ test.finished();
+ });
+
+ this.assertion("it should not be finished", function (test) {
+ assert.ok(true);
+ });
+});
View
158 spec/minitest.js/minitest.js
@@ -0,0 +1,158 @@
+var sys = require("sys");
+var colours = require("./colours");
+
+/* suite */
+function Suite () {
+ this.contexts = [];
+};
+
+Suite.prototype.report = function () {
+ var suite = this;
+ this.contexts.forEach(function(context, index) {
+ sys.puts(context.contextHeader());
+ context.report();
+ if (suite.contexts.length === index) {
+ sys.puts("");
+ };
+ });
+};
+
+Suite.prototype.register = function (context) {
+ this.contexts.push(context);
+};
+
+// there is only one suite instance
+var suite = exports.suite = new Suite();
+
+/* context */
+function Context (description, block) {
+ this.tests = [];
+ this.block = block;
+ this.description = description;
+};
+
+Context.prototype.run = function () {
+ this.block.call(this);
+};
+
+Context.prototype.register = function (test) {
+ this.tests.push(test);
+};
+
+Context.prototype.report = function () {
+ this.tests.forEach(function (test) {
+ test.report();
+ });
+};
+
+/* test */
+function Test (description, block, setupBlock) {
+ this.description = description;
+ this.block = block;
+ this.setupBlock = setupBlock;
+};
+
+Test.prototype.run = function () {
+ try {
+ if (this.setupBlock) {
+ this.setupBlock.call(this);
+ };
+
+ this.block.call(this, this);
+ } catch(error) {
+ this.failed(error);
+ };
+};
+
+Test.prototype.finished = function () {
+ this.result = this.reportSuccess();
+};
+
+Test.prototype.failed = function (error) {
+ this.result = this.reportError(error);
+};
+
+Test.prototype.report = function () {
+ if (this.result) {
+ sys.puts(this.result);
+ } else {
+ sys.puts(this.reportNotFinished());
+ };
+};
+
+/* output formatters */
+Context.prototype.contextHeader = function () {
+ return colours.bold.yellow + "[= " + this.description + " =]" + colours.reset;
+};
+
+Test.prototype.reportSuccess = function () {
+ // return colours.bold.green + " ✔ OK: " + colours.reset + this.description;
+ return colours.bold.green + " OK: " + colours.reset + this.description;
+};
+
+Test.prototype.reportError = function (error) {
+ var stack = error.stack.replace(/^/, " ");
+ // return colours.bold.red + " ✖ Error: " + colours.reset + this.description + "\n" + stack;
+ return colours.bold.red + " Error: " + colours.reset + this.description + "\n" + stack;
+};
+
+Test.prototype.reportNotFinished = function () {
+ // return colours.bold.magenta + " ✖ Didn't finished: " + colours.reset + this.description;
+ return colours.bold.magenta + " Didn't finished: " + colours.reset + this.description;
+};
+
+/* DSL */
+function context (description, block) {
+ var context = new Context(description, block);
+ suite.register(context);
+ context.run();
+};
+
+/*
+ Run an example and print if it was successful or not.
+
+ @example
+ minitest.context("setup()", function () {
+ this.assertion("Default value should be 0", function (test) {
+ assert.equal(value, 0);
+ test.finished();
+ });
+ });
+*/
+Context.prototype.assertion = function (description, block) {
+ var test = new Test(description, block, this.setupBlock);
+ this.register(test);
+ test.run();
+};
+
+Context.prototype.setup = function (block) {
+ this.setupBlock = block;
+};
+
+function runAtExit () {
+ process.addListener("exit", function () {
+ suite.report();
+ });
+};
+
+function setupUncaughtExceptionListener () {
+ // TODO: is there any way how to get the test instance,
+ // so we could just set test.result, so everything would be
+ // reported properly on the correct place, not in the middle of tests
+ process.addListener("uncaughtException", function (error) {
+ sys.puts(Test.prototype.reportError(error));
+ });
+};
+
+function setupListeners () {
+ setupUncaughtExceptionListener();
+ runAtExit();
+};
+
+/* exports */
+exports.Context = Context;
+exports.Test = Test;
+exports.context = context;
+exports.runAtExit = runAtExit;
+exports.setupUncaughtExceptionListener = setupUncaughtExceptionListener;
+exports.setupListeners = setupListeners;
View
BIN spec/minitest.js/minitest.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
View
31 spec/minitest.js/minitest_test.js
@@ -0,0 +1,31 @@
+#!/usr/bin/env node
+
+var assert = require("assert");
+var minitest = require("./minitest");
+
+// setup listeners
+minitest.setupListeners();
+
+// tests
+minitest.context("Namespacing", function () {
+ this.setup(function () {
+ this.user = {name: "Jakub"};
+ });
+
+ this.assertion("instance variable from setup() should exist in assertion", function () {
+ assert.ok(this.user);
+ this.finished();
+ });
+
+ var foobar = true;
+ this.assertion("local variable from context of the current context should exist in assertion", function () {
+ assert.ok(foobar);
+ this.finished();
+ });
+
+ this.foobaz = true;
+ this.assertion("instance variable from context of the current context should not exist in assertion", function () {
+ assert.equal(undefined, this.foobaz);
+ this.finished();
+ });
+});
View
4 spec/run.sh
@@ -0,0 +1,4 @@
+#!/bin/sh
+
+node spec/spec_generate.js
+node spec/spec_recognize.js
View
94 spec/spec_generate.js
@@ -1,60 +1,72 @@
require('../lib/sherpa')
+var minitest = require('./minitest.js/minitest');
+minitest.setupListeners();
+var assert = require('assert');
-describe("Sherpa - generate", function() {
- it("should generate a simple route", function() {
- var router = new Sherpa.Router();
- router.add('/test').name('simple');
- assertEqual('/test', router.generate('simple'));
+minitest.context("Sherpa#generate()", function () {
+ this.setup(function () {
+ this.router = new Sherpa.Router();
});
- it("should generate a route with a variable in it", function() {
- var router = new Sherpa.Router();
- router.add('/:test').name('with_variable');
- assertEqual('/var', router.generate('with_variable', {test: 'var'}));
+ this.assertion("should generate a simple route", function (test) {
+ this.router.add('/test').name('simple');
+ assert.equal('/test', this.router.generate('simple'));
+ test.finished();
});
- it("should generate a route with a regex variable in it", function() {
- var router = new Sherpa.Router();
- router.add('/:test', {matchesWith: {test: /asd|qwe|\d+/}}).name('with_variable');
- assertEqual(undefined, router.generate('with_variable', {test: 'variable'}))
- assertEqual(undefined, router.generate('with_variable', {test: '123qwe'}))
- assertEqual('/123', router.generate('with_variable', {test: '123'}))
- assertEqual('/qwe', router.generate('with_variable', {test: 'qwe'}))
- assertEqual('/asd', router.generate('with_variable', {test: 'asd'}))
+ this.assertion("should generate a route with a variable in it", function (test) {
+ this.router.add('/:test').name('with_variable');
+ assert.equal('/var', this.router.generate('with_variable', {test: 'var'}));
+ test.finished();
});
- it("should generate a route with a optionals in it", function() {
- var router = new Sherpa.Router();
- router.add('/(:test)').name('with_optional');
- assertEqual('/', router.generate('with_optional'))
- assertEqual('/hello', router.generate('with_optional', {test: 'hello'}))
+ this.assertion("should generate a route with a regex variable in it", function(test) {
+ this.router.add('/:test', {matchesWith: {test: /asd|qwe|\d+/}}).name('with_variable');
+ assert.equal(undefined, this.router.generate('with_variable', {test: 'variable'}))
+ assert.equal(undefined, this.router.generate('with_variable', {test: '123qwe'}))
+ assert.equal('/123', this.router.generate('with_variable', {test: '123'}))
+ assert.equal('/qwe', this.router.generate('with_variable', {test: 'qwe'}))
+ assert.equal('/asd', this.router.generate('with_variable', {test: 'asd'}))
+ test.finished();
});
- it("should generate a route with nested optionals in it", function() {
- var router = new Sherpa.Router();
- router.add('/(:test(/:test2))').name('with_optional');
- assertEqual('/', router.generate('with_optional'))
- assertEqual('/hello', router.generate('with_optional', {test: 'hello'}))
- assertEqual('/hello/world', router.generate('with_optional', {test: 'hello', test2: 'world'}))
- assertEqual('/?test2=hello', router.generate('with_optional', {test2: 'hello'}))
+ this.assertion("should generate a route with a optionals in it", function(test) {
+ this.router.add('/(:test)').name('with_optional');
+ assert.equal('/', this.router.generate('with_optional'))
+ assert.equal('/hello', this.router.generate('with_optional', {test: 'hello'}))
+ test.finished();
+ });
+
+ this.assertion("should generate a route with nested optionals in it", function(test) {
+ this.router.add('/(:test(/:test2))').name('with_optional');
+ assert.equal('/', this.router.generate('with_optional'))
+ assert.equal('/hello', this.router.generate('with_optional', {test: 'hello'}))
+ assert.equal('/hello/world', this.router.generate('with_optional', {test: 'hello', test2: 'world'}))
+ assert.equal('/?test2=hello', this.router.generate('with_optional', {test2: 'hello'}))
+ test.finished();
});
- it("should generate extra params as a query string after", function() {
- var router = new Sherpa.Router();
- router.add('/:test', {matchesWith: {test: /asd|qwe|\d+/}}).name('with_variable');
- assertEqual('/123?foo=bar', router.generate('with_variable', {test: '123', foo: 'bar'}))
+ this.assertion("should generate extra params as a query string after", function(test) {
+ this.router.add('/:test', {matchesWith: {test: /asd|qwe|\d+/}}).name('with_variable');
+ assert.equal('/123?foo=bar', this.router.generate('with_variable', {test: '123', foo: 'bar'}));
+ test.finished();
});
- it("should escape values in the URI", function() {
- var router = new Sherpa.Router();
- router.add('/:test').name('with_variable');
- assertEqual('/%5B%20%5D+=-', router.generate('with_variable', {test: '[ ]+=-'}))
+ this.assertion("should generate extra params as a query string after", function(test) {
+ this.router.add('/:test', {matchesWith: {test: /asd|qwe|\d+/}}).name('with_variable');
+ assert.equal('/123?foo=bar', this.router.generate('with_variable', {test: '123', foo: 'bar'}));
+ test.finished();
});
- it("should escape values in the query string", function() {
- var router = new Sherpa.Router();
- router.add('/').name('simple');
- assertEqual('/?test+and+more=%5B+%5D%2B%3D-', router.generate('simple', {"test and more": '[ ]+=-'}))
+ this.assertion("should escape values in the URI", function(test) {
+ this.router.add('/:test').name('with_variable');
+ assert.equal('/%5B%20%5D+=-', this.router.generate('with_variable', {test: '[ ]+=-'}))
+ test.finished();
});
+ this.assertion("should escape values in the query string", function(test) {
+ this.router.add('/').name('simple');
+ assert.equal('/?test+and+more=%5B+%5D%2B%3D-', this.router.generate('simple', {"test and more": '[ ]+=-'}))
+ test.finished();
+ });
});
View
176 spec/spec_recognize.js
@@ -1,111 +1,119 @@
require('../lib/sherpa')
+var minitest = require('./minitest.js/minitest');
+minitest.setupListeners();
+var assert = require('assert');
-describe("Sherpa - recognize", function() {
- it("should recognize a simple route", function() {
- var router = new Sherpa.Router();
- router.add('/test').to('recognized');
- assertEqual('recognized', router.recognize('/test').destination);
+minitest.context("Sherpa#recognize()", function () {
+ this.setup(function () {
+ this.router = new Sherpa.Router();
});
- it("should recognize a simple route", function() {
- var router = new Sherpa.Router();
- router.add('/test').to('recognized');
- assertEqual('recognized', router.recognize('/test').destination);
+ this.assertion("should recognize a simple route", function(test) {
+ this.router.add('/test').to('recognized');
+ assert.equal('recognized', this.router.recognize('/test').destination);
+ test.finished();
});
- it("should recognize a partial route", function() {
- var router = new Sherpa.Router();
- router.add('/test').to('recognized').matchPartially();
- assertEqual('recognized', router.recognize('/test/testing').destination);
+ this.assertion("should recognize a simple route", function(test) {
+ this.router.add('/test').to('recognized');
+ assert.equal('recognized', this.router.recognize('/test').destination);
+ test.finished();
});
- it("should recognize a simple route with optionals", function() {
- var router = new Sherpa.Router();
- router.add('/(test)').to('recognized');
- assertEqual('recognized', router.recognize('/test').destination);
- assertEqual('recognized', router.recognize('/').destination);
+ this.assertion("should recognize a partial route", function(test) {
+ this.router.add('/test').to('recognized').matchPartially();
+ assert.equal('recognized', this.router.recognize('/test/testing').destination);
+ test.finished();
});
- it("should recognize a simple route with nested optionals", function() {
- var router = new Sherpa.Router();
- router.add('(/test(/test2(/test3)))(/test4)').to('recognized');
- assertEqual('recognized', router.recognize('/test').destination);
- assertEqual('recognized', router.recognize('/test/test2').destination);
- assertEqual('recognized', router.recognize('/test/test2/test3').destination);
- assertEqual('recognized', router.recognize('/test/test4').destination);
- assertEqual('recognized', router.recognize('/test/test2/test4').destination);
- assertEqual('recognized', router.recognize('/test/test2/test3/test4').destination);
- assertEqual('recognized', router.recognize('/test4').destination);
- assertEqual(undefined, router.recognize('/test/test3'));
- assertEqual(undefined, router.recognize('/test/test3/test4'));
+ this.assertion("should recognize a simple route with optionals", function(test) {
+ this.router.add('/(test)').to('recognized');
+ assert.equal('recognized', this.router.recognize('/test').destination);
+ assert.equal('recognized', this.router.recognize('/').destination);
+ test.finished();
});
- it("should recognize a route with a variable in it", function() {
- var router = new Sherpa.Router();
- router.add('/:test').to('recognized');
- var response = router.recognize('/variable');
- assertEqual('recognized', response.destination);
- assertEqual({test: 'variable'}, response.params);
+ this.assertion("should recognize a simple route with nested optionals", function(test) {
+ this.router.add('(/test(/test2(/test3)))(/test4)').to('recognized');
+ assert.equal('recognized', this.router.recognize('/test').destination);
+ assert.equal('recognized', this.router.recognize('/test/test2').destination);
+ assert.equal('recognized', this.router.recognize('/test/test2/test3').destination);
+ assert.equal('recognized', this.router.recognize('/test/test4').destination);
+ assert.equal('recognized', this.router.recognize('/test/test2/test4').destination);
+ assert.equal('recognized', this.router.recognize('/test/test2/test3/test4').destination);
+ assert.equal('recognized', this.router.recognize('/test4').destination);
+ assert.equal(undefined, this.router.recognize('/test/test3'));
+ assert.equal(undefined, this.router.recognize('/test/test3/test4'));
+ test.finished();
});
- it("should recognize a route with a regex variable in it", function() {
- var router = new Sherpa.Router();
- router.add('/:test', {matchesWith: {test: /asd|qwe|\d+/}}).to('recognized');
- assertEqual(undefined, router.recognize('/variable'))
- assertEqual(undefined, router.recognize('/123qwe'))
- assertEqual('recognized', router.recognize('/123').destination)
- assertEqual('recognized', router.recognize('/qwe').destination)
- assertEqual('recognized', router.recognize('/asd').destination)
+ this.assertion("should recognize a route with a variable in it", function(test) {
+ this.router.add('/:test').to('recognized');
+ var response = this.router.recognize('/variable');
+ assert.equal('recognized', response.destination);
+ assert.deepEqual({test: 'variable'}, response.params);
+ test.finished();
+ });
+
+ this.assertion("should recognize a route with a regex variable in it", function(test) {
+ this.router.add('/:test', {matchesWith: {test: /asd|qwe|\d+/}}).to('recognized');
+ assert.equal(undefined, this.router.recognize('/variable'))
+ assert.equal(undefined, this.router.recognize('/123qwe'))
+ assert.equal('recognized', this.router.recognize('/123').destination)
+ assert.equal('recognized', this.router.recognize('/qwe').destination)
+ assert.equal('recognized', this.router.recognize('/asd').destination)
+ test.finished();
});
- it("should distinguish between identical routes where one has a matchesWith", function() {
- var router = new Sherpa.Router();
- router.add('/:test', {matchesWith: {test: /^(asd|qwe|\d+)$/}}).to('recognized-regex');
- router.add('/:test').to('recognized-nonregex');
- assertEqual('recognized-nonregex', router.recognize('/poipio').destination)
- assertEqual('recognized-nonregex', router.recognize('/123asd').destination)
- assertEqual('recognized-regex', router.recognize('/123').destination)
- assertEqual('recognized-regex', router.recognize('/qwe').destination)
- assertEqual('recognized-regex', router.recognize('/asd').destination)
+ this.assertion("should distinguish between identical routes where one has a matchesWith", function(test) {
+ this.router.add('/:test', {matchesWith: {test: /^(asd|qwe|\d+)$/}}).to('recognized-regex');
+ this.router.add('/:test').to('recognized-nonregex');
+ assert.equal('recognized-nonregex', this.router.recognize('/poipio').destination)
+ assert.equal('recognized-nonregex', this.router.recognize('/123asd').destination)
+ assert.equal('recognized-regex', this.router.recognize('/123').destination)
+ assert.equal('recognized-regex', this.router.recognize('/qwe').destination)
+ assert.equal('recognized-regex', this.router.recognize('/asd').destination)
+ test.finished();
});
- it("should recognize a route based on a request method", function() {
- var router = new Sherpa.Router();
- router.add('/test').to('any');
- router.add('/test', {conditions:{method: 'GET'}}).to('get');
- router.add('/test', {conditions:{method: 'POST'}}).to('post');
- assertEqual('get', router.recognize('/test', {method: 'GET'}).destination);
- assertEqual('post', router.recognize('/test', {method: 'POST'}).destination);
- assertEqual('any', router.recognize('/test', {method: 'PUT'}).destination);
+ this.assertion("should recognize a route based on a request method", function(test) {
+ this.router.add('/test').to('any');
+ this.router.add('/test', {conditions:{method: 'GET'}}).to('get');
+ this.router.add('/test', {conditions:{method: 'POST'}}).to('post');
+ assert.equal('get', this.router.recognize('/test', {method: 'GET'}).destination);
+ assert.equal('post', this.router.recognize('/test', {method: 'POST'}).destination);
+ assert.equal('any', this.router.recognize('/test', {method: 'PUT'}).destination);
+ test.finished();
});
- it("should recognize a route based on multiple request keys", function() {
- var router = new Sherpa.Router({requestKeys: ['method', 'scheme']});
- router.add('/test', {conditions:{method: 'GET', scheme: 'https'}}).to('https-get');
- router.add('/test', {conditions:{method: 'POST', scheme: 'http'}}).to('http-post');
- router.add('/test', {conditions:{scheme: 'http'}}).to('http-any');
- router.add('/test', {conditions:{scheme: 'https'}}).to('https-any');
- router.add('/test', {conditions:{method: 'POST', scheme: 'https'}}).to('https-post');
- router.add('/test', {conditions:{method: 'GET', scheme: 'http'}}).to('http-get');
+ this.assertion("should recognize a route based on multiple request keys", function(test) {
+ this.router = new Sherpa.Router({requestKeys: ['method', 'scheme']});
+ this.router.add('/test', {conditions:{method: 'GET', scheme: 'https'}}).to('https-get');
+ this.router.add('/test', {conditions:{method: 'POST', scheme: 'http'}}).to('http-post');
+ this.router.add('/test', {conditions:{scheme: 'http'}}).to('http-any');
+ this.router.add('/test', {conditions:{scheme: 'https'}}).to('https-any');
+ this.router.add('/test', {conditions:{method: 'POST', scheme: 'https'}}).to('https-post');
+ this.router.add('/test', {conditions:{method: 'GET', scheme: 'http'}}).to('http-get');
- assertEqual('https-get', router.recognize('/test', {method: 'GET', scheme: 'https'}).destination);
- assertEqual('https-get', router.recognize('/test', {method: 'GET', scheme: 'https'}).destination);
- assertEqual('https-any', router.recognize('/test', {method: 'PUT', scheme: 'https'}).destination);
- assertEqual('http-post', router.recognize('/test', {method: 'POST', scheme: 'http'}).destination);
- assertEqual('http-post', router.recognize('/test', {method: 'POST', scheme: 'http'}).destination);
- assertEqual('http-any', router.recognize('/test', {method: 'PUT', scheme: 'http'}).destination);
+ assert.equal('https-get', this.router.recognize('/test', {method: 'GET', scheme: 'https'}).destination);
+ assert.equal('https-get', this.router.recognize('/test', {method: 'GET', scheme: 'https'}).destination);
+ assert.equal('https-any', this.router.recognize('/test', {method: 'PUT', scheme: 'https'}).destination);
+ assert.equal('http-post', this.router.recognize('/test', {method: 'POST', scheme: 'http'}).destination);
+ assert.equal('http-post', this.router.recognize('/test', {method: 'POST', scheme: 'http'}).destination);
+ assert.equal('http-any', this.router.recognize('/test', {method: 'PUT', scheme: 'http'}).destination);
+ test.finished();
});
- it("should recognize a route based on a request method regex", function() {
- var router = new Sherpa.Router();
- router.add('/test').to('any');
- router.add('/test', {conditions:{method: 'DELETE'}}).to('delete');
- router.add('/test', {conditions:{method: /GET|POST/}}).to('get-post');
- assertEqual('get-post', router.recognize('/test', {method: 'GET'}).destination);
- assertEqual('get-post', router.recognize('/test', {method: 'POST'}).destination);
- assertEqual('delete', router.recognize('/test', {method: 'DELETE'}).destination);
- assertEqual('any', router.recognize('/test', {method: 'PUT'}).destination);
+ this.assertion("should recognize a route based on a request method regex", function(test) {
+ this.router.add('/test').to('any');
+ this.router.add('/test', {conditions:{method: 'DELETE'}}).to('delete');
+ this.router.add('/test', {conditions:{method: /GET|POST/}}).to('get-post');
+ assert.equal('get-post', this.router.recognize('/test', {method: 'GET'}).destination);
+ assert.equal('get-post', this.router.recognize('/test', {method: 'POST'}).destination);
+ assert.equal('delete', this.router.recognize('/test', {method: 'DELETE'}).destination);
+ assert.equal('any', this.router.recognize('/test', {method: 'PUT'}).destination);
+ test.finished();
});
View
214 spec/tacular.js
@@ -1,214 +0,0 @@
-/*
- * spec/tacular
- *
- * A minimal spec library for node.js
- *
- * To run:
- *
- * 1. Place this file in your project's spec directory.
- * 2. Run with "node spec/tacular.js" to test all files beginning with the word "spec".
- *
- * Options:
- *
- * "=verbose": Use verbose mode showing description, tests, and status for each spec.
- *
- * Synopsis:
- *
- * var foo = require("./../lib/foo"); // the file you are specing
- *
- * describe("A foo", function() {
- * beforeEach(function() {
- * // setup goes here
- * });
- *
- * afterEach(function() {
- * // teardown goes here
- * });
- *
- * it("should do X", function() {
- * // place code and assertions here
- * // available: assert(x), assertEqual(x, y), assertNotEqual(x, y)
- * });
- *
- * });
- *
- * Copyright 2009, Jon Crosby, MIT Licensed
- *
- */
-process.mixin(require('sys'));
-
-(function() {
- var path = require('path');
- var posix = require('posix');
- var specCount = 0;
- var specStack = [];
- var specFailures = [];
- var specVerbose = process.ARGV.join(";").match(/;=verbose/);
-
- var describe = function(name, func) {
- specStack.push(name);
- if (specVerbose) print(name);
- specBeforeEach = specAfterEach = function() {};
- func();
- if (specVerbose) print("\n\n");
- specStack.pop();
- };
-
- var it = function(name, func) {
- specCount++;
- specStack.push(name);
- if (specVerbose) print("\n "+name+" : ");
- specBeforeEach();
- try { func(); }
- catch(e) { if (e != 'fail') specError(e); }
- specStack.pop();
- specAfterEach();
- };
-
- var specError = function(message) {
- print(specVerbose ? "Error ("+message+") " : "E");
- specFailures.push(specStack.join(" ") + "\n" + message);
- };
-
- var specFail = function(message) {
- print(specVerbose ? "Fail " : "F");
- specFailures.push(specStack.join(" ") + "\n" + message);
- };
-
- var specPass = function() {
- print(specVerbose ? "Pass " : ".");
- };
-
- var inspectObject = function(obj) {
- if(obj === null) return "null";
- var elements = [], orderedProperties = [], i;
- for(property in obj) {
- orderedProperties.push(property);
- }
- orderedProperties = orderedProperties.sort();
- for(i = 0; i < orderedProperties.length; i++) {
- elements.push([orderedProperties[i], inspect(obj[orderedProperties[i]])].join(":"));
- }
- return "{" + elements.join(",") + "}";
- };
-
- var inspectArray = function(arr) {
- var elements = [];
- if(arr.length == 0) return "[]";
- for(var i = 0; i < arr.length; i++) {
- elements.push(inspect(arr[i]));
- }
- return "[" + elements.join(",") + "]";
- };
-
- var inspectDate = function(date) {
- return date.toString();
- };
-
- var inspectString = function(str) {
- return '"' + str + '"';
- };
-
- var inspectBoolean = function(bool) {
- return bool;
- };
-
- var inspectNumber = function(num) {
- return num;
- };
-
- var inspect = function(element) {
- switch(typeof(element)) {
- case "object":
- if(element instanceof Array) {
- return inspectArray(element);
- } else if (element instanceof Date) {
- return inspectDate(element);
- } else {
- return inspectObject(element);
- }
- break;
- case "string":
- return inspectString(element);
- break;
- case "number":
- return inspectNumber(element);
- break;
- case "boolean":
- return inspectBoolean(element);
- break;
- default:
- if(element === undefined) {
- return "undefined";
- } else {
- return element.toString();
- }
- }
- };
-
- var assert = function(value) {
- value ? specPass() : specFail("Expected " + value + " to be true");
- };
-
- var assertEqual = function(a, b) {
- var debugA = inspect(a), debugB = inspect(b);
- debugA == debugB ? specPass() : specFail("Expected:\n" + debugA + "\n\n" + "Found:\n" + debugB);
- };
-
- var assertNotEqual = function(a, b) {
- var debugA = inspect(a), debugB = inspect(b);
- debugA != debugB ? specPass() : specFail("Expected:\n" + debugA + "\n\nto not equal:\n" + debugB);
- };
-
- var beforeEach = function(func) {
- specBeforeEach = func;
- };
-
- var afterEach = function(func) {
- specAfterEach = func;
- };
-
- var summarize = function() {
- var plural = function(word, isPlural) {
- return word + (isPlural ? "s" : "");
- };
-
- var specSummary = function() {
- return [specCount, plural("example", specCount != 1)].join(" ");
- };
-
- var failSummary = function() {
- return [specFailures.length, plural("failure", specFailures.length != 1)].join(" ");
- };
-
- var summary = function() {
- return [specSummary(), failSummary()].join(", ");
- };
-
- if(specFailures.length) {
- var i;
- for(i = 1; i <= specFailures.length; i++) {
- puts("" + i + ")");
- puts(specFailures[i-1]);
- puts("");
- }
- }
- puts(summary());
- };
-
- var specDirectory = path.dirname(__filename);
- var files = posix.readdir(specDirectory).wait();
- var i;
- for(i = 0; i < files.length; i++) {
- var file = files[i];
- if(file.match(/^spec/)) {
- if (specVerbose) print(file+"\n");
- var content = posix.cat(specDirectory + "/" + file, "utf8").wait();
- eval(content);
- }
- }
- puts("\n");
- process.addListener("exit", function () {
- summarize();
- });
-})();

0 comments on commit 55893c6

Please sign in to comment.
Something went wrong with that request. Please try again.