scenario.ext.params.js |
|
var _ = require('underscore'),
merge = require('deepmerge'),
q = require('q');
module.exports = function(parameterFactory, print) {
return function(ScenarioPrototype) {
ScenarioPrototype.initializers.push(function() {
this.parameters = [];
this.parameterLoaders = [];
this.parameterValues = {};
});
ScenarioPrototype.beforeRun.push(function(runOptions) {
return this.processParameters(runOptions);
});
|
|
¶ Runtime Parameters MethodsParameters can be passed as the |
_.extend(ScenarioPrototype, {
addParam: function(name, options) {
if (!_.isString(name)) {
throw new Error('Parameter name must be a string');
} else if (_.findWhere(this.parameters, { name: name })) {
throw new Error('The parameter "' + name + '" is already defined');
}
var param = parameterFactory(name, options);
this.parameters.push(param);
return param;
},
|
¶ #param(name, options)Returns the value of the parameter with the specified name.
|
param: function(name) {
return this.getParameterValue(name);
},
getParameter: function(name) {
return _.findWhere(this.parameters, { name: name });
},
getParameterValue: function(name) {
var parameter = this.getParameter(name);
this.checkParameterExists(parameter, name);
return this.parameterValues[name];
},
checkParameterExists: function(parameter, name) {
if (!parameter) {
throw new Error('Unknown parameter "' + name + '"; add it to the Scenario object with the `addParam` method');
}
},
loadParametersWith: function(loader) {
if (typeof(loader) !== 'function') {
throw new Error('Parameter loader must be a function');
}
this.parameterLoaders.push(loader);
},
processParameters: function(runOptions) {
return q.fcall(_.bind(this.loadParameters, this), runOptions).then(_.bind(this.ensureParameters, this, runOptions));
},
loadParameters: function(runOptions) {
this.parameterValues = {};
var parameterValues = _.extend({}, this.baseOptions.params, runOptions.params);
var promise = q(parameterValues);
_.each(this.parameterLoaders, function(loader, i) {
promise = promise.then(loader).then(_.bind(this.ensureParameterValues, this, i));
}, this);
return promise;
},
ensureParameterValues: function(loaderIndex, parameterValues) {
if (parameterValues === undefined) {
throw new Error('Parameter loading function at index ' + loaderIndex + ' returned nothing; it must return the updated runtime parameters');
} else if (!_.isObject(parameterValues)) {
throw new Error('Expected parameter loading function at index ' + loaderIndex + ' to return updated runtime parameters as an object, got ' + typeof(parameterValues));
}
return parameterValues;
},
ensureParameters: function(runOptions, parameterValues) {
_.each(_.union(_.pluck(this.parameters, 'name'), _.keys(parameterValues)), function(name) {
var parameter = this.getParameter(name);
this.checkParameterExists(parameter, name);
parameterValues[name] = parameter.processValues(parameterValues[name]);
}, this);
var invalidParameters = [];
var errors = _.reduce(this.parameters, function(memo, param) {
if (!param.validate(parameterValues[param.name], memo)) {
invalidParameters.push(param);
}
return memo;
}, [], this);
if (!errors.length) {
this.setRuntimeParameterValues(parameterValues, runOptions);
return q();
}
print();
print('The scenario cannot be run because the following parameters are either missing or invalid:'.yellow);
_.each(errors, function(error) {
print('- ' + error);
});
print();
print("Run `api-copilot info <scenario>` for help with this scenario's parameters.".green);
print('You will now be asked for the missing or corrected values.'.green);
print('Press Ctrl-C to quit.'.green);
return this.fixInvalidParameters(parameterValues, invalidParameters, runOptions);
},
setRuntimeParameterValues: function(parameterValues, runOptions) {
this.parameterValues = runOptions.params = parameterValues;
},
fixInvalidParameters: function(parameterValues, invalidParameters, runOptions) {
var promise = q();
_.each(invalidParameters, function(param) {
promise = promise.then(_.bind(param.prompt, param)).then(_.bind(this.setFixedParameter, this, parameterValues, param));
}, this);
return promise.then(_.bind(this.setRuntimeParameterValues, this, parameterValues, runOptions)).then(function() {
print("\n");
});
},
setFixedParameter: function(parameterValues, param, newValue) {
parameterValues[param.name] = newValue;
print(('Parameter ' + param.name.bold + ' set to:').green + ' ' + newValue);
}
});
};
};
module.exports['@require'] = [ 'parameter.factory', 'cli.print' ];
|