function Dredd(config) {
this.init(config);
}n/a
function DreddCommand(options, cb) {
if (options == null) {
options = {};
}
this.cb = cb;
this.finished = false;
this.exit = options.exit, this.custom = options.custom;
this.setExitOrCallback();
if (this.custom == null) {
this.custom = {};
}
if (!this.custom.cwd || typeof this.custom.cwd !== 'string') {
this.custom.cwd = process.cwd();
}
if (!this.custom.argv || !Array.isArray(this.custom.argv)) {
this.custom.argv = [];
}
}n/a
function Hooks(options) {
if (options == null) {
options = {};
}
this.dumpHooksFunctionsToStrings = bind(this.dumpHooksFunctionsToStrings, this);
this.log = bind(this.log, this);
this.afterEach = bind(this.afterEach, this);
this.beforeEachValidation = bind(this.beforeEachValidation, this);
this.beforeEach = bind(this.beforeEach, this);
this.afterAll = bind(this.afterAll, this);
this.beforeAll = bind(this.beforeAll, this);
this.after = bind(this.after, this);
this.beforeValidation = bind(this.beforeValidation, this);
this.before = bind(this.before, this);
this.logs = options.logs, this.logger = options.logger;
this.transactions = {};
this.beforeHooks = {};
this.beforeValidationHooks = {};
this.afterHooks = {};
this.beforeAllHooks = [];
this.afterAllHooks = [];
this.beforeEachHooks = [];
this.beforeEachValidationHooks = [];
this.afterEachHooks = [];
}n/a
function HooksWorkerClient(runner) {
var options;
this.runner = runner;
options = this.runner.hooks.configuration.options;
this.language = options.language;
this.timeout = options['hooks-worker-timeout'] || 5000;
this.connectTimeout = options['hooks-worker-connect-timeout'] || 1500;
this.connectRetry = options['hooks-worker-connect-retry'] || 500;
this.afterConnectWait = options['hooks-worker-after-connect-wait'] || 100;
this.termTimeout = options['hooks-worker-term-timeout'] || 5000;
this.termRetry = options['hooks-worker-term-retry'] || 500;
this.handlerHost = options['hooks-worker-handler-host'] || '127.0.0.1';
this.handlerPort = options['hooks-worker-handler-port'] || 61321;
this.handlerMessageDelimiter = '\n';
this.clientConnected = false;
this.connectError = false;
this.emitter = new EventEmitter;
}n/a
function TransactionRunner(configuration1) {
this.configuration = configuration1;
this.executeTransaction = bind(this.executeTransaction, this);
this.configureTransaction = bind(this.configureTransaction, this);
this.logs = [];
this.hookStash = {};
this.error = null;
this.hookHandlerError = null;
}n/a
characterIndexToPosition = function (charIndex, code) {
var codeFragment, ref, row;
if (charIndex == null) {
charIndex = 0;
}
if (code == null) {
code = '';
}
codeFragment = code.substring(0, charIndex);
row = (((ref = codeFragment.match(NEWLINE_RE)) != null ? ref.length : void 0) || 0) + 1;
return {
row: row
};
}n/a
rangesToLinesText = function (ranges) {
var i, len, pos, range, rangeIndex, ref;
pos = '';
ref = ranges || [];
for (rangeIndex = i = 0, len = ref.length; i < len; rangeIndex = ++i) {
range = ref[rangeIndex];
if (rangeIndex > 0) {
pos += ', ';
}
if (range.start !== range.end) {
pos += "lines " + range.start + "-" + range.end;
} else {
pos += "line " + range.start;
}
}
return pos;
}...
error = true;
log = logger.error;
}
if (annotation.component === 'apiDescriptionParser') {
ranges = blueprintUtils.warningLocationToRanges(annotation.location, apiDescriptionDocument);
message = "Parser " + annotation.type + " in file '" + filename + "': (" + annotation
.type + " code " + annotation.code + ") " + annotation.message + " ";
if (ranges != null ? ranges.length : void 0) {
message += "on " + (blueprintUtils.rangesToLinesText(ranges));
}
log(message);
} else {
transactionName = [annotation.origin.resourceGroupName, annotation.origin.resourceName, annotation.origin.actionName].join(
x27; > ');
log("Compilation " + annotation.type + " in file '" + filename + "': " + annotation.
message + " (" + transactionName + ") ");
}
}
...sortNumbersAscending = function (a, b) {
return a - b;
}n/a
warningLocationToRanges = function (warningLocation, text) {
var i, j, lastLocation, len, len1, loc, locKey, position, range, ranges, rowIndex, rowsIndexes;
if (warningLocation == null) {
warningLocation = [];
}
if (text == null) {
text = '';
}
if (!warningLocation.length) {
return [];
}
rowsIndexes = [];
position = characterIndexToPosition(warningLocation[0][0], text);
rowsIndexes.push(position.row);
lastLocation = warningLocation[warningLocation.length - 1];
if (warningLocation.length > 0) {
for (locKey = i = 0, len = warningLocation.length; i < len; locKey = ++i) {
loc = warningLocation[locKey];
if (!(locKey > 0)) {
continue;
}
position = characterIndexToPosition(loc[0], text);
rowsIndexes.push(position.row);
}
}
rowsIndexes.sort(sortNumbersAscending);
ranges = [];
range = {
start: rowsIndexes[0],
end: rowsIndexes[0]
};
for (j = 0, len1 = rowsIndexes.length; j < len1; j++) {
rowIndex = rowsIndexes[j];
if (rowIndex === range.end || rowIndex === range.end + 1) {
range.end = rowIndex;
} else {
ranges.push(range);
range = {
start: rowIndex,
end: rowIndex
};
}
}
ranges.push(range);
return ranges;
}...
if (annotation.type === 'warning') {
log = logger.warn;
} else {
error = true;
log = logger.error;
}
if (annotation.component === 'apiDescriptionParser') {
ranges = blueprintUtils.warningLocationToRanges(annotation.location, apiDescriptionDocument
);
message = "Parser " + annotation.type + " in file '" + filename + "': (" + annotation.
type + " code " + annotation.code + ") " + annotation.message + " ";
if (ranges != null ? ranges.length : void 0) {
message += "on " + (blueprintUtils.rangesToLinesText(ranges));
}
log(message);
} else {
transactionName = [annotation.origin.resourceGroupName, annotation.origin.resourceName, annotation.origin.actionName].join('
; > ');
...signalKill = function (childProcess, callback) {
var taskkill;
childProcess.emit('signalKill');
if (IS_WINDOWS) {
taskkill = spawn('taskkill', ['/F', '/T', '/PID', childProcess.pid]);
return taskkill.on('exit', function(exitStatus) {
var err;
if (exitStatus) {
err = new Error("Unable to forcefully terminate process " + childProcess.pid);
return callback(err);
}
return callback();
});
} else {
childProcess.kill('SIGKILL');
return process.nextTick(callback);
}
}...
return function(exitStatus) {
logger.verbose("Exiting Dredd process with status '" + exitStatus + "'.");
logger.debug('Using configured custom callback to terminate the Dredd process.');
_this.finished = true;
if (_this.sigIntEventAdded) {
if ((_this.serverProcess != null) && !_this.serverProcess.terminated) {
logger.verbose('Killing backend server process before Dredd exits.');
_this.serverProcess.signalKill();
}
process.removeEventListener('SIGINT', _this.commandSigInt);
}
_this.cb(exitStatus);
return _this;
};
})(this);
...signalTerm = function (childProcess, callback) {
childProcess.emit('signalTerm');
if (IS_WINDOWS) {
childProcess.stdin.write(String.fromCharCode(ASCII_CTRL_C));
} else {
childProcess.kill('SIGTERM');
}
return process.nextTick(callback);
}n/a
spawn = function () {
var args, childProcess, killedIntentionally, terminatedIntentionally;
args = 1 <= arguments.length ? slice.call(arguments, 0) : [];
childProcess = crossSpawn.spawn.apply(null, args);
childProcess.terminated = false;
killedIntentionally = false;
terminatedIntentionally = false;
childProcess.on('signalKill', function() {
return killedIntentionally = true;
});
childProcess.on('signalTerm', function() {
return terminatedIntentionally = true;
});
childProcess.signalKill = function() {
return signalKill(childProcess, function(err) {
if (err) {
return childProcess.emit('error', err);
}
});
};
childProcess.signalTerm = function() {
return signalTerm(childProcess, function(err) {
if (err) {
return childProcess.emit('error', err);
}
});
};
childProcess.terminate = function(options) {
return terminate(childProcess, options, function(err) {
if (err) {
return childProcess.emit('error', err);
}
});
};
childProcess.on('exit', function(exitStatus, signal) {
childProcess.terminated = true;
childProcess.killedIntentionally = killedIntentionally;
childProcess.terminatedIntentionally = terminatedIntentionally;
if (!killedIntentionally && !terminatedIntentionally) {
if (signal === 'SIGKILL') {
return childProcess.emit('crash', null, true);
} else if (exitStatus !== 0) {
return childProcess.emit('crash', exitStatus, false);
}
}
});
return childProcess;
}n/a
terminate = function (childProcess, options, callback) {
var check, force, onExit, ref, retryDelay, start, t, terminated, timeout;
if (options == null) {
options = {};
}
if (typeof options === 'function') {
ref = [options, {}], callback = ref[0], options = ref[1];
}
force = options.force || false;
timeout = options.timeout != null ? options.timeout : TERM_DEFAULT_TIMEOUT_MS;
retryDelay = options.retryDelay != null ? options.retryDelay : TERM_DEFAULT_RETRY_MS;
terminated = false;
onExit = function() {
terminated = true;
return childProcess.removeListener('exit', onExit);
};
childProcess.on('exit', onExit);
start = Date.now();
t = void 0;
check = function() {
if (terminated) {
clearTimeout(t);
return callback();
} else {
if ((Date.now() - start) < timeout) {
return signalTerm(childProcess, function(err) {
if (err) {
return callback(err);
}
return t = setTimeout(check, retryDelay);
});
} else {
clearTimeout(t);
if (force) {
return signalKill(childProcess, callback);
} else {
return callback(new Error("Unable to gracefully terminate process " + childProcess.pid));
}
}
}
};
return signalTerm(childProcess, function(err) {
if (err) {
return callback(err);
}
return t = setTimeout(check, TERM_FIRST_CHECK_TIMEOUT_MS);
});
}...
return callback();
}
if (this.serverProcess.terminated) {
logger.debug('The backend server process has already terminated');
return callback();
}
logger.verbose('Terminating backend server process, PID', this.serverProcess.pid);
this.serverProcess.terminate({
force: true
});
return this.serverProcess.on('exit', function() {
return callback();
});
};
...load = function (path) {
var data, yamlData;
if (path == null) {
path = './dredd.yml';
}
yamlData = fs.readFileSync(path);
data = yaml.safeLoad(yamlData);
data['_'] = [data['blueprint'], data['endpoint']];
delete data['blueprint'];
delete data['endpoint'];
return data;
}...
DreddCommand.prototype.loadDreddFile = function() {
var configPath, key, ref, value;
configPath = this.argv.config;
logger.verbose('Loading configuration file:', configPath);
if (configPath && fs.existsSync(configPath)) {
logger.info("Configuration '" + configPath + "' found, ignoring other arguments.");
this.argv = configUtils.load(configPath);
}
ref = this.cliArgv;
for (key in ref) {
value = ref[key];
if (key !== "_" && key !== "$0") {
this.argv[key] = value;
}
...parseCustom = function (customArray) {
var i, len, output, splitted, string;
output = {};
if (Array.isArray(customArray)) {
for (i = 0, len = customArray.length; i < len; i++) {
string = customArray[i];
splitted = string.split(/:(.+)?/);
output[splitted[0]] = splitted[1];
}
}
return output;
}...
this.argv[key] = value;
}
}
return this.argv = applyLoggingOptions(this.argv);
};
DreddCommand.prototype.parseCustomConfig = function() {
return this.argv.custom = configUtils.parseCustom(this.argv.custom);
};
DreddCommand.prototype.runServerAndThenDredd = function(callback) {
var command, parsedArgs, waitMilis, waitSecs;
if (this.argv['server'] == null) {
logger.verbose('No backend server process specified, starting testing at once');
return this.runDredd(this.dreddInstance);
...save = function (argsOrigin, path) {
var args, key, value, yamlArgs;
if (path == null) {
path = './dredd.yml';
}
args = clone(argsOrigin);
args['blueprint'] = args['_'][0];
args['endpoint'] = args['_'][1];
for (key in args) {
value = args[key];
if (key.length === 1) {
delete args[key];
}
}
delete args['$0'];
delete args['_'];
yamlArgs = yaml.dump(args);
return fs.writeFileSync(path, yamlArgs);
}...
DreddCommand.prototype.runExitingActions = function() {
if (this.argv["_"][0] === "init" || this.argv.init === true) {
logger.silly('Starting interactive configuration.');
this.finished = true;
return interactiveConfig.run(this.argv, (function(_this) {
return function(config) {
configUtils.save(config);
console.log("");
console.log("Configuration saved to dredd.yml");
console.log("");
if (config['language'] === "nodejs") {
console.log("Run test now, with:");
} else {
console.log("Install hooks handler and run Dredd test with:");
...applyConfiguration = function (config) {
var authHeader, configuration, customKey, customVal, key, method, ref, value;
configuration = {
blueprintPath: null,
server: null,
emitter: new EventEmitter,
hooksCode: null,
custom: {},
options: {
'dry-run': false,
silent: false,
reporter: null,
output: null,
debug: false,
header: null,
user: null,
'inline-errors': false,
details: false,
method: [],
only: [],
color: true,
level: 'info',
timestamp: false,
sorted: false,
names: false,
hookfiles: null,
sandbox: false,
language: 'nodejs',
'hooks-worker-timeout': 5000,
'hooks-worker-connect-timeout': 1500,
'hooks-worker-connect-retry': 500,
'hooks-worker-after-connect-wait': 100,
'hooks-worker-term-timeout': 5000,
'hooks-worker-term-retry': 500,
'hooks-worker-handler-host': '127.0.0.1',
'hooks-worker-handler-port': 61321
}
};
for (key in config) {
if (!hasProp.call(config, key)) continue;
value = config[key];
if (key !== 'custom') {
configuration[key] = value;
} else {
if (configuration['custom'] == null) {
configuration['custom'] = {};
}
ref = config['custom'] || {};
for (customKey in ref) {
if (!hasProp.call(ref, customKey)) continue;
customVal = ref[customKey];
configuration['custom'][customKey] = clone(customVal, false);
}
}
}
configuration.options.reporter = coerceToArray(configuration.options.reporter);
configuration.options.output = coerceToArray(configuration.options.output);
configuration.options.header = coerceToArray(configuration.options.header);
configuration.options.method = coerceToArray(configuration.options.method);
configuration.options.only = coerceToArray(configuration.options.only);
configuration.options.path = coerceToArray(configuration.options.path);
if (config.blueprintPath) {
configuration.options.path.push(config.blueprintPath);
}
configuration.options.method = (function() {
var i, len, ref1, results;
ref1 = configuration.options.method;
results = [];
for (i = 0, len = ref1.length; i < len; i++) {
method = ref1[i];
results.push(method.toUpperCase());
}
return results;
})();
if (configuration.options.user != null) {
authHeader = 'Authorization:Basic ' + new Buffer(configuration.options.user).toString('base64');
configuration.options.header.push(authHeader);
}
configuration.options = applyLoggingOptions(configuration.options);
return configuration;
}n/a
applyLoggingOptions = function (options) {
if (options.color === 'false') {
options.color = false;
} else if (options.color === 'true') {
options.color = true;
}
logger.transports.console.colorize = options.color;
logger.transports.console.silent = options.silent;
logger.transports.console.timestamp = options.timestamp;
logger.transports.console.level = options.level;
return options;
}n/a
function DreddCommand(options, cb) {
if (options == null) {
options = {};
}
this.cb = cb;
this.finished = false;
this.exit = options.exit, this.custom = options.custom;
this.setExitOrCallback();
if (this.custom == null) {
this.custom = {};
}
if (!this.custom.cwd || typeof this.custom.cwd !== 'string') {
this.custom.cwd = process.cwd();
}
if (!this.custom.argv || !Array.isArray(this.custom.argv)) {
this.custom.argv = [];
}
}n/a
checkRequiredArgs = function () {
var argError;
argError = false;
if (this.argv._[0] == null) {
console.error("\nError: Must specify path to API description document.");
argError = true;
}
if (this.argv._[1] == null) {
console.error("\nError: Must specify URL of the tested API instance.");
argError = true;
}
if (argError) {
console.error("\n");
this.optimist.showHelp(console.error);
return this._processExit(1);
}
}n/a
commandSigInt = function () {
logger.error('\nShutting down from keyboard interruption (Ctrl+C)');
return this.dreddInstance.transactionsComplete((function(_this) {
return function() {
return _this._processExit(0);
};
})(this));
}n/a
exitWithStatus = function (error, stats) {
if (error) {
if (error.message) {
logger.error(error.message);
}
return this._processExit(1);
}
if ((stats.failures + stats.errors) > 0) {
this._processExit(1);
} else {
this._processExit(0);
}
}...
this.sigIntEventAdded = !(this.sigIntEventAdd = false);
process.on('SIGINT', this.commandSigInt);
}
logger.verbose('Running Dredd instance.');
dreddInstance.run((function(_this) {
return function(error, stats) {
logger.verbose('Dredd instance run finished.');
return _this.exitWithStatus(error, stats);
};
})(this));
return this;
};
DreddCommand.prototype.exitWithStatus = function(error, stats) {
if (error) {
...initConfig = function () {
var base, configuration;
this.lastArgvIsApiEndpoint().takeRestOfParamsAsPath();
configuration = {
'server': this.server,
'options': this.argv
};
if ((base = configuration.options).path == null) {
base.path = [];
}
configuration.options.path.push(this.argv._[0]);
configuration.custom = this.custom;
return configuration;
}...
for (i = 0, len = ref.length; i < len; i++) {
task = ref[i];
task.call(this);
if (this.finished) {
return;
}
}
configurationForDredd = this.initConfig();
this.logDebuggingInfo(configurationForDredd);
this.dreddInstance = this.initDredd(configurationForDredd);
try {
this.runServerAndThenDredd();
} catch (error1) {
e = error1;
logger.error(e.message, e.stack);
...initDredd = function (configuration) {
return new Dredd(configuration);
}...
task.call(this);
if (this.finished) {
return;
}
}
configurationForDredd = this.initConfig();
this.logDebuggingInfo(configurationForDredd);
this.dreddInstance = this.initDredd(configurationForDredd);
try {
this.runServerAndThenDredd();
} catch (error1) {
e = error1;
logger.error(e.message, e.stack);
this.stopServer((function(_this) {
return function() {
...lastArgvIsApiEndpoint = function () {
this.server = this.argv._[this.argv._.length - 1];
this.argv._.splice(this.argv._.length - 1, 1);
return this;
}...
DreddCommand.prototype.takeRestOfParamsAsPath = function() {
this.argv['p'] = this.argv['path'] = this.argv['path'].concat(this.argv._);
return this;
};
DreddCommand.prototype.initConfig = function() {
var base, configuration;
this.lastArgvIsApiEndpoint().takeRestOfParamsAsPath();
configuration = {
'server': this.server,
'options': this.argv
};
if ((base = configuration.options).path == null) {
base.path = [];
}
...loadDreddFile = function () {
var configPath, key, ref, value;
configPath = this.argv.config;
logger.verbose('Loading configuration file:', configPath);
if (configPath && fs.existsSync(configPath)) {
logger.info("Configuration '" + configPath + "' found, ignoring other arguments.");
this.argv = configUtils.load(configPath);
}
ref = this.cliArgv;
for (key in ref) {
value = ref[key];
if (key !== "_" && key !== "$0") {
this.argv[key] = value;
}
}
return this.argv = applyLoggingOptions(this.argv);
}n/a
logDebuggingInfo = function (config) {
var err, npmVersion;
logger.debug('Dredd version:', packageData.version);
logger.debug('Node.js version:', process.version);
logger.debug('Node.js environment:', process.versions);
logger.debug('System version:', os.type(), os.release(), os.arch());
try {
npmVersion = spawnSync('npm', ['--version']).stdout.toString().trim();
logger.debug('npm version:', npmVersion || 'unable to determine npm version');
} catch (error1) {
err = error1;
logger.debug('npm version: unable to determine npm version:', err);
}
return logger.debug('Configuration:', JSON.stringify(config));
}...
task = ref[i];
task.call(this);
if (this.finished) {
return;
}
}
configurationForDredd = this.initConfig();
this.logDebuggingInfo(configurationForDredd);
this.dreddInstance = this.initDredd(configurationForDredd);
try {
this.runServerAndThenDredd();
} catch (error1) {
e = error1;
logger.error(e.message, e.stack);
this.stopServer((function(_this) {
...moveBlueprintArgToPath = function () {
if (!Array.isArray(this.argv['path'])) {
return this.argv['path'] = this.argv['p'] = [this.argv['path']];
}
}n/a
parseCustomConfig = function () {
return this.argv.custom = configUtils.parseCustom(this.argv.custom);
}n/a
run = function () {
var configurationForDredd, e, i, len, ref, task;
ref = [this.setOptimistArgv, this.parseCustomConfig, this.runExitingActions, this.loadDreddFile, this.checkRequiredArgs, this.
moveBlueprintArgToPath];
for (i = 0, len = ref.length; i < len; i++) {
task = ref[i];
task.call(this);
if (this.finished) {
return;
}
}
configurationForDredd = this.initConfig();
this.logDebuggingInfo(configurationForDredd);
this.dreddInstance = this.initDredd(configurationForDredd);
try {
this.runServerAndThenDredd();
} catch (error1) {
e = error1;
logger.error(e.message, e.stack);
this.stopServer((function(_this) {
return function() {
return _this._processExit(2);
};
})(this));
}
}...
}
};
DreddCommand.prototype.runExitingActions = function() {
if (this.argv["_"][0] === "init" || this.argv.init === true) {
logger.silly('Starting interactive configuration.');
this.finished = true;
return interactiveConfig.run(this.argv, (function(_this) {
return function(config) {
configUtils.save(config);
console.log("");
console.log("Configuration saved to dredd.yml");
console.log("");
if (config['language'] === "nodejs") {
console.log("Run test now, with:");
...runDredd = function (dreddInstance) {
if (this.sigIntEventAdd) {
this.sigIntEventAdded = !(this.sigIntEventAdd = false);
process.on('SIGINT', this.commandSigInt);
}
logger.verbose('Running Dredd instance.');
dreddInstance.run((function(_this) {
return function(error, stats) {
logger.verbose('Dredd instance run finished.');
return _this.exitWithStatus(error, stats);
};
})(this));
return this;
}...
return this.argv.custom = configUtils.parseCustom(this.argv.custom);
};
DreddCommand.prototype.runServerAndThenDredd = function(callback) {
var command, parsedArgs, waitMilis, waitSecs;
if (this.argv['server'] == null) {
logger.verbose('No backend server process specified, starting testing at once');
return this.runDredd(this.dreddInstance);
} else {
logger.verbose('Backend server process specified, starting backend server and then testing');
parsedArgs = spawnArgs(this.argv['server']);
command = parsedArgs.shift();
logger.verbose("Using '" + command + "' as a server command, " + (JSON.stringify(parsedArgs)) +
x22; as arguments");
this.serverProcess = spawn(command, parsedArgs);
logger.info("Starting backend server process with command: " + this.argv['server']);
...runExitingActions = function () {
if (this.argv["_"][0] === "init" || this.argv.init === true) {
logger.silly('Starting interactive configuration.');
this.finished = true;
return interactiveConfig.run(this.argv, (function(_this) {
return function(config) {
configUtils.save(config);
console.log("");
console.log("Configuration saved to dredd.yml");
console.log("");
if (config['language'] === "nodejs") {
console.log("Run test now, with:");
} else {
console.log("Install hooks handler and run Dredd test with:");
}
console.log("");
if (config['language'] === 'ruby') {
console.log(" $ gem install dredd_hooks");
} else if (config['language'] === 'python') {
console.log(" $ pip install dredd_hooks");
} else if (config['language'] === 'php') {
console.log(" $ composer require ddelnano/dredd-hooks-php --dev");
} else if (config['language'] === 'perl') {
console.log(" $ cpanm Dredd::Hooks");
} else if (config['language'] === 'go') {
console.log(" $ go get github.com/snikch/goodman/cmd/goodman");
}
console.log(" $ dredd");
console.log("");
return _this._processExit(0);
};
})(this));
} else if (this.argv.help === true) {
logger.silly('Printing help.');
this.optimist.showHelp(console.error);
return this._processExit(0);
} else if (this.argv.version === true) {
logger.silly('Printing version.');
console.log(packageData.name + " v" + packageData.version + " (" + (os.type()) + " " + (os.release()) + "; " + (os.arch()) + ")");
return this._processExit(0);
}
}n/a
runServerAndThenDredd = function (callback) {
var command, parsedArgs, waitMilis, waitSecs;
if (this.argv['server'] == null) {
logger.verbose('No backend server process specified, starting testing at once');
return this.runDredd(this.dreddInstance);
} else {
logger.verbose('Backend server process specified, starting backend server and then testing');
parsedArgs = spawnArgs(this.argv['server']);
command = parsedArgs.shift();
logger.verbose("Using '" + command + "' as a server command, " + (JSON.stringify(parsedArgs)) + " as arguments");
this.serverProcess = spawn(command, parsedArgs);
logger.info("Starting backend server process with command: " + this.argv['server']);
this.serverProcess.stdout.setEncoding('utf8');
this.serverProcess.stdout.on('data', function(data) {
return process.stdout.write(data.toString());
});
this.serverProcess.stderr.setEncoding('utf8');
this.serverProcess.stderr.on('data', function(data) {
return process.stdout.write(data.toString());
});
this.serverProcess.on('signalTerm', function() {
return logger.verbose('Gracefully terminating the backend server process');
});
this.serverProcess.on('signalKill', function() {
return logger.verbose('Killing the backend server process');
});
this.serverProcess.on('crash', (function(_this) {
return function(exitStatus, killed) {
if (killed) {
return logger.info('Backend server process was killed');
}
};
})(this));
this.serverProcess.on('exit', (function(_this) {
return function() {
return logger.info('Backend server process exited');
};
})(this));
this.serverProcess.on('error', (function(_this) {
return function(error) {
logger.error('Command to start backend server process failed, exiting Dredd', error);
return _this._processExit(2);
};
})(this));
process.on('beforeExit', (function(_this) {
return function() {
if ((_this.serverProcess != null) && !_this.serverProcess.terminated) {
logger.verbose('Killing backend server process before Dredd exits');
return _this.serverProcess.signalKill();
}
};
})(this));
process.on('exit', (function(_this) {
return function() {
if ((_this.serverProcess != null) && !_this.serverProcess.terminated) {
logger.verbose('Killing backend server process on Dredd\'s exit');
return _this.serverProcess.signalKill();
}
};
})(this));
waitSecs = parseInt(this.argv['server-wait'], 10);
waitMilis = waitSecs * 1000;
logger.info("Waiting " + waitSecs + " seconds for backend server process to start");
return this.wait = setTimeout((function(_this) {
return function() {
return _this.runDredd(_this.dreddInstance);
};
})(this), waitMilis);
}
}...
return;
}
}
configurationForDredd = this.initConfig();
this.logDebuggingInfo(configurationForDredd);
this.dreddInstance = this.initDredd(configurationForDredd);
try {
this.runServerAndThenDredd();
} catch (error1) {
e = error1;
logger.error(e.message, e.stack);
this.stopServer((function(_this) {
return function() {
return _this._processExit(2);
};
...setExitOrCallback = function () {
if (!this.cb) {
if (this.exit && (this.exit === process.exit)) {
this.sigIntEventAdd = true;
}
if (this.exit) {
return this._processExit = (function(_this) {
return function(exitStatus) {
logger.verbose("Exiting Dredd process with status '" + exitStatus + "'.");
logger.debug('Using configured custom exit() method to terminate the Dredd process.');
_this.finished = true;
return _this.stopServer(function() {
return _this.exit(exitStatus);
});
};
})(this);
} else {
return this._processExit = (function(_this) {
return function(exitStatus) {
logger.verbose("Exiting Dredd process with status '" + exitStatus + "'.");
logger.debug('Using native process.exit() method to terminate the Dredd process.');
return _this.stopServer(function() {
return process.exit(exitStatus);
});
};
})(this);
}
} else {
return this._processExit = (function(_this) {
return function(exitStatus) {
logger.verbose("Exiting Dredd process with status '" + exitStatus + "'.");
logger.debug('Using configured custom callback to terminate the Dredd process.');
_this.finished = true;
if (_this.sigIntEventAdded) {
if ((_this.serverProcess != null) && !_this.serverProcess.terminated) {
logger.verbose('Killing backend server process before Dredd exits.');
_this.serverProcess.signalKill();
}
process.removeEventListener('SIGINT', _this.commandSigInt);
}
_this.cb(exitStatus);
return _this;
};
})(this);
}
}...
function DreddCommand(options, cb) {
if (options == null) {
options = {};
}
this.cb = cb;
this.finished = false;
this.exit = options.exit, this.custom = options.custom;
this.setExitOrCallback();
if (this.custom == null) {
this.custom = {};
}
if (!this.custom.cwd || typeof this.custom.cwd !== 'string') {
this.custom.cwd = process.cwd();
}
if (!this.custom.argv || !Array.isArray(this.custom.argv)) {
...setOptimistArgv = function () {
this.optimist = optimist(this.custom.argv, this.custom.cwd);
this.cliArgv = this.optimist.argv;
this.optimist.usage('Usage:\n $ dredd init\n\nOr:\n $ dredd <path or URL to API description document> <URL of tested server> [
OPTIONS]\n\nExample:\n $ dredd ./api-description.apib http://127.0.0.1:3000 --dry-run').options(Dredd.options).wrap(80);
this.argv = this.optimist.argv;
return this.argv = applyLoggingOptions(this.argv);
}n/a
stopServer = function (callback) {
if (this.serverProcess == null) {
logger.verbose('No backend server process to terminate.');
return callback();
}
if (this.serverProcess.terminated) {
logger.debug('The backend server process has already terminated');
return callback();
}
logger.verbose('Terminating backend server process, PID', this.serverProcess.pid);
this.serverProcess.terminate({
force: true
});
return this.serverProcess.on('exit', function() {
return callback();
});
}...
}
if (this.exit) {
return this._processExit = (function(_this) {
return function(exitStatus) {
logger.verbose("Exiting Dredd process with status '" + exitStatus + "'.");
logger.debug('Using configured custom exit() method to terminate the Dredd process.');
_this.finished = true;
return _this.stopServer(function() {
return _this.exit(exitStatus);
});
};
})(this);
} else {
return this._processExit = (function(_this) {
return function(exitStatus) {
...takeRestOfParamsAsPath = function () {
this.argv['p'] = this.argv['path'] = this.argv['path'].concat(this.argv._);
return this;
}...
DreddCommand.prototype.takeRestOfParamsAsPath = function() {
this.argv['p'] = this.argv['path'] = this.argv['path'].concat(this.argv._);
return this;
};
DreddCommand.prototype.initConfig = function() {
var base, configuration;
this.lastArgvIsApiEndpoint().takeRestOfParamsAsPath();
configuration = {
'server': this.server,
'options': this.argv
};
if ((base = configuration.options).path == null) {
base.path = [];
}
...function Hooks(options) {
if (options == null) {
options = {};
}
this.dumpHooksFunctionsToStrings = bind(this.dumpHooksFunctionsToStrings, this);
this.log = bind(this.log, this);
this.afterEach = bind(this.afterEach, this);
this.beforeEachValidation = bind(this.beforeEachValidation, this);
this.beforeEach = bind(this.beforeEach, this);
this.afterAll = bind(this.afterAll, this);
this.beforeAll = bind(this.beforeAll, this);
this.after = bind(this.after, this);
this.beforeValidation = bind(this.beforeValidation, this);
this.before = bind(this.before, this);
this.logs = options.logs, this.logger = options.logger;
this.transactions = {};
this.beforeHooks = {};
this.beforeValidationHooks = {};
this.afterHooks = {};
this.beforeAllHooks = [];
this.afterAllHooks = [];
this.beforeEachHooks = [];
this.beforeEachValidationHooks = [];
this.afterEachHooks = [];
}n/a
addHook = function (hooks, name, hook) {
if (hooks[name]) {
return hooks[name].push(hook);
} else {
return hooks[name] = [hook];
}
}...
this.afterAllHooks = [];
this.beforeEachHooks = [];
this.beforeEachValidationHooks = [];
this.afterEachHooks = [];
}
Hooks.prototype.before = function(name, hook) {
return this.addHook(this.beforeHooks, name, hook);
};
Hooks.prototype.beforeValidation = function(name, hook) {
return this.addHook(this.beforeValidationHooks, name, hook);
};
Hooks.prototype.after = function(name, hook) {
...after = function (name, hook) {
return this.addHook(this.afterHooks, name, hook);
}n/a
afterAll = function (hook) {
return this.afterAllHooks.push(hook);
}...
});
};
})(this);
for (i = 0, len = eachHookNames.length; i < len; i++) {
eventName = eachHookNames[i];
fn(eventName);
}
this.runner.hooks.afterAll((function(_this) {
return function(transactions, hookCallback) {
var index, j, len1, modification, modifications, ref;
if (process.env.TEST_DREDD_HOOKS_HANDLER_ORDER === 'true') {
console.error('FOR TESTING ONLY');
modifications = ((ref = transactions[0]) != null ? ref.hooks_modifications : void 0) || [];
if (!modifications.length) {
throw new Error('Hooks must modify transaction.hooks_modifications');
...afterEach = function (hook) {
return this.afterEachHooks.push(hook);
}n/a
before = function (name, hook) {
return this.addHook(this.beforeHooks, name, hook);
}n/a
beforeAll = function (hook) {
return this.beforeAllHooks.push(hook);
}n/a
beforeEach = function (hook) {
return this.beforeEachHooks.push(hook);
}n/a
beforeEachValidation = function (hook) {
return this.beforeEachValidationHooks.push(hook);
}n/a
beforeValidation = function (name, hook) {
return this.addHook(this.beforeValidationHooks, name, hook);
}n/a
dumpHooksFunctionsToStrings = function () {
var funcArray, hookFunc, i, index, len, names, property, ref, ref1, toReturn, transactionName;
toReturn = {};
names = ['beforeHooks', 'beforeValidationHooks', 'afterHooks', 'beforeAllHooks', 'afterAllHooks', 'beforeEachHooks', 'beforeEachValidationHooks
', 'afterEachHooks'];
for (i = 0, len = names.length; i < len; i++) {
property = names[i];
if (Array.isArray(this[property])) {
toReturn[property] = [];
ref = this[property];
for (index in ref) {
hookFunc = ref[index];
toReturn[property][index] = hookFunc.toString();
}
} else if (typeof this[property] === 'object' && !Array.isArray(this[property])) {
toReturn[property] = {};
ref1 = this[property];
for (transactionName in ref1) {
funcArray = ref1[transactionName];
if (!funcArray.length) {
continue;
}
toReturn[property][transactionName] = [];
for (index in funcArray) {
hookFunc = funcArray[index];
toReturn[property][transactionName][index] = hookFunc.toString();
}
}
}
}
return toReturn;
}...
Pitboss = require('pitboss-ng').Pitboss;
Hooks = require('./hooks');
sandboxHooksCode = function(hooksCode, callback) {
var hooks, sandbox, wrappedCode;
hooks = new Hooks();
wrappedCode = "var _hooks = new _Hooks();\n\nvar before = _hooks.before;\nvar after = _hooks.after;\nvar beforeAll = _hooks
.beforeAll;\nvar afterAll = _hooks.afterAll;\nvar beforeEach = _hooks.beforeEach;\nvar afterEach = _hooks.afterEach;\nvar beforeValidation = _hooks.beforeValidation;\nvar beforeEachValidation = _hooks.beforeEachValidation;\n\nvar log = _hooks.log;\n\n" + hooksCode + "\ntry {\n var output = _hooks.dumpHooksFunctionsToStrings();\n} catch(e) {\n console.log(e.message);\n console.log(e.stack);\n throw(e);\n}\n\noutput";
sandbox = new Pitboss(wrappedCode);
sandbox.run({
libraries: {
'_Hooks': '../../../lib/hooks',
'console': 'console'
}
}, function(err, result) {
...log = function () {
var args;
args = 1 <= arguments.length ? slice.call(arguments, 0) : [];
this.logs = hooksLog.apply(null, [this.logs, this.logger].concat(slice.call(args)));
}...
} catch (error1) {
error = error1;
return logger.warn("Skipping hook loading. Error reading hook file '" + filePath + "'. This probably
means one or more of your hook files are invalid.\nMessage: " + error.message + "\nStack: " + error.stack);
}
};
loadSandboxHooksFromStrings = function(callback) {
if (typeof runner.configuration.hooksData !== 'object' || Array.isArray(runner.configuration.hooksData) !== false) {
return callback(new Error("hooksData option must be an object e.g. {'filename.js':'console.log(\"Hey!\")'}"));
}
return async.eachSeries(Object.keys(runner.configuration.hooksData), function(key, nextHook) {
var data;
data = runner.configuration.hooksData[key];
return sandboxHooksCode(data, function(sandboxError, result) {
if (sandboxError) {
return nextHook(sandboxError);
...function HooksWorkerClient(runner) {
var options;
this.runner = runner;
options = this.runner.hooks.configuration.options;
this.language = options.language;
this.timeout = options['hooks-worker-timeout'] || 5000;
this.connectTimeout = options['hooks-worker-connect-timeout'] || 1500;
this.connectRetry = options['hooks-worker-connect-retry'] || 500;
this.afterConnectWait = options['hooks-worker-after-connect-wait'] || 100;
this.termTimeout = options['hooks-worker-term-timeout'] || 5000;
this.termRetry = options['hooks-worker-term-retry'] || 500;
this.handlerHost = options['hooks-worker-handler-host'] || '127.0.0.1';
this.handlerPort = options['hooks-worker-handler-port'] || 61321;
this.handlerMessageDelimiter = '\n';
this.clientConnected = false;
this.connectError = false;
this.emitter = new EventEmitter;
}n/a
connectToHandler = function (callback) {
var connectAndSetupClient, start, timeout, waitForConnect;
start = Date.now();
waitForConnect = (function(_this) {
return function() {
var error, msg, timeout;
if ((Date.now() - start) < _this.connectTimeout) {
clearTimeout(timeout);
if (_this.connectError !== false) {
logger.warn('Error connecting to the hooks handler process. Is the handler running? Retrying.');
_this.connectError = false;
}
if (_this.clientConnected !== true) {
connectAndSetupClient();
return timeout = setTimeout(waitForConnect, _this.connectRetry);
}
} else {
clearTimeout(timeout);
if (!_this.clientConnected) {
if (_this.handlerClient != null) {
_this.handlerClient.destroy();
}
msg = ("Connection timeout " + (_this.connectTimeout / 1000) + "s to hooks handler ") + ("on " + _this.handlerHost + ":" +
_this.handlerPort + " exceeded. Try increasing the limit.");
error = new Error(msg);
return callback(error);
}
}
};
})(this);
connectAndSetupClient = (function(_this) {
return function() {
var handlerBuffer;
logger.verbose('Starting TCP connection with hooks handler process.');
if (_this.runner.hookHandlerError != null) {
return callback(_this.runner.hookHandlerError);
}
_this.handlerClient = net.connect({
port: _this.handlerPort,
host: _this.handlerHost
});
_this.handlerClient.on('connect', function() {
logger.info("Successfully connected to hooks handler. Waiting " + (_this.afterConnectWait / 1000) + "s to start testing.");
_this.clientConnected = true;
clearTimeout(timeout);
return setTimeout(callback, _this.afterConnectWait);
});
_this.handlerClient.on('close', function() {
return logger.debug('TCP communication with hooks handler closed.');
});
_this.handlerClient.on('error', function(connectError) {
logger.debug('TCP communication with hooks handler errored.', connectError);
return _this.connectError = connectError;
});
handlerBuffer = '';
return _this.handlerClient.on('data', function(data) {
var i, j, len, len1, message, messages, results, splittedData;
logger.debug('Dredd received some data from hooks handler.');
handlerBuffer += data.toString();
if (data.toString().indexOf(_this.handlerMessageDelimiter) > -1) {
splittedData = handlerBuffer.split(_this.handlerMessageDelimiter);
handlerBuffer = splittedData.pop();
messages = [];
for (i = 0, len = splittedData.length; i < len; i++) {
message = splittedData[i];
messages.push(JSON.parse(message));
}
results = [];
for (j = 0, len1 = messages.length; j < len1; j++) {
message = messages[j];
if (message.uuid != null) {
logger.verbose('Dredd received a valid message from hooks handler:', message.uuid);
results.push(_this.emitter.emit(message.uuid, message));
} else {
results.push(logger.verbose('UUID not present in hooks handler message, ignoring:', JSON.stringify(message, null,
2)));
}
}
return results;
}
});
};
})(this);
return timeout = setTimeout(waitForConnect, this.connectRetry);
}...
}
logger.verbose('Starting hooks handler.');
return _this.spawnHandler(function(spawnHandlerError) {
if (spawnHandlerError) {
return callback(spawnHandlerError);
}
logger.verbose('Connecting to hooks handler.');
return _this.connectToHandler(function(connectHandlerError) {
if (connectHandlerError) {
return callback(connectHandlerError);
}
logger.verbose('Registering hooks.');
return _this.registerHooks(function(registerHooksError) {
if (registerHooksError) {
return callback(registerHooksError);
...disconnectFromHandler = function () {
return this.handlerClient.destroy();
}...
});
});
};
})(this));
};
HooksWorkerClient.prototype.stop = function(callback) {
this.disconnectFromHandler();
return this.terminateHandler(callback);
};
HooksWorkerClient.prototype.terminateHandler = function(callback) {
logger.verbose('Terminating hooks handler process, PID', this.handler.pid);
if (this.handler.terminated) {
logger.debug('The hooks handler process has already terminated');
...registerHooks = function (callback) {
var eachHookNames, eventName, fn, i, len;
eachHookNames = ['beforeEach', 'beforeEachValidation', 'afterEach', 'beforeAll', 'afterAll'];
fn = (function(_this) {
return function(eventName) {
return _this.runner.hooks[eventName](function(data, hookCallback) {
var handleTimeout, message, messageHandler, timeout, uuid;
uuid = generateUuid();
message = {
event: eventName,
uuid: uuid,
data: data
};
logger.verbose('Sending HTTP transaction data to hooks handler:', uuid);
_this.handlerClient.write(JSON.stringify(message));
_this.handlerClient.write(_this.handlerMessageDelimiter);
messageHandler = function(receivedMessage) {
var index, j, key, len1, ref, ref1, value;
logger.verbose('Handling hook:', uuid);
clearTimeout(timeout);
if (eventName.indexOf('All') > -1) {
ref = receivedMessage.data;
for (index = j = 0, len1 = ref.length; j < len1; index = ++j) {
value = ref[index];
data[index] = value;
}
} else {
ref1 = receivedMessage.data;
for (key in ref1) {
if (!hasProp.call(ref1, key)) continue;
value = ref1[key];
data[key] = value;
}
}
return hookCallback();
};
handleTimeout = function() {
logger.warn('Hook handling timed out.');
if (eventName.indexOf('All') === -1) {
data.fail = 'Hook timed out.';
}
_this.emitter.removeListener(uuid, messageHandler);
return hookCallback();
};
timeout = setTimeout(handleTimeout, _this.timeout);
return _this.emitter.on(uuid, messageHandler);
});
};
})(this);
for (i = 0, len = eachHookNames.length; i < len; i++) {
eventName = eachHookNames[i];
fn(eventName);
}
this.runner.hooks.afterAll((function(_this) {
return function(transactions, hookCallback) {
var index, j, len1, modification, modifications, ref;
if (process.env.TEST_DREDD_HOOKS_HANDLER_ORDER === 'true') {
console.error('FOR TESTING ONLY');
modifications = ((ref = transactions[0]) != null ? ref.hooks_modifications : void 0) || [];
if (!modifications.length) {
throw new Error('Hooks must modify transaction.hooks_modifications');
}
for (index = j = 0, len1 = modifications.length; j < len1; index = ++j) {
modification = modifications[index];
console.error(index + " " + modification);
}
console.error('FOR TESTING ONLY');
}
return _this.stop(hookCallback);
};
})(this));
return callback();
}...
}
logger.verbose('Connecting to hooks handler.');
return _this.connectToHandler(function(connectHandlerError) {
if (connectHandlerError) {
return callback(connectHandlerError);
}
logger.verbose('Registering hooks.');
return _this.registerHooks(function(registerHooksError) {
if (registerHooksError) {
return callback(registerHooksError);
}
return callback();
});
});
});
...setCommandAndCheckForExecutables = function (callback) {
var gobin, msg, parsedArgs;
if (this.language === 'ruby') {
this.handlerCommand = 'dredd-hooks-ruby';
this.handlerCommandArgs = [];
if (!which.which(this.handlerCommand)) {
msg = "Ruby hooks handler command not found: " + this.handlerCommand + "\nInstall ruby hooks handler by running:\n$ gem install
dredd_hooks";
return callback(new Error(msg));
} else {
return callback();
}
} else if (this.language === 'python') {
this.handlerCommand = 'dredd-hooks-python';
this.handlerCommandArgs = [];
if (!which.which(this.handlerCommand)) {
msg = "Python hooks handler command not found: " + this.handlerCommand + "\nInstall python hooks handler by running:\n$ pip
install dredd_hooks";
return callback(new Error(msg));
} else {
return callback();
}
} else if (this.language === 'php') {
this.handlerCommand = 'dredd-hooks-php';
this.handlerCommandArgs = [];
if (!which.which(this.handlerCommand)) {
msg = "PHP hooks handler command not found: " + this.handlerCommand + "\nInstall php hooks handler by running:\n$ composer
require ddelnano/dredd-hooks-php --dev";
return callback(new Error(msg));
} else {
return callback();
}
} else if (this.language === 'perl') {
this.handlerCommand = 'dredd-hooks-perl';
this.handlerCommandArgs = [];
if (!which.which(this.handlerCommand)) {
msg = "Perl hooks handler command not found: " + this.handlerCommand + "\nInstall perl hooks handler by running:\n$ cpanm
Dredd::Hooks";
return callback(new Error(msg));
} else {
return callback();
}
} else if (this.language === 'nodejs') {
msg = 'Hooks handler should not be used for Node.js. Use Dredd\'s native Node.js hooks instead.';
return callback(new Error(msg));
} else if (this.language === 'go') {
gobin = process.env.GOBIN;
if (!gobin) {
gobin = process.env.GOPATH + "/bin";
}
this.handlerCommand = gobin + "/goodman";
this.handlerCommandArgs = [];
if (!which.which(this.handlerCommand)) {
msg = 'Go hooks handler command not found in $GOBIN or $GOPATH/bin\nInstall go hooks handler by running:\n$ go get github.
com/snikch/goodman/cmd/goodman';
return callback(new Error(msg));
} else {
return callback();
}
} else {
parsedArgs = spawnArgs(this.language);
this.handlerCommand = parsedArgs.shift();
this.handlerCommandArgs = parsedArgs;
logger.verbose("Using '" + this.handlerCommand + "' as a hook handler command, '" + (this.handlerCommandArgs.join(' ')) + "'
as arguments");
if (!which.which(this.handlerCommand)) {
msg = "Hooks handler command not found: " + this.handlerCommand;
return callback(new Error(msg));
} else {
return callback();
}
}
}...
this.clientConnected = false;
this.connectError = false;
this.emitter = new EventEmitter;
}
HooksWorkerClient.prototype.start = function(callback) {
logger.verbose('Looking up hooks handler implementation:', this.language);
return this.setCommandAndCheckForExecutables((function(_this) {
return function(executablesError) {
if (executablesError) {
return callback(executablesError);
}
logger.verbose('Starting hooks handler.');
return _this.spawnHandler(function(spawnHandlerError) {
if (spawnHandlerError) {
...spawnHandler = function (callback) {
var handlerCommandArgs, pathGlobs, ref, ref1, ref2;
pathGlobs = [].concat((ref = this.runner.hooks) != null ? (ref1 = ref.configuration) != null ? (ref2 = ref1.options) != null ?
ref2.hookfiles : void 0 : void 0 : void 0);
handlerCommandArgs = this.handlerCommandArgs.concat(pathGlobs);
logger.info("Spawning '" + this.language + "' hooks handler process.");
this.handler = spawn(this.handlerCommand, handlerCommandArgs);
this.handler.stdout.on('data', function(data) {
return logger.info("Hooks handler stdout:", data.toString());
});
this.handler.stderr.on('data', function(data) {
return logger.info("Hooks handler stderr:", data.toString());
});
this.handler.on('signalTerm', function() {
return logger.verbose('Gracefully terminating the hooks handler process');
});
this.handler.on('signalKill', function() {
return logger.verbose('Killing the hooks handler process');
});
this.handler.on('crash', (function(_this) {
return function(exitStatus, killed) {
var msg;
if (killed) {
msg = "Hooks handler process '" + _this.handlerCommand + " " + (handlerCommandArgs.join(' ')) + "' was killed.";
} else {
msg = "Hooks handler process '" + _this.handlerCommand + " " + (handlerCommandArgs.join(' ')) + "' exited with status: " +
exitStatus;
}
logger.error(msg);
return _this.runner.hookHandlerError = new Error(msg);
};
})(this));
this.handler.on('error', (function(_this) {
return function(err) {
return _this.runner.hookHandlerError = err;
};
})(this));
return callback();
}...
logger.verbose('Looking up hooks handler implementation:', this.language);
return this.setCommandAndCheckForExecutables((function(_this) {
return function(executablesError) {
if (executablesError) {
return callback(executablesError);
}
logger.verbose('Starting hooks handler.');
return _this.spawnHandler(function(spawnHandlerError) {
if (spawnHandlerError) {
return callback(spawnHandlerError);
}
logger.verbose('Connecting to hooks handler.');
return _this.connectToHandler(function(connectHandlerError) {
if (connectHandlerError) {
return callback(connectHandlerError);
...start = function (callback) {
logger.verbose('Looking up hooks handler implementation:', this.language);
return this.setCommandAndCheckForExecutables((function(_this) {
return function(executablesError) {
if (executablesError) {
return callback(executablesError);
}
logger.verbose('Starting hooks handler.');
return _this.spawnHandler(function(spawnHandlerError) {
if (spawnHandlerError) {
return callback(spawnHandlerError);
}
logger.verbose('Connecting to hooks handler.');
return _this.connectToHandler(function(connectHandlerError) {
if (connectHandlerError) {
return callback(connectHandlerError);
}
logger.verbose('Registering hooks.');
return _this.registerHooks(function(registerHooksError) {
if (registerHooksError) {
return callback(registerHooksError);
}
return callback();
});
});
});
};
})(this));
}...
for (k = 0, len2 = files.length; k < len2; k++) {
file = files[k];
loadHookFile(file);
}
return callback();
} else {
hooksWorkerClient = new HooksWorkerClient(runner);
return hooksWorkerClient.start(callback);
}
} else {
logger.info('Loading hook files in sandboxed context:', files);
return async.eachSeries(files, function(fileName, nextFile) {
var resolvedPath;
resolvedPath = path.resolve(customConfigCwd || process.cwd(), fileName);
return fs.readFile(resolvedPath, 'utf8', function(readingError, data) {
...stop = function (callback) {
this.disconnectFromHandler();
return this.terminateHandler(callback);
}...
}
for (index = j = 0, len1 = modifications.length; j < len1; index = ++j) {
modification = modifications[index];
console.error(index + " " + modification);
}
console.error('FOR TESTING ONLY');
}
return _this.stop(hookCallback);
};
})(this));
return callback();
};
return HooksWorkerClient;
...terminateHandler = function (callback) {
logger.verbose('Terminating hooks handler process, PID', this.handler.pid);
if (this.handler.terminated) {
logger.debug('The hooks handler process has already terminated');
return callback();
}
this.handler.terminate({
force: true,
timeout: this.termTimeout,
retryDelay: this.termRetry
});
return this.handler.on('close', function() {
return callback();
});
}...
});
};
})(this));
};
HooksWorkerClient.prototype.stop = function(callback) {
this.disconnectFromHandler();
return this.terminateHandler(callback);
};
HooksWorkerClient.prototype.terminateHandler = function(callback) {
logger.verbose('Terminating hooks handler process, PID', this.handler.pid);
if (this.handler.terminated) {
logger.debug('The hooks handler process has already terminated');
return callback();
...processAnswers = function (config, answers, callback) {
if (config == null) {
config = {};
}
if (config['_'] == null) {
config['_'] = [];
}
config['_'][0] = answers['blueprint'];
config['_'][1] = answers['endpoint'];
config['server'] = answers['server'] || null;
config['language'] = answers['language'];
if (answers['apiary'] === true) {
config['reporter'] = "apiary";
}
if (config['custom'] == null) {
config['custom'] = {};
}
if (answers['apiaryApiKey'] != null) {
config['custom']['apiaryApiKey'] = answers['apiaryApiKey'];
}
if (answers['apiaryApiName'] != null) {
config['custom']['apiaryApiName'] = answers['apiaryApiName'];
}
if (answers['circleAdd'] || answers['circleCreate']) {
interactiveConfig.updateCircle();
}
if (answers['travisAdd'] === true) {
interactiveConfig.updateTravis();
}
callback(config);
}...
interactiveConfig.updateTravis();
}
callback(config);
};
interactiveConfig.run = function(config, callback) {
interactiveConfig.prompt(config, function(answers) {
return interactiveConfig.processAnswers(config, answers, callback);
});
};
interactiveConfig.updateCircle = function() {
var base, base1, config, file, yamlData;
file = "circle.yml";
if (fs.existsSync(file)) {
...prompt = function (config, callback) {
var questions, ref, ref1;
if (config == null) {
config = {};
}
questions = [];
questions.push({
type: "input",
name: "blueprint",
message: "Location of the API description document",
"default": config['blueprint'] || "apiary.apib"
});
questions.push({
type: "input",
name: "server",
message: "Command to start API backend server e.g. (bundle exec rails server)",
"default": config['server']
});
questions.push({
type: "input",
name: "endpoint",
message: "URL of tested API endpoint",
"default": config['endpoint'] || "http://127.0.0.1:3000"
});
questions.push({
type: "list",
name: "language",
message: "Programming language of hooks",
"default": "nodejs",
choices: ["ruby", "python", "nodejs", "php", "perl", "go"]
});
questions.push({
type: "confirm",
name: "apiary",
message: "Do you want to use Apiary test inspector?",
"default": true,
when: function(answers) {
return config['reporter'] !== 'apiary';
}
});
questions.push({
type: "input",
name: "apiaryApiKey",
message: "Please enter Apiary API key or leave empty for anonymous reporter",
"default": (ref = config['custom']) != null ? ref['apiaryApiKey'] : void 0,
when: function(answers) {
var ref1;
return answers['apiary'] === true && (((ref1 = config['custom']) != null ? ref1['apiaryApiKey'] : void 0) == null);
}
});
questions.push({
type: "input",
name: "apiaryApiName",
message: "Please enter Apiary API name",
"default": (ref1 = config['custom']) != null ? ref1['apiaryApiName'] : void 0,
when: function(answers) {
var ref2;
return (answers['apiary'] === true && (((ref2 = config['custom']) != null ? ref2['apiaryApiName'] : void 0) == null)) && (
answers['apiary'] === true && answers['apiaryApiKey'] !== '');
}
});
questions.push({
type: "confirm",
name: "travisAdd",
message: "Found Travis CI configuration, do you want to add Dredd to the build?",
"default": true,
when: function() {
return fs.existsSync('.travis.yml');
}
});
questions.push({
type: "confirm",
name: "circleAdd",
message: "Found CircleCI configuration, do you want to add Dredd to the build?",
"default": true,
when: function() {
return fs.existsSync('circle.yml');
}
});
questions.push({
type: "confirm",
name: "circleCreate",
message: "Dredd is best served with Continuous Integration. Create CircleCI config for Dredd?",
when: function(answers) {
return !fs.existsSync('circle.yml') && !fs.existsSync('.travis.yml');
}
});
return inquirer.prompt(questions).then(callback);
}...
type: "confirm",
name: "circleCreate",
message: "Dredd is best served with Continuous Integration. Create CircleCI config for Dredd?",
when: function(answers) {
return !fs.existsSync('circle.yml') && !fs.existsSync('.travis.yml');
}
});
return inquirer.prompt(questions).then(callback);
};
interactiveConfig.processAnswers = function(config, answers, callback) {
if (config == null) {
config = {};
}
if (config['_'] == null) {
...run = function (config, callback) {
interactiveConfig.prompt(config, function(answers) {
return interactiveConfig.processAnswers(config, answers, callback);
});
}...
}
};
DreddCommand.prototype.runExitingActions = function() {
if (this.argv["_"][0] === "init" || this.argv.init === true) {
logger.silly('Starting interactive configuration.');
this.finished = true;
return interactiveConfig.run(this.argv, (function(_this) {
return function(config) {
configUtils.save(config);
console.log("");
console.log("Configuration saved to dredd.yml");
console.log("");
if (config['language'] === "nodejs") {
console.log("Run test now, with:");
...updateCircle = function () {
var base, base1, config, file, yamlData;
file = "circle.yml";
if (fs.existsSync(file)) {
config = yaml.safeLoad(fs.readFileSync(file));
} else {
config = {};
}
if (config['dependencies'] == null) {
config['dependencies'] = {};
}
if ((base = config['dependencies'])['pre'] == null) {
base['pre'] = [];
}
if (config['dependencies']['pre'].indexOf("npm install -g dredd") === -1) {
config['dependencies']['pre'].push("npm install -g dredd@" + packageData.version);
}
if (config['test'] == null) {
config['test'] = {};
}
if ((base1 = config['test'])['pre'] == null) {
base1['pre'] = [];
}
if (config['test']['pre'].indexOf("dredd") === -1) {
config['test']['pre'].push("dredd");
}
yamlData = yaml.safeDump(config);
fs.writeFileSync(file, yamlData);
}...
if (answers['apiaryApiKey'] != null) {
config['custom']['apiaryApiKey'] = answers['apiaryApiKey'];
}
if (answers['apiaryApiName'] != null) {
config['custom']['apiaryApiName'] = answers['apiaryApiName'];
}
if (answers['circleAdd'] || answers['circleCreate']) {
interactiveConfig.updateCircle();
}
if (answers['travisAdd'] === true) {
interactiveConfig.updateTravis();
}
callback(config);
};
...updateTravis = function () {
var config, file, yamlData;
file = ".travis.yml";
if (fs.existsSync(file)) {
config = yaml.safeLoad(fs.readFileSync(file));
} else {
config = {};
}
if (config['before_install'] == null) {
config['before_install'] = [];
}
if (config['before_install'].indexOf("npm install -g dredd") === -1) {
config['before_install'].push("npm install -g dredd@" + packageData.version);
}
if (config['before_script'] == null) {
config['before_script'] = [];
}
if (config['before_script'].indexOf("dredd") === -1) {
config['before_script'].push("dredd");
}
yamlData = yaml.safeDump(config);
fs.writeFileSync(file, yamlData);
}...
if (answers['apiaryApiName'] != null) {
config['custom']['apiaryApiName'] = answers['apiaryApiName'];
}
if (answers['circleAdd'] || answers['circleCreate']) {
interactiveConfig.updateCircle();
}
if (answers['travisAdd'] === true) {
interactiveConfig.updateTravis();
}
callback(config);
};
interactiveConfig.run = function(config, callback) {
interactiveConfig.prompt(config, function(answers) {
return interactiveConfig.processAnswers(config, answers, callback);
...actual = function (msg) {
// build argument list (level, msg, ... [string interpolate], [{metadata}], [callback])
var args = [level].concat(Array.prototype.slice.call(arguments));
target.log.apply(target, args);
}n/a
complete = function (msg) {
// build argument list (level, msg, ... [string interpolate], [{metadata}], [callback])
var args = [level].concat(Array.prototype.slice.call(arguments));
target.log.apply(target, args);
}n/a
debug = function (msg) {
// build argument list (level, msg, ... [string interpolate], [{metadata}], [callback])
var args = [level].concat(Array.prototype.slice.call(arguments));
target.log.apply(target, args);
}...
DreddCommand.prototype.stopServer = function(callback) {
if (this.serverProcess == null) {
logger.verbose('No backend server process to terminate.');
return callback();
}
if (this.serverProcess.terminated) {
logger.debug('The backend server process has already terminated');
return callback();
}
logger.verbose('Terminating backend server process, PID', this.serverProcess.pid);
this.serverProcess.terminate({
force: true
});
return this.serverProcess.on('exit', function() {
...error = function (msg) {
// build argument list (level, msg, ... [string interpolate], [{metadata}], [callback])
var args = [level].concat(Array.prototype.slice.call(arguments));
target.log.apply(target, args);
}...
}
};
DreddCommand.prototype.checkRequiredArgs = function() {
var argError;
argError = false;
if (this.argv._[0] == null) {
console.error("\nError: Must specify path to API description document.");
argError = true;
}
if (this.argv._[1] == null) {
console.error("\nError: Must specify URL of the tested API instance.");
argError = true;
}
if (argError) {
...expected = function (msg) {
// build argument list (level, msg, ... [string interpolate], [{metadata}], [callback])
var args = [level].concat(Array.prototype.slice.call(arguments));
target.log.apply(target, args);
}n/a
fail = function (msg) {
// build argument list (level, msg, ... [string interpolate], [{metadata}], [callback])
var args = [level].concat(Array.prototype.slice.call(arguments));
target.log.apply(target, args);
}n/a
hook = function (msg) {
// build argument list (level, msg, ... [string interpolate], [{metadata}], [callback])
var args = [level].concat(Array.prototype.slice.call(arguments));
target.log.apply(target, args);
}n/a
info = function (msg) {
// build argument list (level, msg, ... [string interpolate], [{metadata}], [callback])
var args = [level].concat(Array.prototype.slice.call(arguments));
target.log.apply(target, args);
}...
runner.hooks.configuration = clone(runner != null ? runner.configuration : void 0);
files = [];
globs = [].concat(runner != null ? (ref4 = runner.configuration) != null ? (ref5 = ref4.options) != null ? ref5.hookfiles : void
0 : void 0 : void 0);
for (j = 0, len1 = globs.length; j < len1; j++) {
globItem = globs[j];
files = files.concat(glob.sync(globItem));
}
logger.info('Found Hookfiles:', files);
if (!runner.configuration.options.sandbox === true) {
if ((runner != null ? (ref6 = runner.configuration) != null ? (ref7 = ref6.options) != null ? ref7.language : void 0 : void 0 :
void 0) === "" || (runner != null ? (ref8 = runner.configuration) != null ? (ref9 = ref8.options) != null ? ref9.language
: void 0 : void 0 : void 0) === void 0 || (runner != null ? (ref10 = runner.configuration) != null ? (ref11 = ref10.options) !=
null ? ref11.language : void 0 : void 0 : void 0) === "nodejs") {
for (k = 0, len2 = files.length; k < len2; k++) {
file = files[k];
loadHookFile(file);
}
return callback();
...pass = function (msg) {
// build argument list (level, msg, ... [string interpolate], [{metadata}], [callback])
var args = [level].concat(Array.prototype.slice.call(arguments));
target.log.apply(target, args);
}n/a
request = function (msg) {
// build argument list (level, msg, ... [string interpolate], [{metadata}], [callback])
var args = [level].concat(Array.prototype.slice.call(arguments));
target.log.apply(target, args);
}n/a
silly = function (msg) {
// build argument list (level, msg, ... [string interpolate], [{metadata}], [callback])
var args = [level].concat(Array.prototype.slice.call(arguments));
target.log.apply(target, args);
}...
this.optimist.showHelp(console.error);
return this._processExit(1);
}
};
DreddCommand.prototype.runExitingActions = function() {
if (this.argv["_"][0] === "init" || this.argv.init === true) {
logger.silly('Starting interactive configuration.');
this.finished = true;
return interactiveConfig.run(this.argv, (function(_this) {
return function(config) {
configUtils.save(config);
console.log("");
console.log("Configuration saved to dredd.yml");
console.log("");
...skip = function (msg) {
// build argument list (level, msg, ... [string interpolate], [{metadata}], [callback])
var args = [level].concat(Array.prototype.slice.call(arguments));
target.log.apply(target, args);
}n/a
test = function (msg) {
// build argument list (level, msg, ... [string interpolate], [{metadata}], [callback])
var args = [level].concat(Array.prototype.slice.call(arguments));
target.log.apply(target, args);
}n/a
verbose = function (msg) {
// build argument list (level, msg, ... [string interpolate], [{metadata}], [callback])
var args = [level].concat(Array.prototype.slice.call(arguments));
target.log.apply(target, args);
}...
};
configureReporters = function(config, stats, tests, runner) {
var addCli, addReporter, baseReporter, i, j, len, outputs, path, reporter, reporters, results, usedFileReporters, usedFileReportersLength
;
baseReporter = new BaseReporter(config.emitter, stats, tests);
reporters = config.options.reporter;
outputs = config.options.output;
logger.verbose('Configuring reporters:', reporters, outputs);
addCli = function(reporters) {
var cliReporter, usedCliReporters;
if (reporters.length > 0) {
usedCliReporters = intersection(reporters, cliReporters);
if (usedCliReporters.length === 0) {
return cliReporter = new CliReporter(config.emitter, stats, tests, config.options['inline-errors'], config.options
.details);
} else {
...warn = function (msg) {
// build argument list (level, msg, ... [string interpolate], [{metadata}], [callback])
var args = [level].concat(Array.prototype.slice.call(arguments));
target.log.apply(target, args);
}...
try {
proxyquire(filePath, {
'hooks': runner.hooks
});
return fixLegacyTransactionNames(runner.hooks);
} catch (error1) {
error = error1;
return logger.warn("Skipping hook loading. Error reading hook file '"
; + filePath + "'. This probably means one or more of your hook files are invalid.\nMessage: " + error.message + "\nStack: " + error.stack);
}
};
loadSandboxHooksFromStrings = function(callback) {
if (typeof runner.configuration.hooksData !== 'object' || Array.isArray(runner.configuration.hooksData) !== false) {
return callback(new Error("hooksData option must be an object e.g. {'filename.js':'console.log(\"Hey
!\")'}"));
}
return async.eachSeries(Object.keys(runner.configuration.hooksData), function(key, nextHook) {
...function TransactionRunner(configuration1) {
this.configuration = configuration1;
this.executeTransaction = bind(this.executeTransaction, this);
this.configureTransaction = bind(this.configureTransaction, this);
this.logs = [];
this.hookStash = {};
this.error = null;
this.hookHandlerError = null;
}n/a
config = function (config) {
this.configuration = config;
return this.multiBlueprint = Object.keys(this.configuration.data).length > 1;
}n/a
configureTransaction = function (transaction, callback) {
var configuration, configuredTransaction, expected, flatHeaders, fullPath, header, headerKey, headerValue, i, len, mediaType,
origin, ref, ref1, request, response, skip, splitIndex, status, system;
configuration = this.configuration;
origin = transaction.origin, request = transaction.request, response = transaction.response;
mediaType = ((ref = configuration.data[origin.filename]) != null ? ref.mediaType : void 0) || 'text/vnd.apiblueprint';
if (this.parsedUrl == null) {
this.parsedUrl = this.parseServerUrl(configuration.server);
}
fullPath = this.getFullPath(this.parsedUrl.path, request.uri);
flatHeaders = flattenHeaders(request['headers']);
if (!flatHeaders['User-Agent']) {
system = os.type() + ' ' + os.release() + '; ' + os.arch();
flatHeaders['User-Agent'] = "Dredd/" + packageData.version + " (" + system + ")";
}
if (configuration.options.header.length > 0) {
ref1 = configuration.options.header;
for (i = 0, len = ref1.length; i < len; i++) {
header = ref1[i];
splitIndex = header.indexOf(':');
headerKey = header.substring(0, splitIndex);
headerValue = header.substring(splitIndex + 1);
flatHeaders[headerKey] = headerValue;
}
}
request['headers'] = flatHeaders;
expected = {
headers: flattenHeaders(response['headers']),
body: response['body'],
statusCode: response['status']
};
if (response['schema']) {
expected['bodySchema'] = response['schema'];
}
if (!this.multiBlueprint) {
transaction.name = transaction.name.replace(transaction.origin.apiName + " > ", "");
}
skip = false;
if (mediaType.indexOf('swagger') !== -1) {
status = parseInt(response.status, 10);
if (status < 200 || status >= 300) {
skip = true;
}
}
configuredTransaction = {
name: transaction.name,
id: request.method + ' ' + request.uri,
host: this.parsedUrl.hostname,
port: this.parsedUrl.port,
request: request,
expected: expected,
origin: origin,
fullPath: fullPath,
protocol: this.parsedUrl.protocol,
skip: skip
};
return callback(null, configuredTransaction);
}n/a
createTest = function (transaction) {
return {
status: '',
title: transaction.id,
message: transaction.name,
origin: transaction.origin,
startedAt: transaction.startedAt
};
}...
};
TransactionRunner.prototype.emitHookError = function(error, data) {
var test;
if (!(error instanceof Error)) {
error = new Error(error);
}
test = this.createTest(data);
test.request = data.request;
return this.emitError(error, test);
};
TransactionRunner.prototype.sandboxedHookResultsHandler = function(err, data, results, callback) {
var i, key, len, log, ref, ref1, value;
if (results == null) {
...emitError = function (error, test) {
logger.debug('Emitting to reporters: test error');
this.configuration.emitter.emit('test error', error, test, function() {});
return this.error = this.error || error;
}...
TransactionRunner.prototype.emitHookError = function(error, data) {
var test;
if (!(error instanceof Error)) {
error = new Error(error);
}
test = this.createTest(data);
test.request = data.request;
return this.emitError(error, test);
};
TransactionRunner.prototype.sandboxedHookResultsHandler = function(err, data, results, callback) {
var i, key, len, log, ref, ref1, value;
if (results == null) {
results = {};
}
...emitHookError = function (error, data) {
var test;
if (!(error instanceof Error)) {
error = new Error(error);
}
test = this.createTest(data);
test.request = data.request;
return this.emitError(error, test);
}...
var error, hookFn, i, len, transaction, transactions;
hookFn = hooks[hookFnIndex];
try {
if (legacy) {
return _this.runLegacyHook(hookFn, data, function(err) {
if (err) {
logger.debug('Legacy hook errored:', err);
_this.emitHookError(err, data);
}
return runHookCallback();
});
} else {
return _this.runHook(hookFn, data, function(err) {
if (err) {
logger.debug('Hook errored:', err);
...emitResult = function (transaction, callback) {
if (this.error || !transaction.test) {
logger.debug('No emission of test data to reporters', this.error, transaction.test);
this.error = null;
return callback();
}
if (transaction.skip) {
logger.debug('Emitting to reporters: test skip');
this.configuration.emitter.emit('test skip', transaction.test, function() {});
return callback();
}
if (transaction.test.valid) {
if (transaction.fail) {
this.failTransaction(transaction, "Failed in after hook: " + transaction.fail);
logger.debug('Emitting to reporters: test fail');
this.configuration.emitter.emit('test fail', transaction.test, function() {});
} else {
logger.debug('Emitting to reporters: test pass');
this.configuration.emitter.emit('test pass', transaction.test, function() {});
}
return callback();
}
logger.debug('Emitting to reporters: test fail');
this.configuration.emitter.emit('test fail', transaction.test, function() {});
return callback();
}...
}
logger.verbose('Running \'after\' hooks');
return _this.runHooksForData(hooks.afterHooks[transaction.name], transaction, false, function() {
if (_this.hookHandlerError) {
return iterationCallback(_this.hookHandlerError);
}
logger.debug("Evaluating results of transaction execution #" + (transactionIndex + 1) + ":", transaction
.name);
return _this.emitResult(transaction, iterationCallback);
});
});
});
});
});
}, function(iterationError) {
if (iterationError) {
...ensureTransactionResultsGeneralSection = function (transaction) {
var base, base1;
if (transaction.results == null) {
transaction.results = {};
}
if ((base = transaction.results).general == null) {
base.general = {};
}
return (base1 = transaction.results.general).results != null ? base1.results : base1.results = [];
}...
startedAt: transaction.startedAt
};
};
TransactionRunner.prototype.failTransaction = function(transaction, reason) {
var base;
transaction.fail = true;
this.ensureTransactionResultsGeneralSection(transaction);
if (reason) {
transaction.results.general.results.push({
severity: 'error',
message: reason
});
}
if (transaction.test == null) {
...executeAllTransactions = function (transactions, hooks, callback) {
var i, len, transaction;
if (!hooks.transactions) {
hooks.transactions = {};
for (i = 0, len = transactions.length; i < len; i++) {
transaction = transactions[i];
hooks.transactions[transaction.name] = transaction;
}
}
if (this.hookHandlerError) {
return callback(this.hookHandlerError);
}
logger.verbose('Running \'beforeAll\' hooks');
return this.runHooksForData(hooks.beforeAllHooks, transactions, true, (function(_this) {
return function() {
if (_this.hookHandlerError) {
return callback(_this.hookHandlerError);
}
return async.timesSeries(transactions.length, function(transactionIndex, iterationCallback) {
transaction = transactions[transactionIndex];
logger.verbose("Processing transaction #" + (transactionIndex + 1) + ":", transaction.name);
logger.verbose('Running \'beforeEach\' hooks');
return _this.runHooksForData(hooks.beforeEachHooks, transaction, false, function() {
if (_this.hookHandlerError) {
return iterationCallback(_this.hookHandlerError);
}
logger.verbose('Running \'before\' hooks');
return _this.runHooksForData(hooks.beforeHooks[transaction.name], transaction, false, function() {
if (_this.hookHandlerError) {
return iterationCallback(_this.hookHandlerError);
}
return _this.executeTransaction(transaction, hooks, function() {
if (_this.hookHandlerError) {
return iterationCallback(_this.hookHandlerError);
}
logger.verbose('Running \'afterEach\' hooks');
return _this.runHooksForData(hooks.afterEachHooks, transaction, false, function() {
if (_this.hookHandlerError) {
return iterationCallback(_this.hookHandlerError);
}
logger.verbose('Running \'after\' hooks');
return _this.runHooksForData(hooks.afterHooks[transaction.name], transaction, false, function() {
if (_this.hookHandlerError) {
return iterationCallback(_this.hookHandlerError);
}
logger.debug("Evaluating results of transaction execution #" + (transactionIndex + 1) + ":", transaction.name);
return _this.emitResult(transaction, iterationCallback);
});
});
});
});
});
}, function(iterationError) {
if (iterationError) {
return callback(iterationError);
}
logger.verbose('Running \'afterAll\' hooks');
return _this.runHooksForData(hooks.afterAllHooks, transactions, true, function() {
if (_this.hookHandlerError) {
return callback(_this.hookHandlerError);
}
return callback();
});
});
};
})(this));
}...
transactions = results;
logger.verbose('Reading hook files and registering hooks');
return addHooks(_this, transactions, function(addHooksError) {
if (addHooksError) {
return callback(addHooksError);
}
logger.verbose('Executing HTTP transactions');
return _this.executeAllTransactions(transactions, _this.hooks, callback);
});
};
})(this));
};
TransactionRunner.prototype.executeAllTransactions = function(transactions, hooks, callback) {
var i, len, transaction;
...executeTransaction = function (transaction, hooks, callback) {
var m, ref, ref1, ref2, test;
if (!callback) {
ref = [hooks, void 0], callback = ref[0], hooks = ref[1];
}
transaction.startedAt = Date.now();
test = this.createTest(transaction);
logger.debug('Emitting to reporters: test start');
this.configuration.emitter.emit('test start', test, function() {});
this.ensureTransactionResultsGeneralSection(transaction);
if (transaction.skip) {
logger.verbose('HTTP transaction was marked in hooks as to be skipped. Skipping');
transaction.test = test;
this.skipTransaction(transaction, 'Skipped in before hook');
return callback();
} else if (transaction.fail) {
logger.verbose('HTTP transaction was marked in hooks as to be failed. Reporting as failed');
transaction.test = test;
this.failTransaction(transaction, "Failed in before hook: " + transaction.fail);
return callback();
} else if (this.configuration.options['dry-run']) {
logger.info('Dry run. Not performing HTTP request');
transaction.test = test;
this.skipTransaction(transaction);
return callback();
} else if (this.configuration.options.names) {
logger.info(transaction.name);
transaction.test = test;
this.skipTransaction(transaction);
return callback();
} else if (this.configuration.options.method.length > 0 && !(ref1 = transaction.request.method, indexOf.call(this.configuration
.options.method, ref1) >= 0)) {
logger.info("Only " + (((function() {
var i, len, ref2, results1;
ref2 = this.configuration.options.method;
results1 = [];
for (i = 0, len = ref2.length; i < len; i++) {
m = ref2[i];
results1.push(m.toUpperCase());
}
return results1;
}).call(this)).join(', ')) + "requests are set to be executed. Not performing HTTP " + (transaction.request.method.toUpperCase
()) + " request.");
transaction.test = test;
this.skipTransaction(transaction);
return callback();
} else if (this.configuration.options.only.length > 0 && !(ref2 = transaction.name, indexOf.call(this.configuration.options.only
, ref2) >= 0)) {
logger.info("Only '" + this.configuration.options.only + "' transaction is set to be executed. Not performing HTTP request for
'" + transaction.name + "'.");
transaction.test = test;
this.skipTransaction(transaction);
return callback();
} else {
return this.performRequestAndValidate(test, transaction, hooks, callback);
}
}...
return iterationCallback(_this.hookHandlerError);
}
logger.verbose('Running \'before\' hooks');
return _this.runHooksForData(hooks.beforeHooks[transaction.name], transaction, false, function() {
if (_this.hookHandlerError) {
return iterationCallback(_this.hookHandlerError);
}
return _this.executeTransaction(transaction, hooks, function() {
if (_this.hookHandlerError) {
return iterationCallback(_this.hookHandlerError);
}
logger.verbose('Running \'afterEach\' hooks');
return _this.runHooksForData(hooks.afterEachHooks, transaction, false, function() {
if (_this.hookHandlerError) {
return iterationCallback(_this.hookHandlerError);
...failTransaction = function (transaction, reason) {
var base;
transaction.fail = true;
this.ensureTransactionResultsGeneralSection(transaction);
if (reason) {
transaction.results.general.results.push({
severity: 'error',
message: reason
});
}
if (transaction.test == null) {
transaction.test = this.createTest(transaction);
}
transaction.test.status = 'fail';
if (reason) {
transaction.test.message = reason;
}
return (base = transaction.test).results != null ? base.results : base.results = transaction.results;
}...
}
} catch (error1) {
error = error1;
if (error instanceof chai.AssertionError) {
transactions = Array.isArray(data) ? data : [data];
for (i = 0, len = transactions.length; i < len; i++) {
transaction = transactions[i];
_this.failTransaction(transaction, "Failed assertion in hooks: " + error
.message);
}
} else {
logger.debug('Hook errored:', error);
_this.emitHookError(error, data);
}
return runHookCallback();
}
...getFullPath = function (serverPath, requestPath) {
var segment, segments, trailingSlash;
if (serverPath === '/') {
return requestPath;
}
if (!requestPath) {
return serverPath;
}
segments = [serverPath, requestPath];
segments = (function() {
var i, len, results1;
results1 = [];
for (i = 0, len = segments.length; i < len; i++) {
segment = segments[i];
results1.push(segment.replace(/^\/|\/$/g, ''));
}
return results1;
})();
trailingSlash = requestPath !== '/' && requestPath.slice(-1) === '/' ? '/' : '';
return '/' + segments.join('/') + trailingSlash;
}...
var configuration, configuredTransaction, expected, flatHeaders, fullPath, header, headerKey, headerValue, i, len, mediaType, origin
, ref, ref1, request, response, skip, splitIndex, status, system;
configuration = this.configuration;
origin = transaction.origin, request = transaction.request, response = transaction.response;
mediaType = ((ref = configuration.data[origin.filename]) != null ? ref.mediaType : void 0) || 'text/vnd.apiblueprint';
if (this.parsedUrl == null) {
this.parsedUrl = this.parseServerUrl(configuration.server);
}
fullPath = this.getFullPath(this.parsedUrl.path, request.uri);
flatHeaders = flattenHeaders(request['headers']);
if (!flatHeaders['User-Agent']) {
system = os.type() + ' ' + os.release() + '; ' + os.arch();
flatHeaders['User-Agent'] = "Dredd/" + packageData.version + " (" + system + ")";
}
if (configuration.options.header.length > 0) {
ref1 = configuration.options.header;
...getRequestOptionsFromTransaction = function (transaction) {
var options, urlObject;
urlObject = {
protocol: transaction.protocol,
hostname: transaction.host,
port: transaction.port
};
options = clone(this.configuration.http || {});
options.uri = url.format(urlObject) + transaction.fullPath;
options.method = transaction.request.method;
options.headers = transaction.request.headers;
options.body = transaction.request.body;
options.proxy = false;
return options;
}...
return headers['Content-Length'] = body ? Buffer.byteLength(body) : 0;
}
};
TransactionRunner.prototype.performRequestAndValidate = function(test, transaction, hooks, callback) {
var error, handleRequest, requestOptions;
this.setContentLength(transaction);
requestOptions = this.getRequestOptionsFromTransaction(transaction);
handleRequest = (function(_this) {
return function(err, res, body) {
var real;
if (err) {
logger.debug('Requesting tested server errored:', ("" + err) || err.code);
test.title = transaction.id;
test.expected = transaction.expected;
...isMultipart = function (requestOptions) {
var caseInsensitiveRequestHeaders, key, ref, ref1, value;
caseInsensitiveRequestHeaders = {};
ref = requestOptions.headers;
for (key in ref) {
value = ref[key];
caseInsensitiveRequestHeaders[key.toLowerCase()] = value;
}
return ((ref1 = caseInsensitiveRequestHeaders['content-type']) != null ? ref1.indexOf("multipart") : void 0) > -1;
}...
return callback(_this.hookHandlerError);
}
return _this.validateTransaction(test, transaction, callback);
});
});
};
})(this);
if (transaction.request['body'] && this.isMultipart(requestOptions
)) {
this.replaceLineFeedInBody(transaction, requestOptions);
}
try {
return this.performRequest(requestOptions, handleRequest);
} catch (error1) {
error = error1;
logger.debug('Requesting tested server errored:', error);
...parseServerUrl = function (serverUrl) {
if (!serverUrl.match(/^https?:\/\//i)) {
serverUrl = 'http://' + serverUrl.replace(/^[:\/]*/, '');
}
return url.parse(serverUrl);
}...
TransactionRunner.prototype.configureTransaction = function(transaction, callback) {
var configuration, configuredTransaction, expected, flatHeaders, fullPath, header, headerKey, headerValue, i, len, mediaType, origin
, ref, ref1, request, response, skip, splitIndex, status, system;
configuration = this.configuration;
origin = transaction.origin, request = transaction.request, response = transaction.response;
mediaType = ((ref = configuration.data[origin.filename]) != null ? ref.mediaType : void 0) || 'text/vnd.apiblueprint';
if (this.parsedUrl == null) {
this.parsedUrl = this.parseServerUrl(configuration.server);
}
fullPath = this.getFullPath(this.parsedUrl.path, request.uri);
flatHeaders = flattenHeaders(request['headers']);
if (!flatHeaders['User-Agent']) {
system = os.type() + ' ' + os.release() + '; ' + os.arch();
flatHeaders['User-Agent'] = "Dredd/" + packageData.version + " (" + system + ")";
}
...performRequest = function (options, callback) {
var protocol;
protocol = options.uri.split(':')[0].toUpperCase();
logger.verbose("About to perform an " + protocol + " request to the server under test: " + options.method + " " + options.uri);
return requestLib(options, callback);
}...
});
};
})(this);
if (transaction.request['body'] && this.isMultipart(requestOptions)) {
this.replaceLineFeedInBody(transaction, requestOptions);
}
try {
return this.performRequest(requestOptions, handleRequest);
} catch (error1) {
error = error1;
logger.debug('Requesting tested server errored:', error);
test.title = transaction.id;
test.expected = transaction.expected;
test.request = transaction.request;
this.emitError(error, test);
...performRequestAndValidate = function (test, transaction, hooks, callback) {
var error, handleRequest, requestOptions;
this.setContentLength(transaction);
requestOptions = this.getRequestOptionsFromTransaction(transaction);
handleRequest = (function(_this) {
return function(err, res, body) {
var real;
if (err) {
logger.debug('Requesting tested server errored:', ("" + err) || err.code);
test.title = transaction.id;
test.expected = transaction.expected;
test.request = transaction.request;
_this.emitError(err, test);
return callback();
}
logger.verbose('Handling HTTP response from tested server');
real = {
statusCode: res.statusCode,
headers: res.headers,
body: body
};
transaction['real'] = real;
logger.verbose('Running \'beforeEachValidation\' hooks');
return _this.runHooksForData(hooks != null ? hooks.beforeEachValidationHooks : void 0, transaction, false, function() {
if (_this.hookHandlerError) {
return callback(_this.hookHandlerError);
}
logger.verbose('Running \'beforeValidation\' hooks');
return _this.runHooksForData(hooks != null ? hooks.beforeValidationHooks[transaction.name] : void 0, transaction, false,
function() {
if (_this.hookHandlerError) {
return callback(_this.hookHandlerError);
}
return _this.validateTransaction(test, transaction, callback);
});
});
};
})(this);
if (transaction.request['body'] && this.isMultipart(requestOptions)) {
this.replaceLineFeedInBody(transaction, requestOptions);
}
try {
return this.performRequest(requestOptions, handleRequest);
} catch (error1) {
error = error1;
logger.debug('Requesting tested server errored:', error);
test.title = transaction.id;
test.expected = transaction.expected;
test.request = transaction.request;
this.emitError(error, test);
return callback();
}
}...
return callback();
} else if (this.configuration.options.only.length > 0 && !(ref2 = transaction.name, indexOf.call(this.configuration
.options.only, ref2) >= 0)) {
logger.info("Only '" + this.configuration.options.only + "' transaction is set to be executed. Not
performing HTTP request for '" + transaction.name + "'.");
transaction.test = test;
this.skipTransaction(transaction);
return callback();
} else {
return this.performRequestAndValidate(test, transaction, hooks, callback);
}
};
TransactionRunner.prototype.setContentLength = function(transaction) {
var body, calculatedContentLengthValue, contentLengthHeaderName, contentLengthValue, headers;
headers = transaction.request.headers;
body = transaction.request.body;
...replaceLineFeedInBody = function (transaction, requestOptions) {
if (transaction.request['body'].indexOf('\r\n') === -1) {
transaction.request['body'] = transaction.request['body'].replace(/\n/g, '\r\n');
transaction.request['headers']['Content-Length'] = Buffer.byteLength(transaction.request['body'], 'utf8');
return requestOptions.headers = transaction.request['headers'];
}
}...
}
return _this.validateTransaction(test, transaction, callback);
});
});
};
})(this);
if (transaction.request['body'] && this.isMultipart(requestOptions)) {
this.replaceLineFeedInBody(transaction, requestOptions);
}
try {
return this.performRequest(requestOptions, handleRequest);
} catch (error1) {
error = error1;
logger.debug('Requesting tested server errored:', error);
test.title = transaction.id;
...run = function (transactions, callback) {
logger.verbose('Sorting HTTP transactions');
transactions = this.configuration.options['sorted'] ? sortTransactions(transactions) : transactions;
logger.verbose('Configuring HTTP transactions');
return async.mapSeries(transactions, this.configureTransaction.bind(this), (function(_this) {
return function(err, results) {
transactions = results;
logger.verbose('Reading hook files and registering hooks');
return addHooks(_this, transactions, function(addHooksError) {
if (addHooksError) {
return callback(addHooksError);
}
logger.verbose('Executing HTTP transactions');
return _this.executeAllTransactions(transactions, _this.hooks, callback);
});
};
})(this));
}...
}
};
DreddCommand.prototype.runExitingActions = function() {
if (this.argv["_"][0] === "init" || this.argv.init === true) {
logger.silly('Starting interactive configuration.');
this.finished = true;
return interactiveConfig.run(this.argv, (function(_this) {
return function(config) {
configUtils.save(config);
console.log("");
console.log("Configuration saved to dredd.yml");
console.log("");
if (config['language'] === "nodejs") {
console.log("Run test now, with:");
...runHook = function (hook, data, callback) {
if (typeof hook === 'function') {
if (hook.length === 1) {
hook(data);
callback();
} else if (hook.length === 2) {
hook(data, function() {
return callback();
});
}
}
if (typeof hook === 'string') {
return this.runSandboxedHookFromString(hook, data, callback);
}
}...
if (err) {
logger.debug('Legacy hook errored:', err);
_this.emitHookError(err, data);
}
return runHookCallback();
});
} else {
return _this.runHook(hookFn, data, function(err) {
if (err) {
logger.debug('Hook errored:', err);
_this.emitHookError(err, data);
}
return runHookCallback();
});
}
...runHooksForData = function (hooks, data, legacy, callback) {
var runHookWithData;
if (legacy == null) {
legacy = false;
}
if ((hooks != null) && Array.isArray(hooks)) {
logger.debug('Running hooks...');
runHookWithData = (function(_this) {
return function(hookFnIndex, runHookCallback) {
var error, hookFn, i, len, transaction, transactions;
hookFn = hooks[hookFnIndex];
try {
if (legacy) {
return _this.runLegacyHook(hookFn, data, function(err) {
if (err) {
logger.debug('Legacy hook errored:', err);
_this.emitHookError(err, data);
}
return runHookCallback();
});
} else {
return _this.runHook(hookFn, data, function(err) {
if (err) {
logger.debug('Hook errored:', err);
_this.emitHookError(err, data);
}
return runHookCallback();
});
}
} catch (error1) {
error = error1;
if (error instanceof chai.AssertionError) {
transactions = Array.isArray(data) ? data : [data];
for (i = 0, len = transactions.length; i < len; i++) {
transaction = transactions[i];
_this.failTransaction(transaction, "Failed assertion in hooks: " + error.message);
}
} else {
logger.debug('Hook errored:', error);
_this.emitHookError(error, data);
}
return runHookCallback();
}
};
})(this);
return async.timesSeries(hooks.length, runHookWithData, function() {
return callback();
});
} else {
return callback();
}
}...
hooks.transactions[transaction.name] = transaction;
}
}
if (this.hookHandlerError) {
return callback(this.hookHandlerError);
}
logger.verbose('Running \'beforeAll\' hooks');
return this.runHooksForData(hooks.beforeAllHooks, transactions, true, (function(_this
) {
return function() {
if (_this.hookHandlerError) {
return callback(_this.hookHandlerError);
}
return async.timesSeries(transactions.length, function(transactionIndex, iterationCallback) {
transaction = transactions[transactionIndex];
logger.verbose("Processing transaction #" + (transactionIndex + 1) + ":", transaction.name);
...runLegacyHook = function (hook, data, callback) {
if (typeof hook === 'function') {
if (hook.length === 1) {
logger.warn('DEPRECATION WARNING!\n\nYou are using only one argument for the `beforeAll` or `afterAll` hook function.\nOne
argument hook functions will be treated as synchronous in the near future.\nTo keep the async behaviour, just define hook function with two parameters.\n\nInterface of the hooks functions will be unified soon across all hook functions:\n\n - `beforeAll` and `afterAll` hooks will support sync API depending on number of arguments\n - Signatures of callbacks of all hooks will be the same\n - First passed argument will be a `transactions` object\n - Second passed argument will be a optional callback function for async\n - `transactions` object in `hooks` module object will be removed\n - Manipulation with transaction data will have to be performed on the first function argument');
hook(callback);
} else if (hook.length === 2) {
hook(data, function() {
return callback();
});
}
}
if (typeof hook === 'string') {
return this.runSandboxedHookFromString(hook, data, callback);
}
}...
logger.debug('Running hooks...');
runHookWithData = (function(_this) {
return function(hookFnIndex, runHookCallback) {
var error, hookFn, i, len, transaction, transactions;
hookFn = hooks[hookFnIndex];
try {
if (legacy) {
return _this.runLegacyHook(hookFn, data, function(err) {
if (err) {
logger.debug('Legacy hook errored:', err);
_this.emitHookError(err, data);
}
return runHookCallback();
});
} else {
...runSandboxedHookFromString = function (hookString, data, callback) {
var sandbox, wrappedCode;
wrappedCode = this.sandboxedWrappedCode(hookString);
sandbox = new Pitboss(wrappedCode, {
timeout: 500
});
return sandbox.run({
context: {
'_data': data,
'_logs': [],
'stash': this.hookStash
},
libraries: {
'_log': sandboxedLogLibraryPath
}
}, (function(_this) {
return function(err, result) {
if (result == null) {
result = {};
}
sandbox.kill();
return _this.sandboxedHookResultsHandler(err, data, result, callback);
};
})(this));
}...
} else if (hook.length === 2) {
hook(data, function() {
return callback();
});
}
}
if (typeof hook === 'string') {
return this.runSandboxedHookFromString(hook, data, callback);
}
};
TransactionRunner.prototype.runHook = function(hook, data, callback) {
if (typeof hook === 'function') {
if (hook.length === 1) {
hook(data);
...sandboxedHookResultsHandler = function (err, data, results, callback) {
var i, key, len, log, ref, ref1, value;
if (results == null) {
results = {};
}
if (err) {
return callback(err);
}
ref = results.data || {};
for (key in ref) {
value = ref[key];
data[key] = value;
}
this.hookStash = results.stash;
if (this.logs == null) {
this.logs = [];
}
ref1 = results.logs || [];
for (i = 0, len = ref1.length; i < len; i++) {
log = ref1[i];
this.logs.push(log);
}
while (Date.now() - results.now < 0) {}
callback();
}...
}
}, (function(_this) {
return function(err, result) {
if (result == null) {
result = {};
}
sandbox.kill();
return _this.sandboxedHookResultsHandler(err, data, result, callback);
};
})(this));
};
TransactionRunner.prototype.runLegacyHook = function(hook, data, callback) {
if (typeof hook === 'function') {
if (hook.length === 1) {
...sandboxedWrappedCode = function (hookCode) {
return "// run the hook\nvar log = _log.bind(null, _logs);\n\nvar _func = " + hookCode + ";\n_func(_data);\n\n// setup the return
object\nvar output = {};\noutput[\"data\"] = _data;\noutput[\"stash\"] = stash;\noutput[\"logs\"] = _logs;\noutput[\"now\"] = Date.now();\noutput;";
}...
TransactionRunner.prototype.sandboxedWrappedCode = function(hookCode) {
return "// run the hook\nvar log = _log.bind(null, _logs);\n\nvar _func = " + hookCode + ";\n_func(_data);\n\n//
setup the return object\nvar output = {};\noutput[\"data\"] = _data;\noutput[\"stash\"] = stash;\noutput[\"logs\"] = _logs;\noutput[\"now\"] = Date.now();\noutput;";
};
TransactionRunner.prototype.runSandboxedHookFromString = function(hookString, data, callback) {
var sandbox, wrappedCode;
wrappedCode = this.sandboxedWrappedCode(hookString);
sandbox = new Pitboss(wrappedCode, {
timeout: 500
});
return sandbox.run({
context: {
'_data': data,
'_logs': [],
...setContentLength = function (transaction) {
var body, calculatedContentLengthValue, contentLengthHeaderName, contentLengthValue, headers;
headers = transaction.request.headers;
body = transaction.request.body;
contentLengthHeaderName = caseless(headers).has('Content-Length');
if (contentLengthHeaderName) {
contentLengthValue = parseInt(headers[contentLengthHeaderName], 10);
if (body) {
calculatedContentLengthValue = Buffer.byteLength(body);
if (contentLengthValue !== calculatedContentLengthValue) {
logger.warn("Specified Content-Length header is " + contentLengthValue + ", but the real body length is " + calculatedContentLengthValue
+ ". Using " + calculatedContentLengthValue + " instead.");
return headers[contentLengthHeaderName] = calculatedContentLengthValue;
}
} else if (contentLengthValue !== 0) {
logger.warn("Specified Content-Length header is " + contentLengthValue + ", but the real body length is 0. Using 0 instead
.");
return headers[contentLengthHeaderName] = 0;
}
} else {
return headers['Content-Length'] = body ? Buffer.byteLength(body) : 0;
}
}...
} else {
return headers['Content-Length'] = body ? Buffer.byteLength(body) : 0;
}
};
TransactionRunner.prototype.performRequestAndValidate = function(test, transaction, hooks, callback) {
var error, handleRequest, requestOptions;
this.setContentLength(transaction);
requestOptions = this.getRequestOptionsFromTransaction(transaction);
handleRequest = (function(_this) {
return function(err, res, body) {
var real;
if (err) {
logger.debug('Requesting tested server errored:', ("" + err) || err.code);
test.title = transaction.id;
...skipTransaction = function (transaction, reason) {
var base;
transaction.skip = true;
this.ensureTransactionResultsGeneralSection(transaction);
if (reason) {
transaction.results.general.results.push({
severity: 'warning',
message: reason
});
}
if (transaction.test == null) {
transaction.test = this.createTest(transaction);
}
transaction.test.status = 'skip';
if (reason) {
transaction.test.message = reason;
}
return (base = transaction.test).results != null ? base.results : base.results = transaction.results;
}...
test = this.createTest(transaction);
logger.debug('Emitting to reporters: test start');
this.configuration.emitter.emit('test start', test, function() {});
this.ensureTransactionResultsGeneralSection(transaction);
if (transaction.skip) {
logger.verbose('HTTP transaction was marked in hooks as to be skipped. Skipping');
transaction.test = test;
this.skipTransaction(transaction, 'Skipped in before hook');
return callback();
} else if (transaction.fail) {
logger.verbose('HTTP transaction was marked in hooks as to be failed. Reporting as failed');
transaction.test = test;
this.failTransaction(transaction, "Failed in before hook: " + transaction.fail);
return callback();
} else if (this.configuration.options['dry-run']) {
...validateTransaction = function (test, transaction, callback) {
var configuration;
configuration = this.configuration;
logger.verbose('Validating HTTP transaction by Gavel.js');
logger.debug('Determining whether HTTP transaction is valid (getting boolean verdict)');
return gavel.isValid(transaction.real, transaction.expected, 'response', function(isValidError, isValid) {
if (isValidError) {
logger.debug('Gavel.js validation errored:', isValidError);
this.emitError(isValidError, test);
}
test.title = transaction.id;
test.actual = transaction.real;
test.expected = transaction.expected;
test.request = transaction.request;
if (isValid) {
test.status = 'pass';
} else {
test.status = 'fail';
}
logger.debug('Validating HTTP transaction (getting verbose validation result)');
return gavel.validate(transaction.real, transaction.expected, 'response', function(validateError, gavelResult) {
var gavelError, i, len, message, rawValidatorOutput, ref, ref1, results, sectionName, validatorOutput;
if (!isValidError && validateError) {
logger.debug('Gavel.js validation errored:', validateError);
this.emitError(validateError, test);
}
message = '';
ref = gavelResult || {};
for (sectionName in ref) {
if (!hasProp.call(ref, sectionName)) continue;
validatorOutput = ref[sectionName];
if (sectionName !== 'version') {
ref1 = validatorOutput.results || [];
for (i = 0, len = ref1.length; i < len; i++) {
gavelError = ref1[i];
message += sectionName + ": " + gavelError.message + "\n";
}
}
}
test.message = message;
results = transaction.results || {};
for (sectionName in gavelResult) {
if (!hasProp.call(gavelResult, sectionName)) continue;
rawValidatorOutput = gavelResult[sectionName];
if (!(sectionName !== 'version')) {
continue;
}
if (results[sectionName] == null) {
results[sectionName] = {};
}
validatorOutput = clone(rawValidatorOutput);
if (results[sectionName].results) {
validatorOutput.results = validatorOutput.results.concat(results[sectionName].results);
}
results[sectionName] = validatorOutput;
}
transaction.results = results;
test.results = transaction.results;
test.valid = isValid;
transaction.test = test;
return callback();
});
});
}...
return callback(_this.hookHandlerError);
}
logger.verbose('Running \'beforeValidation\' hooks');
return _this.runHooksForData(hooks != null ? hooks.beforeValidationHooks[transaction.name] : void 0, transaction, false, function
() {
if (_this.hookHandlerError) {
return callback(_this.hookHandlerError);
}
return _this.validateTransaction(test, transaction, callback);
});
});
};
})(this);
if (transaction.request['body'] && this.isMultipart(requestOptions)) {
this.replaceLineFeedInBody(transaction, requestOptions);
}
...which = function (command) {
var e;
try {
which.sync(command);
return true;
} catch (error) {
e = error;
return false;
}
}...
};
HooksWorkerClient.prototype.setCommandAndCheckForExecutables = function(callback) {
var gobin, msg, parsedArgs;
if (this.language === 'ruby') {
this.handlerCommand = 'dredd-hooks-ruby';
this.handlerCommandArgs = [];
if (!which.which(this.handlerCommand)) {
msg = "Ruby hooks handler command not found: " + this.handlerCommand + "\nInstall ruby hooks handler by running
:\n$ gem install dredd_hooks";
return callback(new Error(msg));
} else {
return callback();
}
} else if (this.language === 'python') {
this.handlerCommand = 'dredd-hooks-python';
...