UNPKG

node-vitals

Version:

Do more with less. A simple, high-performing, functional JavaScript library.

418 lines (349 loc) 9.85 kB
/** * ----------------------------------------------------------------------------- * VITALS UNIT TESTS: interface * ----------------------------------------------------------------------------- * @author Adam Smith <adam@imaginate.life> (https://github.com/imaginate) * @copyright 2017 Adam A Smith <adam@imaginate.life> (https://github.com/imaginate) * * Annotations: * @see [JSDoc3](http://usejsdoc.org) * @see [Closure Compiler JSDoc Syntax](https://developers.google.com/closure/compiler/docs/js-for-compiler) * * Copyright Notice: * The below code is a modified version of the Mocha [bdd interface](https://github.com/mochajs/mocha/blob/master/lib/interfaces/bdd.js). * @copyright 2017 TJ Holowaychuk <tj@vision-media.ca> */ 'use strict'; var sliceArr = require('../helpers/slice-arr'); var testCall = require('../helpers/test-call'); var Mocha = require('mocha'); var Suite = Mocha.Suite; var Test = Mocha.Test; Mocha.interfaces['vitals'] = Interface; module.exports = Interface; /** * Custom interface example: * * method('each', function() { * * should('return a valid object', function() { * * test([ '<object>', '<iteratee>' ], function() { * var obj = {}; * var result = vitals.each(obj, function(val, key){}); * assert( result === obj ); * }); * }); * }); * * @param {Suite} suite - The root suite. */ function Interface(suite) { /** @type {!Array<Suite>} */ var suites; suites = [ suite ]; suite.on('pre-require', function(context, file, mocha) { /** * Defines a suite of tests for a single vitals method. * * @public * @param {string} method - The vitals method (e.g. `has` or `is.string`). * @param {string=} alias - An alias to use for test titles (e.g. `is.str`). * @param {function} tests * @return {Suite} */ context.method = function(method, alias, tests) { /** @type {Suite} */ var suite; /** @type {string} */ var title; title = 'vitals.' + method; if (arguments.length < 3) { tests = alias; alias = undefined; } suite = Suite.create(suites[0], title); suite.file = file; suite.main = true; suite.method = alias || method; suites.unshift(suite); tests.call(suite); suites.shift(); return suite; }; /** * Defines a skipped suite of tests for a single vitals method. * * @public * @param {string} method - The vitals method (e.g. `has` or `is.string`). * @param {string=} alias - An alias to use for test titles (e.g. `is.str`). * @param {function} tests */ context.method.skip = function(method, alias, tests) { /** @type {Suite} */ var suite; /** @type {string} */ var title; title = 'vitals.' + method; if (arguments.length < 3) { tests = alias; alias = undefined; } suite = Suite.create(suites[0], title); suite.pending = true; suite.method = alias || method; suite.main = true; suites.unshift(suite); tests.call(suite); suites.shift(); return suite; }; /** * Defines the only not skipped suite of tests for a single vitals method. * * @public * @param {string} method - The vitals method (e.g. `has` or `is.string`). * @param {string=} alias - An alias to use for test titles (e.g. `is.str`). * @param {function} tests * @return {Suite} */ context.method.only = function(method, alias, tests) { /** @type {Suite} */ var suite; if (arguments.length < 3) { tests = alias; alias = undefined; } suite = context.method(method, alias, tests); mocha.grep( suite.fullTitle() ); return suite; }; /** * Defines a suite of tests within a method suite that should _do something_. * * @public * @param {string} msg - What this suite of tests should do. * @param {function} tests * @return {Suite} */ context.should = function(msg, tests) { /** @type {Suite} */ var suite; msg = 'should ' + msg.replace(/^(?: *should)? +/, ''); suite = Suite.create(suites[0], msg); suite.file = file; suite.should = true; suite.method = suite.parent.method; suites.unshift(suite); tests.call(suite); suites.shift(); return suite; }; /** * Defines a skipped suite of tests within a method suite that should * _do something_. * * @public * @param {string} msg - What this suite of tests should do. * @param {function} tests * @return {Suite} */ context.should.skip = function(msg, tests) { /** @type {Suite} */ var suite; msg = 'should ' + msg.replace(/^(?: *should)? +/, ''); suite = Suite.create(suites[0], msg); suite.pending = true; suite.should = true; suite.method = suite.parent.method; suites.unshift(suite); tests.call(suite); suites.shift(); return suite; }; /** * Defines the only not skipped suite of tests within a method suite that * should _do something_. * * @public * @param {string} msg - What this suite of tests should do. * @param {function} tests * @return {Suite} */ context.should.only = function(msg, tests) { /** @type {Suite} */ var suite; suite = context.should(msg, tests); mocha.grep( suite.fullTitle() ); return suite; }; /** * Defines a test. * * @public * @param {...*=} args - The arguments passed to the vitals method. * @param {function} tests * @return {Test} */ context.test = function(args, tests) { /** @type {Suite} */ var suite; /** @type {Test} */ var test; /** @type {string} */ var msg; args = sliceArr(arguments, 0, -1); tests = arguments[args.length]; suite = suites[0]; tests = suite.pending ? null : tests; msg = testCall(suite.method, args); test = new Test(msg, tests); test.file = file; suite.addTest(test); return test; }; /** * Defines a skipped test. * * @public * @param {...*=} args - The arguments passed to the vitals method. * @param {function} tests * @return {Test} */ context.test.skip = function(args, tests) { /** @type {Suite} */ var suite; /** @type {Test} */ var test; /** @type {string} */ var msg; args = sliceArr(arguments, 0, -1); tests = null; suite = suites[0]; msg = testCall(suite.method, args); test = new Test(msg, tests); test.file = file; suite.addTest(test); return test; }; /** * Defines the only not skipped test. * * @public * @param {...*=} args - The arguments passed to the vitals method. * @param {function} tests * @return {Test} */ context.test.only = function(args, tests) { /** @type {Suite} */ var suite; /** @type {Test} */ var test; /** @type {string} */ var msg; args = sliceArr(arguments, 0, -1); tests = arguments[args.length]; suite = suites[0]; tests = suite.pending ? null : tests; msg = testCall(suite.method, args); test = new Test(msg, tests); test.file = file; suite.addTest(test); mocha.grep( test.fullTitle() ); return test; }; /** * Defines a suite of tests. * * @public * @param {string} msg * @param {function} tests * @return {Suite} */ context.suite = function(msg, tests) { /** @type {Suite} */ var suite; suite = Suite.create(suites[0], msg); suite.file = file; suite.method = suite.parent.method; suites.unshift(suite); tests.call(suite); suites.shift(); return suite; }; /** * Defines a skipped suite of tests. * * @public * @param {string} msg * @param {function} tests * @return {Suite} */ context.suite.skip = function(msg, tests) { /** @type {Suite} */ var suite; suite = Suite.create(suites[0], msg); suite.pending = true; suite.method = suite.parent.method; suites.unshift(suite); tests.call(suite); suites.shift(); return suite; }; /** * Defines the only not skipped suite of tests. * * @public * @param {string} msg * @param {function} tests * @return {Suite} */ context.suite.only = function(msg, tests) { /** @type {Suite} */ var suite; suite = context.suite(msg, tests); mocha.grep( suite.fullTitle() ); return suite; }; /** * Execute before running tests. * * @public * @param {string} name * @param {function} fn */ context.before = function(name, fn) { suites[0].beforeAll(name, fn); }; /** * Execute after running tests. * * @public * @param {string} name * @param {function} fn */ context.after = function(name, fn) { suites[0].afterAll(name, fn); }; /** * Execute before each test case. * * @public * @param {string} name * @param {function} fn */ context.beforeEach = function(name, fn) { suites[0].beforeEach(name, fn); }; /** * Execute after each test case. * * @public * @param {string} name * @param {function} fn */ context.afterEach = function(name, fn) { suites[0].afterEach(name, fn); }; }); };