node package manager

vows-is

vows-is link

A library to make unit testing with vows-fluent even easier!

It brings the sugar of should and allows you to write your vows tests in BDD fashion

Why not use APIeasy instead? link

APIeasy is similar to vows-is but is a full abstraction on top of vows. It's not a one-to-one mapping between vows. Vow-is strives to be a thin abstraction and maps directly to vows itself.

It also allows you to mix and match vows-fluent and vows-is code as vows-is is a full superset of the vow-fluent API.

Under active development link

The API is unstable, the edge-cases are un-tested and the feature list is unfinished.

I'm actively using this to do my own unit testing and once I've finished that this code base should be stable.

Consider v0.2.0 stable (Currently 0.1.11)

Examples link

See the examples

See the tests, tests of my blog and tests of contract

Documentation link

Annotated Source Code

Is link

Claim that the current topic is a value

.topic.is("value")
.topic.is(null)

Is error handling link

Both Is and Is.invocation have a wrapper to deal with errors. This allows you to do the following

.topic.is(function() {
	throw new Error("foo")
})
.vow.it.should.error

Note that this only works when calling test through node test/... since vows is currently broken. See vows issue 63

Is.request link

Claim that the current topic is a request to an url. This url should be relative to config.server.uri

.topic.is.a.request("GET /")
.topic.is.a.request("POST /blog/")

Is.property link

Claim that the current topic is a property of the previous topic

.topic.is.property("name")

Is.invocation link

Invokes the previous topic with the passed arguments and returns the result

.topic.is(function() {
	return function(n) { return n; };
})
.context("...")
	.topic.is.an.invocation(42)
	// topic is 42

It.should link

Should is the same should object as in should.js

This should however has a few extra pieces of sugar

should.header link

Asserts that the topic has a header of name & value

vow.it.should.have.header("content-type", "text/plain")

is link

var is = require("vows-is");
// is.Is the Is object.
// is.It the It object.
// is.Should the Should object
// is.Assertion the should Assertion object
// is.console the vows console object
// is.suite and all other vows-fluent methods

is.prettyPrint link

You can overwrite the way vows-is prints text to the terminal for should assertions. By default header is already overwritten to print as follows.

is.prettyPrint["header"] = function(args) {
	// args[0] == "content-type"
	// args[1] == "text/plain"
	return args[0] + " with value " + args[1];
};

is.partial link

Define partial re-usable blocks of code. When you call .partial in your chain it will run the partial method of that name and pass in the current context you are on in your chain.

is.partial("is ok", function(context, data) {
	return context.vow.it.should.be.ok;	
});

is.suite("test").batch()
	.context("test partial")
		.topic.is("this string")
		.partial("is ok", {"pass": "in data"});

is.end link

Call this function to trigger tidy up methods.

is.suite() 
...
.run({}, function() {
	is.end();
})

is.reporter link

A custom reporter that looks better than spec. Screenshot

is.suite()
...
.run({
	"reporter": is.reported
}, function() {
	is.end();
});

is.config link

Set's the configuration options for vows-is.

is.config({
	"server": {
		"factory": function(cb) {
			// create an instance of HTTPServer
			// then call cb(server)
			var app = express.createServer();
			...
			app.listen(4000);
			cb(app);
		},
		"kill": function(app) {
			// is.end() was called
			// clean up your HTTPServer	
		},
		"defaults": {
			// defaults options to pass to request
		},
		"uri": // the base url to your HTTPServer.
	}
})

is.config.server.factory link

Pass in a function that takes a callback as an argument, construct your HTTPServer, make sure you listen to the server and then pass this server as the first argument to the callback.

This method will only be called once and the HTTPServer will be cached internally inside vows-is.

The HTTPServer is currently not used internally but will be in the future. You can pass in null and cheat currently but it may/will break with future versions.

is.config.server.kill link

Pass in a function that takes your HTTPServer as the first argument. This function will be called when is.end() is called and your expected to tear down your server.

is.config.server.uri link

Pass in a base string to use as your uri.

Examples:

http://localhost:8080
http://myserver.com
https://myOtherserver.com

is.config.server.defaults link

Set defaults options on request. The following is called internally

request.defaults(defaults.server.defaults);

Running your tests link

If your exporting the module you can run tests with vow --spec.

If your running the module with is.reporter you can run them with node test/url/to/test/file

There are a few issues with vows that are fixed in vows-is so it's more stable to run your tests with node test/my-test.js

Example link

An example of using vows-is to tests HTTP requests

.context("a request to GET /")
	.topic.is.a.request("GET /")
	.vow.it.should.have.status(200)
	.vow.it.should.have
		.header("content-type", "text/html; charset=utf-8")
	.context("contains a body that")
		.topic.is.property('body')
		.vow.it.should.be.ok
		.vow.it.should.include.string("hello world")

vows-is turns the following vows-fluent code

suite("Arithmetic Test").batch()

    .context("2 into 6")
        .topic(function() { return 6 / 2 })
        .vow("is a number", function (topic) { assert.isNumber(topic); })
        .vow("equals 3", function (topic) { assert.equal(topic, 3); })
        .batch()

    .context("123")
        .topic(123)
        .vow("is a number", function(topic) { assert.isNumber(topic); })
        .vow("equals 123", function(topic) { assert.equal(topic, 123); })
        .context("divided by 10")
            .topic(function(topic) { return topic / 10; })
            .vow("equas 12.3", function (topic) { assert.equal(topic, 12.3); })
            .batch()

    .context("1 plus 3")
        .topic(function() { return 1 + 3; })
        .vow("is a number", function(topic) { assert.isNumber(topic); })
        .vow("equals 4", function(topic) { assert.equal(topic, 4); })
        .context("subtract 5")
            .topic(function(topic) { return topic - 5; })
            .vow("is a number", function (topic) { assert.isNumber(topic); })
            .vow("equals -1", function(topic) { assert.equal(topic, -1); })
            .context("times 2")
                .topic(function(topic) { return topic * 2; })
                .vow("is a number", function(topic) { assert.isNumber(topic); })
                .vow("equals-2", function(topic) { assert.equal(topic, -2); })
                .parent()
            .context("times 0")
                .topic(function (topic) { return topic * 0; })
                .vow("equals 0", function(topic) { assert.equal(topic, 0); })

.suite().export(module);

Into

is.suite("vows-is").batch()

	.context("2 into 6")
		.topic.is(function() { return 6 / 2; })
		.vow.it.should.be.a("number")
		.vow.it.should.eql(3)
		.parent()
		
	.context("123")
		.topic.is(123)
		.vow.it.should.be.a("number")
		.vow.it.should.eql(123)
		.context("divided by 10")
			.topic.is(function(topic) { return topic / 10 })
			.vow.it.should.eql(12.3)
			.batch()

	.context("1 plus 3")
		.topic.is(function() { return 1 + 3; })
		.vow.it.should.be.a("number")
		.vow.it.should.eql(4)
		.context("subtract 5")
			.topic.is(function(topic) { return topic - 5; })
			.vow.it.should.be.a("number")
			.vow.it.should.eql(-1)
			.context("times 2")
				.topic.is(function(topic) { return topic * 2; })
				.vow.it.should.be.a("number")
				.vow.it.should.eql(-2)
				.parent()
			.context("times 0")
				.topic.is(function (topic) { return topic * 0; })
				.vow.it.should.eql(0)
				
.suite().export(module);