1 | /*
|
2 | * Licensed to Cloudkick, Inc ('Cloudkick') under one or more
|
3 | * contributor license agreements. See the NOTICE file distributed with
|
4 | * this work for additional information regarding copyright ownership.
|
5 | * Cloudkick licenses this file to You under the Apache License, Version 2.0
|
6 | * (the "License"); you may not use this file except in compliance with
|
7 | * the License. You may obtain a copy of the License at
|
8 | *
|
9 | * http://www.apache.org/licenses/LICENSE-2.0
|
10 | *
|
11 | * Unless required by applicable law or agreed to in writing, software
|
12 | * distributed under the License is distributed on an "AS IS" BASIS,
|
13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
14 | * See the License for the specific language governing permissions and
|
15 | * limitations under the License.
|
16 | */
|
17 |
|
18 | var sprintf = require('sprintf').sprintf;
|
19 |
|
20 | function Expect(actual) {
|
21 | this._actual = actual;
|
22 | }
|
23 |
|
24 | /**
|
25 | * @param {Object} imports The foreign exports object to add bdd tests to
|
26 | * @returns {Object} bdd A collection of test functions
|
27 | */
|
28 | exports.init = function(imports) {
|
29 | var bdd = {
|
30 | '_suiteSetup': function() {}
|
31 | };
|
32 |
|
33 | /** @param {Function} setup function to call before each suite */
|
34 | bdd.beforeEach = function(setup) {
|
35 | bdd._suiteSetup = setup;
|
36 | };
|
37 |
|
38 | /** @description creates a test suite
|
39 | * @param {string} title
|
40 | * @param {Function} suite
|
41 | */
|
42 | bdd.describe = function(title, suite) {
|
43 |
|
44 | /** @description it() is the equivalent of a exports['test blah'] in the whiskey idiom.
|
45 | * This function, when called, adds a whiskey test to the imports object.
|
46 | * @param {string} name
|
47 | * @param {Function} spec(expect, callback)
|
48 | */
|
49 | function it(name, spec) {
|
50 | var whiskeyName = sprintf("test %s %s", title, name);
|
51 |
|
52 | function expect(actual) {
|
53 | return new Expect(actual);
|
54 | }
|
55 |
|
56 | /** @description Re-binds the Expect test methods using the newly-injected assert.
|
57 | * @param {object} test the test object injected by whiskey
|
58 | * @param {object} assert the assert object injected by whiskey
|
59 | */
|
60 | imports[whiskeyName] = function(test, assert) {
|
61 |
|
62 | // make the whiskey test and assert objects available to bdd tests
|
63 | bdd.test = test;
|
64 | bdd.assert = assert;
|
65 |
|
66 | /** @description maps an assert method to a bdd matcher
|
67 | * @param {string} assertion the name of a whiskey assert method
|
68 | * @param {string} bddName the name of the equivalent expect method
|
69 | */
|
70 | function translateMatcher(assertion, bddName) {
|
71 | Expect.prototype[bddName] = function() {
|
72 | assert[assertion].bind(this, this._actual).apply(this, arguments);
|
73 | }
|
74 | }
|
75 |
|
76 | // This must be done each time a test is created,
|
77 | // as test and assert are injected in each test function.
|
78 | translateMatcher('equal', 'toEqual');
|
79 | translateMatcher('isNull', 'toBeNull');
|
80 | translateMatcher('isDefined', 'toBeDefined');
|
81 | translateMatcher('isUndefined', 'toBeUndefined');
|
82 | translateMatcher('match', 'toMatch');
|
83 |
|
84 | spec(expect, test.finish);
|
85 | if (spec.length === 1) {
|
86 | // if spec isn't expecting test.finish as an async callback, call it directly
|
87 | test.finish();
|
88 | }
|
89 | }
|
90 | }
|
91 |
|
92 | bdd._suiteSetup();
|
93 | suite(it);
|
94 | };
|
95 |
|
96 | return bdd;
|
97 | }
|