[tests] added test for aggConfig#toDsl() and related functions

This commit is contained in:
Spencer Alger 2014-09-03 15:36:53 -07:00
parent 9dd0c0bd5d
commit 8afeea1ff3
7 changed files with 508 additions and 2 deletions

View file

@ -7,10 +7,12 @@ define(function (require) {
_(AggConfigs).inherits(Registry);
function AggConfigs(vis, configStates) {
this.vis = vis;
AggConfigs.Super.call(this, {
index: ['id'],
group: ['schema.group'],
group: ['schema.group', 'type.name'],
initialSet: (configStates || []).map(function (aggConfigState) {
if (aggConfigState instanceof AggConfig) return aggConfigState;
return new AggConfig(vis, aggConfigState);
})
});

View file

@ -88,7 +88,8 @@
'specs/index_patterns/_flatten_search_response',
'specs/utils/registry/index',
'specs/directives/filter_bar',
'specs/components/agg_types/index'
'specs/components/agg_types/index',
'specs/components/vis/index'
], function (kibana, sinon) {
kibana.load(function () {
var xhr = sinon.useFakeXMLHttpRequest();

View file

@ -0,0 +1,193 @@
define(function (require) {
return ['bucketCountBetween util', function () {
var _ = require('lodash');
var indexPattern;
var Vis;
var visTypes;
var aggTypes;
var AggConfig;
var bucketCountBetween;
// http://cwestblog.com/2014/02/25/javascript-testing-for-negative-zero/
// works for -0 and +0
function isNegative(n) {
return ((n = +n) || 1 / n) < 0;
}
beforeEach(module('kibana'));
beforeEach(inject(function (Private) {
indexPattern = Private(require('fixtures/stubbed_logstash_index_pattern'));
Vis = Private(require('components/vis/vis'));
visTypes = Private(require('components/vis_types/index'));
aggTypes = Private(require('components/agg_types/index'));
AggConfig = Private(require('components/vis/_agg_config'));
bucketCountBetween = Private(require('components/agg_types/buckets/_bucket_count_between'));
}));
it('returns a positive number when a is before b', function () {
var vis = new Vis(indexPattern, {
type: 'histogram',
aggs: [
{
type: 'date_histogram',
schema: 'segment'
},
{
type: 'terms',
schema: 'segment'
}
]
});
var a = vis.aggs.byTypeName.date_histogram[0];
var b = vis.aggs.byTypeName.terms[0];
var count = bucketCountBetween(a, b);
expect(isNegative(count)).to.be(false);
});
it('returns a negative number when a is after b', function () {
var vis = new Vis(indexPattern, {
type: 'histogram',
aggs: [
{
type: 'date_histogram',
schema: 'segment'
},
{
type: 'terms',
schema: 'segment'
}
]
});
var a = vis.aggs.byTypeName.terms[0];
var b = vis.aggs.byTypeName.date_histogram[0];
var count = bucketCountBetween(a, b);
expect(isNegative(count)).to.be(true);
});
it('returns 0 when there are no buckets between a and b', function () {
var vis = new Vis(indexPattern, {
type: 'histogram',
aggs: [
{
type: 'date_histogram',
schema: 'segment'
},
{
type: 'terms',
schema: 'segment'
}
]
});
var a = vis.aggs.byTypeName.date_histogram[0];
var b = vis.aggs.byTypeName.terms[0];
expect(bucketCountBetween(a, b)).to.be(0);
});
it('returns null when b is not in the aggs', function () {
var vis = new Vis(indexPattern, {
type: 'histogram',
aggs: [
{
type: 'date_histogram',
schema: 'segment'
}
]
});
var a = vis.aggs.byTypeName.date_histogram[0];
var b = new AggConfig(vis, {
type: 'terms',
schema: 'segment'
});
expect(bucketCountBetween(a, b)).to.be(null);
});
it('returns null when a is not in the aggs', function () {
var vis = new Vis(indexPattern, {
type: 'histogram',
aggs: [
{
type: 'date_histogram',
schema: 'segment'
}
]
});
var a = new AggConfig(vis, {
type: 'terms',
schema: 'segment'
});
var b = vis.aggs.byTypeName.date_histogram[0];
expect(bucketCountBetween(a, b)).to.be(null);
});
it('returns null when a and b are not in the aggs', function () {
var vis = new Vis(indexPattern, {
type: 'histogram',
aggs: []
});
var a = new AggConfig(vis, {
type: 'terms',
schema: 'segment'
});
var b = new AggConfig(vis, {
type: 'date_histogram',
schema: 'segment'
});
expect(bucketCountBetween(a, b)).to.be(null);
});
it('can count', function () {
var schemas = visTypes.byName.histogram.schemas.buckets;
// slow for this test is actually somewhere around 1/2 a sec
this.slow(500);
function randBucketAggForVis(vis) {
var schema = _.sample(schemas);
var aggType = _.sample(aggTypes.byType.buckets);
return new AggConfig(vis, {
schema: schema,
type: aggType
});
}
_.times(50, function (n) {
var vis = new Vis(indexPattern, {
type: 'histogram',
aggs: []
});
var randBucketAgg = _.partial(randBucketAggForVis, vis);
var a = randBucketAgg();
var b = randBucketAgg();
// create n aggs between a and b
var aggs = [];
for (var i = 0; i < n; i++) {
aggs.push(randBucketAgg());
}
aggs.unshift(a);
aggs.push(b);
vis.setState({
type: 'histogram',
aggs: aggs
});
expect(bucketCountBetween(a, b)).to.be(n);
});
});
}];
});

View file

@ -3,6 +3,7 @@ define(function (require) {
var childSuites = [
require('specs/components/agg_types/_agg_type'),
require('specs/components/agg_types/_agg_params'),
require('specs/components/agg_types/_bucket_count_between'),
require('specs/components/agg_types/bucket_aggs/histogram'),
require('specs/components/agg_types/bucket_aggs/date_histogram'),
require('specs/components/agg_types/_metric_aggs')

View file

@ -0,0 +1,106 @@
define(function (require) {
return ['AggConfig', function () {
var sinon = require('test_utils/auto_release_sinon');
var Vis;
var AggConfig;
var indexPattern;
beforeEach(module('kibana'));
beforeEach(inject(function (Private) {
Vis = Private(require('components/vis/vis'));
AggConfig = Private(require('components/vis/_agg_config'));
indexPattern = Private(require('fixtures/stubbed_logstash_index_pattern'));
}));
describe('#toDsl', function () {
it('calls #write()', function () {
var vis = new Vis(indexPattern, {
type: 'histogram',
aggs: [
{
type: 'date_histogram',
schema: 'segment'
}
]
});
var aggConfig = vis.aggs.byTypeName.date_histogram[0];
var stub = sinon.stub(aggConfig, 'write').returns({ params: {} });
aggConfig.toDsl();
expect(stub.callCount).to.be(1);
});
it('uses the type name as the agg name', function () {
var vis = new Vis(indexPattern, {
type: 'histogram',
aggs: [
{
type: 'date_histogram',
schema: 'segment'
}
]
});
var aggConfig = vis.aggs.byTypeName.date_histogram[0];
sinon.stub(aggConfig, 'write').returns({ params: {} });
var dsl = aggConfig.toDsl();
expect(dsl).to.have.property('date_histogram');
});
it('uses the params from #write() output as the agg params', function () {
var vis = new Vis(indexPattern, {
type: 'histogram',
aggs: [
{
type: 'date_histogram',
schema: 'segment'
}
]
});
var aggConfig = vis.aggs.byTypeName.date_histogram[0];
var football = {};
sinon.stub(aggConfig, 'write').returns({ params: football });
var dsl = aggConfig.toDsl();
expect(dsl.date_histogram).to.be(football);
});
it('includes subAggs from #write() output', function () {
var vis = new Vis(indexPattern, {
type: 'histogram',
aggs: [
{
type: 'avg',
schema: 'metric'
},
{
type: 'date_histogram',
schema: 'segment'
}
]
});
var histoConfig = vis.aggs.byTypeName.date_histogram[0];
var avgConfig = vis.aggs.byTypeName.avg[0];
var football = {};
sinon.stub(histoConfig, 'write').returns({ params: {}, subAggs: [avgConfig] });
sinon.stub(avgConfig, 'write').returns({ params: football });
var dsl = histoConfig.toDsl();
// didn't use .eql() because of variable key names, and final check is strict
expect(dsl).to.have.property('aggs');
expect(dsl.aggs).to.have.property(avgConfig.id);
expect(dsl.aggs[avgConfig.id]).to.have.property('avg');
expect(dsl.aggs[avgConfig.id].avg).to.be(football);
});
});
}];
});

View file

@ -0,0 +1,193 @@
define(function (require) {
return ['AggConfigs', function () {
var _ = require('lodash');
var sinon = require('test_utils/auto_release_sinon');
var Vis;
var Registry;
var AggConfig;
var AggConfigs;
var SpiedAggConfig;
var indexPattern;
beforeEach(module('kibana'));
beforeEach(inject(function (Private) {
// replace the AggConfig module with a spy
var RealAggConfigPM = require('components/vis/_agg_config');
AggConfig = Private(RealAggConfigPM);
Private.stub(RealAggConfigPM, sinon.spy(AggConfig));
// load main deps
Vis = Private(require('components/vis/vis'));
SpiedAggConfig = Private(require('components/vis/_agg_config'));
AggConfigs = Private(require('components/vis/_agg_configs'));
Registry = require('utils/registry/registry');
indexPattern = Private(require('fixtures/stubbed_logstash_index_pattern'));
}));
it('extends Registry', function () {
var ac = new AggConfigs();
expect(ac).to.be.a(Registry);
});
describe('constructor', function () {
it('handles passing just a vis', function () {
var vis = new Vis(indexPattern, {
type: 'histogram',
aggs: []
});
var ac = new AggConfigs(vis);
expect(ac).to.have.length(0);
});
it('converts configStates into AggConfig objects if they are not already', function () {
var vis = new Vis(indexPattern, {
type: 'histogram',
aggs: []
});
var ac = new AggConfigs(vis, [
{
type: 'date_histogram',
schema: 'segment'
},
new AggConfig({
type: 'terms',
schema: 'split'
})
]);
expect(ac).to.have.length(2);
expect(SpiedAggConfig).to.have.property('callCount', 1);
});
});
describe('#getSorted', function () {
it('performs a stable sort, but moves metrics to the bottom', function () {
var vis = new Vis(indexPattern, {
type: 'histogram',
aggs: [
{ type: 'avg', schema: 'metric' },
{ type: 'terms', schema: 'split' },
{ type: 'histogram', schema: 'split' },
{ type: 'sum', schema: 'metric' },
{ type: 'date_histogram', schema: 'segment' },
{ type: 'filters', schema: 'split' },
{ type: 'count', schema: 'metric' }
]
});
var avg = vis.aggs.byTypeName.avg[0];
var sum = vis.aggs.byTypeName.sum[0];
var count = vis.aggs.byTypeName.count[0];
var terms = vis.aggs.byTypeName.terms[0];
var histo = vis.aggs.byTypeName.histogram[0];
var dateHisto = vis.aggs.byTypeName.date_histogram[0];
var filters = vis.aggs.byTypeName.filters[0];
var sorted = vis.aggs.getSorted();
expect(sorted.shift()).to.be(terms);
expect(sorted.shift()).to.be(histo);
expect(sorted.shift()).to.be(dateHisto);
expect(sorted.shift()).to.be(filters);
expect(sorted.shift()).to.be(avg);
expect(sorted.shift()).to.be(sum);
expect(sorted.shift()).to.be(count);
expect(sorted).to.have.length(0);
});
});
describe('#toDsl', function () {
it('uses the sorted aggs', function () {
var vis = new Vis(indexPattern, { type: 'histogram' });
sinon.spy(vis.aggs, 'getSorted');
vis.aggs.toDsl();
expect(vis.aggs.getSorted).to.have.property('callCount', 1);
});
it('calls aggConfig#toDsl() on each aggConfig and compiles the nested output', function () {
var vis = new Vis(indexPattern, {
type: 'histogram',
aggs: [
{ type: 'date_histogram', schema: 'segment' },
{ type: 'filters', schema: 'split' }
]
});
var aggInfos = vis.aggs.map(function (aggConfig) {
var football = {};
sinon.stub(aggConfig, 'toDsl', function () {
return football;
});
return {
id: aggConfig.id,
football: football
};
});
(function recurse(lvl) {
var info = aggInfos.shift();
expect(lvl).to.have.property(info.id);
expect(lvl[info.id]).to.be(info.football);
if (lvl[info.id].aggs) {
return recurse(lvl[info.id].aggs);
}
}(vis.aggs.toDsl()));
expect(aggInfos).to.have.length(0);
});
it('skips aggs that don\'t have a dsl representation', function () {
var vis = new Vis(indexPattern, {
type: 'histogram',
aggs: [
{ type: 'date_histogram', schema: 'segment', params: { field: '@timestamp' } },
{ type: 'count', schema: 'metric' }
]
});
var dsl = vis.aggs.toDsl();
var histo = vis.aggs.byTypeName.date_histogram[0];
var count = vis.aggs.byTypeName.count[0];
expect(dsl).to.have.property(histo.id);
expect(dsl[histo.id]).to.be.an('object');
expect(dsl[histo.id]).to.not.have.property('aggs');
expect(dsl).to.not.have.property(count.id);
});
it('writes multiple metric aggregations at the same level', function () {
var vis = new Vis(indexPattern, {
type: 'histogram',
aggs: [
{ type: 'date_histogram', schema: 'segment', params: { field: '@timestamp' } },
{ type: 'avg', schema: 'metric', params: { field: 'bytes' } },
{ type: 'sum', schema: 'metric', params: { field: 'bytes' } },
{ type: 'min', schema: 'metric', params: { field: 'bytes' } },
{ type: 'max', schema: 'metric', params: { field: 'bytes' } }
]
});
var dsl = vis.aggs.toDsl();
var histo = vis.aggs.byTypeName.date_histogram[0];
var metrics = vis.aggs.bySchemaGroup.metrics;
expect(dsl).to.have.property(histo.id);
expect(dsl[histo.id]).to.be.an('object');
expect(dsl[histo.id]).to.have.property('aggs');
metrics.forEach(function (metric) {
expect(dsl[histo.id].aggs).to.have.property(metric.id);
expect(dsl[histo.id].aggs[metric.id]).to.not.have.property('aggs');
});
});
});
}];
});

View file

@ -0,0 +1,10 @@
define(function (require) {
describe('Vis Component', function () {
var childSuites = [
require('specs/components/vis/_agg_config'),
require('specs/components/vis/_agg_configs')
].forEach(function (s) {
describe(s[0], s[1]);
});
});
});