Skip to content

Commit

Permalink
Merge pull request #37 from robert-chiniquy/master
Browse files Browse the repository at this point in the history
Adds an optional BDD testing idiom to whiskey
  • Loading branch information
Kami committed Jun 12, 2012
2 parents 66bb309 + 69c474a commit a29eb55
Show file tree
Hide file tree
Showing 7 changed files with 238 additions and 0 deletions.
3 changes: 3 additions & 0 deletions CHANGES.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
Changes
=======

* Add an optional, minimal BDD idiom implementation.
[Robert Chiniquy]

* Send the SIGKILL signal instead of SIGTERM when killing child processes managed by the process runner.
[Robert Chiniquy]

Expand Down
12 changes: 12 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,18 @@ exports['test_two_equals_one'] = function(test, assert) {
}
```

A simple example using the optional BDD module:
``` javascript
var bdd = require('whiskey').bdd.init(exports);
var describe = bdd.describe;

describe('the bdd module', function(it) {
it('supports it(), expect(), and toEqual()', function(expect) {
expect(true).toEqual(true);
});
});
```

For more examples please check the `example/` folder.

# Build status
Expand Down
39 changes: 39 additions & 0 deletions example/test-bdd-failures.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
/*
* Licensed to Cloudkick, Inc ('Cloudkick') under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* Cloudkick licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

var bdd = require('../lib/bdd').init(exports);
var describe = bdd.describe;

describe('the bdd expect()', function(it) {

it('correctly fails toBeNull()', function(expect) {
expect("not null").toBeNull();
});

it('correctly fails toBeDefined()', function(expect) {
expect(undefined).toBeDefined();
});

it('correctly fails toBeUndefined()', function(expect) {
expect(true).toBeUndefined();
});

it('correctly fails toMatch()', function(expect) {
expect('fish').toMatch(/not a fish/);
});

});
69 changes: 69 additions & 0 deletions example/test-bdd.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
/*
* Licensed to Cloudkick, Inc ('Cloudkick') under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* Cloudkick licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

var bdd = require('../lib/bdd').init(exports);
var describe = bdd.describe;
var beforeEach = bdd.beforeEach;

var wasBeforeEachCalled = false;

beforeEach(function() {
wasBeforeEachCalled = true;
});

describe('the bdd module', function(it) {

it('supports it(), expect(), and toEqual()', function(expect) {
expect(true).toEqual(true);
});

it('supports beforeEach()', function(expect) {
expect(wasBeforeEachCalled).toEqual(true);
});

it('supports async tests', function(expect, callback) {
var called = false;
setTimeout(function() {
called = true;
}, 1);
setTimeout(function() {
expect(called).toEqual(true);
callback();
}, 3);
});

});

describe('the bdd expect()', function(it) {

it('handles toBeNull()', function(expect) {
expect(null).toBeNull();
});

it('handles toBeDefined()', function(expect) {
expect(true).toBeDefined();
});

it('handles toBeUndefined()', function(expect) {
expect(undefined).toBeUndefined();
});

it('handles toMatch()', function(expect) {
expect('fish').toMatch(/is/);
});

});
1 change: 1 addition & 0 deletions index.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,5 +15,6 @@
* limitations under the License.
*/

exports.bdd = require('./lib/bdd.js');
exports.run = require('./lib/run.js').run;
exports.installCoverageHandler = require('./lib/coverage').installCoverageHandler;
97 changes: 97 additions & 0 deletions lib/bdd.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
/*
* Licensed to Cloudkick, Inc ('Cloudkick') under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* Cloudkick licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

var sprintf = require('sprintf').sprintf;

function Expect(actual) {
this._actual = actual;
}

/**
* @param {Object} imports The foreign exports object to add bdd tests to
* @returns {Object} bdd A collection of test functions
*/
exports.init = function(imports) {
var bdd = {
'_suiteSetup': function() {}
};

/** @param {Function} setup function to call before each suite */
bdd.beforeEach = function(setup) {
bdd._suiteSetup = setup;
};

/** @description creates a test suite
* @param {string} title
* @param {Function} suite
*/
bdd.describe = function(title, suite) {

/** @description it() is the equivalent of a exports['test blah'] in the whiskey idiom.
* This function, when called, adds a whiskey test to the imports object.
* @param {string} name
* @param {Function} spec(expect, callback)
*/
function it(name, spec) {
var whiskeyName = sprintf("test %s %s", title, name);

function expect(actual) {
return new Expect(actual);
}

/** @description Re-binds the Expect test methods using the newly-injected assert.
* @param {object} test the test object injected by whiskey
* @param {object} assert the assert object injected by whiskey
*/
imports[whiskeyName] = function(test, assert) {

// make the whiskey test and assert objects available to bdd tests
bdd.test = test;
bdd.assert = assert;

/** @description maps an assert method to a bdd matcher
* @param {string} assertion the name of a whiskey assert method
* @param {string} bddName the name of the equivalent expect method
*/
function translateMatcher(assertion, bddName) {
Expect.prototype[bddName] = function() {
assert[assertion].bind(this, this._actual).apply(this, arguments);
}
}

// This must be done each time a test is created,
// as test and assert are injected in each test function.
translateMatcher('equal', 'toEqual');
translateMatcher('isNull', 'toBeNull');
translateMatcher('isDefined', 'toBeDefined');
translateMatcher('isUndefined', 'toBeUndefined');
translateMatcher('match', 'toMatch');

spec(expect, test.finish);
if (spec.length === 1) {
// if spec isn't expecting test.finish as an async callback, call it directly
test.finish();
}
}
}

bdd._suiteSetup();
suite(it);
};

return bdd;
}
17 changes: 17 additions & 0 deletions test/run.sh
Original file line number Diff line number Diff line change
Expand Up @@ -268,6 +268,23 @@ if [ $? -ne 0 ]; then
exit 1
fi

"${CWD}/bin/whiskey" --timeout 1000 \
--tests "${CWD}/example/test-bdd.js"

if [ $? -ne 0 ]; then
echo "BDD test didn't exit with zero exit code."
exit 1
fi

"${CWD}/bin/whiskey" --timeout 1000 \
--tests "${CWD}/example/test-bdd-failures.js"

if [ $? -ne 4 ]; then
echo "BDD failure test didn't fail as expected."
exit 1
fi


echo ""
echo "* * * Whiskey test suite PASSED. * * *"
exit 0

0 comments on commit a29eb55

Please sign in to comment.