Squashed commit of the following: commit 606d572db561d8de659bce6ac96252f8a1d7ee29 Author: Oliver Gorwits <oliver@cpan.org> Date: Sat May 6 14:56:07 2017 +0100 tests should be release tests, so move to xt/ commit7673f3ee1eAuthor: Oliver Gorwits <oliver@cpan.org> Date: Sat May 6 14:19:19 2017 +0100 allow check_acl to accept Device or NetAddr::IP instance commitc31059bc01Author: Oliver Gorwits <oliver@cpan.org> Date: Sat May 6 14:19:00 2017 +0100 update docs commitdeaeab2670Author: Oliver Gorwits <oliver@cpan.org> Date: Sat May 6 14:18:27 2017 +0100 SNMP only stanza has access to full check_acl features commit4a44fa5863Author: Oliver Gorwits <oliver@cpan.org> Date: Mon May 1 18:49:38 2017 +0100 add AND operator and negation support to ACLs
379 lines
13 KiB
JavaScript
379 lines
13 KiB
JavaScript
/**
|
|
* QUnit-TAP - A TAP Output Producer Plugin for QUnit
|
|
*
|
|
* https://github.com/twada/qunit-tap
|
|
* version: 1.4.2
|
|
*
|
|
* Copyright (c) 2010-2014 Takuto Wada
|
|
* Dual licensed under the MIT and GPLv2 licenses.
|
|
* https://raw.github.com/twada/qunit-tap/master/MIT-LICENSE.txt
|
|
* https://raw.github.com/twada/qunit-tap/master/GPL-LICENSE.txt
|
|
*
|
|
* A part of extend function is:
|
|
* Copyright 2012 jQuery Foundation and other contributors
|
|
* Released under the MIT license.
|
|
* http://jquery.org/license
|
|
*
|
|
* A part of stripTags function is:
|
|
* Copyright (c) 2005-2010 Sam Stephenson
|
|
* Released under the MIT license.
|
|
* http://prototypejs.org
|
|
*/
|
|
(function (root, factory) {
|
|
'use strict';
|
|
|
|
// using returnExports UMD pattern
|
|
if (typeof define === 'function' && define.amd) {
|
|
define(factory);
|
|
} else if (typeof exports === 'object') {
|
|
module.exports = factory();
|
|
} else {
|
|
root.qunitTap = factory();
|
|
}
|
|
}(this, function () {
|
|
'use strict';
|
|
|
|
var qunitTapVersion = '1.4.2',
|
|
slice = Array.prototype.slice;
|
|
|
|
// borrowed from qunit.js
|
|
function extend (a, b) {
|
|
var prop;
|
|
for (prop in b) {
|
|
if (b.hasOwnProperty(prop)) {
|
|
if (typeof b[prop] === 'undefined') {
|
|
delete a[prop];
|
|
} else {
|
|
a[prop] = b[prop];
|
|
}
|
|
}
|
|
}
|
|
return a;
|
|
}
|
|
|
|
function indexOf (ary, element) {
|
|
var i;
|
|
for (i = 0; i < ary.length; i += 1) {
|
|
if (ary[i] === element) {
|
|
return i;
|
|
}
|
|
}
|
|
return -1;
|
|
}
|
|
|
|
function removeElement (ary, element) {
|
|
var index = indexOf(ary, element);
|
|
if (index !== -1) {
|
|
return ary.splice(index, 1);
|
|
} else {
|
|
return [];
|
|
}
|
|
}
|
|
|
|
function isPlanRequired (conf) {
|
|
return (typeof conf !== 'undefined' && typeof conf.requireExpects !== 'undefined' && conf.requireExpects);
|
|
}
|
|
|
|
function isPassed (details) {
|
|
return !!(details.result);
|
|
}
|
|
|
|
function isFailed (details) {
|
|
return !(isPassed(details));
|
|
}
|
|
|
|
function isAssertOkFailed (details) {
|
|
return isFailed(details) && typeof details.expected === 'undefined' && typeof details.actual === 'undefined';
|
|
}
|
|
|
|
// borrowed from prototype.js
|
|
// not required since QUnit.log receives raw data (details). see jquery/qunit@c2cde34
|
|
function stripTags (str) {
|
|
if (!str) {
|
|
return str;
|
|
}
|
|
return str.replace(/<\w+(\s+("[^"]*"|'[^']*'|[^>])+)?>|<\/\w+>/gi, '');
|
|
}
|
|
|
|
function escapeLineEndings (str) {
|
|
return str.replace(/(\r?\n)/g, '$&# ');
|
|
}
|
|
|
|
function ltrim (str) {
|
|
return str.replace(/^\s+/, '');
|
|
}
|
|
|
|
function noop (obj) {
|
|
return obj;
|
|
}
|
|
|
|
function render (desc, fieldName, fieldValue, formatter) {
|
|
desc.push(fieldName + ': ' + formatter(fieldValue));
|
|
}
|
|
|
|
function renderIf (shouldRender, desc, fieldName, fieldValue, formatter) {
|
|
if (!shouldRender || typeof fieldValue === 'undefined') {
|
|
return;
|
|
}
|
|
render(desc, fieldName, fieldValue, formatter);
|
|
}
|
|
|
|
function formatTestLine (testLine, rest) {
|
|
if (!rest) {
|
|
return testLine;
|
|
}
|
|
return testLine + ' - ' + escapeLineEndings(rest);
|
|
}
|
|
|
|
var extractDetailsFrom = (function () {
|
|
var detailsExtractor;
|
|
|
|
function setupExtractor (logArguments) {
|
|
switch (logArguments.length) {
|
|
case 1: // details
|
|
detailsExtractor = function (args) { return args[0]; };
|
|
break;
|
|
case 2: // result, message(with tags)
|
|
detailsExtractor = function (args) { return {result: args[0], message: stripTags(args[1])}; };
|
|
break;
|
|
case 3: // result, message, details
|
|
detailsExtractor = function (args) { return args[2]; };
|
|
break;
|
|
default:
|
|
throw new Error('QUnit-TAP does not support QUnit#log arguments like this.');
|
|
}
|
|
}
|
|
|
|
return function (logArguments) {
|
|
if (detailsExtractor) {
|
|
return detailsExtractor(logArguments);
|
|
}
|
|
setupExtractor(logArguments);
|
|
return detailsExtractor(logArguments);
|
|
};
|
|
})();
|
|
|
|
var createCallbackAppenderFor = function (qu) {
|
|
// detect QUnit's multipleCallbacks feature. see jquery/qunit@34f6bc1
|
|
var isMultipleLoggingCallbacksSupported =
|
|
(typeof qu.config !== 'undefined' &&
|
|
typeof qu.config.log !== 'undefined' &&
|
|
typeof qu.config.done !== 'undefined' &&
|
|
typeof qu.config.testDone !== 'undefined' &&
|
|
typeof qu.config.moduleStart !== 'undefined' &&
|
|
typeof qu.config.testStart !== 'undefined');
|
|
return function (subject, observer, event) {
|
|
var originalLoggingCallback = subject[event],
|
|
callback;
|
|
if (isMultipleLoggingCallbacksSupported) {
|
|
callback = function () {
|
|
// make listener methods (moduleStart,testStart,log, ...) overridable.
|
|
observer[event].apply(observer, slice.apply(arguments));
|
|
};
|
|
originalLoggingCallback(callback);
|
|
} else if (typeof originalLoggingCallback === 'function') {
|
|
// do not overwrite old-style logging callbacks
|
|
callback = function () {
|
|
var args = slice.apply(arguments);
|
|
originalLoggingCallback.apply(subject, args);
|
|
observer[event].apply(observer, args);
|
|
};
|
|
subject[event] = callback;
|
|
}
|
|
return callback;
|
|
};
|
|
};
|
|
|
|
|
|
/**
|
|
* QUnit-TAP - A TAP Output Producer Plugin for QUnit
|
|
* @param qunitObject QUnit object reference.
|
|
* @param printLikeFunction print-like function for TAP output (assumes line-separator is added by this function for each call).
|
|
* @param options configuration options to customize default behavior.
|
|
* @return object to provide QUnit-TAP API and customization subject.
|
|
*/
|
|
function qunitTap(qunitObject, printLikeFunction, options) {
|
|
if (!qunitObject) {
|
|
throw new Error('should pass QUnit object reference. Please check QUnit\'s "require" path if you are using Node.js (or any CommonJS env).');
|
|
} else if (typeof printLikeFunction !== 'function') {
|
|
throw new Error('should pass print-like function');
|
|
}
|
|
|
|
var qu = qunitObject,
|
|
tap = {},
|
|
jsDumpExists = (typeof qu.jsDump !== 'undefined' && typeof qu.jsDump.parse === 'function'),
|
|
explain = (jsDumpExists ? function explain (obj) { return qu.jsDump.parse(obj); } : noop),
|
|
deprecateOption = function deprecateOption (optionName, fallback) {
|
|
// option deprecation and fallback function
|
|
if (!options || typeof options !== 'object') {
|
|
return;
|
|
}
|
|
if (typeof options[optionName] === 'undefined') {
|
|
return;
|
|
}
|
|
printLikeFunction('# WARNING: Option "' + optionName + '" is deprecated and will be removed in future version.');
|
|
fallback(options[optionName]);
|
|
},
|
|
targetEvents = [
|
|
'moduleStart',
|
|
'testStart',
|
|
'log',
|
|
'testDone',
|
|
'done'
|
|
],
|
|
registeredCallbacks = {};
|
|
|
|
|
|
tap.config = extend(
|
|
{
|
|
initialCount: 1,
|
|
showModuleNameOnFailure: true,
|
|
showTestNameOnFailure: true,
|
|
showExpectationOnFailure: true,
|
|
showSourceOnFailure: true
|
|
},
|
|
options
|
|
);
|
|
deprecateOption('noPlan', function (flag) {
|
|
printLikeFunction('# Now QUnit-TAP works as with "noPlan: true" by default. If you want to delare plan explicitly, please use "QUnit.config.requireExpects" option instead.');
|
|
tap.config.noPlan = flag;
|
|
});
|
|
deprecateOption('count', function (count) {
|
|
tap.config.initialCount = (count + 1);
|
|
});
|
|
deprecateOption('showDetailsOnFailure', function (flag) {
|
|
tap.config.showModuleNameOnFailure = flag;
|
|
tap.config.showTestNameOnFailure = flag;
|
|
tap.config.showExpectationOnFailure = flag;
|
|
tap.config.showSourceOnFailure = flag;
|
|
});
|
|
tap.VERSION = qunitTapVersion;
|
|
tap.puts = printLikeFunction;
|
|
tap.count = tap.config.initialCount - 1;
|
|
tap.expectedCount = tap.config.initialCount - 1;
|
|
|
|
function isEnabled (configName) {
|
|
return tap.config[configName];
|
|
}
|
|
|
|
function formatDetails (details) {
|
|
if (isPassed(details)) {
|
|
return details.message;
|
|
}
|
|
var desc = [];
|
|
if (details.message) {
|
|
desc.push(details.message);
|
|
}
|
|
if (isEnabled('showExpectationOnFailure') && !(isAssertOkFailed(details))) {
|
|
render(desc, 'expected', details.expected, explain);
|
|
render(desc, 'got', details.actual, explain);
|
|
}
|
|
renderIf(isEnabled('showTestNameOnFailure'), desc, 'test', details.name, noop);
|
|
renderIf(isEnabled('showModuleNameOnFailure'), desc, 'module', details.module, noop);
|
|
renderIf(isEnabled('showSourceOnFailure'), desc, 'source', details.source, ltrim);
|
|
return desc.join(', ');
|
|
}
|
|
|
|
function printPlanLine (toCount) {
|
|
tap.puts(tap.config.initialCount + '..' + toCount);
|
|
}
|
|
|
|
function unsubscribeEvent (eventName) {
|
|
var listeners;
|
|
if (indexOf(targetEvents, eventName) === -1) {
|
|
return;
|
|
}
|
|
listeners = qu.config[eventName];
|
|
if (typeof listeners === 'undefined') {
|
|
return;
|
|
}
|
|
removeElement(listeners, registeredCallbacks[eventName]);
|
|
}
|
|
|
|
function unsubscribeEvents (eventNames) {
|
|
var i;
|
|
for (i = 0; i < eventNames.length; i += 1) {
|
|
unsubscribeEvent(eventNames[i]);
|
|
}
|
|
}
|
|
|
|
tap.explain = explain;
|
|
|
|
tap.note = function note (obj) {
|
|
tap.puts(escapeLineEndings('# ' + obj));
|
|
};
|
|
|
|
tap.diag = function diag (obj) {
|
|
tap.note(obj);
|
|
return false;
|
|
};
|
|
|
|
tap.moduleStart = function moduleStart (arg) {
|
|
var name = (typeof arg === 'string') ? arg : arg.name;
|
|
tap.note('module: ' + name);
|
|
};
|
|
|
|
tap.testStart = function testStart (arg) {
|
|
var name = (typeof arg === 'string') ? arg : arg.name;
|
|
tap.note('test: ' + name);
|
|
};
|
|
|
|
tap.log = function log () {
|
|
var details = extractDetailsFrom(arguments),
|
|
testLine = '';
|
|
tap.count += 1;
|
|
if (isFailed(details)) {
|
|
testLine += 'not ';
|
|
}
|
|
testLine += ('ok ' + tap.count);
|
|
tap.puts(formatTestLine(testLine, formatDetails(details)));
|
|
};
|
|
|
|
tap.testDone = function testDone () {
|
|
if (isPlanRequired(qu.config)) {
|
|
tap.expectedCount += qu.config.current.expected;
|
|
}
|
|
};
|
|
|
|
tap.done = function done () {
|
|
if (typeof tap.config.noPlan !== 'undefined' && !(tap.config.noPlan)) {
|
|
// Do nothing until removal of 'noPlan' option.
|
|
} else if (isPlanRequired(qu.config)) {
|
|
printPlanLine(tap.expectedCount);
|
|
} else {
|
|
printPlanLine(tap.count);
|
|
}
|
|
};
|
|
|
|
tap.unsubscribe = function unsubscribe () {
|
|
if (typeof qu.config === 'undefined') {
|
|
return;
|
|
}
|
|
if (arguments.length === 0) {
|
|
unsubscribeEvents(targetEvents);
|
|
} else {
|
|
unsubscribeEvents(slice.apply(arguments));
|
|
}
|
|
};
|
|
|
|
(function () {
|
|
var appendCallback = createCallbackAppenderFor(qu),
|
|
eventName, i, callback;
|
|
for (i = 0; i < targetEvents.length; i += 1) {
|
|
eventName = targetEvents[i];
|
|
callback = appendCallback(qu, tap, eventName);
|
|
registeredCallbacks[eventName] = callback;
|
|
}
|
|
})();
|
|
|
|
return tap;
|
|
}
|
|
|
|
qunitTap.qunitTap = function () {
|
|
throw new Error('[BC BREAK] Since 1.4.0, QUnit-TAP exports single qunitTap function as module.exports. Therefore, require("qunit-tap") returns qunitTap function itself. Please fix your code if you are using Node.js (or any CommonJS env).');
|
|
};
|
|
|
|
// using substack pattern (export single function)
|
|
return qunitTap;
|
|
}));
|