added filterPath support to master api and enhanced yaml testing

This commit is contained in:
Spencer Alger
2015-06-02 11:11:30 -07:00
parent 7d14e7d24e
commit 5e1da82688
9 changed files with 139 additions and 68 deletions

View File

@ -17,6 +17,10 @@ NOTE: the https://github.com/fullscale/elastic.js[elastic.js] library can be use
+
`Number, Number[]` -- HTTP status codes which should not be considered errors for this request.
`filterPath`::
+
`String|String[]` -- Starting in **elasticsearch 2.0** the `filterPath` parameter can be passed to any API to filter it's reponse values. See the https://www.elastic.co/guide/en/elasticsearch/reference/master/common-options.html#_response_filtering[elasticsearch response filtering docs] for more information.
=== Config values you can override per request
* `requestTimeout` -- <<config-request-timeout, more info>>
* `maxRetries` -- <<config-max-retries, more info>>

View File

@ -38,7 +38,10 @@ var config = {
},
integration: {
src: null
src: null,
options: {
reporter: 'spec'
}
},
jenkins_integration: {

View File

@ -64,7 +64,7 @@
"js-yaml": "~2.1.3",
"load-grunt-config": "~0.7.0",
"load-grunt-tasks": "~0.2.0",
"mocha": "~1.21.4",
"mocha": "^2.2.5",
"mocha-lcov-reporter": "0.0.1",
"mocha-screencast-reporter": "~0.1.4",
"moment": "~2.4.0",
@ -98,4 +98,4 @@
"node": ">=0.8 <=0.12",
"iojs": ">=1.5"
}
}
}

View File

@ -29,7 +29,7 @@ module.exports = function (branch, done) {
var m;
// master === the highest version number
if (branch === 'master') return '999.999.999';
if (branch === 'master') return '2.0.0';
// n.m -> n.m.0
if (m = branch.match(/^\d+\.\d+$/)) return branch + '.0';
// n.x -> n.(maxVersion + 1).0
@ -48,7 +48,8 @@ module.exports = function (branch, done) {
return _.merge(overrides, _.omit(rule, 'version'));
}, {
aliases: {},
paramAsBody: {}
paramAsBody: {},
clientActionModifier: false
});
var steps = [
@ -106,7 +107,8 @@ module.exports = function (branch, done) {
apiSpec = {
actions: groups.normal || [],
proxies: groups.proxies || [],
namespaces: _.unique(namespaces.sort(), true)
namespaces: _.unique(namespaces.sort(), true),
clientActionModifier: overrides.clientActionModifier
};
var create = _.assign({}, _.find(apiSpec.actions, { name: 'index' }), {

View File

@ -177,5 +177,26 @@ module.exports = [
'/{index}/_aliases/{name}'
]
}
},
{
version: '>=2.0.0',
/* jshint ignore:start */
// strange indentation makes pretty api files
clientActionModifier:
function (spec) {
return require('../utils').merge(spec, {
params: {
filterPath: {
type: 'list',
name: 'filter_path'
}
}
});
}
/* jshint ignore:end */
}
];

View File

@ -1,7 +1,11 @@
/* jshint maxlen: false */
var ca = require('../client_action').factory;
var proxy = require('../client_action').proxyFactory;
var ca = require('../client_action').<%
if (!clientActionModifier) print('factory');
else print('makeFactoryWithModifier(' + clientActionModifier.toString() + ')');
%>;
var namespace = require('../client_action').namespaceFactory;
var api = module.exports = {};

View File

@ -9,7 +9,7 @@ _.each(allParams, function(param, paramName) { %>
}
%><% }) %>
*/
api<%= (location[0] === '[' ? '' : '.') + location %> = proxy(<%= 'api' + (proxy[0] === '[' ? '' : '.') + proxy %><%
api<%= (location[0] === '[' ? '' : '.') + location %> = ca.proxy(<%= 'api' + (proxy[0] === '[' ? '' : '.') + proxy %><%
if (typeof transformBody === 'string') { %>, {
transform: function (params) {
<%= indent(transformBody, 4) %>

View File

@ -1,15 +1,23 @@
var _ = require('./utils');
/**
* Constructs a client action factory that uses specific defaults
* @type {Function}
*/
exports.makeFactoryWithModifier = makeFactoryWithModifier;
/**
* Constructs a function that can be called to make a request to ES
* @type {Function}
*/
exports.factory = factory;
exports.factory = makeFactoryWithModifier();
/**
* Constructs a proxy to another api method
* @type {Function}
*/
exports.proxyFactory = proxyFactory;
exports.proxyFactory = exports.factory.proxy;
// export so that we can test this
exports._resolveUrl = resolveUrl;
@ -25,60 +33,66 @@ exports.namespaceFactory = function () {
return ClientNamespace;
};
var _ = require('./utils');
function makeFactoryWithModifier(modifier) {
modifier = modifier || _.identity;
function factory(spec) {
if (!_.isPlainObject(spec.params)) {
spec.params = {};
}
var factory = function (spec) {
spec = modifier(spec);
if (!spec.method) {
spec.method = 'GET';
}
function action(params, cb) {
if (typeof params === 'function') {
cb = params;
params = {};
} else {
params = params || {};
cb = typeof cb === 'function' ? cb : null;
if (!_.isPlainObject(spec.params)) {
spec.params = {};
}
try {
return exec(this.transport, spec, _.clone(params), cb);
} catch (e) {
if (typeof cb === 'function') {
_.nextTick(cb, e);
if (!spec.method) {
spec.method = 'GET';
}
function action(params, cb) {
if (typeof params === 'function') {
cb = params;
params = {};
} else {
var def = this.transport.defer();
def.reject(e);
return def.promise;
params = params || {};
cb = typeof cb === 'function' ? cb : null;
}
try {
return exec(this.transport, spec, _.clone(params), cb);
} catch (e) {
if (typeof cb === 'function') {
_.nextTick(cb, e);
} else {
var def = this.transport.defer();
def.reject(e);
return def.promise;
}
}
}
}
action.spec = spec;
action.spec = spec;
return action;
}
function proxyFactory(fn, spec) {
return function (params, cb) {
if (typeof params === 'function') {
cb = params;
params = {};
} else {
params = params || {};
cb = typeof cb === 'function' ? cb : null;
}
if (spec.transform) {
spec.transform(params);
}
return fn.call(this, params, cb);
return action;
};
factory.proxy = function (fn, spec) {
return function (params, cb) {
if (typeof params === 'function') {
cb = params;
params = {};
} else {
params = params || {};
cb = typeof cb === 'function' ? cb : null;
}
if (spec.transform) {
spec.transform(params);
}
return fn.call(this, params, cb);
};
};
return factory;
}
var castType = {
@ -288,9 +302,7 @@ function exec(transport, spec, params, cb) {
}, []);
}
var key, paramSpec;
for (key in params) {
for (var key in params) {
if (params.hasOwnProperty(key) && params[key] != null) {
switch (key) {
case 'body':
@ -305,7 +317,7 @@ function exec(transport, spec, params, cb) {
request.method = _.toUpperString(params[key]);
break;
default:
paramSpec = spec.params[key];
var paramSpec = spec.params[key];
if (paramSpec) {
// param keys don't always match the param name, in those cases it's stored in the param def as "name"
paramSpec.name = paramSpec.name || key;

View File

@ -12,7 +12,7 @@ var expect = require('expect.js');
var clientManager = require('./client_manager');
var inspect = require('util').inspect;
var implementedFeatures = ['gtelte', 'regex', 'benchmark'];
var implementedFeatures = ['gtelte', 'regex', 'benchmark', 'stash_in_path'];
/**
* The version that ES is running, in comparable string form XXX-XXX-XXX, fetched when needed
@ -239,21 +239,25 @@ YamlDoc.prototype = {
* @return {*} - The value requested, or undefined if it was not found
*/
get: function (path, from) {
var self = this;
var log = process.env.LOG_GETS && !from ? console.log.bind(console) : function () {};
var i;
if (path === '$body') {
// shortcut, the test just wants the whole body
return this._last_requests_response;
return self._last_requests_response;
} else if (path) {
path = path.replace(/\.\$([a-zA-Z0-9_]+)/g, function (m, name) {
return '.' + self._stash[name];
});
}
if (!from) {
if (path[0] === '$') {
from = this._stash;
from = self._stash;
path = path.substring(1);
} else {
from = this._last_requests_response;
from = self._last_requests_response;
}
}
@ -331,6 +335,15 @@ YamlDoc.prototype = {
do_do: function (args, done) {
var catcher;
if (process.env.LOG_DO) {
var __done = done;
done = function (err, resp) {
console.log('doing', clientActionName, 'with', params);
console.log('got', resp);
__done(err, resp);
};
}
// resolve the catch arg to a value used for matching once the request is complete
switch (args.catch) {
case void 0:
@ -475,7 +488,12 @@ YamlDoc.prototype = {
* @return {undefined}
*/
do_is_true: function (path) {
expect(Boolean(this.get(path))).to.be(true, 'path: ' + path);
var val = this.get(path);
try {
expect(Boolean(val)).to.be(true, 'path: ' + path);
} catch (e) {
throw new Error('expected path "' + path + '" to be true but got ' + val);
}
},
/**
@ -486,7 +504,12 @@ YamlDoc.prototype = {
* @return {undefined}
*/
do_is_false: function (path) {
expect(Boolean(this.get(path))).to.be(false, 'path: ' + path);
var val = this.get(path);
try {
expect(Boolean(val)).to.be(false, 'path: ' + path);
} catch (e) {
throw new Error('expected path "' + path + '" to be false but got ' + val);
}
},
/**
@ -529,8 +552,10 @@ YamlDoc.prototype = {
return _.each(val, recurse);
}
if (_.isString(val) && val[0] === '$') {
lvl[key] = self.get(val);
if (_.isString(val)) {
lvl[key] = val.replace(/\$[a-zA-Z0-9_]+/g, function (name) {
return self.get(name);
});
}
});